pynect 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +478 -2
- package/SECURITY.md +34 -0
- package/binding.gyp +60 -0
- package/dist/cli/codegen.d.ts +3 -0
- package/dist/cli/codegen.d.ts.map +1 -0
- package/dist/cli/codegen.js +543 -0
- package/dist/cli/codegen.js.map +1 -0
- package/dist/cli/sync.d.ts +3 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +48 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/config/project.d.ts +57 -0
- package/dist/config/project.d.ts.map +1 -0
- package/dist/config/project.js +176 -0
- package/dist/config/project.js.map +1 -0
- package/dist/core/IsolatedWorker.d.ts +39 -0
- package/dist/core/IsolatedWorker.d.ts.map +1 -0
- package/dist/core/IsolatedWorker.js +178 -0
- package/dist/core/IsolatedWorker.js.map +1 -0
- package/dist/core/PyCallable.d.ts +67 -0
- package/dist/core/PyCallable.d.ts.map +1 -0
- package/dist/core/PyCallable.js +104 -0
- package/dist/core/PyCallable.js.map +1 -0
- package/dist/core/PyContext.d.ts +76 -0
- package/dist/core/PyContext.d.ts.map +1 -0
- package/dist/core/PyContext.js +239 -0
- package/dist/core/PyContext.js.map +1 -0
- package/dist/core/PyIterator.d.ts +84 -0
- package/dist/core/PyIterator.d.ts.map +1 -0
- package/dist/core/PyIterator.js +243 -0
- package/dist/core/PyIterator.js.map +1 -0
- package/dist/core/PyModule.d.ts +53 -0
- package/dist/core/PyModule.d.ts.map +1 -0
- package/dist/core/PyModule.js +162 -0
- package/dist/core/PyModule.js.map +1 -0
- package/dist/core/PyProxy.d.ts +75 -0
- package/dist/core/PyProxy.d.ts.map +1 -0
- package/dist/core/PyProxy.js +563 -0
- package/dist/core/PyProxy.js.map +1 -0
- package/dist/core/PyRuntime.d.ts +112 -0
- package/dist/core/PyRuntime.d.ts.map +1 -0
- package/dist/core/PyRuntime.js +546 -0
- package/dist/core/PyRuntime.js.map +1 -0
- package/dist/env/PackageInstaller.d.ts +232 -0
- package/dist/env/PackageInstaller.d.ts.map +1 -0
- package/dist/env/PackageInstaller.js +628 -0
- package/dist/env/PackageInstaller.js.map +1 -0
- package/dist/env/ProjectEnvironment.d.ts +63 -0
- package/dist/env/ProjectEnvironment.d.ts.map +1 -0
- package/dist/env/ProjectEnvironment.js +379 -0
- package/dist/env/ProjectEnvironment.js.map +1 -0
- package/dist/env/PyfigAdapter.d.ts +32 -0
- package/dist/env/PyfigAdapter.d.ts.map +1 -0
- package/dist/env/PyfigAdapter.js +10 -0
- package/dist/env/PyfigAdapter.js.map +1 -0
- package/dist/env/PythonDetector.d.ts +48 -0
- package/dist/env/PythonDetector.d.ts.map +1 -0
- package/dist/env/PythonDetector.js +182 -0
- package/dist/env/PythonDetector.js.map +1 -0
- package/dist/env/PythonProvisioner.d.ts +16 -0
- package/dist/env/PythonProvisioner.d.ts.map +1 -0
- package/dist/env/PythonProvisioner.js +42 -0
- package/dist/env/PythonProvisioner.js.map +1 -0
- package/dist/env/VenvManager.d.ts +55 -0
- package/dist/env/VenvManager.d.ts.map +1 -0
- package/dist/env/VenvManager.js +153 -0
- package/dist/env/VenvManager.js.map +1 -0
- package/dist/env/executables.d.ts +3 -0
- package/dist/env/executables.d.ts.map +1 -0
- package/dist/env/executables.js +14 -0
- package/dist/env/executables.js.map +1 -0
- package/dist/index.d.ts +182 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +393 -0
- package/dist/index.js.map +1 -0
- package/dist/native/NativeAddonLoader.d.ts +11 -0
- package/dist/native/NativeAddonLoader.d.ts.map +1 -0
- package/dist/native/NativeAddonLoader.js +75 -0
- package/dist/native/NativeAddonLoader.js.map +1 -0
- package/dist/plugins/Plugin.interface.d.ts +41 -0
- package/dist/plugins/Plugin.interface.d.ts.map +1 -0
- package/dist/plugins/Plugin.interface.js +12 -0
- package/dist/plugins/Plugin.interface.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +26 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +174 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts +17 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.js +41 -0
- package/dist/plugins/builtin/NumpyPlugin.js.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts +19 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.js +57 -0
- package/dist/plugins/builtin/PandasPlugin.js.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts +23 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.js +50 -0
- package/dist/plugins/builtin/TorchPlugin.js.map +1 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +12 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/serialization/DataFrameBridge.d.ts +141 -0
- package/dist/serialization/DataFrameBridge.d.ts.map +1 -0
- package/dist/serialization/DataFrameBridge.js +355 -0
- package/dist/serialization/DataFrameBridge.js.map +1 -0
- package/dist/serialization/MsgPackSerializer.d.ts +45 -0
- package/dist/serialization/MsgPackSerializer.d.ts.map +1 -0
- package/dist/serialization/MsgPackSerializer.js +242 -0
- package/dist/serialization/MsgPackSerializer.js.map +1 -0
- package/dist/serialization/NumpyBridge.d.ts +96 -0
- package/dist/serialization/NumpyBridge.d.ts.map +1 -0
- package/dist/serialization/NumpyBridge.js +323 -0
- package/dist/serialization/NumpyBridge.js.map +1 -0
- package/dist/serialization/Serializer.d.ts +78 -0
- package/dist/serialization/Serializer.d.ts.map +1 -0
- package/dist/serialization/Serializer.js +281 -0
- package/dist/serialization/Serializer.js.map +1 -0
- package/dist/types/addon.d.ts +131 -0
- package/dist/types/addon.d.ts.map +1 -0
- package/dist/types/addon.js +32 -0
- package/dist/types/addon.js.map +1 -0
- package/dist/types/config.d.ts +233 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +60 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/python.d.ts +235 -0
- package/dist/types/python.d.ts.map +1 -0
- package/dist/types/python.js +7 -0
- package/dist/types/python.js.map +1 -0
- package/dist/utils/ErrorTranslator.d.ts +83 -0
- package/dist/utils/ErrorTranslator.d.ts.map +1 -0
- package/dist/utils/ErrorTranslator.js +210 -0
- package/dist/utils/ErrorTranslator.js.map +1 -0
- package/dist/utils/Locking.d.ts +3 -0
- package/dist/utils/Locking.d.ts.map +1 -0
- package/dist/utils/Locking.js +10 -0
- package/dist/utils/Locking.js.map +1 -0
- package/dist/utils/Logger.d.ts +27 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +115 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/MemoryMonitor.d.ts +43 -0
- package/dist/utils/MemoryMonitor.d.ts.map +1 -0
- package/dist/utils/MemoryMonitor.js +143 -0
- package/dist/utils/MemoryMonitor.js.map +1 -0
- package/package.json +114 -4
- package/python/ast_inspector.py +248 -0
- package/python/error_handler.py +432 -0
- package/python/isolated_worker.py +94 -0
- package/python/pynect_dispatcher.py +382 -0
- package/python/pynect_runtime.py +574 -0
- package/python/serializer.py +373 -0
- package/python/type_inspector.py +315 -0
- package/scripts/build-native.js +50 -0
- package/scripts/cli.js +21 -0
- package/scripts/ensure-native.js +85 -0
- package/scripts/postinstall.js +40 -0
- package/scripts/pyfig.js +113 -0
- package/scripts/python-provisioner.js +23 -0
- package/scripts/smoke-python-boundary.js +103 -0
- package/src/native/NativeAddonLoader.ts +98 -0
- package/src/native/gil_guard.cpp +25 -0
- package/src/native/gil_guard.h +174 -0
- package/src/native/pynect_addon.cpp +942 -0
- package/src/native/python_bridge.cpp +904 -0
- package/src/native/python_bridge.h +263 -0
- package/src/native/thread_pool.cpp +375 -0
- package/src/native/thread_pool.h +185 -0
- package/src/native/type_converter.cpp +906 -0
- package/src/native/type_converter.h +271 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pynect - GIL Guard Header
|
|
3
|
+
* RAII wrappers for the Python Global Interpreter Lock (GIL).
|
|
4
|
+
*
|
|
5
|
+
* The GIL ensures only one thread executes Python bytecode at a time.
|
|
6
|
+
* These guards make GIL management safe via RAII idiom.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <Python.h>
|
|
12
|
+
#include <stdexcept>
|
|
13
|
+
|
|
14
|
+
namespace pynect {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* GILAcquire - RAII guard that acquires the GIL on construction
|
|
18
|
+
* and releases it on destruction.
|
|
19
|
+
*
|
|
20
|
+
* Use when Python code needs to run in a non-Python thread (e.g. a worker thread).
|
|
21
|
+
* The calling thread must NOT already hold the GIL.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```cpp
|
|
25
|
+
* void worker_thread_func() {
|
|
26
|
+
* GILAcquire gil; // GIL acquired
|
|
27
|
+
* PyObject* result = PyEval_EvalCode(...);
|
|
28
|
+
* // GIL released when gil goes out of scope
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
class GILAcquire {
|
|
33
|
+
public:
|
|
34
|
+
GILAcquire() noexcept : _state(PyGILState_Ensure()) {}
|
|
35
|
+
~GILAcquire() noexcept { PyGILState_Release(_state); }
|
|
36
|
+
|
|
37
|
+
// Non-copyable, non-movable
|
|
38
|
+
GILAcquire(const GILAcquire&) = delete;
|
|
39
|
+
GILAcquire& operator=(const GILAcquire&) = delete;
|
|
40
|
+
GILAcquire(GILAcquire&&) = delete;
|
|
41
|
+
GILAcquire& operator=(GILAcquire&&) = delete;
|
|
42
|
+
|
|
43
|
+
private:
|
|
44
|
+
PyGILState_STATE _state;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* GILRelease - RAII guard that releases the GIL on construction
|
|
49
|
+
* and re-acquires it on destruction.
|
|
50
|
+
*
|
|
51
|
+
* Use to temporarily release the GIL while performing blocking I/O or
|
|
52
|
+
* other operations that don't need Python, allowing other Python threads to run.
|
|
53
|
+
* The calling thread MUST already hold the GIL.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```cpp
|
|
57
|
+
* // Inside Python-holding code:
|
|
58
|
+
* {
|
|
59
|
+
* GILRelease release; // GIL released - other Python threads can run
|
|
60
|
+
* perform_blocking_io();
|
|
61
|
+
* } // GIL re-acquired here
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
class GILRelease {
|
|
65
|
+
public:
|
|
66
|
+
GILRelease() noexcept : _state(PyEval_SaveThread()) {}
|
|
67
|
+
~GILRelease() noexcept { PyEval_RestoreThread(_state); }
|
|
68
|
+
|
|
69
|
+
// Non-copyable, non-movable
|
|
70
|
+
GILRelease(const GILRelease&) = delete;
|
|
71
|
+
GILRelease& operator=(const GILRelease&) = delete;
|
|
72
|
+
GILRelease(GILRelease&&) = delete;
|
|
73
|
+
GILRelease& operator=(GILRelease&&) = delete;
|
|
74
|
+
|
|
75
|
+
private:
|
|
76
|
+
PyThreadState* _state;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* PyRef - RAII wrapper for PyObject* reference counting.
|
|
81
|
+
*
|
|
82
|
+
* Automatically calls Py_XDECREF on destruction.
|
|
83
|
+
* Use steal() for objects returned from Python C API with new references.
|
|
84
|
+
* Use borrow() for borrowed references (won't decref).
|
|
85
|
+
*/
|
|
86
|
+
class PyRef {
|
|
87
|
+
public:
|
|
88
|
+
PyRef() noexcept : _obj(nullptr), _owned(false) {}
|
|
89
|
+
|
|
90
|
+
~PyRef() noexcept {
|
|
91
|
+
reset();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Take ownership of an object (new reference from Python API) */
|
|
95
|
+
static PyRef steal(PyObject* obj) noexcept {
|
|
96
|
+
PyRef ref;
|
|
97
|
+
ref._obj = obj;
|
|
98
|
+
ref._owned = true;
|
|
99
|
+
return ref;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Borrow a reference (will Py_INCREF and Py_DECREF) */
|
|
103
|
+
static PyRef borrow(PyObject* obj) noexcept {
|
|
104
|
+
PyRef ref;
|
|
105
|
+
ref._obj = obj;
|
|
106
|
+
ref._owned = false;
|
|
107
|
+
if (obj) {
|
|
108
|
+
Py_INCREF(obj);
|
|
109
|
+
ref._owned = true;
|
|
110
|
+
}
|
|
111
|
+
return ref;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Increment reference count and get raw pointer */
|
|
115
|
+
PyObject* incref() const noexcept {
|
|
116
|
+
Py_XINCREF(_obj);
|
|
117
|
+
return _obj;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Get raw pointer without changing reference count */
|
|
121
|
+
PyObject* get() const noexcept { return _obj; }
|
|
122
|
+
|
|
123
|
+
/** Release ownership without decrementing ref count */
|
|
124
|
+
PyObject* release() noexcept {
|
|
125
|
+
PyObject* obj = _obj;
|
|
126
|
+
_obj = nullptr;
|
|
127
|
+
_owned = false;
|
|
128
|
+
return obj;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Reset - decrements ref count if owned */
|
|
132
|
+
void reset() noexcept {
|
|
133
|
+
if (_owned && _obj) {
|
|
134
|
+
Py_DECREF(_obj);
|
|
135
|
+
}
|
|
136
|
+
_obj = nullptr;
|
|
137
|
+
_owned = false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Check if the object is valid (non-null) */
|
|
141
|
+
explicit operator bool() const noexcept { return _obj != nullptr; }
|
|
142
|
+
|
|
143
|
+
/** Check for Python exception state */
|
|
144
|
+
bool hasException() const noexcept {
|
|
145
|
+
return _obj == nullptr && PyErr_Occurred() != nullptr;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Non-copyable
|
|
149
|
+
PyRef(const PyRef&) = delete;
|
|
150
|
+
PyRef& operator=(const PyRef&) = delete;
|
|
151
|
+
|
|
152
|
+
// Movable
|
|
153
|
+
PyRef(PyRef&& other) noexcept : _obj(other._obj), _owned(other._owned) {
|
|
154
|
+
other._obj = nullptr;
|
|
155
|
+
other._owned = false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
PyRef& operator=(PyRef&& other) noexcept {
|
|
159
|
+
if (this != &other) {
|
|
160
|
+
reset();
|
|
161
|
+
_obj = other._obj;
|
|
162
|
+
_owned = other._owned;
|
|
163
|
+
other._obj = nullptr;
|
|
164
|
+
other._owned = false;
|
|
165
|
+
}
|
|
166
|
+
return *this;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private:
|
|
170
|
+
PyObject* _obj;
|
|
171
|
+
bool _owned;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
} // namespace pynect
|