private-attribute-cpp 2.1.22__tar.gz → 2.1.24__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.22/private_attribute_cpp.egg-info → private_attribute_cpp-2.1.24}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/private_attribute.cpp +190 -256
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/private_attribute.pyi +1 -1
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/setup.py +1 -1
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_private_wrap.py +10 -2
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/LICENSE +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/README.md +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/picosha2.h +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/setup.cfg +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_attr_classify_owner.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_gc_collect.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/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.24
|
|
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,18 @@ public:
|
|
|
125
125
|
PyObjectStorage(PyObject* obj) noexcept : obj(obj) {
|
|
126
126
|
Py_XINCREF(obj);
|
|
127
127
|
}
|
|
128
|
+
// Construct a PyObjectStorage that takes ownership of a strong reference
|
|
129
|
+
// already held by the caller (a "new reference"). The reference count is
|
|
130
|
+
// NOT incremented; the stored object's ownership is simply transferred
|
|
131
|
+
// into the storage, and the destructor will release it exactly once.
|
|
132
|
+
static PyObjectStorage from_new_ref(PyObject* obj) noexcept {
|
|
133
|
+
PyObjectStorage storage;
|
|
134
|
+
storage.obj = obj;
|
|
135
|
+
return storage;
|
|
136
|
+
}
|
|
137
|
+
static PyObjectStorage from_new_ref(PyCodeObject* obj) noexcept {
|
|
138
|
+
return from_new_ref(reinterpret_cast<PyObject*>(obj));
|
|
139
|
+
}
|
|
128
140
|
// support for PyCodeObject*
|
|
129
141
|
PyObjectStorage(PyCodeObject* obj) noexcept : obj(reinterpret_cast<PyObject*>(obj)) {
|
|
130
142
|
Py_XINCREF(obj);
|
|
@@ -176,9 +188,10 @@ public:
|
|
|
176
188
|
return obj;
|
|
177
189
|
}
|
|
178
190
|
|
|
179
|
-
operator
|
|
180
|
-
return
|
|
191
|
+
explicit operator bool() const noexcept {
|
|
192
|
+
return obj != NULL;
|
|
181
193
|
}
|
|
194
|
+
|
|
182
195
|
PyObject* get() const noexcept {
|
|
183
196
|
return obj;
|
|
184
197
|
}
|
|
@@ -506,22 +519,22 @@ custom_random_string(uintptr_t obj_id, const std::string& attr_name, PyObject* f
|
|
|
506
519
|
return result;
|
|
507
520
|
} else {
|
|
508
521
|
lock.unlock();
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
522
|
+
PyObjectStorage python_result = PyObjectStorage::from_new_ref(
|
|
523
|
+
PyObject_CallFunction(
|
|
524
|
+
func,
|
|
525
|
+
"Ks",
|
|
526
|
+
static_cast<unsigned long long>(obj_id),
|
|
527
|
+
attr_name.c_str()
|
|
528
|
+
)
|
|
514
529
|
);
|
|
515
530
|
if (python_result) {
|
|
516
531
|
if (!PyUnicode_Check(python_result)) {
|
|
517
|
-
|
|
518
|
-
PyErr_SetString(PyExc_TypeError, "private_func function must return a string");
|
|
532
|
+
PyErr_Format(PyExc_TypeError, "private_func function must return a string, not '%s'", Py_TYPE(python_result)->tp_name);
|
|
519
533
|
result.ok = false;
|
|
520
534
|
result.value = "private_func function must return a string";
|
|
521
535
|
return result;
|
|
522
536
|
}
|
|
523
537
|
result.value = PyUnicode_AsUTF8(python_result);
|
|
524
|
-
Py_DECREF(python_result);
|
|
525
538
|
std::string original_result = result.value;
|
|
526
539
|
unsigned long long i = 1;
|
|
527
540
|
std::unique_lock<std::shared_mutex> lock2(::AllData::cache_mutex);
|
|
@@ -1462,6 +1475,10 @@ PrivateWrap_New(PyObject *decorator, PyObject *func, PyObject *list) noexcept
|
|
|
1462
1475
|
|
|
1463
1476
|
PrivateWrapObject *self =
|
|
1464
1477
|
PyObject_GC_New(PrivateWrapObject, &PrivateWrapType);
|
|
1478
|
+
if (!self) {
|
|
1479
|
+
Py_DECREF(wrapped);
|
|
1480
|
+
return NULL;
|
|
1481
|
+
}
|
|
1465
1482
|
self->func_list = list;
|
|
1466
1483
|
Py_INCREF(list);
|
|
1467
1484
|
|
|
@@ -1499,19 +1516,20 @@ PrivateWrapProxy_call(PrivateWrapProxyObject *self, PyObject *args, PyObject* /*
|
|
|
1499
1516
|
PyObject *func;
|
|
1500
1517
|
if (!PyArg_ParseTuple(args, "O:private_attribute.PrivateWrapProxy.__call__", &func)) return NULL;
|
|
1501
1518
|
if(PyObject_TypeCheck(func, &PrivateWrapType)) {
|
|
1519
|
+
PyObjectStorage final_func_list = PyObjectStorage::from_new_ref(
|
|
1520
|
+
PySequence_Concat(((PrivateWrapObject*)func)->func_list, self->func_list));
|
|
1502
1521
|
return (PyObject*)PrivateWrap_New(
|
|
1503
1522
|
self->decorator,
|
|
1504
1523
|
((PrivateWrapObject*)func)->result,
|
|
1505
|
-
|
|
1506
|
-
self->func_list)
|
|
1524
|
+
final_func_list
|
|
1507
1525
|
);
|
|
1508
1526
|
}
|
|
1509
1527
|
|
|
1510
1528
|
PyObject *new_list = PyList_New(0);
|
|
1511
1529
|
PyList_Append(new_list, func);
|
|
1512
1530
|
|
|
1513
|
-
|
|
1514
|
-
PySequence_Concat(new_list, self->func_list);
|
|
1531
|
+
PyObjectStorage combined =
|
|
1532
|
+
PyObjectStorage::from_new_ref(PySequence_Concat(new_list, self->func_list));
|
|
1515
1533
|
|
|
1516
1534
|
return (PyObject*)PrivateWrap_New(
|
|
1517
1535
|
self->decorator,
|
|
@@ -1668,25 +1686,24 @@ PrivateAttr_tp_getattro(PyObject* self, PyObject* name) noexcept
|
|
|
1668
1686
|
uintptr_t type_id = (uintptr_t)typ;
|
|
1669
1687
|
PrivateAttr_object_init_private_dict((uintptr_t)self, type_id);
|
|
1670
1688
|
std::string name_str = PyUnicode_AsUTF8(name);
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
if (
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1689
|
+
{
|
|
1690
|
+
PyObjectStorage code = PyObjectStorage::from_new_ref(get_now_code());
|
|
1691
|
+
if (type_private_attr(type_id, name_str)) {
|
|
1692
|
+
if (!code) {
|
|
1693
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
1694
|
+
return NULL;
|
|
1695
|
+
}
|
|
1696
|
+
AttrClassifyResult classify = attr_classify(type_id, name_str, (PyCodeObject*)(code.get()));
|
|
1697
|
+
if (!classify.allowed) {
|
|
1698
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
1699
|
+
return NULL;
|
|
1700
|
+
}
|
|
1701
|
+
if (classify.type_id != 0) {
|
|
1702
|
+
return id_getattr(classify.type_id, name_str, self, (PyObject*)typ);
|
|
1703
|
+
}
|
|
1704
|
+
// owner is 0: not private for this access context -> normal attribute
|
|
1686
1705
|
}
|
|
1687
|
-
// owner is 0: not private for this access context -> normal attribute
|
|
1688
1706
|
}
|
|
1689
|
-
Py_XDECREF(code);
|
|
1690
1707
|
if (::AllData::all_type_getattro.find(type_id) != ::AllData::all_type_getattro.end()){
|
|
1691
1708
|
if (::AllData::all_type_getattro[type_id]) {
|
|
1692
1709
|
PyObject* result = ::AllData::all_type_getattro[type_id](self, name);
|
|
@@ -1707,28 +1724,27 @@ PrivateAttr_tp_setattro(PyObject* self, PyObject* name, PyObject* value) noexcep
|
|
|
1707
1724
|
return -1;
|
|
1708
1725
|
}
|
|
1709
1726
|
std::string name_str(c_name);
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
if (
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
return -1;
|
|
1722
|
-
}
|
|
1723
|
-
if (classify.type_id != 0) {
|
|
1724
|
-
if (!value) {
|
|
1725
|
-
return id_delattr(classify.type_id, name_str, self, (PyObject*)typ);
|
|
1727
|
+
{
|
|
1728
|
+
PyObjectStorage code = PyObjectStorage::from_new_ref(get_now_code());
|
|
1729
|
+
if (type_private_attr(typ_id, name_str)) {
|
|
1730
|
+
if (!code) {
|
|
1731
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
1732
|
+
return -1;
|
|
1733
|
+
}
|
|
1734
|
+
AttrClassifyResult classify = attr_classify(typ_id, name_str, (PyCodeObject*)(code.get()));
|
|
1735
|
+
if (!classify.allowed) {
|
|
1736
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
1737
|
+
return -1;
|
|
1726
1738
|
}
|
|
1727
|
-
|
|
1739
|
+
if (classify.type_id != 0) {
|
|
1740
|
+
if (!value) {
|
|
1741
|
+
return id_delattr(classify.type_id, name_str, self, (PyObject*)typ);
|
|
1742
|
+
}
|
|
1743
|
+
return id_setattr(classify.type_id, name_str, self, (PyObject*)typ, value);
|
|
1744
|
+
}
|
|
1745
|
+
// owner is 0: not private for this access context -> normal attribute
|
|
1728
1746
|
}
|
|
1729
|
-
// owner is 0: not private for this access context -> normal attribute
|
|
1730
1747
|
}
|
|
1731
|
-
Py_XDECREF(code);
|
|
1732
1748
|
if (::AllData::all_type_setattro.find(typ_id) != ::AllData::all_type_setattro.end()){
|
|
1733
1749
|
int result = ::AllData::all_type_setattro[typ_id](self, name, value);
|
|
1734
1750
|
ensure_tp(typ);
|
|
@@ -2636,10 +2652,9 @@ analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyObjectStorage>&
|
|
|
2636
2652
|
Py_ssize_t len = PySequence_Length(co_contain);
|
|
2637
2653
|
if (len >= 0) {
|
|
2638
2654
|
for (Py_ssize_t i = 0; i < len; i++) {
|
|
2639
|
-
|
|
2655
|
+
PyObjectStorage item = PyObjectStorage::from_new_ref(PySequence_GetItem(co_contain, i));
|
|
2640
2656
|
if (item) {
|
|
2641
2657
|
analyse_all_code(item, map, _seen);
|
|
2642
|
-
Py_DECREF(item);
|
|
2643
2658
|
}
|
|
2644
2659
|
}
|
|
2645
2660
|
}
|
|
@@ -2653,10 +2668,9 @@ analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyObjectStorage>&
|
|
|
2653
2668
|
Py_ssize_t len = PySequence_Length(func_list);
|
|
2654
2669
|
if (len >= 0) {
|
|
2655
2670
|
for (Py_ssize_t i = 0; i < len; i++) {
|
|
2656
|
-
|
|
2671
|
+
PyObjectStorage func = PyObjectStorage::from_new_ref(PySequence_GetItem(func_list, i));
|
|
2657
2672
|
if (func) {
|
|
2658
2673
|
analyse_all_code(func, map, _seen);
|
|
2659
|
-
Py_DECREF(func);
|
|
2660
2674
|
}
|
|
2661
2675
|
}
|
|
2662
2676
|
}
|
|
@@ -2664,50 +2678,44 @@ analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyObjectStorage>&
|
|
|
2664
2678
|
return;
|
|
2665
2679
|
}
|
|
2666
2680
|
if (PyObject_TypeCheck(obj, &PyProperty_Type)) {
|
|
2667
|
-
|
|
2681
|
+
PyObjectStorage fget = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "fget"));
|
|
2668
2682
|
if (fget) {
|
|
2669
2683
|
analyse_all_code(fget, map, _seen);
|
|
2670
|
-
Py_DECREF(fget);
|
|
2671
2684
|
}
|
|
2672
|
-
|
|
2685
|
+
PyObjectStorage fset = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "fset"));
|
|
2673
2686
|
if (fset) {
|
|
2674
2687
|
analyse_all_code(fset, map, _seen);
|
|
2675
|
-
Py_DECREF(fset);
|
|
2676
2688
|
}
|
|
2677
|
-
PyObject* fdel = try_get_attr_string(obj, "fdel");
|
|
2689
|
+
PyObject* fdel = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "fdel"));
|
|
2678
2690
|
if (fdel) {
|
|
2679
2691
|
analyse_all_code(fdel, map, _seen);
|
|
2680
|
-
Py_DECREF(fdel);
|
|
2681
2692
|
}
|
|
2682
2693
|
return;
|
|
2683
2694
|
}
|
|
2684
2695
|
if (PyObject_TypeCheck(obj, &PyClassMethod_Type) || PyObject_TypeCheck(obj, &PyStaticMethod_Type)) {
|
|
2685
|
-
|
|
2696
|
+
PyObjectStorage func = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "__func__"));
|
|
2686
2697
|
if (func) {
|
|
2687
2698
|
analyse_all_code(func, map, _seen);
|
|
2688
|
-
Py_DECREF(func);
|
|
2689
2699
|
}
|
|
2690
2700
|
return;
|
|
2691
2701
|
}
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
if (wrap
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2702
|
+
{
|
|
2703
|
+
PyObjectStorage wrap = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "__wrapped__"));
|
|
2704
|
+
if (wrap) {
|
|
2705
|
+
if (wrap == obj) {
|
|
2706
|
+
PyObjectStorage code = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "__code__"));
|
|
2707
|
+
if (code) {
|
|
2708
|
+
analyse_all_code(code, map, _seen);
|
|
2709
|
+
}
|
|
2710
|
+
return;
|
|
2699
2711
|
}
|
|
2700
|
-
|
|
2712
|
+
analyse_all_code(wrap, map, _seen);
|
|
2701
2713
|
return;
|
|
2702
2714
|
}
|
|
2703
|
-
analyse_all_code(wrap, map, _seen);
|
|
2704
|
-
Py_DECREF(wrap);
|
|
2705
|
-
return;
|
|
2706
2715
|
}
|
|
2707
|
-
|
|
2716
|
+
PyObjectStorage code = PyObjectStorage::from_new_ref(try_get_attr_string(obj, "__code__"));
|
|
2708
2717
|
if (code) {
|
|
2709
2718
|
analyse_all_code(code, map, _seen);
|
|
2710
|
-
Py_DECREF(code);
|
|
2711
2719
|
}
|
|
2712
2720
|
}
|
|
2713
2721
|
|
|
@@ -2854,8 +2862,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2854
2862
|
__private_attrs__ = PyDict_GetItemString(data.attrs, "__private_attrs__");
|
|
2855
2863
|
}
|
|
2856
2864
|
else {
|
|
2857
|
-
__private_attrs__ = PyTuple_New(0);
|
|
2858
|
-
Py_DECREF(__private_attrs__);
|
|
2865
|
+
__private_attrs__ = PyObjectStorage::from_new_ref(PyTuple_New(0));
|
|
2859
2866
|
}
|
|
2860
2867
|
|
|
2861
2868
|
if (PyUnicode_Check(__private_attrs__)) {
|
|
@@ -2864,8 +2871,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2864
2871
|
return false;
|
|
2865
2872
|
}
|
|
2866
2873
|
PyTuple_SET_ITEM(new___private_attrs__, 0, __private_attrs__);
|
|
2867
|
-
__private_attrs__ = new___private_attrs__;
|
|
2868
|
-
Py_DECREF(__private_attrs__);
|
|
2874
|
+
__private_attrs__ = PyObjectStorage::from_new_ref(new___private_attrs__);
|
|
2869
2875
|
}
|
|
2870
2876
|
|
|
2871
2877
|
if (!PySequence_Check(__private_attrs__)) {
|
|
@@ -2935,41 +2941,38 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2935
2941
|
if (PyUnicode_Check(all_slots)) {
|
|
2936
2942
|
const char* slot_cstr = PyUnicode_AsUTF8(all_slots);
|
|
2937
2943
|
if (data.private_attrs_vector_string.find((std::string)slot_cstr) != data.private_attrs_vector_string.end()){
|
|
2938
|
-
|
|
2939
|
-
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
2944
|
+
PyErr_Format(PyExc_TypeError, "'__slots__' and '__private_attrs__' cannot have the same attribute name: '%s'", slot_cstr);
|
|
2940
2945
|
return false;
|
|
2941
2946
|
}
|
|
2942
2947
|
} else {
|
|
2943
|
-
|
|
2948
|
+
PyObjectStorage slot_seq;
|
|
2944
2949
|
if (PyAnyDict_Check(all_slots)) {
|
|
2945
2950
|
// use the key of the dict as the slot name
|
|
2946
2951
|
PyObject* keys = PyDict_Keys(all_slots);
|
|
2947
2952
|
if (!keys) {
|
|
2948
2953
|
return false;
|
|
2949
2954
|
}
|
|
2950
|
-
slot_seq = keys;
|
|
2955
|
+
slot_seq = PyObjectStorage::from_new_ref(keys);
|
|
2951
2956
|
} else {
|
|
2952
|
-
slot_seq = PySequence_Fast(all_slots, "__slots__ must be a string, dict or sequence");
|
|
2957
|
+
slot_seq = PyObjectStorage::from_new_ref(PySequence_Fast(all_slots, "__slots__ must be a string, dict or sequence"));
|
|
2953
2958
|
}
|
|
2954
|
-
if (!slot_seq) {
|
|
2959
|
+
if (!slot_seq.get()) {
|
|
2955
2960
|
return false;
|
|
2956
2961
|
}
|
|
2957
2962
|
|
|
2958
|
-
Py_ssize_t slot_len = PySequence_Fast_GET_SIZE(slot_seq);
|
|
2963
|
+
Py_ssize_t slot_len = PySequence_Fast_GET_SIZE(slot_seq.get());
|
|
2959
2964
|
|
|
2960
2965
|
for (Py_ssize_t j = 0; j < slot_len; j++) {
|
|
2961
|
-
PyObject* slot = PySequence_Fast_GET_ITEM(slot_seq, j);
|
|
2966
|
+
PyObject* slot = PySequence_Fast_GET_ITEM(slot_seq.get(), j);
|
|
2962
2967
|
if (PyUnicode_Check(slot)) {
|
|
2963
2968
|
const char* slot_cstr = PyUnicode_AsUTF8(slot);
|
|
2964
2969
|
std::string final_name = real_class_name(slot_cstr, data.class_name);
|
|
2965
2970
|
if (data.private_attrs_vector_string.find(final_name) != data.private_attrs_vector_string.end()){
|
|
2966
2971
|
PyErr_Format(PyExc_TypeError, "'__slots__' and '__private_attrs__' cannot have the same attribute name: '%s'", final_name.c_str());
|
|
2967
|
-
Py_DECREF(slot_seq);
|
|
2968
2972
|
return false;
|
|
2969
2973
|
}
|
|
2970
2974
|
}
|
|
2971
2975
|
}
|
|
2972
|
-
Py_DECREF(slot_seq);
|
|
2973
2976
|
}
|
|
2974
2977
|
}
|
|
2975
2978
|
|
|
@@ -2999,7 +3002,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2999
3002
|
{
|
|
3000
3003
|
Py_ssize_t pos = 0;
|
|
3001
3004
|
PyObject* key, *value;
|
|
3002
|
-
|
|
3005
|
+
PyObjectStorage forward_analyse = PyObjectStorage::from_new_ref(PyDict_Copy(data.attrs_copy));
|
|
3003
3006
|
while (PyDict_Next(forward_analyse, &pos, &key, &value)) {
|
|
3004
3007
|
if (!key || !PyUnicode_Check(key)) {
|
|
3005
3008
|
PyErr_SetString(PyExc_TypeError, "all keys in 'attrs' must be strings");
|
|
@@ -3038,7 +3041,6 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
3038
3041
|
if (PyDict_SetItem(data.attrs_copy, key, need_value) < 0) return false;
|
|
3039
3042
|
}
|
|
3040
3043
|
}
|
|
3041
|
-
Py_DECREF(forward_analyse);
|
|
3042
3044
|
}
|
|
3043
3045
|
|
|
3044
3046
|
// get "private_func" from kwds
|
|
@@ -3314,7 +3316,8 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
3314
3316
|
}
|
|
3315
3317
|
|
|
3316
3318
|
if (data.private_func) {
|
|
3317
|
-
|
|
3319
|
+
// The PyObjectStorage assignment already INCREFs (RAII); the manual
|
|
3320
|
+
// INCREF was removed to avoid a +1 leak.
|
|
3318
3321
|
::AllData::type_need_call[type_id] = data.private_func;
|
|
3319
3322
|
}
|
|
3320
3323
|
|
|
@@ -3402,25 +3405,23 @@ PrivateAttrType_getattr(PyObject* cls, PyObject* name) noexcept
|
|
|
3402
3405
|
}
|
|
3403
3406
|
uintptr_t typ_id = (uintptr_t)(cls);
|
|
3404
3407
|
std::string name_str = PyUnicode_AsUTF8(name);
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
if (
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3408
|
+
{
|
|
3409
|
+
PyObjectStorage now_code = PyObjectStorage::from_new_ref(get_now_code());
|
|
3410
|
+
if (type_private_attr(typ_id, name_str)) {
|
|
3411
|
+
if (!now_code) {
|
|
3412
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
3413
|
+
return NULL;
|
|
3414
|
+
}
|
|
3415
|
+
AttrClassifyResult classify = attr_classify(typ_id, name_str, (PyCodeObject*)(now_code.get()));
|
|
3416
|
+
if (!classify.allowed) {
|
|
3417
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
3418
|
+
return NULL;
|
|
3419
|
+
}
|
|
3420
|
+
if (classify.type_id != 0) {
|
|
3421
|
+
return type_getattr(cls, name_str);
|
|
3422
|
+
}
|
|
3420
3423
|
}
|
|
3421
|
-
// owner is 0: not private for this access context -> normal attribute
|
|
3422
3424
|
}
|
|
3423
|
-
Py_XDECREF(now_code);
|
|
3424
3425
|
PyTypeObject* base = Py_TYPE(cls)->tp_base;
|
|
3425
3426
|
while (base && base->tp_base && base->tp_getattro == PrivateAttrType_getattr) {
|
|
3426
3427
|
base = base->tp_base;
|
|
@@ -3493,35 +3494,31 @@ init_all_slots() noexcept
|
|
|
3493
3494
|
return 0;
|
|
3494
3495
|
}
|
|
3495
3496
|
original_type_tp_setattro = PyType_Type.tp_setattro;
|
|
3496
|
-
|
|
3497
|
+
PyObjectStorage original_setattr = PyObjectStorage::from_new_ref(PyObject_GetAttrString((PyObject*)&PyType_Type, "__setattr__"));
|
|
3497
3498
|
if (!original_setattr) {return -1;}
|
|
3498
3499
|
if (original_setattr && PyObject_IsInstance(original_setattr, (PyObject*)&PyWrapperDescr_Type)) {
|
|
3499
|
-
((PyWrapperDescrObject*)original_setattr)->d_wrapped = (void*)new_type_tp_setattro;
|
|
3500
|
+
((PyWrapperDescrObject*)(original_setattr.get()))->d_wrapped = (void*)new_type_tp_setattro;
|
|
3500
3501
|
}
|
|
3501
|
-
|
|
3502
|
-
PyObject* original_delattr = PyObject_GetAttrString((PyObject*)&PyType_Type, "__delattr__");
|
|
3502
|
+
PyObjectStorage original_delattr = PyObjectStorage::from_new_ref(PyObject_GetAttrString((PyObject*)&PyType_Type, "__delattr__"));
|
|
3503
3503
|
if (!original_delattr) {return -1;}
|
|
3504
3504
|
if (original_delattr && PyObject_IsInstance(original_delattr, (PyObject*)&PyWrapperDescr_Type)) {
|
|
3505
|
-
((PyWrapperDescrObject*)original_delattr)->d_wrapped = (void*)new_type_tp_setattro;
|
|
3505
|
+
((PyWrapperDescrObject*)(original_delattr.get()))->d_wrapped = (void*)new_type_tp_setattro;
|
|
3506
3506
|
}
|
|
3507
|
-
Py_DECREF(original_delattr);
|
|
3508
3507
|
PyType_Type.tp_setattro = new_type_tp_setattro;
|
|
3509
|
-
|
|
3508
|
+
PyObjectStorage all_metaclasses = PyObjectStorage::from_new_ref(PyObject_CallMethod((PyObject*)&PyType_Type, "__subclasses__", "O", (PyObject*)&PyType_Type));
|
|
3510
3509
|
if (!all_metaclasses) {return -1;}
|
|
3511
3510
|
if (!PyList_Check(all_metaclasses)) {
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
return 0;
|
|
3511
|
+
PyErr_SetString(PyExc_TypeError, "subclasses of type is not list");
|
|
3512
|
+
return -1;
|
|
3515
3513
|
}
|
|
3516
|
-
Py_ssize_t list_len = PyList_GET_SIZE(all_metaclasses);
|
|
3514
|
+
Py_ssize_t list_len = PyList_GET_SIZE(all_metaclasses.get());
|
|
3517
3515
|
for (Py_ssize_t i = 0; i < list_len; i++) {
|
|
3518
|
-
PyObject* metaclass = PyList_GET_ITEM(all_metaclasses, i);
|
|
3516
|
+
PyObject* metaclass = PyList_GET_ITEM(all_metaclasses.get(), i);
|
|
3519
3517
|
if (!PyType_Check(metaclass)) {continue;}
|
|
3520
3518
|
if (((PyTypeObject*)metaclass)->tp_setattro == original_type_tp_setattro) {
|
|
3521
3519
|
((PyTypeObject*)metaclass)->tp_setattro = new_type_tp_setattro;
|
|
3522
3520
|
}
|
|
3523
3521
|
}
|
|
3524
|
-
Py_DECREF(all_metaclasses);
|
|
3525
3522
|
has_init_slots = true;
|
|
3526
3523
|
return 0;
|
|
3527
3524
|
}
|
|
@@ -3756,25 +3753,24 @@ PrivateAttrType_setattr(PyObject* cls, PyObject* name, PyObject* value) noexcept
|
|
|
3756
3753
|
PyErr_SetString(PyExc_TypeError, error_message.c_str());
|
|
3757
3754
|
return -1;
|
|
3758
3755
|
}
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
if (
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3756
|
+
{
|
|
3757
|
+
PyObjectStorage now_code = PyObjectStorage::from_new_ref(get_now_code());
|
|
3758
|
+
if (type_private_attr(typ_id, name_str)) {
|
|
3759
|
+
if (!now_code) {
|
|
3760
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
3761
|
+
return -1;
|
|
3762
|
+
}
|
|
3763
|
+
AttrClassifyResult classify = attr_classify(typ_id, name_str, (PyCodeObject*)(now_code.get()));
|
|
3764
|
+
if (!classify.allowed) {
|
|
3765
|
+
PyErr_SetString(PyExc_AttributeError, "private attribute");
|
|
3766
|
+
return -1;
|
|
3767
|
+
}
|
|
3768
|
+
if (classify.type_id != 0) {
|
|
3769
|
+
return type_setattr(cls, name_str, value);
|
|
3770
|
+
}
|
|
3771
|
+
// owner is 0: not private for this access context -> normal attribute
|
|
3774
3772
|
}
|
|
3775
|
-
// owner is 0: not private for this access context -> normal attribute
|
|
3776
3773
|
}
|
|
3777
|
-
Py_XDECREF(now_code);
|
|
3778
3774
|
PyTypeObject* base = Py_TYPE(cls)->tp_base;
|
|
3779
3775
|
while (base && base->tp_base && base->tp_setattro == PrivateAttrType_setattr) {
|
|
3780
3776
|
base = base->tp_base;
|
|
@@ -3854,86 +3850,55 @@ PrivateAttrType_del(PyObject* cls) noexcept
|
|
|
3854
3850
|
PyType_Type.tp_dealloc(cls);
|
|
3855
3851
|
}
|
|
3856
3852
|
|
|
3857
|
-
static const char* PrivateAttrBase_doc = "The class to help
|
|
3853
|
+
static const char* PrivateAttrBase_doc = "The class to help creating private attribute. It does not have any special behavior.";
|
|
3858
3854
|
|
|
3859
3855
|
// PrivateAttrBase
|
|
3860
3856
|
static PyObject*
|
|
3861
3857
|
create_private_attr_base_simple(void) noexcept
|
|
3862
3858
|
{
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
PyObject* dict = NULL;
|
|
3866
|
-
PyObject* private_attrs = NULL;
|
|
3867
|
-
PyObject* doc = NULL;
|
|
3868
|
-
PyObject* module_name = NULL;
|
|
3869
|
-
PyObject* args = NULL;
|
|
3870
|
-
PyObject* base_type = NULL;
|
|
3871
|
-
|
|
3872
|
-
name = PyUnicode_InternFromString("PrivateAttrBase");
|
|
3873
|
-
if (!name) goto fail;
|
|
3874
|
-
|
|
3875
|
-
bases = PyTuple_New(0);
|
|
3876
|
-
if (!bases) goto fail;
|
|
3859
|
+
PyObjectStorage name = PyObjectStorage::from_new_ref(PyUnicode_InternFromString("PrivateAttrBase"));
|
|
3860
|
+
if (!name) return NULL;
|
|
3877
3861
|
|
|
3878
|
-
|
|
3879
|
-
if (!
|
|
3862
|
+
PyObjectStorage bases = PyObjectStorage::from_new_ref(PyTuple_New(0));
|
|
3863
|
+
if (!bases) return NULL;
|
|
3880
3864
|
|
|
3881
|
-
|
|
3882
|
-
if (!
|
|
3865
|
+
PyObjectStorage dict = PyObjectStorage::from_new_ref(PyDict_New());
|
|
3866
|
+
if (!dict) return NULL;
|
|
3883
3867
|
|
|
3884
|
-
|
|
3885
|
-
if (!
|
|
3868
|
+
PyObjectStorage private_attrs = PyObjectStorage::from_new_ref(PyTuple_New(0));
|
|
3869
|
+
if (!private_attrs) return NULL;
|
|
3886
3870
|
|
|
3887
|
-
|
|
3888
|
-
if (!
|
|
3871
|
+
PyObjectStorage doc = PyObjectStorage::from_new_ref(PyUnicode_InternFromString(PrivateAttrBase_doc));
|
|
3872
|
+
if (!doc) return NULL;
|
|
3889
3873
|
|
|
3890
|
-
|
|
3891
|
-
if (
|
|
3892
|
-
if (PyDict_SetItemString(dict, "__doc__", doc) < 0) goto fail;
|
|
3893
|
-
if (PyDict_SetItemString(dict, "__module__", module_name) < 0) goto fail;
|
|
3874
|
+
PyObjectStorage module_name = PyObjectStorage::from_new_ref(PyUnicode_InternFromString("private_attribute"));
|
|
3875
|
+
if (!module_name) return NULL;
|
|
3894
3876
|
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
module_name
|
|
3877
|
+
if (PyDict_SetItemString(dict, "__private_attrs__", private_attrs) < 0) return NULL;
|
|
3878
|
+
if (PyDict_SetItemString(dict, "__slots__", private_attrs) < 0) return NULL;
|
|
3879
|
+
if (PyDict_SetItemString(dict, "__doc__", doc) < 0) return NULL;
|
|
3880
|
+
if (PyDict_SetItemString(dict, "__module__", module_name) < 0) return NULL;
|
|
3899
3881
|
|
|
3900
|
-
args = PyTuple_Pack(3, name, bases, dict);
|
|
3901
|
-
if (!args)
|
|
3882
|
+
PyObjectStorage args = PyObjectStorage::from_new_ref(PyTuple_Pack(3, name.get(), bases.get(), dict.get()));
|
|
3883
|
+
if (!args) return NULL;
|
|
3902
3884
|
|
|
3885
|
+
PyObject* base_type = NULL;
|
|
3903
3886
|
{
|
|
3904
3887
|
// RAII: the first heap type created through tp_new (PrivateAttrBase)
|
|
3905
3888
|
// carries CPython's pristine subtype_traverse/subtype_clear in its
|
|
3906
3889
|
// tp_traverse/tp_clear; PrivateAttrType_new captures those pointers
|
|
3907
3890
|
// while this guard is active.
|
|
3908
3891
|
PrivateAttrCaptureGuard capture_guard;
|
|
3909
|
-
base_type = PrivateAttrType_new((PyTypeObject*)&PrivateAttrType, args, NULL);
|
|
3892
|
+
base_type = PrivateAttrType_new((PyTypeObject*)&PrivateAttrType, args.get(), NULL);
|
|
3910
3893
|
}
|
|
3911
|
-
Py_DECREF(args);
|
|
3912
|
-
args = NULL;
|
|
3913
|
-
|
|
3914
|
-
Py_DECREF(name);
|
|
3915
|
-
name = NULL;
|
|
3916
|
-
Py_DECREF(bases);
|
|
3917
|
-
bases = NULL;
|
|
3918
|
-
Py_DECREF(dict);
|
|
3919
|
-
dict = NULL;
|
|
3920
3894
|
|
|
3921
|
-
if (!base_type)
|
|
3895
|
+
if (!base_type) return NULL;
|
|
3922
3896
|
|
|
3923
3897
|
((PyTypeObject*)base_type)->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
|
3924
3898
|
return base_type;
|
|
3925
|
-
|
|
3926
|
-
fail:
|
|
3927
|
-
Py_XDECREF(name);
|
|
3928
|
-
Py_XDECREF(bases);
|
|
3929
|
-
Py_XDECREF(dict);
|
|
3930
|
-
Py_XDECREF(private_attrs);
|
|
3931
|
-
Py_XDECREF(doc);
|
|
3932
|
-
Py_XDECREF(module_name);
|
|
3933
|
-
Py_XDECREF(args);
|
|
3934
|
-
return NULL;
|
|
3935
3899
|
}
|
|
3936
3900
|
|
|
3901
|
+
|
|
3937
3902
|
typedef struct {
|
|
3938
3903
|
PyObject_HEAD
|
|
3939
3904
|
PrivateAttrCreationData* tmp;
|
|
@@ -4132,7 +4097,8 @@ metaclass_weakref_callback(PyObject* self, PyObject* /*weakref*/) noexcept
|
|
|
4132
4097
|
|
|
4133
4098
|
auto it = ::AllData::all_register_type_weak_ref.find(id);
|
|
4134
4099
|
if (it != ::AllData::all_register_type_weak_ref.end()) {
|
|
4135
|
-
|
|
4100
|
+
// The PyObjectStorage destructor releases the stored reference on
|
|
4101
|
+
// erase; do not DECREF here (double-DECREF).
|
|
4136
4102
|
::AllData::all_register_type_weak_ref.erase(it);
|
|
4137
4103
|
}
|
|
4138
4104
|
METACLASS_WEAKREF_CALLBACK_REMOVE_ITEM(getattro);
|
|
@@ -4229,7 +4195,9 @@ register_metaclass_head(PyObject* metaclass) noexcept
|
|
|
4229
4195
|
Py_DECREF(capsule);
|
|
4230
4196
|
return NULL;
|
|
4231
4197
|
}
|
|
4232
|
-
|
|
4198
|
+
// PyWeakref_NewRef returns a new reference; transfer it into the storage
|
|
4199
|
+
// without an extra INCREF (which the plain assignment operator would add).
|
|
4200
|
+
::AllData::all_register_type_weak_ref[id] = PyObjectStorage::from_new_ref(ref);
|
|
4233
4201
|
PyTypeObject* mt = (PyTypeObject*)metaclass;
|
|
4234
4202
|
// Save the ORIGINAL slots before wrapping. Always resolve through the
|
|
4235
4203
|
// get_type_need_tp_* walkers so a delegating default (CPython's
|
|
@@ -4374,50 +4342,33 @@ PrivateModule_get_PrivateAttrBase(PyObject* /*self*/, void* /*closure*/) noexcep
|
|
|
4374
4342
|
return NULL;
|
|
4375
4343
|
}
|
|
4376
4344
|
AllData::store_module_self[AllData::kPrivateAttrBaseKey] = base;
|
|
4377
|
-
|
|
4378
|
-
it = AllData::store_module_self.find(AllData::kPrivateAttrBaseKey);
|
|
4345
|
+
return base;
|
|
4379
4346
|
}
|
|
4380
4347
|
PyObject* PrivateAttrBase = it->second.get();
|
|
4381
4348
|
Py_INCREF(PrivateAttrBase);
|
|
4382
4349
|
return PrivateAttrBase;
|
|
4383
4350
|
}
|
|
4384
4351
|
|
|
4385
|
-
static int
|
|
4386
|
-
PyList_AppendString(PyObject* list, const char* str) noexcept
|
|
4387
|
-
{
|
|
4388
|
-
PyObject* obj = PyUnicode_InternFromString(str);
|
|
4389
|
-
if (!obj) return -1;
|
|
4390
|
-
if (PyList_Append(list, obj) < 0) {
|
|
4391
|
-
Py_DECREF(obj);
|
|
4392
|
-
return -1;
|
|
4393
|
-
}
|
|
4394
|
-
Py_DECREF(obj);
|
|
4395
|
-
return 0;
|
|
4396
|
-
}
|
|
4397
|
-
|
|
4398
|
-
#define DIR_CHECK(command) do {if (command < 0) goto finally;} while (0)
|
|
4399
|
-
|
|
4400
4352
|
static PyObject*
|
|
4401
4353
|
PrivateModule_dir(PyObject* self, PyObject* /*args*/) noexcept
|
|
4402
4354
|
{
|
|
4403
4355
|
PyObject* parent_dir = PyObject_CallMethod((PyObject*)&PyModule_Type, "__dir__", "O", self);
|
|
4404
4356
|
if (!parent_dir) return NULL;
|
|
4405
|
-
PyObject* attr_list =
|
|
4357
|
+
PyObject* attr_list = Py_BuildValue("[ssssssss]",
|
|
4358
|
+
"PrivateWrapProxy",
|
|
4359
|
+
"PrivateAttrType",
|
|
4360
|
+
"PrivateAttrBase",
|
|
4361
|
+
"prepare",
|
|
4362
|
+
"postprocess",
|
|
4363
|
+
"register_metaclass",
|
|
4364
|
+
"ensure_type",
|
|
4365
|
+
"ensure_metaclass"
|
|
4366
|
+
);
|
|
4406
4367
|
if (!attr_list) {
|
|
4407
4368
|
Py_DECREF(parent_dir);
|
|
4408
4369
|
return NULL;
|
|
4409
4370
|
}
|
|
4410
|
-
PyObject* result =
|
|
4411
|
-
DIR_CHECK(PyList_AppendString(attr_list, "PrivateWrapProxy"));
|
|
4412
|
-
DIR_CHECK(PyList_AppendString(attr_list, "PrivateAttrType"));
|
|
4413
|
-
DIR_CHECK(PyList_AppendString(attr_list, "PrivateAttrBase"));
|
|
4414
|
-
DIR_CHECK(PyList_AppendString(attr_list, "prepare"));
|
|
4415
|
-
DIR_CHECK(PyList_AppendString(attr_list, "postprocess"));
|
|
4416
|
-
DIR_CHECK(PyList_AppendString(attr_list, "register_metaclass"));
|
|
4417
|
-
DIR_CHECK(PyList_AppendString(attr_list, "ensure_type"));
|
|
4418
|
-
DIR_CHECK(PyList_AppendString(attr_list, "ensure_metaclass"));
|
|
4419
|
-
result = PySequence_Concat(parent_dir, attr_list);
|
|
4420
|
-
finally:
|
|
4371
|
+
PyObject* result = PySequence_Concat(parent_dir, attr_list);
|
|
4421
4372
|
Py_DECREF(parent_dir);
|
|
4422
4373
|
Py_DECREF(attr_list);
|
|
4423
4374
|
return result;
|
|
@@ -4676,25 +4627,21 @@ atexit_register_clean_func(void) noexcept
|
|
|
4676
4627
|
if (resigtered_clean_func) {
|
|
4677
4628
|
return 0;
|
|
4678
4629
|
}
|
|
4679
|
-
|
|
4630
|
+
PyObjectStorage atexit = PyObjectStorage::from_new_ref(PyImport_ImportModule("atexit"));
|
|
4680
4631
|
if (!atexit) {
|
|
4681
4632
|
return -1;
|
|
4682
4633
|
}
|
|
4683
4634
|
|
|
4684
|
-
|
|
4635
|
+
PyObjectStorage func = PyObjectStorage::from_new_ref(PyCFunction_New(&clean_storage, NULL));
|
|
4685
4636
|
if (!func) {
|
|
4686
|
-
Py_DECREF(atexit);
|
|
4687
4637
|
return -1;
|
|
4688
4638
|
}
|
|
4689
4639
|
|
|
4690
|
-
|
|
4691
|
-
Py_DECREF(func);
|
|
4692
|
-
Py_DECREF(atexit);
|
|
4640
|
+
PyObjectStorage result = PyObjectStorage::from_new_ref(PyObject_CallMethod(atexit, "register", "O", func.get()));
|
|
4693
4641
|
|
|
4694
4642
|
if (!result) {
|
|
4695
4643
|
return -1;
|
|
4696
4644
|
}
|
|
4697
|
-
Py_DECREF(result);
|
|
4698
4645
|
resigtered_clean_func = true;
|
|
4699
4646
|
return 0;
|
|
4700
4647
|
}
|
|
@@ -4702,7 +4649,7 @@ atexit_register_clean_func(void) noexcept
|
|
|
4702
4649
|
static PyObject*
|
|
4703
4650
|
PrivateModule_create(PyObject* spec, PyModuleDef* /*def*/) noexcept
|
|
4704
4651
|
{
|
|
4705
|
-
|
|
4652
|
+
PyObjectStorage name = PyObjectStorage::from_new_ref(PyObject_GetAttrString(spec, "name"));
|
|
4706
4653
|
if (!name) {
|
|
4707
4654
|
return NULL;
|
|
4708
4655
|
}
|
|
@@ -4711,13 +4658,9 @@ PrivateModule_create(PyObject* spec, PyModuleDef* /*def*/) noexcept
|
|
|
4711
4658
|
// PyInit_private_attribute is genuinely a
|
|
4712
4659
|
// `private_attribute.private_attribute_module` instance from the start,
|
|
4713
4660
|
// rather than a plain module re-typed with Py_SET_TYPE afterwards.
|
|
4714
|
-
|
|
4715
|
-
Py_DECREF(name);
|
|
4716
|
-
return m;
|
|
4661
|
+
return PyObject_CallFunction((PyObject*)&PrivateModuleType, "O", name.get());
|
|
4717
4662
|
}
|
|
4718
4663
|
|
|
4719
|
-
#define MODULE_EXEC_CHECK(command) do {if (command < 0) {return -1;}} while(0)
|
|
4720
|
-
|
|
4721
4664
|
static int
|
|
4722
4665
|
PrivateModule_exec(PyObject* m) noexcept
|
|
4723
4666
|
{
|
|
@@ -4730,7 +4673,16 @@ PrivateModule_exec(PyObject* m) noexcept
|
|
|
4730
4673
|
return -1;
|
|
4731
4674
|
}
|
|
4732
4675
|
Py_DECREF(private_attr_base);
|
|
4733
|
-
PyObject* all =
|
|
4676
|
+
PyObject* all = Py_BuildValue("[ssssssss]",
|
|
4677
|
+
"PrivateWrapProxy",
|
|
4678
|
+
"PrivateAttrType",
|
|
4679
|
+
"PrivateAttrBase",
|
|
4680
|
+
"prepare",
|
|
4681
|
+
"postprocess",
|
|
4682
|
+
"register_metaclass",
|
|
4683
|
+
"ensure_type",
|
|
4684
|
+
"ensure_metaclass"
|
|
4685
|
+
);
|
|
4734
4686
|
if (!all) {
|
|
4735
4687
|
return -1;
|
|
4736
4688
|
}
|
|
@@ -4738,24 +4690,6 @@ PrivateModule_exec(PyObject* m) noexcept
|
|
|
4738
4690
|
Py_DECREF(all);
|
|
4739
4691
|
return -1;
|
|
4740
4692
|
}
|
|
4741
|
-
/* all contains:
|
|
4742
|
-
* PrivateWrapProxy
|
|
4743
|
-
* PrivateAttrType
|
|
4744
|
-
* PrivateAttrBase
|
|
4745
|
-
* prepare
|
|
4746
|
-
* postprocess
|
|
4747
|
-
* register_metaclass
|
|
4748
|
-
* ensure_type
|
|
4749
|
-
* ensure_metaclass
|
|
4750
|
-
*/
|
|
4751
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "PrivateWrapProxy"));
|
|
4752
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "PrivateAttrType"));
|
|
4753
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "PrivateAttrBase"));
|
|
4754
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "prepare"));
|
|
4755
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "postprocess"));
|
|
4756
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "register_metaclass"));
|
|
4757
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "ensure_type"));
|
|
4758
|
-
MODULE_EXEC_CHECK(PyList_AppendString(all, "ensure_metaclass"));
|
|
4759
4693
|
|
|
4760
4694
|
AllData::store_module_self[AllData::kModuleSelfKey] = m; // store module self
|
|
4761
4695
|
|
|
@@ -102,7 +102,7 @@ class PrivateAttrType(type):
|
|
|
102
102
|
private_func: Callable[[int, str], str]|None = None) -> PrivateAttrType: ...
|
|
103
103
|
|
|
104
104
|
class PrivateAttrBase(metaclass=PrivateAttrType):
|
|
105
|
-
"The class to help
|
|
105
|
+
"The class to help creating private attribute. It does not have any special behavior."
|
|
106
106
|
__slots__ = ()
|
|
107
107
|
__private_attrs__ = ()
|
|
108
108
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.24
|
|
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.24',
|
|
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.',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import private_attribute
|
|
2
2
|
import unittest
|
|
3
3
|
|
|
4
|
+
# test whether the PrivateWrapProxy can find the original function if the decorator is a custom type
|
|
4
5
|
class MyWrap:
|
|
5
6
|
def __init__(self, func):
|
|
6
7
|
self.func1 = func
|
|
@@ -19,6 +20,12 @@ class MyWrap:
|
|
|
19
20
|
return func.__get__(instance, owner)(*args, **kwargs)
|
|
20
21
|
return wrapper
|
|
21
22
|
|
|
23
|
+
# test whether the PrivateWrapProxy can find the original function if the decorator forgets to use functools.wrap
|
|
24
|
+
def ill_decorator(func):
|
|
25
|
+
def wrapper(*args, **kwargs):
|
|
26
|
+
return func(*args, **kwargs)
|
|
27
|
+
return wrapper
|
|
28
|
+
|
|
22
29
|
class MyClass(private_attribute.PrivateAttrBase):
|
|
23
30
|
__private_attrs__ = ["_secret1", "_secret2", "_secret3"]
|
|
24
31
|
def __init__(self, secret1, secret2, secret3):
|
|
@@ -27,11 +34,12 @@ class MyClass(private_attribute.PrivateAttrBase):
|
|
|
27
34
|
self._secret3 = secret3
|
|
28
35
|
|
|
29
36
|
@private_attribute.PrivateWrapProxy(MyWrap)
|
|
30
|
-
def get_secret(self):
|
|
37
|
+
def get_secret(self): # type: ignore
|
|
31
38
|
return self._secret1
|
|
32
39
|
|
|
33
40
|
@private_attribute.PrivateWrapProxy(get_secret.result.add, get_secret)
|
|
34
|
-
|
|
41
|
+
@private_attribute.PrivateWrapProxy(ill_decorator, get_secret)
|
|
42
|
+
def get_secret(self): # type: ignore
|
|
35
43
|
return self._secret2
|
|
36
44
|
|
|
37
45
|
@private_attribute.PrivateWrapProxy(get_secret.result.add, get_secret)
|
|
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.22 → private_attribute_cpp-2.1.24}/tests/test_attr_classify_owner.py
RENAMED
|
File without changes
|
{private_attribute_cpp-2.1.22 → private_attribute_cpp-2.1.24}/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.22 → private_attribute_cpp-2.1.24}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|