private-attribute-cpp 1.4.5__tar.gz → 1.4.7__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-1.4.5/private_attribute_cpp.egg-info → private_attribute_cpp-1.4.7}/PKG-INFO +3 -2
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/README.md +2 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/private_attribute.cpp +35 -33
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/private_attribute.pyi +1 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7/private_attribute_cpp.egg-info}/PKG-INFO +3 -2
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/setup.py +1 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_class_private_attrs.py +2 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_private_abc.py +3 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_private_attrs.py +2 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_private_func.py +1 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_private_inheritance.py +1 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_private_method.py +1 -1
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_private_wrap.py +11 -7
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/LICENSE +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/MANIFEST.in +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/picosha2.h +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/setup.cfg +0 -0
{private_attribute_cpp-1.4.5/private_attribute_cpp.egg-info → private_attribute_cpp-1.4.7}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.7
|
|
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
|
|
@@ -250,7 +250,8 @@ TypeError: Can't instantiate abstract class MyClass without an implementation fo
|
|
|
250
250
|
- One class defined in another class cannot use another class's private attribute.
|
|
251
251
|
- One parent class defined an attribute which not in `__private_attrs__` or not a `PrivateAttrType` instance, the child class shouldn't contain the attribute in its `__private_attrs__`.
|
|
252
252
|
- CPython may change "tp_getattro", "tp_setattro" and so on when you change the attribute "\_\_getattribute\_\_", "\_\_setattr\_\_" and so on. If you are fear about it, you can use `ensure_type` to reset those tp slots. For the other metaclasses, you can use `ensure_metaclass` to reset those tp slots. Also, don't set those methods on these classes in your code.
|
|
253
|
-
- `private_attribute.register_metaclass` must be called with the metaclass which
|
|
253
|
+
- `private_attribute.register_metaclass` must be called with the metaclass which supports weakref.
|
|
254
|
+
- Don't set `__static_attributes__` in private attribute class, or it will be removed.
|
|
254
255
|
|
|
255
256
|
## License
|
|
256
257
|
|
|
@@ -231,7 +231,8 @@ TypeError: Can't instantiate abstract class MyClass without an implementation fo
|
|
|
231
231
|
- One class defined in another class cannot use another class's private attribute.
|
|
232
232
|
- One parent class defined an attribute which not in `__private_attrs__` or not a `PrivateAttrType` instance, the child class shouldn't contain the attribute in its `__private_attrs__`.
|
|
233
233
|
- CPython may change "tp_getattro", "tp_setattro" and so on when you change the attribute "\_\_getattribute\_\_", "\_\_setattr\_\_" and so on. If you are fear about it, you can use `ensure_type` to reset those tp slots. For the other metaclasses, you can use `ensure_metaclass` to reset those tp slots. Also, don't set those methods on these classes in your code.
|
|
234
|
-
- `private_attribute.register_metaclass` must be called with the metaclass which
|
|
234
|
+
- `private_attribute.register_metaclass` must be called with the metaclass which supports weakref.
|
|
235
|
+
- Don't set `__static_attributes__` in private attribute class, or it will be removed.
|
|
235
236
|
|
|
236
237
|
## License
|
|
237
238
|
|
|
@@ -57,7 +57,7 @@ private:
|
|
|
57
57
|
std::string attr_onehash;
|
|
58
58
|
std::string another_string_hash;
|
|
59
59
|
public:
|
|
60
|
-
AllPyobjectAttrCacheKey(uintptr_t obj_id, std::string attr_name) : obj_id(obj_id) {
|
|
60
|
+
AllPyobjectAttrCacheKey(uintptr_t obj_id, const std::string& attr_name) : obj_id(obj_id) {
|
|
61
61
|
std::string one_name = "_" + std::to_string(obj_id) + "_" + attr_name;
|
|
62
62
|
std::string another_name = "_" + module_running_time_string + attr_name;
|
|
63
63
|
picosha2::hash256_hex_string(one_name, attr_onehash);
|
|
@@ -82,7 +82,7 @@ private:
|
|
|
82
82
|
std::string first;
|
|
83
83
|
std::string second;
|
|
84
84
|
public:
|
|
85
|
-
TwoStringTuple(std::string first, std::string second) : first(first), second(second) {}
|
|
85
|
+
TwoStringTuple(const std::string& first, const std::string& second) : first(first), second(second) {}
|
|
86
86
|
bool operator==(const TwoStringTuple& other) const {
|
|
87
87
|
return this->first == other.first && this->second == other.second;
|
|
88
88
|
}
|
|
@@ -162,11 +162,11 @@ struct FinalObject
|
|
|
162
162
|
}
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
-
static TwoStringTuple get_string_hash_tuple2(std::string name);
|
|
165
|
+
static TwoStringTuple get_string_hash_tuple2(const std::string& name);
|
|
166
166
|
static PyCodeObject* get_now_code();
|
|
167
|
-
static uintptr_t type_set_attr_long_long_guidance(uintptr_t type, std::string name);
|
|
168
|
-
static bool type_private_attr(uintptr_t type, std::string name);
|
|
169
|
-
static FinalObject type_get_final_attr(uintptr_t type_id, std::string name);
|
|
167
|
+
static uintptr_t type_set_attr_long_long_guidance(uintptr_t type, const std::string& name);
|
|
168
|
+
static bool type_private_attr(uintptr_t type, const std::string& name);
|
|
169
|
+
static FinalObject type_get_final_attr(uintptr_t type_id, const std::string& name);
|
|
170
170
|
|
|
171
171
|
static bool
|
|
172
172
|
is_class_code(uintptr_t typ_id, PyCodeObject* code)
|
|
@@ -182,7 +182,7 @@ is_class_code(uintptr_t typ_id, PyCodeObject* code)
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
static bool
|
|
185
|
-
is_type_private(uintptr_t typ_id, std::string name)
|
|
185
|
+
is_type_private(uintptr_t typ_id, const std::string& name)
|
|
186
186
|
{
|
|
187
187
|
if (::AllData::all_type_attr_set.find(typ_id) != ::AllData::all_type_attr_set.end()){
|
|
188
188
|
auto& attr_set = ::AllData::all_type_attr_set[typ_id];
|
|
@@ -195,7 +195,7 @@ is_type_private(uintptr_t typ_id, std::string name)
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
static bool
|
|
198
|
-
attr_classify(uintptr_t typ_id, std::string name, PyCodeObject* code)
|
|
198
|
+
attr_classify(uintptr_t typ_id, const std::string& name, PyCodeObject* code)
|
|
199
199
|
{
|
|
200
200
|
if (is_class_code(typ_id, code)) {
|
|
201
201
|
return true;
|
|
@@ -248,7 +248,7 @@ generate_private_attr_name(uintptr_t obj_id, const std::string& attr_name)
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
static std::string
|
|
251
|
-
default_random_string(uintptr_t obj_id, std::string attr_name)
|
|
251
|
+
default_random_string(uintptr_t obj_id, const std::string& attr_name)
|
|
252
252
|
{
|
|
253
253
|
AllPyobjectAttrCacheKey key(obj_id, attr_name);
|
|
254
254
|
std::string result;
|
|
@@ -262,7 +262,7 @@ default_random_string(uintptr_t obj_id, std::string attr_name)
|
|
|
262
262
|
lock.unlock();
|
|
263
263
|
result = generate_private_attr_name(obj_id, attr_name);
|
|
264
264
|
std::string original_result = result;
|
|
265
|
-
|
|
265
|
+
unsigned long long i = 1;
|
|
266
266
|
std::unique_lock<std::shared_mutex> lock2(::AllData::cache_mutex);
|
|
267
267
|
auto it = ::AllData::cache.find(key); // twice check
|
|
268
268
|
if (it != ::AllData::cache.end()) {
|
|
@@ -333,7 +333,7 @@ private:
|
|
|
333
333
|
};
|
|
334
334
|
|
|
335
335
|
static std::string
|
|
336
|
-
custom_random_string(uintptr_t obj_id, std::string attr_name, PyObject* func)
|
|
336
|
+
custom_random_string(uintptr_t obj_id, const std::string& attr_name, PyObject* func)
|
|
337
337
|
{
|
|
338
338
|
AllPyobjectAttrCacheKey key(obj_id, attr_name);
|
|
339
339
|
std::string result;
|
|
@@ -363,7 +363,7 @@ custom_random_string(uintptr_t obj_id, std::string attr_name, PyObject* func)
|
|
|
363
363
|
result = PyUnicode_AsUTF8(python_result);
|
|
364
364
|
Py_DECREF(python_result);
|
|
365
365
|
std::string original_result = result;
|
|
366
|
-
|
|
366
|
+
unsigned long long i = 1;
|
|
367
367
|
std::unique_lock<std::shared_mutex> lock2(::AllData::cache_mutex);
|
|
368
368
|
auto it = ::AllData::cache.find(key); // twice check
|
|
369
369
|
if (it != ::AllData::cache.end()) {
|
|
@@ -426,7 +426,7 @@ static void ensure_tp(PyTypeObject* type_instance);
|
|
|
426
426
|
static void ensure_subclass_tp(PyTypeObject* type_instance);
|
|
427
427
|
|
|
428
428
|
static PyObject*
|
|
429
|
-
id_getattr(std::string attr_name, PyObject* obj, PyObject* typ)
|
|
429
|
+
id_getattr(const std::string& attr_name, PyObject* obj, PyObject* typ)
|
|
430
430
|
{
|
|
431
431
|
uintptr_t obj_id, typ_id, final_id;
|
|
432
432
|
obj_id = (uintptr_t) obj;
|
|
@@ -533,7 +533,7 @@ id_getattr(std::string attr_name, PyObject* obj, PyObject* typ)
|
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
static PyObject*
|
|
536
|
-
type_getattr(PyObject* typ, std::string attr_name)
|
|
536
|
+
type_getattr(PyObject* typ, const std::string& attr_name)
|
|
537
537
|
{
|
|
538
538
|
uintptr_t typ_id = (uintptr_t)typ;
|
|
539
539
|
FinalObject final_object = type_get_final_attr(typ_id, attr_name);
|
|
@@ -567,7 +567,7 @@ type_getattr(PyObject* typ, std::string attr_name)
|
|
|
567
567
|
}
|
|
568
568
|
|
|
569
569
|
static int
|
|
570
|
-
id_setattr(std::string attr_name, PyObject* obj, PyObject* typ, PyObject* value)
|
|
570
|
+
id_setattr(const std::string& attr_name, PyObject* obj, PyObject* typ, PyObject* value)
|
|
571
571
|
{
|
|
572
572
|
uintptr_t obj_id, typ_id, final_id;
|
|
573
573
|
obj_id = (uintptr_t) obj;
|
|
@@ -636,10 +636,10 @@ id_setattr(std::string attr_name, PyObject* obj, PyObject* typ, PyObject* value)
|
|
|
636
636
|
return 0;
|
|
637
637
|
}
|
|
638
638
|
|
|
639
|
-
static int type_delattr(PyObject* typ, std::string attr_name);
|
|
639
|
+
static int type_delattr(PyObject* typ, const std::string& attr_name);
|
|
640
640
|
|
|
641
641
|
static int
|
|
642
|
-
type_setattr(PyObject* typ, std::string attr_name, PyObject* value)
|
|
642
|
+
type_setattr(PyObject* typ, const std::string& attr_name, PyObject* value)
|
|
643
643
|
{
|
|
644
644
|
if (!value) {
|
|
645
645
|
return type_delattr(typ, attr_name);
|
|
@@ -711,7 +711,7 @@ type_setattr(PyObject* typ, std::string attr_name, PyObject* value)
|
|
|
711
711
|
}
|
|
712
712
|
|
|
713
713
|
static int
|
|
714
|
-
id_delattr(std::string attr_name, PyObject* obj, PyObject* typ)
|
|
714
|
+
id_delattr(const std::string& attr_name, PyObject* obj, PyObject* typ)
|
|
715
715
|
{
|
|
716
716
|
uintptr_t obj_id, typ_id, final_id;
|
|
717
717
|
obj_id = (uintptr_t) obj;
|
|
@@ -789,7 +789,7 @@ id_delattr(std::string attr_name, PyObject* obj, PyObject* typ)
|
|
|
789
789
|
}
|
|
790
790
|
|
|
791
791
|
static int
|
|
792
|
-
type_delattr(PyObject* typ, std::string attr_name)
|
|
792
|
+
type_delattr(PyObject* typ, const std::string& attr_name)
|
|
793
793
|
{
|
|
794
794
|
uintptr_t typ_id = (uintptr_t) typ;
|
|
795
795
|
uintptr_t final_id = type_set_attr_long_long_guidance(typ_id, attr_name);
|
|
@@ -1438,7 +1438,7 @@ static PyTypeObject PrivateAttrType = {
|
|
|
1438
1438
|
};
|
|
1439
1439
|
|
|
1440
1440
|
static PyObject*
|
|
1441
|
-
get_string_hash_tuple(std::string name)
|
|
1441
|
+
get_string_hash_tuple(const std::string& name)
|
|
1442
1442
|
{
|
|
1443
1443
|
std::string name1;
|
|
1444
1444
|
std::string name2;
|
|
@@ -1452,7 +1452,7 @@ get_string_hash_tuple(std::string name)
|
|
|
1452
1452
|
}
|
|
1453
1453
|
|
|
1454
1454
|
static TwoStringTuple
|
|
1455
|
-
get_string_hash_tuple2(std::string name)
|
|
1455
|
+
get_string_hash_tuple2(const std::string& name)
|
|
1456
1456
|
{
|
|
1457
1457
|
std::string name1;
|
|
1458
1458
|
std::string name2;
|
|
@@ -1466,7 +1466,7 @@ get_string_hash_tuple2(std::string name)
|
|
|
1466
1466
|
}
|
|
1467
1467
|
|
|
1468
1468
|
static FinalObject
|
|
1469
|
-
type_get_final_attr(uintptr_t type_id, std::string name)
|
|
1469
|
+
type_get_final_attr(uintptr_t type_id, const std::string& name)
|
|
1470
1470
|
{
|
|
1471
1471
|
TwoStringTuple hash_tuple = get_string_hash_tuple2(name);
|
|
1472
1472
|
if (::AllData::all_type_attr_set.find(type_id) != ::AllData::all_type_attr_set.end()) {
|
|
@@ -1580,7 +1580,7 @@ type_get_final_attr(uintptr_t type_id, std::string name)
|
|
|
1580
1580
|
}
|
|
1581
1581
|
|
|
1582
1582
|
static uintptr_t
|
|
1583
|
-
type_set_attr_long_long_guidance(uintptr_t type_id, std::string name)
|
|
1583
|
+
type_set_attr_long_long_guidance(uintptr_t type_id, const std::string& name)
|
|
1584
1584
|
{
|
|
1585
1585
|
TwoStringTuple hash_tuple = get_string_hash_tuple2(name);
|
|
1586
1586
|
if (::AllData::all_type_attr_set.find(type_id) != ::AllData::all_type_attr_set.end()) {
|
|
@@ -1602,7 +1602,7 @@ type_set_attr_long_long_guidance(uintptr_t type_id, std::string name)
|
|
|
1602
1602
|
}
|
|
1603
1603
|
|
|
1604
1604
|
static bool
|
|
1605
|
-
type_private_attr(uintptr_t type_id, std::string name)
|
|
1605
|
+
type_private_attr(uintptr_t type_id, const std::string& name)
|
|
1606
1606
|
{
|
|
1607
1607
|
TwoStringTuple hash_tuple = get_string_hash_tuple2(name);
|
|
1608
1608
|
if (::AllData::all_type_attr_set.find(type_id) != ::AllData::all_type_attr_set.end()) {
|
|
@@ -1722,7 +1722,7 @@ analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyCodeObject*>& ma
|
|
|
1722
1722
|
}
|
|
1723
1723
|
|
|
1724
1724
|
static std::string
|
|
1725
|
-
real_class_name(std::string name, std::string class_name)
|
|
1725
|
+
real_class_name(const std::string& name, const std::string& class_name)
|
|
1726
1726
|
{
|
|
1727
1727
|
// if the name starts with "__" but does not end with "__", change to _ClassName__name
|
|
1728
1728
|
if (name.length() >= 2 && name.substr(0, 2) == "__" && name.substr(name.length() - 2) != "__") {
|
|
@@ -2127,6 +2127,11 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2127
2127
|
return (uintptr_t)0;
|
|
2128
2128
|
};
|
|
2129
2129
|
|
|
2130
|
+
// forbidden to have "__static_attributes__" in attrs, because it exposes the private attributes name.
|
|
2131
|
+
if (PyDict_ContainsString(data.attrs_copy, "__static_attributes__")) {
|
|
2132
|
+
PyDict_DelItemString(data.attrs_copy, "__static_attributes__");
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2130
2135
|
{
|
|
2131
2136
|
Py_ssize_t pos = 0;
|
|
2132
2137
|
PyObject* key, *value;
|
|
@@ -2335,6 +2340,10 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data)
|
|
|
2335
2340
|
|
|
2336
2341
|
PyTypeObject* type_instance = (PyTypeObject*)new_type;
|
|
2337
2342
|
uintptr_t type_id = (uintptr_t)(type_instance);
|
|
2343
|
+
if (PyDict_ContainsString(type_instance->tp_dict, "__static_attributes__")) {
|
|
2344
|
+
PyErr_SetString(PyExc_SystemError, "'__static_attributes__' will expose private attribute names and cannot be used in private attribute types");
|
|
2345
|
+
return false;
|
|
2346
|
+
}
|
|
2338
2347
|
|
|
2339
2348
|
ensure_tp(type_instance);
|
|
2340
2349
|
if (PyDict_ContainsString(type_instance->tp_dict, "__getattribute__") || PyDict_ContainsString(type_instance->tp_dict, "__getattr__")) {
|
|
@@ -2441,12 +2450,6 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data)
|
|
|
2441
2450
|
}
|
|
2442
2451
|
}
|
|
2443
2452
|
|
|
2444
|
-
// Python >= 3.13, delete the attr "__static_attributes__"
|
|
2445
|
-
#if PY_VERSION_HEX >= 0x030D0000
|
|
2446
|
-
PyDict_DelItemString(type_instance->tp_dict, "__static_attributes__");
|
|
2447
|
-
PyErr_Clear();
|
|
2448
|
-
#endif
|
|
2449
|
-
|
|
2450
2453
|
return true;
|
|
2451
2454
|
}
|
|
2452
2455
|
|
|
@@ -2808,6 +2811,7 @@ create_private_attr_base_simple(void)
|
|
|
2808
2811
|
PyDict_SetItemString(dict, "__private_attrs__", private_attrs);
|
|
2809
2812
|
PyDict_SetItemString(dict, "__slots__", private_attrs);
|
|
2810
2813
|
PyDict_SetItemString(dict, "__doc__", PyUnicode_FromString(PrivateAttrBase_doc));
|
|
2814
|
+
PyDict_SetItemString(dict, "__module__", PyUnicode_FromString("private_attribute"));
|
|
2811
2815
|
PyObject *args = PyTuple_Pack(3, name, bases, dict);
|
|
2812
2816
|
PyObject* base_type;
|
|
2813
2817
|
if (args) {
|
|
@@ -2825,8 +2829,6 @@ create_private_attr_base_simple(void)
|
|
|
2825
2829
|
if (!base_type) {
|
|
2826
2830
|
return NULL;
|
|
2827
2831
|
}
|
|
2828
|
-
// set "__module__"
|
|
2829
|
-
PyType_Type.tp_setattro(base_type, PyUnicode_FromString("__module__"), PyUnicode_FromString("private_attribute"));
|
|
2830
2832
|
((PyTypeObject*)base_type)->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
|
2831
2833
|
return base_type;
|
|
2832
2834
|
}
|
|
@@ -71,7 +71,7 @@ class PrivateWrapProxy:
|
|
|
71
71
|
```
|
|
72
72
|
"""
|
|
73
73
|
def __init__(self, decorator: Callable[[_TVar], _T], orig: _PrivateWrap[Any]|None = None, /) -> None: ...
|
|
74
|
-
def __call__(self, func: _TVar, /) -> _PrivateWrap[_T]: ...
|
|
74
|
+
def __call__(self, func: _TVar | _PrivateWrap[_TVar], /) -> _PrivateWrap[_T]: ...
|
|
75
75
|
|
|
76
76
|
class PrivateAttrType(type):
|
|
77
77
|
"metaclass for private attributes"
|
{private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7/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: 1.4.
|
|
3
|
+
Version: 1.4.7
|
|
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
|
|
@@ -250,7 +250,8 @@ TypeError: Can't instantiate abstract class MyClass without an implementation fo
|
|
|
250
250
|
- One class defined in another class cannot use another class's private attribute.
|
|
251
251
|
- One parent class defined an attribute which not in `__private_attrs__` or not a `PrivateAttrType` instance, the child class shouldn't contain the attribute in its `__private_attrs__`.
|
|
252
252
|
- CPython may change "tp_getattro", "tp_setattro" and so on when you change the attribute "\_\_getattribute\_\_", "\_\_setattr\_\_" and so on. If you are fear about it, you can use `ensure_type` to reset those tp slots. For the other metaclasses, you can use `ensure_metaclass` to reset those tp slots. Also, don't set those methods on these classes in your code.
|
|
253
|
-
- `private_attribute.register_metaclass` must be called with the metaclass which
|
|
253
|
+
- `private_attribute.register_metaclass` must be called with the metaclass which supports weakref.
|
|
254
|
+
- Don't set `__static_attributes__` in private attribute class, or it will be removed.
|
|
254
255
|
|
|
255
256
|
## License
|
|
256
257
|
|
|
@@ -18,7 +18,7 @@ readme = open('README.md').read()
|
|
|
18
18
|
|
|
19
19
|
setup(
|
|
20
20
|
name='private_attribute_cpp',
|
|
21
|
-
version='1.4.
|
|
21
|
+
version='1.4.7',
|
|
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.',
|
{private_attribute_cpp-1.4.5 → private_attribute_cpp-1.4.7}/tests/test_class_private_attrs.py
RENAMED
|
@@ -4,6 +4,7 @@ import unittest
|
|
|
4
4
|
class MyClass(private_attribute.PrivateAttrBase):
|
|
5
5
|
__private_attrs__ = ["_secret"]
|
|
6
6
|
_secret = 1
|
|
7
|
+
|
|
7
8
|
@classmethod
|
|
8
9
|
def get_secret(cls):
|
|
9
10
|
return cls._secret
|
|
@@ -19,4 +20,4 @@ class TestClassPrivateAttrs(unittest.TestCase):
|
|
|
19
20
|
self.assertEqual(a.get_secret(), 1)
|
|
20
21
|
|
|
21
22
|
if __name__ == "__main__":
|
|
22
|
-
unittest.main()
|
|
23
|
+
unittest.main()
|
|
@@ -16,6 +16,7 @@ private_attribute.register_metaclass(PrivateAbcMeta)
|
|
|
16
16
|
class MyClass(ABC, metaclass=PrivateAbcMeta):
|
|
17
17
|
__private_attrs__ = ["_secret1"]
|
|
18
18
|
_secret1 = 10
|
|
19
|
+
|
|
19
20
|
@classmethod
|
|
20
21
|
def get_secret1(cls):
|
|
21
22
|
return cls._secret1
|
|
@@ -26,6 +27,7 @@ class MyClass(ABC, metaclass=PrivateAbcMeta):
|
|
|
26
27
|
|
|
27
28
|
class ConcreteClass(MyClass):
|
|
28
29
|
__private_attrs__ = ["_secret2"]
|
|
30
|
+
|
|
29
31
|
def __init__(self, secret1, secret2):
|
|
30
32
|
self._secret1 = secret1
|
|
31
33
|
self._secret2 = secret2
|
|
@@ -50,4 +52,4 @@ class TestPrivateAbc(unittest.TestCase):
|
|
|
50
52
|
self.assertEqual(ConcreteClass.get_secret1(), 10)
|
|
51
53
|
|
|
52
54
|
if __name__ == '__main__':
|
|
53
|
-
unittest.main()
|
|
55
|
+
unittest.main()
|
|
@@ -4,6 +4,7 @@ import unittest
|
|
|
4
4
|
class BaseClass(private_attribute.PrivateAttrBase):
|
|
5
5
|
__private_attrs__ = ["_a", "_b"]
|
|
6
6
|
__slots__ = ["c", "d"]
|
|
7
|
+
|
|
7
8
|
def __init__(self, a, b, c, d):
|
|
8
9
|
self._a = a
|
|
9
10
|
self._b = b
|
|
@@ -47,4 +48,4 @@ class TestPrivateAttributes(unittest.TestCase):
|
|
|
47
48
|
self.assertTrue(isinstance(i, tuple))
|
|
48
49
|
|
|
49
50
|
if __name__ == "__main__":
|
|
50
|
-
unittest.main()
|
|
51
|
+
unittest.main()
|
|
@@ -11,9 +11,13 @@ class MyWrap:
|
|
|
11
11
|
setattr(self, f"func{self.index}", func)
|
|
12
12
|
return self
|
|
13
13
|
|
|
14
|
-
def
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
def __get__(self, instance, owner):
|
|
15
|
+
if instance is None:
|
|
16
|
+
return self
|
|
17
|
+
def wrapper(index, *args, **kwargs):
|
|
18
|
+
func = getattr(self, f"func{index}")
|
|
19
|
+
return func.__get__(instance, owner)(*args, **kwargs)
|
|
20
|
+
return wrapper
|
|
17
21
|
|
|
18
22
|
class MyClass(private_attribute.PrivateAttrBase):
|
|
19
23
|
__private_attrs__ = ["_secret1", "_secret2", "_secret3"]
|
|
@@ -37,9 +41,9 @@ class MyClass(private_attribute.PrivateAttrBase):
|
|
|
37
41
|
class TestPrivateWrap(unittest.TestCase):
|
|
38
42
|
def test_private_wrap(self):
|
|
39
43
|
a = MyClass(1, 2, 3)
|
|
40
|
-
self.assertEqual(a.get_secret
|
|
41
|
-
self.assertEqual(a.get_secret
|
|
42
|
-
self.assertEqual(a.get_secret
|
|
44
|
+
self.assertEqual(a.get_secret(1), 1)
|
|
45
|
+
self.assertEqual(a.get_secret(2), 2)
|
|
46
|
+
self.assertEqual(a.get_secret(3), 3)
|
|
43
47
|
with self.assertRaises(AttributeError):
|
|
44
48
|
a._secret1
|
|
45
49
|
with self.assertRaises(AttributeError):
|
|
@@ -48,4 +52,4 @@ class TestPrivateWrap(unittest.TestCase):
|
|
|
48
52
|
a._secret3
|
|
49
53
|
|
|
50
54
|
if __name__ == "__main__":
|
|
51
|
-
unittest.main()
|
|
55
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|