private-attribute-cpp 2.1.0__tar.gz → 2.1.2__tar.gz
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.
- {private_attribute_cpp-2.1.0/private_attribute_cpp.egg-info → private_attribute_cpp-2.1.2}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/private_attribute.cpp +126 -40
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/setup.py +1 -1
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/LICENSE +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/README.md +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/picosha2.h +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/private_attribute.pyi +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/setup.cfg +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_wrap.py +0 -0
{private_attribute_cpp-2.1.0/private_attribute_cpp.egg-info → private_attribute_cpp-2.1.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: A Python package that provides a way to define private attributes in C++ implementation.
|
|
5
5
|
Home-page: https://github.com/Locked-chess-official/private_attribute_cpp
|
|
6
6
|
Author: HuangHaoHua
|
|
@@ -125,6 +125,10 @@ public:
|
|
|
125
125
|
PyObjectStorage(PyObject* obj) noexcept : obj(obj) {
|
|
126
126
|
Py_XINCREF(obj);
|
|
127
127
|
}
|
|
128
|
+
// support for PyCodeObject*
|
|
129
|
+
PyObjectStorage(PyCodeObject* obj) noexcept : obj(reinterpret_cast<PyObject*>(obj)) {
|
|
130
|
+
Py_XINCREF(obj);
|
|
131
|
+
}
|
|
128
132
|
PyObjectStorage(const PyObjectStorage& other) noexcept : obj(other.obj) {
|
|
129
133
|
Py_XINCREF(obj);
|
|
130
134
|
}
|
|
@@ -155,13 +159,26 @@ public:
|
|
|
155
159
|
obj = new_obj;
|
|
156
160
|
return *this;
|
|
157
161
|
}
|
|
158
|
-
|
|
162
|
+
PyObjectStorage& operator=(PyCodeObject* new_obj) noexcept {
|
|
163
|
+
Py_XINCREF(reinterpret_cast<PyObject*>(new_obj));
|
|
159
164
|
Py_XDECREF(obj);
|
|
165
|
+
obj = reinterpret_cast<PyObject*>(new_obj);
|
|
166
|
+
return *this;
|
|
167
|
+
}
|
|
168
|
+
~PyObjectStorage() noexcept {
|
|
169
|
+
// if python has exit we don't do anything
|
|
170
|
+
if (Py_IsInitialized()) {
|
|
171
|
+
Py_XDECREF(obj);
|
|
172
|
+
}
|
|
160
173
|
}
|
|
161
174
|
|
|
162
175
|
operator PyObject*() const noexcept {
|
|
163
176
|
return obj;
|
|
164
177
|
}
|
|
178
|
+
|
|
179
|
+
operator PyCodeObject*() const noexcept {
|
|
180
|
+
return reinterpret_cast<PyCodeObject*>(obj);
|
|
181
|
+
}
|
|
165
182
|
PyObject* get() const noexcept {
|
|
166
183
|
return obj;
|
|
167
184
|
}
|
|
@@ -176,12 +193,8 @@ namespace {
|
|
|
176
193
|
namespace {
|
|
177
194
|
static std::unordered_map<uintptr_t, std::unordered_map<std::string, PyObjectStorage>> type_attr_dict;
|
|
178
195
|
};
|
|
179
|
-
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t,
|
|
196
|
+
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t, PyObjectStorage>> type_allowed_code_map;
|
|
180
197
|
static std::unordered_map<uintptr_t, std::shared_ptr<std::shared_mutex>> all_type_mutex;
|
|
181
|
-
// private_func per type, stored with RAII ownership (PyObjectStorage
|
|
182
|
-
// INCREFs on assignment and DECREFs on destruction), so the map entry
|
|
183
|
-
// always owns exactly one reference - no dangling-pointer risk when the
|
|
184
|
-
// last external reference to the function disappears.
|
|
185
198
|
static std::unordered_map<uintptr_t, PyObjectStorage> type_need_call;
|
|
186
199
|
static std::unordered_map<uintptr_t, std::unordered_set<TwoStringTuple>> all_type_attr_set;
|
|
187
200
|
namespace {
|
|
@@ -210,9 +223,34 @@ namespace {
|
|
|
210
223
|
static std::unordered_map<uintptr_t, destructor> all_type_finalize;
|
|
211
224
|
|
|
212
225
|
static std::shared_mutex all_register_new_metaclass_mutex;
|
|
213
|
-
static std::unordered_map<uintptr_t,
|
|
226
|
+
static std::unordered_map<uintptr_t, PyObjectStorage> all_register_type_weak_ref;
|
|
214
227
|
};
|
|
215
228
|
};
|
|
229
|
+
|
|
230
|
+
static void
|
|
231
|
+
clean_all_storages() noexcept
|
|
232
|
+
{
|
|
233
|
+
AllData::cache.clear();
|
|
234
|
+
AllData::all_exist_name.clear();
|
|
235
|
+
AllData::obj_attr_keys.clear();
|
|
236
|
+
AllData::type_attr_dict.clear();
|
|
237
|
+
AllData::type_allowed_code_map.clear();
|
|
238
|
+
AllData::all_type_mutex.clear();
|
|
239
|
+
AllData::type_need_call.clear();
|
|
240
|
+
AllData::all_type_attr_set.clear();
|
|
241
|
+
AllData::all_object_attr.clear();
|
|
242
|
+
AllData::all_type_subclass_attr.clear();
|
|
243
|
+
AllData::all_object_mutex.clear();
|
|
244
|
+
AllData::all_type_subclass_mutex.clear();
|
|
245
|
+
AllData::all_type_parent_id.clear();
|
|
246
|
+
AllData::all_type_getattro.clear();
|
|
247
|
+
AllData::all_type_setattro.clear();
|
|
248
|
+
AllData::all_type_traverse.clear();
|
|
249
|
+
AllData::all_type_clear.clear();
|
|
250
|
+
AllData::all_type_finalize.clear();
|
|
251
|
+
AllData::all_register_type_weak_ref.clear();
|
|
252
|
+
}
|
|
253
|
+
|
|
216
254
|
struct FinalObject
|
|
217
255
|
{
|
|
218
256
|
PyObjectStorage result;
|
|
@@ -1623,6 +1661,21 @@ PrivateAttr_tp_clear(PyObject* self) noexcept
|
|
|
1623
1661
|
return 0;
|
|
1624
1662
|
}
|
|
1625
1663
|
|
|
1664
|
+
// get_type_need_tp_* : the metaclass counterparts of get_need_tp_*.
|
|
1665
|
+
// get_need_tp_* -> find the original slots of *types created by* the
|
|
1666
|
+
// metaclasses (wrapped with the instance-level
|
|
1667
|
+
// PrivateAttr_tp_* / PrivateAttr_tp_getattro set).
|
|
1668
|
+
// get_type_need_tp_* -> find the original slots of the *metaclasses*
|
|
1669
|
+
// themselves (wrapped with the metaclass-level
|
|
1670
|
+
// PrivateAttrType_getattr / PrivateAttrType_setattr /
|
|
1671
|
+
// register_finalize / PrivateAttrType_tp_traverse /
|
|
1672
|
+
// PrivateAttrType_tp_clear).
|
|
1673
|
+
static getattrofunc get_type_need_tp_getattro(PyTypeObject* cls) noexcept;
|
|
1674
|
+
static setattrofunc get_type_need_tp_setattro(PyTypeObject* cls) noexcept;
|
|
1675
|
+
static traverseproc get_type_need_tp_traverse(PyTypeObject* cls) noexcept;
|
|
1676
|
+
static inquiry get_type_need_tp_clear(PyTypeObject* cls) noexcept;
|
|
1677
|
+
static destructor get_type_need_tp_finalize(PyTypeObject* cls) noexcept;
|
|
1678
|
+
|
|
1626
1679
|
// metaclass-level (type object) traverse/clear: call original if any, and handle AllData-stored type attributes
|
|
1627
1680
|
static int
|
|
1628
1681
|
PrivateAttrType_tp_traverse(PyObject* self, visitproc visit, void* arg) noexcept
|
|
@@ -1644,7 +1697,7 @@ PrivateAttrType_tp_traverse(PyObject* self, visitproc visit, void* arg) noexcept
|
|
|
1644
1697
|
if (res) return res;
|
|
1645
1698
|
}
|
|
1646
1699
|
} else {
|
|
1647
|
-
traverseproc orig =
|
|
1700
|
+
traverseproc orig = get_type_need_tp_traverse(typ);
|
|
1648
1701
|
if (orig) {
|
|
1649
1702
|
int res = orig(self, visit, arg);
|
|
1650
1703
|
if (res) return res;
|
|
@@ -1731,7 +1784,7 @@ PrivateAttrType_tp_clear(PyObject* self) noexcept
|
|
|
1731
1784
|
inquiry orig = ::AllData::all_type_clear[typ_id];
|
|
1732
1785
|
if (orig) orig(self);
|
|
1733
1786
|
} else {
|
|
1734
|
-
inquiry orig =
|
|
1787
|
+
inquiry orig = get_type_need_tp_clear(typ);
|
|
1735
1788
|
if (orig) orig(self);
|
|
1736
1789
|
}
|
|
1737
1790
|
|
|
@@ -1815,8 +1868,8 @@ static PyTypeObject PrivateAttrType = {
|
|
|
1815
1868
|
0, // tp_as_buffer
|
|
1816
1869
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, // tp_flags
|
|
1817
1870
|
"metaclass for private attributes", // tp_doc
|
|
1818
|
-
|
|
1819
|
-
|
|
1871
|
+
(traverseproc)PrivateAttrType_tp_traverse, // tp_travers
|
|
1872
|
+
(inquiry)PrivateAttrType_tp_clear, // tp_clear
|
|
1820
1873
|
0, // tp_richcompare
|
|
1821
1874
|
0, // tp_weaklistoffset
|
|
1822
1875
|
0, // tp_iter
|
|
@@ -2048,7 +2101,7 @@ try_get_attr_string(PyObject* obj, const char* name) noexcept
|
|
|
2048
2101
|
}
|
|
2049
2102
|
|
|
2050
2103
|
static void
|
|
2051
|
-
analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t,
|
|
2104
|
+
analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyObjectStorage>& map, std::unordered_set<uintptr_t>& _seen) noexcept
|
|
2052
2105
|
{
|
|
2053
2106
|
uintptr_t obj_id = (uintptr_t)obj;
|
|
2054
2107
|
if (_seen.find(obj_id) != _seen.end()) {
|
|
@@ -2056,8 +2109,7 @@ analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyCodeObject*>& ma
|
|
|
2056
2109
|
}
|
|
2057
2110
|
_seen.insert(obj_id);
|
|
2058
2111
|
if (PyObject_TypeCheck(obj, &PyCode_Type)) {
|
|
2059
|
-
|
|
2060
|
-
map[(uintptr_t)obj] = (PyCodeObject*)obj;
|
|
2112
|
+
map[(uintptr_t)obj] = obj;
|
|
2061
2113
|
PyObject* co_contain = try_get_attr_string(obj, "co_consts");
|
|
2062
2114
|
if (co_contain && PySequence_Check(co_contain)) {
|
|
2063
2115
|
Py_ssize_t len = PySequence_Length(co_contain);
|
|
@@ -2218,11 +2270,11 @@ need_analyse_type(PyObject* type) noexcept
|
|
|
2218
2270
|
}
|
|
2219
2271
|
std::shared_lock lock(::AllData::all_register_new_metaclass_mutex);
|
|
2220
2272
|
for (auto& [id, metaclassref]: ::AllData::all_register_type_weak_ref){
|
|
2221
|
-
if (!PyWeakref_CheckRef(metaclassref)) {
|
|
2273
|
+
if (!PyWeakref_CheckRef((PyObject*)metaclassref)) {
|
|
2222
2274
|
continue;
|
|
2223
2275
|
}
|
|
2224
2276
|
#if PY_VERSION_HEX < 0x030D0000
|
|
2225
|
-
PyObject* metaclass = PyWeakref_GET_OBJECT(metaclassref);
|
|
2277
|
+
PyObject* metaclass = PyWeakref_GET_OBJECT((PyObject*)metaclassref);
|
|
2226
2278
|
if (type == metaclass) continue;
|
|
2227
2279
|
if (PyObject_IsInstance(type, metaclass)) {
|
|
2228
2280
|
return true;
|
|
@@ -2505,21 +2557,6 @@ static traverseproc get_need_tp_traverse(PyTypeObject* cls) noexcept;
|
|
|
2505
2557
|
static inquiry get_need_tp_clear(PyTypeObject* cls) noexcept;
|
|
2506
2558
|
static destructor get_need_tp_finalize(PyTypeObject* cls) noexcept;
|
|
2507
2559
|
|
|
2508
|
-
// get_type_need_tp_* : the metaclass counterparts of get_need_tp_*.
|
|
2509
|
-
// get_need_tp_* -> find the original slots of *types created by* the
|
|
2510
|
-
// metaclasses (wrapped with the instance-level
|
|
2511
|
-
// PrivateAttr_tp_* / PrivateAttr_tp_getattro set).
|
|
2512
|
-
// get_type_need_tp_* -> find the original slots of the *metaclasses*
|
|
2513
|
-
// themselves (wrapped with the metaclass-level
|
|
2514
|
-
// PrivateAttrType_getattr / PrivateAttrType_setattr /
|
|
2515
|
-
// register_finalize / PrivateAttrType_tp_traverse /
|
|
2516
|
-
// PrivateAttrType_tp_clear).
|
|
2517
|
-
static getattrofunc get_type_need_tp_getattro(PyTypeObject* cls) noexcept;
|
|
2518
|
-
static setattrofunc get_type_need_tp_setattro(PyTypeObject* cls) noexcept;
|
|
2519
|
-
static traverseproc get_type_need_tp_traverse(PyTypeObject* cls) noexcept;
|
|
2520
|
-
static inquiry get_type_need_tp_clear(PyTypeObject* cls) noexcept;
|
|
2521
|
-
static destructor get_type_need_tp_finalize(PyTypeObject* cls) noexcept;
|
|
2522
|
-
|
|
2523
2560
|
// instance-level traverse/clear for types that use private attributes
|
|
2524
2561
|
static int PrivateAttr_tp_traverse(PyObject* self, visitproc visit, void* arg) noexcept;
|
|
2525
2562
|
static int PrivateAttr_tp_clear(PyObject* self) noexcept;
|
|
@@ -2739,10 +2776,7 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2739
2776
|
}
|
|
2740
2777
|
|
|
2741
2778
|
if (data.private_func) {
|
|
2742
|
-
|
|
2743
|
-
// data's reference is released by PrivateAttrCreationData::clear()
|
|
2744
|
-
// right after this, and the map entry's reference is released when the
|
|
2745
|
-
// entry is erased in PrivateAttrType_finalize.
|
|
2779
|
+
Py_INCREF(data.private_func);
|
|
2746
2780
|
::AllData::type_need_call[type_id] = data.private_func;
|
|
2747
2781
|
}
|
|
2748
2782
|
|
|
@@ -3225,13 +3259,9 @@ PrivateAttrType_finalize(PyObject* cls) noexcept
|
|
|
3225
3259
|
::AllData::all_type_attr_set.erase(typ_id);
|
|
3226
3260
|
}
|
|
3227
3261
|
if (::AllData::type_allowed_code_map.find(typ_id) != ::AllData::type_allowed_code_map.end()) {
|
|
3228
|
-
for (auto& [id, obj] : ::AllData::type_allowed_code_map[typ_id]) {
|
|
3229
|
-
Py_XDECREF(obj);
|
|
3230
|
-
}
|
|
3231
3262
|
::AllData::type_allowed_code_map.erase(typ_id);
|
|
3232
3263
|
}
|
|
3233
3264
|
if (::AllData::type_need_call.find(typ_id) != ::AllData::type_need_call.end()) {
|
|
3234
|
-
// erase() destroys the PyObjectStorage, which DECREFs private_func.
|
|
3235
3265
|
::AllData::type_need_call.erase(typ_id);
|
|
3236
3266
|
}
|
|
3237
3267
|
if (::AllData::type_attr_dict.find(typ_id) != ::AllData::type_attr_dict.end()) {
|
|
@@ -3541,7 +3571,7 @@ is_class_of_registed_type(PyObject* metaclass) noexcept
|
|
|
3541
3571
|
continue;
|
|
3542
3572
|
}
|
|
3543
3573
|
#if PY_VERSION_HEX < 0x030D0000
|
|
3544
|
-
PyObject* instance = PyWeakref_GET_OBJECT(instanceref);
|
|
3574
|
+
PyObject* instance = PyWeakref_GET_OBJECT((PyObject*)instanceref);
|
|
3545
3575
|
if (instance == metaclass) continue;
|
|
3546
3576
|
if (PyObject_IsInstance(instance, metaclass)) {
|
|
3547
3577
|
return true;
|
|
@@ -4033,10 +4063,66 @@ static PyModuleDef def = {
|
|
|
4033
4063
|
NULL
|
|
4034
4064
|
};
|
|
4035
4065
|
|
|
4066
|
+
static PyObject*
|
|
4067
|
+
AtExit_clean_storage(PyObject* /*self*/, PyObject* /*obj*/) noexcept
|
|
4068
|
+
{
|
|
4069
|
+
clean_all_storages();
|
|
4070
|
+
Py_RETURN_NONE;
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
static PyMethodDef clean_storage = {
|
|
4074
|
+
"clean_storage",
|
|
4075
|
+
(PyCFunction)AtExit_clean_storage,
|
|
4076
|
+
METH_NOARGS,
|
|
4077
|
+
"Clean all storages"
|
|
4078
|
+
};
|
|
4079
|
+
|
|
4080
|
+
static int
|
|
4081
|
+
atexit_register_clean_func(void) noexcept
|
|
4082
|
+
{
|
|
4083
|
+
PyObject* atexit = PyImport_ImportModule("atexit");
|
|
4084
|
+
if (!atexit) {
|
|
4085
|
+
return -1;
|
|
4086
|
+
}
|
|
4087
|
+
PyObject* register_func = PyObject_GetAttrString(atexit, "register");
|
|
4088
|
+
if (!register_func) {
|
|
4089
|
+
Py_DECREF(atexit);
|
|
4090
|
+
return -1;
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4093
|
+
PyObject* func = PyCFunction_New(&clean_storage, NULL);
|
|
4094
|
+
if (!func) {
|
|
4095
|
+
Py_DECREF(register_func);
|
|
4096
|
+
Py_DECREF(atexit);
|
|
4097
|
+
return -1;
|
|
4098
|
+
}
|
|
4099
|
+
PyObject* args = PyTuple_New(1);
|
|
4100
|
+
if (!args) {
|
|
4101
|
+
Py_DECREF(func);
|
|
4102
|
+
Py_DECREF(register_func);
|
|
4103
|
+
Py_DECREF(atexit);
|
|
4104
|
+
return -1;
|
|
4105
|
+
}
|
|
4106
|
+
PyTuple_SET_ITEM(args, 0, func);
|
|
4107
|
+
PyObject* result = PyObject_CallObject(register_func, args);
|
|
4108
|
+
if (result == NULL) {
|
|
4109
|
+
Py_DECREF(args);
|
|
4110
|
+
Py_DECREF(register_func);
|
|
4111
|
+
Py_DECREF(atexit);
|
|
4112
|
+
return -1;
|
|
4113
|
+
}
|
|
4114
|
+
Py_DECREF(args);
|
|
4115
|
+
Py_DECREF(register_func);
|
|
4116
|
+
Py_DECREF(atexit);
|
|
4117
|
+
Py_DECREF(result);
|
|
4118
|
+
return 0;
|
|
4119
|
+
}
|
|
4120
|
+
|
|
4036
4121
|
PyMODINIT_FUNC
|
|
4037
4122
|
PyInit_private_attribute(void) noexcept
|
|
4038
4123
|
{
|
|
4039
4124
|
if (init_all_slots() <0 ||
|
|
4125
|
+
atexit_register_clean_func() < 0 ||
|
|
4040
4126
|
PyType_Ready(&PrivateWrapType) < 0 ||
|
|
4041
4127
|
PyType_Ready(&PrivateWrapProxyType) < 0 ||
|
|
4042
4128
|
PyType_Ready(&PrivateAttrType) < 0 ||
|
{private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2/private_attribute_cpp.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: A Python package that provides a way to define private attributes in C++ implementation.
|
|
5
5
|
Home-page: https://github.com/Locked-chess-official/private_attribute_cpp
|
|
6
6
|
Author: HuangHaoHua
|
|
@@ -18,7 +18,7 @@ readme = open('README.md').read()
|
|
|
18
18
|
|
|
19
19
|
setup(
|
|
20
20
|
name='private_attribute_cpp',
|
|
21
|
-
version='2.1.
|
|
21
|
+
version='2.1.2',
|
|
22
22
|
author="HuangHaoHua",
|
|
23
23
|
author_email="13140752715@example.com",
|
|
24
24
|
description='A Python package that provides a way to define private attributes in C++ implementation.',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_class_private_attrs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.1.0 → private_attribute_cpp-2.1.2}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|