private-attribute-cpp 2.0.2__tar.gz → 2.0.4__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.0.2/private_attribute_cpp.egg-info → private_attribute_cpp-2.0.4}/PKG-INFO +1 -1
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/private_attribute.cpp +146 -126
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/setup.py +1 -1
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/LICENSE +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/README.md +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/picosha2.h +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/private_attribute.pyi +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/setup.cfg +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_wrap.py +0 -0
{private_attribute_cpp-2.0.2/private_attribute_cpp.egg-info → private_attribute_cpp-2.0.4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
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
|
|
@@ -115,6 +115,56 @@ namespace std {
|
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
struct PyObjectStorage
|
|
119
|
+
{
|
|
120
|
+
PyObject* obj = NULL;
|
|
121
|
+
|
|
122
|
+
PyObjectStorage() noexcept = default;
|
|
123
|
+
PyObjectStorage(PyObject* obj) noexcept : obj(obj) {
|
|
124
|
+
Py_XINCREF(obj);
|
|
125
|
+
}
|
|
126
|
+
PyObjectStorage(const PyObjectStorage& other) noexcept : obj(other.obj) {
|
|
127
|
+
Py_XINCREF(obj);
|
|
128
|
+
}
|
|
129
|
+
PyObjectStorage(PyObjectStorage&& other) noexcept : obj(other.obj) {
|
|
130
|
+
other.obj = NULL;
|
|
131
|
+
}
|
|
132
|
+
PyObjectStorage& operator=(const PyObjectStorage& other) noexcept {
|
|
133
|
+
if (this == &other) {
|
|
134
|
+
return *this;
|
|
135
|
+
}
|
|
136
|
+
PyObject* new_obj = other.obj;
|
|
137
|
+
Py_XINCREF(new_obj);
|
|
138
|
+
Py_XDECREF(obj);
|
|
139
|
+
obj = new_obj;
|
|
140
|
+
return *this;
|
|
141
|
+
}
|
|
142
|
+
PyObjectStorage& operator=(PyObjectStorage&& other) noexcept {
|
|
143
|
+
if (this != &other) {
|
|
144
|
+
Py_XDECREF(obj);
|
|
145
|
+
obj = other.obj;
|
|
146
|
+
other.obj = NULL;
|
|
147
|
+
}
|
|
148
|
+
return *this;
|
|
149
|
+
}
|
|
150
|
+
PyObjectStorage& operator=(PyObject* new_obj) noexcept {
|
|
151
|
+
Py_XINCREF(new_obj);
|
|
152
|
+
Py_XDECREF(obj);
|
|
153
|
+
obj = new_obj;
|
|
154
|
+
return *this;
|
|
155
|
+
}
|
|
156
|
+
~PyObjectStorage() noexcept {
|
|
157
|
+
Py_XDECREF(obj);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
operator PyObject*() const noexcept {
|
|
161
|
+
return obj;
|
|
162
|
+
}
|
|
163
|
+
PyObject* get() const noexcept {
|
|
164
|
+
return obj;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
118
168
|
namespace {
|
|
119
169
|
namespace AllData {
|
|
120
170
|
static std::unordered_map<AllPyobjectAttrCacheKey, std::string> cache;
|
|
@@ -122,7 +172,7 @@ namespace {
|
|
|
122
172
|
static std::unordered_map<uintptr_t, std::vector<AllPyobjectAttrCacheKey>> obj_attr_keys;
|
|
123
173
|
static std::shared_mutex cache_mutex;
|
|
124
174
|
namespace {
|
|
125
|
-
static std::unordered_map<uintptr_t, std::unordered_map<std::string,
|
|
175
|
+
static std::unordered_map<uintptr_t, std::unordered_map<std::string, PyObjectStorage>> type_attr_dict;
|
|
126
176
|
};
|
|
127
177
|
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t, PyCodeObject*>> type_allowed_code_map;
|
|
128
178
|
static std::unordered_map<uintptr_t, std::shared_ptr<std::shared_mutex>> all_type_mutex;
|
|
@@ -130,7 +180,7 @@ namespace {
|
|
|
130
180
|
static std::unordered_map<uintptr_t, std::unordered_set<TwoStringTuple>> all_type_attr_set;
|
|
131
181
|
namespace {
|
|
132
182
|
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t,
|
|
133
|
-
std::unordered_map<std::string,
|
|
183
|
+
std::unordered_map<std::string, PyObjectStorage>>> all_object_attr, all_type_subclass_attr;
|
|
134
184
|
};
|
|
135
185
|
static std::unordered_map<uintptr_t, std::unordered_map<uintptr_t, std::shared_ptr<std::shared_mutex>>>
|
|
136
186
|
all_object_mutex, all_type_subclass_mutex;
|
|
@@ -149,16 +199,12 @@ namespace {
|
|
|
149
199
|
|
|
150
200
|
struct FinalObject
|
|
151
201
|
{
|
|
152
|
-
|
|
202
|
+
PyObjectStorage result;
|
|
153
203
|
int status = 0;
|
|
154
|
-
FinalObject(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
FinalObject(int status) noexcept: status(status) {}
|
|
159
|
-
~FinalObject() noexcept {
|
|
160
|
-
Py_XDECREF(result);
|
|
161
|
-
}
|
|
204
|
+
FinalObject() noexcept = default;
|
|
205
|
+
FinalObject(PyObject* result) noexcept : result(result) {}
|
|
206
|
+
FinalObject(PyObjectStorage result) noexcept : result(std::move(result)) {}
|
|
207
|
+
FinalObject(int status) noexcept : status(status) {}
|
|
162
208
|
};
|
|
163
209
|
|
|
164
210
|
static TwoStringTuple get_string_hash_tuple2(const std::string& name) noexcept;
|
|
@@ -476,9 +522,7 @@ id_getattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
476
522
|
if (type_name == NULL) {
|
|
477
523
|
return NULL;
|
|
478
524
|
}
|
|
479
|
-
|
|
480
|
-
std::string exception_information = "'" + string_type_name + "' objects has no attribute '" + attr_name + "'";
|
|
481
|
-
PyErr_SetString(PyExc_AttributeError, exception_information.c_str());
|
|
525
|
+
PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type_name, attr_name.c_str());
|
|
482
526
|
return NULL;
|
|
483
527
|
}
|
|
484
528
|
|
|
@@ -510,9 +554,7 @@ type_getattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
510
554
|
if (type_name == NULL) {
|
|
511
555
|
return NULL;
|
|
512
556
|
}
|
|
513
|
-
|
|
514
|
-
std::string message = "type object '" + string_type_name + "' has no attribute '" + attr_name + "'";
|
|
515
|
-
PyErr_SetString(PyExc_AttributeError, message.c_str());
|
|
557
|
+
PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type_name, attr_name.c_str());
|
|
516
558
|
return NULL;
|
|
517
559
|
}
|
|
518
560
|
|
|
@@ -574,12 +616,8 @@ id_setattr(const std::string& attr_name, PyObject* obj, PyObject* typ, PyObject*
|
|
|
574
616
|
}
|
|
575
617
|
|
|
576
618
|
// second: set attribute on obj
|
|
577
|
-
Py_INCREF(value);
|
|
578
619
|
{
|
|
579
620
|
std::unique_lock<std::shared_mutex> lock(*::AllData::all_object_mutex[final_id][obj_id]);
|
|
580
|
-
if (::AllData::all_object_attr[final_id][obj_id].find(obj_private_name) != ::AllData::all_object_attr[final_id][obj_id].end()) {
|
|
581
|
-
Py_XDECREF(::AllData::all_object_attr[final_id][obj_id][obj_private_name]);
|
|
582
|
-
}
|
|
583
621
|
::AllData::all_object_attr[final_id][obj_id][obj_private_name] = value;
|
|
584
622
|
}
|
|
585
623
|
return 0;
|
|
@@ -625,11 +663,7 @@ type_setattr(PyObject* typ, const std::string& attr_name, PyObject* value) noexc
|
|
|
625
663
|
}
|
|
626
664
|
{
|
|
627
665
|
std::unique_lock<std::shared_mutex> lock(*::AllData::all_type_mutex[typ_id]);
|
|
628
|
-
if (::AllData::type_attr_dict[typ_id].find(final_key) != ::AllData::type_attr_dict[typ_id].end()) {
|
|
629
|
-
Py_XDECREF(::AllData::type_attr_dict[typ_id][final_key]);
|
|
630
|
-
}
|
|
631
666
|
::AllData::type_attr_dict[typ_id][final_key] = value;
|
|
632
|
-
Py_INCREF(value);
|
|
633
667
|
}
|
|
634
668
|
return 0;
|
|
635
669
|
} else {
|
|
@@ -648,11 +682,7 @@ type_setattr(PyObject* typ, const std::string& attr_name, PyObject* value) noexc
|
|
|
648
682
|
}
|
|
649
683
|
{
|
|
650
684
|
std::unique_lock<std::shared_mutex> lock(*::AllData::all_type_subclass_mutex[final_id][typ_id]);
|
|
651
|
-
if (::AllData::all_type_subclass_attr[final_id][typ_id].find(final_key) != ::AllData::all_type_subclass_attr[final_id][typ_id].end()) {
|
|
652
|
-
Py_XDECREF(::AllData::all_type_subclass_attr[final_id][typ_id][final_key]);
|
|
653
|
-
}
|
|
654
685
|
::AllData::all_type_subclass_attr[final_id][typ_id][final_key] = value;
|
|
655
|
-
Py_INCREF(value);
|
|
656
686
|
return 0;
|
|
657
687
|
}
|
|
658
688
|
}
|
|
@@ -723,14 +753,9 @@ id_delattr(const std::string& attr_name, PyObject* obj, PyObject* typ) noexcept
|
|
|
723
753
|
if (type_name == NULL) {
|
|
724
754
|
return -1;
|
|
725
755
|
}
|
|
726
|
-
|
|
727
|
-
std::string exception_information = "'" + string_type_name + "' objects has no attribute '" + attr_name + "'";
|
|
728
|
-
PyErr_SetString(PyExc_AttributeError, exception_information.c_str());
|
|
729
|
-
return -1;
|
|
756
|
+
PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type_name, attr_name.c_str());
|
|
730
757
|
}
|
|
731
|
-
PyObject* delete_obj = ::AllData::all_object_attr[final_id][obj_id][obj_private_name];
|
|
732
758
|
::AllData::all_object_attr[final_id][obj_id].erase(obj_private_name);
|
|
733
|
-
Py_XDECREF(delete_obj);
|
|
734
759
|
}
|
|
735
760
|
return 0;
|
|
736
761
|
}
|
|
@@ -774,14 +799,10 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
774
799
|
if (type_name == NULL) {
|
|
775
800
|
return -1;
|
|
776
801
|
}
|
|
777
|
-
|
|
778
|
-
std::string message = "type object '" + string_type_name + "' has no attribute '" + attr_name + "'";
|
|
779
|
-
PyErr_SetString(PyExc_AttributeError, message.c_str());
|
|
802
|
+
PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '%s'", type_name, attr_name.c_str());
|
|
780
803
|
return -1;
|
|
781
804
|
}
|
|
782
|
-
PyObject* delete_obj = ::AllData::type_attr_dict[typ_id][final_key];
|
|
783
805
|
::AllData::type_attr_dict[typ_id].erase(final_key);
|
|
784
|
-
Py_XDECREF(delete_obj);
|
|
785
806
|
} else {
|
|
786
807
|
if (::AllData::all_type_subclass_attr.find(final_id) == ::AllData::all_type_subclass_attr.end()) {
|
|
787
808
|
::AllData::all_type_subclass_attr[final_id] = {};
|
|
@@ -802,14 +823,10 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
802
823
|
if (type_name == NULL) {
|
|
803
824
|
return -1;
|
|
804
825
|
}
|
|
805
|
-
|
|
806
|
-
std::string message = "type object '" + string_type_name + "' has no attribute '" + attr_name + "'";
|
|
807
|
-
PyErr_SetString(PyExc_AttributeError, message.c_str());
|
|
826
|
+
PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '%s'", type_name, attr_name.c_str());
|
|
808
827
|
return -1;
|
|
809
828
|
}
|
|
810
|
-
PyObject* delete_obj = ::AllData::all_type_subclass_attr[final_id][typ_id][final_key];
|
|
811
829
|
::AllData::all_type_subclass_attr[final_id][typ_id].erase(final_key);
|
|
812
|
-
Py_XDECREF(delete_obj);
|
|
813
830
|
}
|
|
814
831
|
return 0;
|
|
815
832
|
}
|
|
@@ -1323,10 +1340,6 @@ PrivateAttr_tp_finalize(PyObject* self) noexcept
|
|
|
1323
1340
|
if (::AllData::all_object_attr.find(typ_id) != ::AllData::all_object_attr.end()){
|
|
1324
1341
|
auto& all_object_attr = ::AllData::all_object_attr[typ_id];
|
|
1325
1342
|
if (all_object_attr.find(id_self) != all_object_attr.end()){
|
|
1326
|
-
auto& all_object_attr_self = all_object_attr[id_self];
|
|
1327
|
-
for (auto& attr : all_object_attr_self){
|
|
1328
|
-
Py_XDECREF(attr.second);
|
|
1329
|
-
}
|
|
1330
1343
|
all_object_attr.erase(id_self);
|
|
1331
1344
|
}
|
|
1332
1345
|
}
|
|
@@ -1341,10 +1354,6 @@ PrivateAttr_tp_finalize(PyObject* self) noexcept
|
|
|
1341
1354
|
if (::AllData::all_object_attr.find(parent_id) != ::AllData::all_object_attr.end()){
|
|
1342
1355
|
auto& all_object_attr = ::AllData::all_object_attr[parent_id];
|
|
1343
1356
|
if (all_object_attr.find(id_self) != all_object_attr.end()){
|
|
1344
|
-
auto& all_object_attr_self = all_object_attr[id_self];
|
|
1345
|
-
for (auto& attr : all_object_attr_self){
|
|
1346
|
-
Py_XDECREF(attr.second);
|
|
1347
|
-
}
|
|
1348
1357
|
all_object_attr.erase(id_self);
|
|
1349
1358
|
}
|
|
1350
1359
|
}
|
|
@@ -1621,6 +1630,21 @@ get_now_code() noexcept
|
|
|
1621
1630
|
return code;
|
|
1622
1631
|
}
|
|
1623
1632
|
|
|
1633
|
+
static PyObject*
|
|
1634
|
+
try_get_attr_string(PyObject* obj, const char* name) noexcept
|
|
1635
|
+
{
|
|
1636
|
+
if (obj == NULL || name == NULL) {
|
|
1637
|
+
return NULL;
|
|
1638
|
+
}
|
|
1639
|
+
if (PyObject_HasAttrString(obj, name) <= 0) {
|
|
1640
|
+
if (PyErr_Occurred()) {
|
|
1641
|
+
PyErr_Clear();
|
|
1642
|
+
}
|
|
1643
|
+
return NULL;
|
|
1644
|
+
}
|
|
1645
|
+
return PyObject_GetAttrString(obj, name);
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1624
1648
|
static void
|
|
1625
1649
|
analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyCodeObject*>& map, std::unordered_set<uintptr_t>& _seen) noexcept
|
|
1626
1650
|
{
|
|
@@ -1632,88 +1656,83 @@ analyse_all_code(PyObject* obj, std::unordered_map<uintptr_t, PyCodeObject*>& ma
|
|
|
1632
1656
|
if (PyObject_TypeCheck(obj, &PyCode_Type)) {
|
|
1633
1657
|
Py_INCREF(obj);
|
|
1634
1658
|
map[(uintptr_t)obj] = (PyCodeObject*)obj;
|
|
1635
|
-
PyObject* co_contain =
|
|
1659
|
+
PyObject* co_contain = try_get_attr_string(obj, "co_consts");
|
|
1636
1660
|
if (co_contain && PySequence_Check(co_contain)) {
|
|
1637
1661
|
Py_ssize_t len = PySequence_Length(co_contain);
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1662
|
+
if (len >= 0) {
|
|
1663
|
+
for (Py_ssize_t i = 0; i < len; i++) {
|
|
1664
|
+
PyObject* item = PySequence_GetItem(co_contain, i);
|
|
1665
|
+
if (item) {
|
|
1666
|
+
analyse_all_code(item, map, _seen);
|
|
1667
|
+
Py_DECREF(item);
|
|
1668
|
+
}
|
|
1644
1669
|
}
|
|
1645
1670
|
}
|
|
1646
1671
|
}
|
|
1672
|
+
Py_XDECREF(co_contain);
|
|
1647
1673
|
return;
|
|
1648
1674
|
}
|
|
1649
1675
|
if (PyObject_TypeCheck(obj, &PrivateWrapType)) {
|
|
1650
1676
|
PyObject* func_list = ((PrivateWrapObject*)obj)->func_list;
|
|
1651
1677
|
if (func_list && PySequence_Check(func_list)) {
|
|
1652
1678
|
Py_ssize_t len = PySequence_Length(func_list);
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1679
|
+
if (len >= 0) {
|
|
1680
|
+
for (Py_ssize_t i = 0; i < len; i++) {
|
|
1681
|
+
PyObject* func = PySequence_GetItem(func_list, i);
|
|
1682
|
+
if (func) {
|
|
1683
|
+
analyse_all_code(func, map, _seen);
|
|
1684
|
+
Py_DECREF(func);
|
|
1685
|
+
}
|
|
1659
1686
|
}
|
|
1660
1687
|
}
|
|
1661
1688
|
}
|
|
1662
1689
|
return;
|
|
1663
1690
|
}
|
|
1664
1691
|
if (PyObject_TypeCheck(obj, &PyProperty_Type)) {
|
|
1665
|
-
PyObject* fget =
|
|
1692
|
+
PyObject* fget = try_get_attr_string(obj, "fget");
|
|
1666
1693
|
if (fget) {
|
|
1667
1694
|
analyse_all_code(fget, map, _seen);
|
|
1668
|
-
|
|
1669
|
-
PyErr_Clear();
|
|
1695
|
+
Py_DECREF(fget);
|
|
1670
1696
|
}
|
|
1671
|
-
PyObject* fset =
|
|
1697
|
+
PyObject* fset = try_get_attr_string(obj, "fset");
|
|
1672
1698
|
if (fset) {
|
|
1673
1699
|
analyse_all_code(fset, map, _seen);
|
|
1700
|
+
Py_DECREF(fset);
|
|
1674
1701
|
}
|
|
1675
|
-
|
|
1676
|
-
PyErr_Clear();
|
|
1677
|
-
}
|
|
1678
|
-
PyObject* fdel = PyObject_GetAttrString(obj, "fdel");
|
|
1702
|
+
PyObject* fdel = try_get_attr_string(obj, "fdel");
|
|
1679
1703
|
if (fdel) {
|
|
1680
1704
|
analyse_all_code(fdel, map, _seen);
|
|
1681
|
-
|
|
1682
|
-
PyErr_Clear();
|
|
1705
|
+
Py_DECREF(fdel);
|
|
1683
1706
|
}
|
|
1684
1707
|
return;
|
|
1685
1708
|
}
|
|
1686
1709
|
if (PyObject_TypeCheck(obj, &PyClassMethod_Type) || PyObject_TypeCheck(obj, &PyStaticMethod_Type)) {
|
|
1687
|
-
PyObject* func =
|
|
1710
|
+
PyObject* func = try_get_attr_string(obj, "__func__");
|
|
1688
1711
|
if (func) {
|
|
1689
1712
|
analyse_all_code(func, map, _seen);
|
|
1690
|
-
|
|
1691
|
-
PyErr_Clear();
|
|
1713
|
+
Py_DECREF(func);
|
|
1692
1714
|
}
|
|
1693
1715
|
return;
|
|
1694
1716
|
}
|
|
1695
|
-
PyObject* wrap =
|
|
1717
|
+
PyObject* wrap = try_get_attr_string(obj, "__wrapped__");
|
|
1696
1718
|
if (wrap) {
|
|
1697
1719
|
if (wrap == obj) {
|
|
1698
|
-
PyObject* code =
|
|
1720
|
+
PyObject* code = try_get_attr_string(obj, "__code__");
|
|
1699
1721
|
if (code) {
|
|
1700
1722
|
analyse_all_code(code, map, _seen);
|
|
1701
|
-
|
|
1702
|
-
PyErr_Clear();
|
|
1723
|
+
Py_DECREF(code);
|
|
1703
1724
|
}
|
|
1725
|
+
Py_DECREF(wrap);
|
|
1704
1726
|
return;
|
|
1705
1727
|
}
|
|
1706
1728
|
analyse_all_code(wrap, map, _seen);
|
|
1729
|
+
Py_DECREF(wrap);
|
|
1707
1730
|
return;
|
|
1708
1731
|
}
|
|
1709
|
-
|
|
1710
|
-
PyErr_Clear();
|
|
1711
|
-
}
|
|
1712
|
-
PyObject* code = PyObject_GetAttrString(obj, "__code__");
|
|
1732
|
+
PyObject* code = try_get_attr_string(obj, "__code__");
|
|
1713
1733
|
if (code) {
|
|
1714
1734
|
analyse_all_code(code, map, _seen);
|
|
1715
|
-
|
|
1716
|
-
PyErr_Clear();
|
|
1735
|
+
Py_DECREF(code);
|
|
1717
1736
|
}
|
|
1718
1737
|
}
|
|
1719
1738
|
|
|
@@ -1735,8 +1754,8 @@ struct PrivateAttrCreationData
|
|
|
1735
1754
|
std::unordered_set<TwoStringTuple> private_attrs_set;
|
|
1736
1755
|
std::unordered_set<std::string> private_attrs_vector_string;
|
|
1737
1756
|
std::vector<uintptr_t> all_need_analyse_base;
|
|
1738
|
-
std::unordered_map<std::string,
|
|
1739
|
-
std::unordered_map<uintptr_t, std::unordered_map<std::string,
|
|
1757
|
+
std::unordered_map<std::string, PyObjectStorage> need_remove_itself;
|
|
1758
|
+
std::unordered_map<uintptr_t, std::unordered_map<std::string, PyObjectStorage>> need_remove_subclass;
|
|
1740
1759
|
PyObject* private_func = nullptr;
|
|
1741
1760
|
PyObject* base_kwds = nullptr;
|
|
1742
1761
|
PyObject* name = nullptr;
|
|
@@ -1777,16 +1796,7 @@ struct PrivateAttrCreationData
|
|
|
1777
1796
|
base_kwds = nullptr;
|
|
1778
1797
|
}
|
|
1779
1798
|
|
|
1780
|
-
for (auto& pair : need_remove_itself) {
|
|
1781
|
-
Py_XDECREF(pair.second);
|
|
1782
|
-
}
|
|
1783
1799
|
need_remove_itself.clear();
|
|
1784
|
-
|
|
1785
|
-
for (auto& outer_pair : need_remove_subclass) {
|
|
1786
|
-
for (auto& inner_pair : outer_pair.second) {
|
|
1787
|
-
Py_XDECREF(inner_pair.second);
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
1800
|
need_remove_subclass.clear();
|
|
1791
1801
|
cleared = true;
|
|
1792
1802
|
}
|
|
@@ -1937,26 +1947,46 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1937
1947
|
|
|
1938
1948
|
if (has_slots) {
|
|
1939
1949
|
PyObject* all_slots = PyDict_GetItemString(data.attrs_copy, "__slots__");
|
|
1940
|
-
|
|
1941
|
-
if (
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
Py_DECREF(slot_seq);
|
|
1950
|
+
if (!all_slots) {return false;}
|
|
1951
|
+
if (PyUnicode_Check(all_slots)) {
|
|
1952
|
+
const char* slot_cstr = PyUnicode_AsUTF8(all_slots);
|
|
1953
|
+
if (data.private_attrs_vector_string.find((std::string)slot_cstr) != data.private_attrs_vector_string.end()){
|
|
1954
|
+
std::string error_msg = "'__slots__' and '__private_attrs__' cannot have the same attribute name: '" + std::string(slot_cstr) + "'";
|
|
1955
|
+
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
1956
|
+
return false;
|
|
1957
|
+
}
|
|
1958
|
+
} else {
|
|
1959
|
+
PyObject* slot_seq;
|
|
1960
|
+
if (PyAnyDict_Check(all_slots)) {
|
|
1961
|
+
// use the key of the dict as the slot name
|
|
1962
|
+
PyObject* keys = PyDict_Keys(all_slots);
|
|
1963
|
+
if (!keys) {
|
|
1955
1964
|
return false;
|
|
1956
1965
|
}
|
|
1966
|
+
slot_seq = keys;
|
|
1967
|
+
} else {
|
|
1968
|
+
slot_seq = PySequence_Fast(all_slots, "__slots__ must be a sequence");
|
|
1969
|
+
}
|
|
1970
|
+
if (!slot_seq) {
|
|
1971
|
+
return false;
|
|
1957
1972
|
}
|
|
1973
|
+
|
|
1974
|
+
Py_ssize_t slot_len = PySequence_Fast_GET_SIZE(slot_seq);
|
|
1975
|
+
|
|
1976
|
+
for (Py_ssize_t j = 0; j < slot_len; j++) {
|
|
1977
|
+
PyObject* slot = PySequence_Fast_GET_ITEM(slot_seq, j);
|
|
1978
|
+
if (PyUnicode_Check(slot)) {
|
|
1979
|
+
const char* slot_cstr = PyUnicode_AsUTF8(slot);
|
|
1980
|
+
if (data.private_attrs_vector_string.find((std::string)slot_cstr) != data.private_attrs_vector_string.end()){
|
|
1981
|
+
std::string error_msg = "'__slots__' and '__private_attrs__' cannot have the same attribute name: '" + std::string(slot_cstr) + "'";
|
|
1982
|
+
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
1983
|
+
Py_DECREF(slot_seq);
|
|
1984
|
+
return false;
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
Py_DECREF(slot_seq);
|
|
1958
1989
|
}
|
|
1959
|
-
Py_DECREF(slot_seq);
|
|
1960
1990
|
}
|
|
1961
1991
|
|
|
1962
1992
|
Py_ssize_t bases_len = PyTuple_GET_SIZE(data.bases);
|
|
@@ -2207,7 +2237,6 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2207
2237
|
} else {
|
|
2208
2238
|
final_key = default_random_string(type_id, key);
|
|
2209
2239
|
}
|
|
2210
|
-
Py_INCREF(value);
|
|
2211
2240
|
::AllData::type_attr_dict[type_id][final_key] = value;
|
|
2212
2241
|
}
|
|
2213
2242
|
|
|
@@ -2235,7 +2264,6 @@ PrivateAttrType_postprocess(PyObject* new_type, PrivateAttrCreationData& data) n
|
|
|
2235
2264
|
} else {
|
|
2236
2265
|
final_key = default_random_string(type_id, key);
|
|
2237
2266
|
}
|
|
2238
|
-
Py_INCREF(value);
|
|
2239
2267
|
::AllData::all_type_subclass_attr[i][type_id][final_key] = value;
|
|
2240
2268
|
}
|
|
2241
2269
|
}
|
|
@@ -2513,10 +2541,6 @@ PrivateAttrType_finalize(PyObject* cls) noexcept
|
|
|
2513
2541
|
::AllData::type_need_call.erase(typ_id);
|
|
2514
2542
|
}
|
|
2515
2543
|
if (::AllData::type_attr_dict.find(typ_id) != ::AllData::type_attr_dict.end()) {
|
|
2516
|
-
auto& private_attrs = ::AllData::type_attr_dict[typ_id];
|
|
2517
|
-
for (auto& attr : private_attrs) {
|
|
2518
|
-
Py_XDECREF(attr.second);
|
|
2519
|
-
}
|
|
2520
2544
|
::AllData::type_attr_dict.erase(typ_id);
|
|
2521
2545
|
}
|
|
2522
2546
|
if (::AllData::all_type_subclass_attr.find(typ_id) != ::AllData::all_type_subclass_attr.end()) {
|
|
@@ -2533,10 +2557,6 @@ PrivateAttrType_finalize(PyObject* cls) noexcept
|
|
|
2533
2557
|
for (auto& parent_id : parent_ids) {
|
|
2534
2558
|
if (::AllData::all_type_subclass_attr.find(parent_id) != ::AllData::all_type_subclass_attr.end()) {
|
|
2535
2559
|
if (::AllData::all_type_subclass_attr[parent_id].find(typ_id) != ::AllData::all_type_subclass_attr[parent_id].end()) {
|
|
2536
|
-
auto& private_attrs = ::AllData::all_type_subclass_attr[parent_id][typ_id];
|
|
2537
|
-
for (auto& attr : private_attrs) {
|
|
2538
|
-
Py_XDECREF(attr.second);
|
|
2539
|
-
}
|
|
2540
2560
|
::AllData::all_type_subclass_attr[parent_id].erase(typ_id);
|
|
2541
2561
|
}
|
|
2542
2562
|
}
|
{private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4/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.0.
|
|
3
|
+
Version: 2.0.4
|
|
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.0.
|
|
21
|
+
version='2.0.4',
|
|
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.0.2 → private_attribute_cpp-2.0.4}/tests/test_class_private_attrs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.0.2 → private_attribute_cpp-2.0.4}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|