Skip to content

Commit 97324a8

Browse files
committed
Work on probe API
1 parent 532aa13 commit 97324a8

File tree

5 files changed

+321
-107
lines changed

5 files changed

+321
-107
lines changed

jpype/_core.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ def removeShutdownHook(self, thread):
610610
# Dictionary of Type to Tuple(Interface[], Dict)
611611
_jpype._cache = weakref.WeakKeyDictionary()
612612
# Dictionary of Tuple(Interface[]) to Tuple(Interface[])
613-
_jpype._interfaces = {}
614-
# Dictionary of Tuple(Interface[]) to Dict
613+
_jpype._cache_interfaces = {}
614+
_jpype._cache_methods = {}
615+
# Dictionary of Tuple(Interface) to Dict
615616
_jpype._methods = {}

jpype/_jbridge.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ def _step(x):
537537

538538

539539
def initialize():
540+
return
540541
# Install the handler
541542
bridge = JClass("org.jpype.bridge.Interpreter").getInstance()
542543
Backend = JClass("org.jpype.bridge.Backend")

native/python/include/jp_pythontypes.h

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,45 +74,72 @@ typedef _object PyObject;
7474
*/
7575
class JPPyObject
7676
{
77-
/** Create a new reference to a Python object.
78-
*
79-
* @param obj is the python object.
80-
*/
77+
/**
78+
* Creates a new reference to a Python object.
79+
*
80+
* This constructor takes ownership of the provided Python object reference.
81+
* If the object is not null, the reference count is incremented to ensure
82+
* the object remains valid for the lifetime of the `JPPyObject` instance.
83+
*
84+
* @param obj A pointer to the Python object (`PyObject*`). May be null.
85+
*/
8186
explicit JPPyObject(PyObject* obj);
8287

8388
public:
84-
8589
/**
86-
* This policy is used if we need to hold a reference to an existing
87-
* object for some duration. The object may be null.
90+
* Creates a strong reference to an existing Python object for a limited duration.
91+
*
92+
* This policy is used when the caller needs to temporarily manage an existing
93+
* Python object. It can be applied to both existing references and "borrowed"
94+
* references returned by Python methods.
95+
*
96+
* If the object is not null, its reference count is incremented upon creation
97+
* and decremented when the `JPPyObject` instance is destroyed.
8898
*
89-
* Increment reference count if not null, and decrement when done.
99+
* @param obj A pointer to the Python object (`PyObject*`). Must not be null.
100+
* @return A `JPPyObject` instance managing the provided reference.
101+
* @throws std::runtime_error if the object is null.
90102
*/
91103
static JPPyObject use(PyObject* obj);
92104

93105
/**
94-
* This policy is used when we are given a new reference that we must
95-
* destroy. This will steal a reference.
106+
* Unconditionally takes ownership of a new Python object reference.
96107
*
97-
* claim reference, and decremented when done. Clears errors if NULL.
108+
* This policy is used when the caller is responsible for managing a new
109+
* Python object reference and transfers ownership to the `JPPyObject` instance.
110+
* If the object is null, any existing Python errors are cleared. The caller
111+
* must ensure the reference is valid before using this method.
112+
*
113+
* @param obj A pointer to the Python object (`PyObject*`). May be null.
114+
* @return A `JPPyObject` instance managing the provided reference.
98115
*/
99116
static JPPyObject accept(PyObject* obj);
100117

101118
/**
102-
* This policy is used when we are given a new reference that we must
103-
* destroy. This will steal a reference.
119+
* Takes ownership of a new Python object reference, ensuring it is not null.
120+
*
121+
* This policy is used when the caller is responsible for managing a new
122+
* Python object reference and transfers ownership to the `JPPyObject` instance.
123+
* If the object is null, an exception is thrown.
104124
*
105-
* Assert not null, claim reference, and decremented when done.
106-
* Will throw an exception in the object is null.
125+
* @param obj A pointer to the Python object (`PyObject*`). Must not be null.
126+
* @return A `JPPyObject` instance managing the provided reference.
127+
* @throws std::runtime_error if the object is null.
107128
*/
108129
static JPPyObject claim(PyObject* obj);
109130

110131
/**
111-
* This policy is used when we are capturing an object returned from a python
112-
* call that we are responsible for. This will steal a reference.
132+
* Captures and takes ownership of a Python object returned from a Python call.
133+
*
134+
* This policy is used when the caller is responsible for managing a Python
135+
* object returned from a Python call. Ownership of the reference is transferred
136+
* to the `JPPyObject` instance. Before claiming the reference, this method
137+
* first checks for Python errors and then ensures the object is not null.
138+
* If an error occurs or the object is null, an exception is thrown.
113139
*
114-
* Check for errors, assert not null, then claim.
115-
* Will throw an exception an error occurs.
140+
* @param obj A pointer to the Python object (`PyObject*`). Must not be null.
141+
* @return A `JPPyObject` instance managing the provided reference.
142+
* @throws std::runtime_error if the object is null or if a Python error occurs.
116143
*/
117144
static JPPyObject call(PyObject* obj);
118145

@@ -127,13 +154,23 @@ class JPPyObject
127154
JPPyObject& operator=(const JPPyObject& o);
128155

129156
/**
130-
* Keep an object by creating a reference.
157+
* Transfers ownership of the Python object reference.
131158
*
132-
* This should only appear in the return statement in the cpython module.
133-
* The reference must not be null. Keep invalidates this handle from any
134-
* further use as you were supposed to have called return.
159+
* This method is used to transfer control of an existing reference, such as:
160+
* - Returning a reference from a function.
161+
* - Passing a reference to a Python method that steals ownership of the reference.
135162
*
136-
* @return the pointer to the Python object.
163+
* Important Notes:
164+
* - The reference must not be null. If the reference is null, this method will raise
165+
* a SystemError exception.
166+
* - Calling `keep()` invalidates this handle, meaning the `JPPyObject` instance
167+
* should no longer be used after calling this method.
168+
* - This method does NOT increment the reference counter. Instead, it transfers
169+
* ownership of the existing reference to the caller. The caller is responsible
170+
* for managing the reference lifecycle (e.g., calling `Py_DECREF` when appropriate).
171+
*
172+
* @return A pointer to the Python object (`PyObject*`).
173+
* @throws PyExc_SystemError if the reference is null.
137174
*/
138175
PyObject* keep();
139176

@@ -153,6 +190,15 @@ class JPPyObject
153190
return m_PyObject;
154191
}
155192

193+
/** Determine if this python reference is valid.
194+
*
195+
* @returns true if is a valid reference.
196+
*/
197+
bool isValid() const
198+
{
199+
return m_PyObject != nullptr;
200+
}
201+
156202
/** Determine if this python reference is null.
157203
*
158204
* @returns true if null.

0 commit comments

Comments
 (0)