private-attribute-cpp 2.1.12__tar.gz → 2.1.13__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.12/private_attribute_cpp.egg-info → private_attribute_cpp-2.1.13}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/private_attribute.cpp +94 -53
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/setup.py +1 -1
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/LICENSE +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/README.md +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/picosha2.h +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/private_attribute.pyi +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/setup.cfg +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_attr_classify_owner.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_gc_collect.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_wrap.py +0 -0
- {private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_slots_cycle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.13
|
|
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
|
|
@@ -194,14 +194,14 @@ namespace {
|
|
|
194
194
|
static std::unordered_map<uintptr_t, std::unordered_map<std::string, PyObjectStorage>> type_attr_dict;
|
|
195
195
|
};
|
|
196
196
|
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t, PyObjectStorage>> type_allowed_code_map;
|
|
197
|
-
static std::unordered_map<uintptr_t, std::
|
|
197
|
+
static std::unordered_map<uintptr_t, std::unique_ptr<std::shared_mutex>> all_type_mutex;
|
|
198
198
|
static std::unordered_map<uintptr_t, PyObjectStorage> type_need_call;
|
|
199
199
|
static std::unordered_map<uintptr_t, std::unordered_set<TwoStringTuple>> all_type_attr_set;
|
|
200
200
|
namespace {
|
|
201
201
|
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t,
|
|
202
202
|
std::unordered_map<std::string, PyObjectStorage>>> all_object_attr, all_type_subclass_attr;
|
|
203
203
|
};
|
|
204
|
-
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t, std::
|
|
204
|
+
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t, std::unique_ptr<std::shared_mutex>>>
|
|
205
205
|
all_object_mutex, all_type_subclass_mutex;
|
|
206
206
|
static std::mutex object_creatmutex_mutex, type_createmutex_mutex, type_parenttype_createmutex_mutex;
|
|
207
207
|
static std::unordered_map<uintptr_t, std::vector<uintptr_t>> all_type_parent_id;
|
|
@@ -224,7 +224,12 @@ namespace {
|
|
|
224
224
|
|
|
225
225
|
static std::shared_mutex all_register_new_metaclass_mutex;
|
|
226
226
|
static std::unordered_map<uintptr_t, PyObjectStorage> all_register_type_weak_ref;
|
|
227
|
-
|
|
227
|
+
// Single dict-backed strong-ref cache shared by the module itself (keyed by
|
|
228
|
+
// kModuleSelfKey) and by PrivateAttrBase (keyed by kPrivateAttrBaseKey),
|
|
229
|
+
// so clean_all_storages can release everything at interpreter shutdown.
|
|
230
|
+
static std::unordered_map<uintptr_t, PyObjectStorage> store_module_self;
|
|
231
|
+
static constexpr uintptr_t kModuleSelfKey = 0;
|
|
232
|
+
static constexpr uintptr_t kPrivateAttrBaseKey = 1;
|
|
228
233
|
};
|
|
229
234
|
};
|
|
230
235
|
|
|
@@ -237,11 +242,10 @@ object_create_mutex(uintptr_t final_id, uintptr_t obj_id) noexcept
|
|
|
237
242
|
::AllData::all_object_attr[final_id][obj_id] = {};
|
|
238
243
|
}
|
|
239
244
|
if (::AllData::all_object_mutex.find(final_id) == ::AllData::all_object_mutex.end()) {
|
|
240
|
-
::AllData::all_object_mutex[final_id]
|
|
245
|
+
::AllData::all_object_mutex[final_id].clear();
|
|
241
246
|
}
|
|
242
247
|
if (::AllData::all_object_mutex[final_id].find(obj_id) == ::AllData::all_object_mutex[final_id].end()) {
|
|
243
|
-
std::
|
|
244
|
-
::AllData::all_object_mutex[final_id][obj_id] = lock;
|
|
248
|
+
::AllData::all_object_mutex[final_id][obj_id] = std::make_unique<std::shared_mutex>();
|
|
245
249
|
}
|
|
246
250
|
}
|
|
247
251
|
|
|
@@ -252,8 +256,7 @@ type_create_mutex(uintptr_t typ_id) noexcept {
|
|
|
252
256
|
::AllData::type_attr_dict[typ_id] = {};
|
|
253
257
|
}
|
|
254
258
|
if (::AllData::all_type_mutex.find(typ_id) == ::AllData::all_type_mutex.end()) {
|
|
255
|
-
std::
|
|
256
|
-
::AllData::all_type_mutex[typ_id] = lock;
|
|
259
|
+
::AllData::all_type_mutex[typ_id] = std::make_unique<std::shared_mutex>();
|
|
257
260
|
}
|
|
258
261
|
}
|
|
259
262
|
|
|
@@ -268,11 +271,10 @@ type_parenttype_create_mutex(uintptr_t final_id, uintptr_t typ_id) noexcept
|
|
|
268
271
|
::AllData::all_type_subclass_attr[final_id][typ_id] = {};
|
|
269
272
|
}
|
|
270
273
|
if (::AllData::all_type_subclass_mutex.find(final_id) == ::AllData::all_type_subclass_mutex.end()) {
|
|
271
|
-
::AllData::all_type_subclass_mutex[final_id]
|
|
274
|
+
::AllData::all_type_subclass_mutex[final_id].clear();
|
|
272
275
|
}
|
|
273
276
|
if (::AllData::all_type_subclass_mutex[final_id].find(typ_id) == ::AllData::all_type_subclass_mutex[final_id].end()) {
|
|
274
|
-
std::
|
|
275
|
-
::AllData::all_type_subclass_mutex[final_id][typ_id] = lock;
|
|
277
|
+
::AllData::all_type_subclass_mutex[final_id][typ_id] = std::make_unique<std::shared_mutex>();
|
|
276
278
|
}
|
|
277
279
|
}
|
|
278
280
|
|
|
@@ -2057,13 +2059,13 @@ static void
|
|
|
2057
2059
|
PrivateAttr_object_init_private_dict(uintptr_t obj_id, uintptr_t type_id) noexcept
|
|
2058
2060
|
{
|
|
2059
2061
|
if (::AllData::all_object_mutex.find(type_id) == ::AllData::all_object_mutex.end()) {
|
|
2060
|
-
::AllData::all_object_mutex[type_id]
|
|
2062
|
+
::AllData::all_object_mutex[type_id].clear();
|
|
2061
2063
|
}
|
|
2062
2064
|
if (::AllData::all_object_attr.find(type_id) == ::AllData::all_object_attr.end()) {
|
|
2063
2065
|
::AllData::all_object_attr[type_id] = {};
|
|
2064
2066
|
}
|
|
2065
2067
|
if (::AllData::all_object_mutex[type_id].find(obj_id) == ::AllData::all_object_mutex[type_id].end()) {
|
|
2066
|
-
::AllData::all_object_mutex[type_id][obj_id] = std::
|
|
2068
|
+
::AllData::all_object_mutex[type_id][obj_id] = std::make_unique<std::shared_mutex>();
|
|
2067
2069
|
}
|
|
2068
2070
|
if (::AllData::all_object_attr[type_id].find(obj_id) == ::AllData::all_object_attr[type_id].end()) {
|
|
2069
2071
|
::AllData::all_object_attr[type_id][obj_id] = {};
|
|
@@ -2956,21 +2958,21 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2956
2958
|
::AllData::all_type_parent_id[type_id] = mro_vector;
|
|
2957
2959
|
|
|
2958
2960
|
::AllData::type_allowed_code_map[type_id] = {};
|
|
2959
|
-
::AllData::all_object_mutex[type_id]
|
|
2960
|
-
::AllData::all_type_mutex[type_id] = std::
|
|
2961
|
+
::AllData::all_object_mutex[type_id].clear();
|
|
2962
|
+
::AllData::all_type_mutex[type_id] = std::make_unique<std::shared_mutex>();
|
|
2961
2963
|
::AllData::all_object_attr[type_id] = {};
|
|
2962
2964
|
::AllData::all_type_subclass_attr[type_id] = {};
|
|
2963
|
-
::AllData::all_type_subclass_mutex[type_id]
|
|
2965
|
+
::AllData::all_type_subclass_mutex[type_id].clear();
|
|
2964
2966
|
|
|
2965
2967
|
for (uintptr_t i: mro_vector) {
|
|
2966
2968
|
if (::AllData::all_type_subclass_attr.find(i) == ::AllData::all_type_subclass_attr.end()) {
|
|
2967
2969
|
::AllData::all_type_subclass_attr[i] = {};
|
|
2968
2970
|
}
|
|
2969
2971
|
if (::AllData::all_type_subclass_mutex.find(i) == ::AllData::all_type_subclass_mutex.end()) {
|
|
2970
|
-
::AllData::all_type_subclass_mutex[i]
|
|
2972
|
+
::AllData::all_type_subclass_mutex[i].clear();
|
|
2971
2973
|
}
|
|
2972
2974
|
::AllData::all_type_subclass_attr[i][type_id] = {};
|
|
2973
|
-
::AllData::all_type_subclass_mutex[i][type_id] = std::
|
|
2975
|
+
::AllData::all_type_subclass_mutex[i][type_id] = std::make_unique<std::shared_mutex>();
|
|
2974
2976
|
}
|
|
2975
2977
|
|
|
2976
2978
|
for (auto& [key, value]: data.need_remove_itself) {
|
|
@@ -2992,13 +2994,13 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2992
2994
|
::AllData::all_type_subclass_attr[i] = {};
|
|
2993
2995
|
}
|
|
2994
2996
|
if (::AllData::all_type_subclass_mutex.find(i) == ::AllData::all_type_subclass_mutex.end()) {
|
|
2995
|
-
::AllData::all_type_subclass_mutex[i]
|
|
2997
|
+
::AllData::all_type_subclass_mutex[i].clear();
|
|
2996
2998
|
}
|
|
2997
2999
|
if (::AllData::all_type_subclass_attr[i].find(type_id) == ::AllData::all_type_subclass_attr[i].end()) {
|
|
2998
3000
|
::AllData::all_type_subclass_attr[i][type_id] = {};
|
|
2999
3001
|
}
|
|
3000
3002
|
if (::AllData::all_type_subclass_mutex[i].find(type_id) == ::AllData::all_type_subclass_mutex[i].end()) {
|
|
3001
|
-
::AllData::all_type_subclass_mutex[i][type_id] = std::
|
|
3003
|
+
::AllData::all_type_subclass_mutex[i][type_id] = std::make_unique<std::shared_mutex>();
|
|
3002
3004
|
}
|
|
3003
3005
|
for (auto& [key, value]: map) {
|
|
3004
3006
|
std::string final_key;
|
|
@@ -4004,13 +4006,22 @@ PrivateModule_get_PrivateAttrType(PyObject* /*self*/, void* /*closure*/) noexcep
|
|
|
4004
4006
|
static PyObject*
|
|
4005
4007
|
PrivateModule_get_PrivateAttrBase(PyObject* /*self*/, void* /*closure*/) noexcept
|
|
4006
4008
|
{
|
|
4007
|
-
static
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4009
|
+
static std::mutex base_mutex;
|
|
4010
|
+
std::lock_guard<std::mutex> lock(base_mutex);
|
|
4011
|
+
auto it = AllData::store_module_self.find(AllData::kPrivateAttrBaseKey);
|
|
4012
|
+
if (it == AllData::store_module_self.end()) {
|
|
4013
|
+
PyObject* base = create_private_attr_base_simple();
|
|
4014
|
+
if (!base) {
|
|
4015
|
+
if (!PyErr_Occurred()) {
|
|
4016
|
+
PyErr_SetString(PyExc_RuntimeError, "failed to create PrivateAttrBase");
|
|
4017
|
+
}
|
|
4018
|
+
return NULL;
|
|
4011
4019
|
}
|
|
4012
|
-
|
|
4020
|
+
AllData::store_module_self[AllData::kPrivateAttrBaseKey] = base;
|
|
4021
|
+
Py_DECREF(base);
|
|
4022
|
+
it = AllData::store_module_self.find(AllData::kPrivateAttrBaseKey);
|
|
4013
4023
|
}
|
|
4024
|
+
PyObject* PrivateAttrBase = it->second.get();
|
|
4014
4025
|
Py_INCREF(PrivateAttrBase);
|
|
4015
4026
|
return PrivateAttrBase;
|
|
4016
4027
|
}
|
|
@@ -4259,13 +4270,25 @@ class MyClass(PrivateAttrBase):
|
|
|
4259
4270
|
```
|
|
4260
4271
|
)";
|
|
4261
4272
|
|
|
4273
|
+
static int PrivateModule_exec(PyObject* m) noexcept;
|
|
4274
|
+
static PyObject* PrivateModule_create(PyObject* spec, PyModuleDef* def) noexcept;
|
|
4275
|
+
|
|
4276
|
+
static PyModuleDef_Slot PrivateModule_slots[] = {
|
|
4277
|
+
{Py_mod_create, (void*)PrivateModule_create},
|
|
4278
|
+
{Py_mod_exec, (void*)PrivateModule_exec},
|
|
4279
|
+
#if PY_VERSION_HEX >= 0x030D0000
|
|
4280
|
+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
|
|
4281
|
+
#endif
|
|
4282
|
+
{0, NULL}
|
|
4283
|
+
};
|
|
4284
|
+
|
|
4262
4285
|
static PyModuleDef def = {
|
|
4263
4286
|
PyModuleDef_HEAD_INIT,
|
|
4264
4287
|
"private_attribute",
|
|
4265
4288
|
module_doc,
|
|
4266
4289
|
0,
|
|
4267
4290
|
NULL,
|
|
4268
|
-
|
|
4291
|
+
PrivateModule_slots,
|
|
4269
4292
|
NULL,
|
|
4270
4293
|
NULL,
|
|
4271
4294
|
NULL
|
|
@@ -4310,47 +4333,44 @@ atexit_register_clean_func(void) noexcept
|
|
|
4310
4333
|
return 0;
|
|
4311
4334
|
}
|
|
4312
4335
|
|
|
4313
|
-
|
|
4314
|
-
|
|
4336
|
+
static PyObject*
|
|
4337
|
+
PrivateModule_create(PyObject* spec, PyModuleDef* /*def*/) noexcept
|
|
4315
4338
|
{
|
|
4316
|
-
|
|
4317
|
-
if (
|
|
4318
|
-
PyObject* m = AllData::store_module_self[0];
|
|
4319
|
-
Py_INCREF(m);
|
|
4320
|
-
return m;
|
|
4321
|
-
}
|
|
4322
|
-
if (init_all_slots() <0 ||
|
|
4323
|
-
atexit_register_clean_func() < 0 ||
|
|
4324
|
-
PyType_Ready(&PrivateWrapType) < 0 ||
|
|
4325
|
-
PyType_Ready(&PrivateWrapProxyType) < 0 ||
|
|
4326
|
-
PyType_Ready(&PrivateAttrType) < 0 ||
|
|
4327
|
-
PyType_Ready(&PrivateModuleType) < 0 ||
|
|
4328
|
-
PyType_Ready(&PrivateTempType) < 0) {
|
|
4339
|
+
PyObject* name = PyObject_GetAttrString(spec, "name");
|
|
4340
|
+
if (!name) {
|
|
4329
4341
|
return NULL;
|
|
4330
4342
|
}
|
|
4343
|
+
// Instantiate the module directly as an instance of PrivateModuleType
|
|
4344
|
+
// (a subclass of `module`) so that the object returned from
|
|
4345
|
+
// PyInit_private_attribute is genuinely a
|
|
4346
|
+
// `private_attribute.private_attribute_module` instance from the start,
|
|
4347
|
+
// rather than a plain module re-typed with Py_SET_TYPE afterwards.
|
|
4348
|
+
PyObject* m = PyObject_CallFunction((PyObject*)&PrivateModuleType, "O", name);
|
|
4349
|
+
Py_DECREF(name);
|
|
4350
|
+
return m;
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
static int
|
|
4354
|
+
PrivateModule_exec(PyObject* m) noexcept
|
|
4355
|
+
{
|
|
4331
4356
|
// Eagerly create PrivateAttrBase so that CPython's subtype_traverse /
|
|
4332
4357
|
// subtype_clear pointers are captured at import time (see
|
|
4333
4358
|
// PrivateAttrCaptureGuard and ::AllData::captured_subtype_*), instead of
|
|
4334
4359
|
// waiting for the first lazy attribute access to the module.
|
|
4335
4360
|
PyObject* private_attr_base = PrivateModule_get_PrivateAttrBase(NULL, NULL);
|
|
4336
4361
|
if (!private_attr_base) {
|
|
4337
|
-
return
|
|
4362
|
+
return -1;
|
|
4338
4363
|
}
|
|
4339
4364
|
PyObject* all = PyList_New(0);
|
|
4340
4365
|
if (!all) {
|
|
4341
4366
|
Py_DECREF(private_attr_base);
|
|
4342
|
-
return
|
|
4367
|
+
return -1;
|
|
4343
4368
|
}
|
|
4344
|
-
|
|
4345
|
-
if (!m) {
|
|
4369
|
+
if (PyModule_AddObject(m, "__all__", all) < 0) {
|
|
4346
4370
|
Py_DECREF(all);
|
|
4347
4371
|
Py_DECREF(private_attr_base);
|
|
4348
|
-
return
|
|
4372
|
+
return -1;
|
|
4349
4373
|
}
|
|
4350
|
-
#ifdef Py_GIL_DISABLED
|
|
4351
|
-
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
|
4352
|
-
#endif
|
|
4353
|
-
PyModule_AddObject(m, "__all__", all);
|
|
4354
4374
|
/* all contains:
|
|
4355
4375
|
* PrivateWrapProxy
|
|
4356
4376
|
* PrivateAttrType
|
|
@@ -4369,10 +4389,31 @@ PyInit_private_attribute(void) noexcept
|
|
|
4369
4389
|
PyList_AppendString(all, "register_metaclass");
|
|
4370
4390
|
PyList_AppendString(all, "ensure_type");
|
|
4371
4391
|
PyList_AppendString(all, "ensure_metaclass");
|
|
4372
|
-
Py_SET_TYPE(m, &PrivateModuleType);
|
|
4373
4392
|
|
|
4374
4393
|
Py_DECREF(private_attr_base);
|
|
4375
|
-
AllData::store_module_self
|
|
4394
|
+
AllData::store_module_self[AllData::kModuleSelfKey] = m; // store module self
|
|
4376
4395
|
|
|
4377
|
-
return
|
|
4396
|
+
return 0;
|
|
4397
|
+
}
|
|
4398
|
+
|
|
4399
|
+
PyMODINIT_FUNC
|
|
4400
|
+
PyInit_private_attribute(void) noexcept
|
|
4401
|
+
{
|
|
4402
|
+
// check if AllData::store_module_self already holds the module
|
|
4403
|
+
auto it = AllData::store_module_self.find(AllData::kModuleSelfKey);
|
|
4404
|
+
if (it != AllData::store_module_self.end()) {
|
|
4405
|
+
PyObject* m = it->second.get();
|
|
4406
|
+
Py_INCREF(m);
|
|
4407
|
+
return m;
|
|
4408
|
+
}
|
|
4409
|
+
if (init_all_slots() <0 ||
|
|
4410
|
+
atexit_register_clean_func() < 0 ||
|
|
4411
|
+
PyType_Ready(&PrivateWrapType) < 0 ||
|
|
4412
|
+
PyType_Ready(&PrivateWrapProxyType) < 0 ||
|
|
4413
|
+
PyType_Ready(&PrivateAttrType) < 0 ||
|
|
4414
|
+
PyType_Ready(&PrivateModuleType) < 0 ||
|
|
4415
|
+
PyType_Ready(&PrivateTempType) < 0) {
|
|
4416
|
+
return NULL;
|
|
4417
|
+
}
|
|
4418
|
+
return PyModuleDef_Init(&def);
|
|
4378
4419
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.13
|
|
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
|
|
@@ -24,7 +24,7 @@ readme = open('README.md').read()
|
|
|
24
24
|
|
|
25
25
|
setup(
|
|
26
26
|
name='private_attribute_cpp',
|
|
27
|
-
version='2.1.
|
|
27
|
+
version='2.1.13',
|
|
28
28
|
author="HuangHaoHua",
|
|
29
29
|
author_email="13140752715@example.com",
|
|
30
30
|
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.12 → private_attribute_cpp-2.1.13}/tests/test_attr_classify_owner.py
RENAMED
|
File without changes
|
{private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_class_private_attrs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.1.12 → private_attribute_cpp-2.1.13}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|