private-attribute-cpp 1.3.5__tar.gz → 1.3.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.3.5/private_attribute_cpp.egg-info → private_attribute_cpp-1.3.7}/PKG-INFO +1 -1
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/private_attribute.cpp +297 -34
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/setup.py +1 -1
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/LICENSE +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/MANIFEST.in +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/README.md +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/picosha2.h +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/private_attribute.pyi +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.7}/setup.cfg +0 -0
{private_attribute_cpp-1.3.5/private_attribute_cpp.egg-info → private_attribute_cpp-1.3.7}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.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
|
|
@@ -61,7 +61,8 @@ public:
|
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
class TwoStringTuple
|
|
64
|
+
class TwoStringTuple
|
|
65
|
+
{
|
|
65
66
|
private:
|
|
66
67
|
std::string first;
|
|
67
68
|
std::string second;
|
|
@@ -127,7 +128,14 @@ namespace {
|
|
|
127
128
|
};
|
|
128
129
|
};
|
|
129
130
|
|
|
130
|
-
|
|
131
|
+
namespace AllSlots {
|
|
132
|
+
static getattrofunc original_getattro = nullptr;
|
|
133
|
+
static setattrofunc original_setattro = nullptr;
|
|
134
|
+
static destructor original_finalize = nullptr;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
struct FinalObject
|
|
138
|
+
{
|
|
131
139
|
PyObject* result = NULL;
|
|
132
140
|
int status = 0;
|
|
133
141
|
FinalObject(PyObject* result)
|
|
@@ -1189,6 +1197,8 @@ typedef struct {
|
|
|
1189
1197
|
static void PrivateAttr_object_init_private_dict(uintptr_t obj_id, uintptr_t type_id);
|
|
1190
1198
|
static void ensure_tp(PyTypeObject* type_instance);
|
|
1191
1199
|
static void ensure_subclass_tp(PyTypeObject* type_instance);
|
|
1200
|
+
static int PrivateAttr_tp_setattro(PyObject* self, PyObject* name, PyObject* value);
|
|
1201
|
+
static void PrivateAttr_tp_finalize(PyObject* self);
|
|
1192
1202
|
|
|
1193
1203
|
static PyObject*
|
|
1194
1204
|
PrivateAttr_tp_getattro(PyObject* self, PyObject* name)
|
|
@@ -1210,8 +1220,11 @@ PrivateAttr_tp_getattro(PyObject* self, PyObject* name)
|
|
|
1210
1220
|
}
|
|
1211
1221
|
Py_XDECREF(code);
|
|
1212
1222
|
if (::AllData::all_type_getattro.find(type_id) != ::AllData::all_type_getattro.end()){
|
|
1213
|
-
|
|
1214
|
-
|
|
1223
|
+
if (::AllData::all_type_getattro[type_id]) {
|
|
1224
|
+
PyObject* result = ::AllData::all_type_getattro[type_id](self, name);
|
|
1225
|
+
ensure_tp(typ);
|
|
1226
|
+
return result;
|
|
1227
|
+
}
|
|
1215
1228
|
}
|
|
1216
1229
|
return PyObject_GenericGetAttr(self, name);
|
|
1217
1230
|
}
|
|
@@ -1243,6 +1256,7 @@ PrivateAttr_tp_setattro(PyObject* self, PyObject* name, PyObject* value)
|
|
|
1243
1256
|
Py_XDECREF(code);
|
|
1244
1257
|
if (::AllData::all_type_setattro.find(typ_id) != ::AllData::all_type_setattro.end()){
|
|
1245
1258
|
int result = ::AllData::all_type_setattro[typ_id](self, name, value);
|
|
1259
|
+
ensure_tp(typ);
|
|
1246
1260
|
return result;
|
|
1247
1261
|
}
|
|
1248
1262
|
return PyObject_GenericSetAttr(self, name, value);
|
|
@@ -1256,7 +1270,10 @@ PrivateAttr_tp_finalize(PyObject* self)
|
|
|
1256
1270
|
uintptr_t typ_id = (uintptr_t)typ;
|
|
1257
1271
|
Py_ssize_t original_ref = Py_REFCNT(self);
|
|
1258
1272
|
if (::AllData::all_type_finalize.find(typ_id) != ::AllData::all_type_finalize.end()){
|
|
1259
|
-
::AllData::all_type_finalize[typ_id]
|
|
1273
|
+
if (::AllData::all_type_finalize[typ_id]) {
|
|
1274
|
+
::AllData::all_type_finalize[typ_id](self);
|
|
1275
|
+
ensure_tp(typ);
|
|
1276
|
+
}
|
|
1260
1277
|
}
|
|
1261
1278
|
if (original_ref != Py_REFCNT(self)) {
|
|
1262
1279
|
return;
|
|
@@ -1669,7 +1686,8 @@ real_class_name(std::string name, std::string class_name)
|
|
|
1669
1686
|
return name;
|
|
1670
1687
|
}
|
|
1671
1688
|
|
|
1672
|
-
struct PrivateAttrCreationData
|
|
1689
|
+
struct PrivateAttrCreationData
|
|
1690
|
+
{
|
|
1673
1691
|
std::string class_name;
|
|
1674
1692
|
PyObject* attrs_copy = nullptr;
|
|
1675
1693
|
PyObject* new_hash_private_attrs = nullptr;
|
|
@@ -1740,6 +1758,21 @@ need_analyse_type(PyObject* type)
|
|
|
1740
1758
|
return false;
|
|
1741
1759
|
}
|
|
1742
1760
|
|
|
1761
|
+
// python under 3.13 doesn't has PyDict_ContainsString, so we implement it ourselves
|
|
1762
|
+
#if PY_VERSION_HEX < 0x030D0000
|
|
1763
|
+
static int
|
|
1764
|
+
PyDict_ContainsString(PyObject *op, const char *key)
|
|
1765
|
+
{
|
|
1766
|
+
PyObject *key_obj = PyUnicode_FromString(key);
|
|
1767
|
+
if (key_obj == NULL) {
|
|
1768
|
+
return -1;
|
|
1769
|
+
}
|
|
1770
|
+
int res = PyDict_Contains(op, key_obj);
|
|
1771
|
+
Py_DECREF(key_obj);
|
|
1772
|
+
return res;
|
|
1773
|
+
}
|
|
1774
|
+
#endif
|
|
1775
|
+
|
|
1743
1776
|
static bool
|
|
1744
1777
|
PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationData& data)
|
|
1745
1778
|
{
|
|
@@ -1806,7 +1839,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1806
1839
|
}
|
|
1807
1840
|
|
|
1808
1841
|
if (!PyUnicode_Check(attr)) {
|
|
1809
|
-
|
|
1842
|
+
PyErr_Format(PyExc_TypeError, "all items in '__private_attrs__' must be 'str', not '%.200s'", Py_TYPE(attr)->tp_name);
|
|
1810
1843
|
return false;
|
|
1811
1844
|
}
|
|
1812
1845
|
|
|
@@ -1818,7 +1851,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1818
1851
|
std::string attr_str = real_class_name(attr_cstr, data.class_name);
|
|
1819
1852
|
|
|
1820
1853
|
for (const char** p = invalid_name; *p != NULL; p++) {
|
|
1821
|
-
if (attr_str
|
|
1854
|
+
if (strcmp(attr_str.c_str(), *p) == 0) {
|
|
1822
1855
|
std::string error_msg = "invalid attribute name: '" + std::string(*p) + "'";
|
|
1823
1856
|
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
1824
1857
|
return false;
|
|
@@ -1839,10 +1872,10 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1839
1872
|
return false;
|
|
1840
1873
|
}
|
|
1841
1874
|
|
|
1842
|
-
|
|
1843
|
-
bool has_slots = (all_slots != NULL);
|
|
1875
|
+
int has_slots = PyDict_ContainsString(data.attrs_copy, "__slots__");
|
|
1844
1876
|
|
|
1845
1877
|
if (has_slots) {
|
|
1878
|
+
PyObject* all_slots = PyDict_GetItemString(data.attrs_copy, "__slots__");
|
|
1846
1879
|
PyObject* slot_seq = PySequence_Fast(all_slots, "__slots__ must be a sequence");
|
|
1847
1880
|
if (!slot_seq) {
|
|
1848
1881
|
return false;
|
|
@@ -1863,8 +1896,6 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1863
1896
|
}
|
|
1864
1897
|
}
|
|
1865
1898
|
Py_DECREF(slot_seq);
|
|
1866
|
-
} else {
|
|
1867
|
-
PyErr_Clear();
|
|
1868
1899
|
}
|
|
1869
1900
|
|
|
1870
1901
|
Py_ssize_t bases_len = PyTuple_GET_SIZE(data.bases);
|
|
@@ -1924,16 +1955,16 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1924
1955
|
|
|
1925
1956
|
// get "private_func" from kwds
|
|
1926
1957
|
if (kwds && PyDict_Check(kwds)) {
|
|
1927
|
-
|
|
1928
|
-
if (
|
|
1958
|
+
bool has_private_func = PyDict_ContainsString(kwds, "private_func");
|
|
1959
|
+
if (has_private_func) {
|
|
1960
|
+
data.private_func = PyDict_GetItemString(kwds, "private_func");
|
|
1929
1961
|
Py_INCREF(data.private_func);
|
|
1930
1962
|
}
|
|
1931
1963
|
data.base_kwds = PyDict_Copy(kwds);
|
|
1932
1964
|
if (!data.base_kwds) {
|
|
1933
1965
|
return false;
|
|
1934
1966
|
}
|
|
1935
|
-
PyDict_DelItemString(data.base_kwds, "private_func");
|
|
1936
|
-
PyErr_Clear();
|
|
1967
|
+
if (has_private_func) PyDict_DelItemString(data.base_kwds, "private_func");
|
|
1937
1968
|
}
|
|
1938
1969
|
|
|
1939
1970
|
return true;
|
|
@@ -1965,13 +1996,21 @@ PrivateAttrType_create(PyTypeObject* type, PrivateAttrCreationData& data)
|
|
|
1965
1996
|
return new_type;
|
|
1966
1997
|
}
|
|
1967
1998
|
|
|
1999
|
+
static getattrofunc get_need_tp_getattro(PyTypeObject* cls);
|
|
2000
|
+
static setattrofunc get_need_tp_setattro(PyTypeObject* cls);
|
|
2001
|
+
static destructor get_need_tp_finalize(PyTypeObject* cls);
|
|
2002
|
+
|
|
1968
2003
|
static void
|
|
1969
2004
|
ensure_tp(PyTypeObject* type_instance)
|
|
1970
2005
|
{
|
|
1971
2006
|
uintptr_t type_id = (uintptr_t)(type_instance);
|
|
1972
|
-
|
|
2007
|
+
{
|
|
1973
2008
|
if (type_instance->tp_getattro != PrivateAttr_tp_getattro) {
|
|
1974
|
-
|
|
2009
|
+
if (!type_instance->tp_getattro) {
|
|
2010
|
+
::AllData::all_type_getattro[type_id] = get_need_tp_getattro(type_instance);
|
|
2011
|
+
} else {
|
|
2012
|
+
::AllData::all_type_getattro[type_id] = type_instance->tp_getattro;
|
|
2013
|
+
}
|
|
1975
2014
|
type_instance->tp_getattro = PrivateAttr_tp_getattro;
|
|
1976
2015
|
} else {
|
|
1977
2016
|
PyTypeObject* base = type_instance->tp_base;
|
|
@@ -1983,9 +2022,13 @@ ensure_tp(PyTypeObject* type_instance)
|
|
|
1983
2022
|
}
|
|
1984
2023
|
}
|
|
1985
2024
|
}
|
|
1986
|
-
|
|
2025
|
+
{
|
|
1987
2026
|
if (type_instance->tp_setattro != PrivateAttr_tp_setattro) {
|
|
1988
|
-
|
|
2027
|
+
if (!type_instance->tp_setattro) {
|
|
2028
|
+
::AllData::all_type_setattro[type_id] = get_need_tp_setattro(type_instance);
|
|
2029
|
+
} else {
|
|
2030
|
+
::AllData::all_type_setattro[type_id] = type_instance->tp_setattro;
|
|
2031
|
+
}
|
|
1989
2032
|
type_instance->tp_setattro = PrivateAttr_tp_setattro;
|
|
1990
2033
|
} else {
|
|
1991
2034
|
PyTypeObject* base = type_instance->tp_base;
|
|
@@ -1997,9 +2040,13 @@ ensure_tp(PyTypeObject* type_instance)
|
|
|
1997
2040
|
}
|
|
1998
2041
|
}
|
|
1999
2042
|
}
|
|
2000
|
-
|
|
2043
|
+
{
|
|
2001
2044
|
if (type_instance->tp_finalize != PrivateAttr_tp_finalize) {
|
|
2002
|
-
|
|
2045
|
+
if (!type_instance->tp_finalize) {
|
|
2046
|
+
::AllData::all_type_finalize[type_id] = get_need_tp_finalize(type_instance);
|
|
2047
|
+
} else {
|
|
2048
|
+
::AllData::all_type_finalize[type_id] = type_instance->tp_finalize;
|
|
2049
|
+
}
|
|
2003
2050
|
type_instance->tp_finalize = PrivateAttr_tp_finalize;
|
|
2004
2051
|
} else {
|
|
2005
2052
|
PyTypeObject* base = type_instance->tp_base;
|
|
@@ -2019,23 +2066,37 @@ ensure_subclass_tp(PyTypeObject* type_instance)
|
|
|
2019
2066
|
// type.__subclasses__
|
|
2020
2067
|
PyObject* type_subclasses = (PyObject*)type_instance->tp_subclasses;
|
|
2021
2068
|
if (!type_subclasses) {
|
|
2022
|
-
PyErr_Clear();
|
|
2023
2069
|
return;
|
|
2024
2070
|
}
|
|
2025
|
-
if (!
|
|
2026
|
-
Py_DECREF(type_subclasses);
|
|
2071
|
+
if (!PyDict_Check(type_subclasses)) {
|
|
2027
2072
|
return;
|
|
2028
2073
|
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2074
|
+
// check all values in the dict. It should be a weakref to a type. If not, continue.
|
|
2075
|
+
PyObject* key, *value;
|
|
2076
|
+
Py_ssize_t pos = 0;
|
|
2077
|
+
while (PyDict_Next(type_subclasses, &pos, &key, &value)) {
|
|
2078
|
+
if (!value || !PyWeakref_CheckRef(value)) {
|
|
2079
|
+
continue;
|
|
2080
|
+
}
|
|
2081
|
+
// python<3.13 use PyWeakref_GetObject, python>=3.13 use PyWeakref_GetRef
|
|
2082
|
+
#if PY_VERSION_HEX < 0x030D0000
|
|
2083
|
+
PyObject* subclass = PyWeakref_GetObject(value);
|
|
2084
|
+
if (!subclass || !PyType_Check(subclass)) {
|
|
2085
|
+
continue;
|
|
2086
|
+
}
|
|
2087
|
+
ensure_tp((PyTypeObject*)subclass);
|
|
2088
|
+
#else
|
|
2089
|
+
PyObject* subclass;
|
|
2090
|
+
if (PyWeakref_GetRef(value, (PyObject**)&subclass) != 0) {
|
|
2091
|
+
continue;
|
|
2092
|
+
}
|
|
2032
2093
|
if (!subclass || !PyType_Check(subclass)) {
|
|
2033
2094
|
continue;
|
|
2034
2095
|
}
|
|
2035
2096
|
ensure_tp((PyTypeObject*)subclass);
|
|
2036
|
-
|
|
2097
|
+
Py_XDECREF(subclass);
|
|
2098
|
+
#endif
|
|
2037
2099
|
}
|
|
2038
|
-
Py_DECREF(type_subclasses);
|
|
2039
2100
|
}
|
|
2040
2101
|
|
|
2041
2102
|
static bool
|
|
@@ -2202,6 +2263,178 @@ PrivateAttrType_getattr(PyObject* cls, PyObject* name)
|
|
|
2202
2263
|
return result;
|
|
2203
2264
|
}
|
|
2204
2265
|
|
|
2266
|
+
static int
|
|
2267
|
+
init_all_slots()
|
|
2268
|
+
{
|
|
2269
|
+
PyObject* class_locals = PyDict_New();
|
|
2270
|
+
if (!class_locals) {
|
|
2271
|
+
return -1;
|
|
2272
|
+
}
|
|
2273
|
+
// set "__getattribute__", "__setattr__", "__delattr__", "__del__" to class_locals
|
|
2274
|
+
if (PyDict_SetItemString(class_locals, "__getattribute__", Py_None) < 0) {
|
|
2275
|
+
Py_DECREF(class_locals);
|
|
2276
|
+
return -1;
|
|
2277
|
+
}
|
|
2278
|
+
if (PyDict_SetItemString(class_locals, "__setattr__", Py_None) < 0) {
|
|
2279
|
+
Py_DECREF(class_locals);
|
|
2280
|
+
return -1;
|
|
2281
|
+
}
|
|
2282
|
+
if (PyDict_SetItemString(class_locals, "__delattr__", Py_None) < 0) {
|
|
2283
|
+
Py_DECREF(class_locals);
|
|
2284
|
+
return -1;
|
|
2285
|
+
}
|
|
2286
|
+
if (PyDict_SetItemString(class_locals, "__del__", Py_None) < 0) {
|
|
2287
|
+
Py_DECREF(class_locals);
|
|
2288
|
+
return -1;
|
|
2289
|
+
}
|
|
2290
|
+
PyObject* class_name = PyUnicode_FromString("_TempClass");
|
|
2291
|
+
if (!class_name) {
|
|
2292
|
+
Py_DECREF(class_locals);
|
|
2293
|
+
return -1;
|
|
2294
|
+
}
|
|
2295
|
+
PyObject* args = PyTuple_Pack(3, class_name, PyTuple_New(0), class_locals);
|
|
2296
|
+
if (!args) {
|
|
2297
|
+
Py_DECREF(class_name);
|
|
2298
|
+
Py_DECREF(class_locals);
|
|
2299
|
+
return -1;
|
|
2300
|
+
}
|
|
2301
|
+
PyObject* temp_class = PyType_Type.tp_new(&PyType_Type, args, NULL);
|
|
2302
|
+
Py_DECREF(args);
|
|
2303
|
+
if (!temp_class) {
|
|
2304
|
+
return -1;
|
|
2305
|
+
}
|
|
2306
|
+
PyTypeObject* temp_type = (PyTypeObject*)temp_class;
|
|
2307
|
+
AllSlots::original_getattro = temp_type->tp_getattro;
|
|
2308
|
+
AllSlots::original_setattro = temp_type->tp_setattro;
|
|
2309
|
+
AllSlots::original_finalize = temp_type->tp_finalize;
|
|
2310
|
+
Py_DECREF(temp_class);
|
|
2311
|
+
return 0;
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
static getattrofunc
|
|
2315
|
+
get_need_tp_getattro(PyTypeObject* cls)
|
|
2316
|
+
{
|
|
2317
|
+
if (PyDict_ContainsString(cls->tp_dict, "__getattribute__") || PyDict_ContainsString(cls->tp_dict, "__getattr__")) {
|
|
2318
|
+
return AllSlots::original_getattro;
|
|
2319
|
+
}
|
|
2320
|
+
PyTypeObject* base = cls->tp_base;
|
|
2321
|
+
while (base) {
|
|
2322
|
+
if (base->tp_getattro != PrivateAttr_tp_getattro) {
|
|
2323
|
+
return base->tp_getattro;
|
|
2324
|
+
} else if (::AllData::all_type_getattro.find((uintptr_t)base) != ::AllData::all_type_getattro.end()) {
|
|
2325
|
+
if (::AllData::all_type_getattro[(uintptr_t)base]) {
|
|
2326
|
+
return ::AllData::all_type_getattro[(uintptr_t)base];
|
|
2327
|
+
}
|
|
2328
|
+
base = base->tp_base;
|
|
2329
|
+
} else {
|
|
2330
|
+
base = base->tp_base;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
return NULL;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2336
|
+
static setattrofunc
|
|
2337
|
+
get_need_tp_setattro(PyTypeObject* cls)
|
|
2338
|
+
{
|
|
2339
|
+
if (PyDict_ContainsString(cls->tp_dict, "__setattr__") || PyDict_ContainsString(cls->tp_dict, "__delattr__")) {
|
|
2340
|
+
return AllSlots::original_setattro;
|
|
2341
|
+
}
|
|
2342
|
+
PyTypeObject* base = cls->tp_base;
|
|
2343
|
+
while (base) {
|
|
2344
|
+
if (base->tp_setattro != PrivateAttr_tp_setattro) {
|
|
2345
|
+
return base->tp_setattro;
|
|
2346
|
+
} else if (::AllData::all_type_setattro.find((uintptr_t)base) != ::AllData::all_type_setattro.end()) {
|
|
2347
|
+
if (::AllData::all_type_setattro[(uintptr_t)base]) {
|
|
2348
|
+
return ::AllData::all_type_setattro[(uintptr_t)base];
|
|
2349
|
+
}
|
|
2350
|
+
base = base->tp_base;
|
|
2351
|
+
} else {
|
|
2352
|
+
base = base->tp_base;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
return NULL;
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
static destructor
|
|
2359
|
+
get_need_tp_finalize(PyTypeObject* cls)
|
|
2360
|
+
{
|
|
2361
|
+
if (PyDict_ContainsString(cls->tp_dict, "__del__")) {
|
|
2362
|
+
return AllSlots::original_finalize;
|
|
2363
|
+
}
|
|
2364
|
+
PyTypeObject* base = cls->tp_base;
|
|
2365
|
+
while (base) {
|
|
2366
|
+
if (base->tp_finalize != PrivateAttr_tp_finalize) {
|
|
2367
|
+
return base->tp_finalize;
|
|
2368
|
+
} else if (::AllData::all_type_finalize.find((uintptr_t)base) != ::AllData::all_type_finalize.end()) {
|
|
2369
|
+
if (::AllData::all_type_finalize[(uintptr_t)base]) {
|
|
2370
|
+
return ::AllData::all_type_finalize[(uintptr_t)base];
|
|
2371
|
+
}
|
|
2372
|
+
base = base->tp_base;
|
|
2373
|
+
} else {
|
|
2374
|
+
base = base->tp_base;
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
return NULL;
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
static void
|
|
2381
|
+
type_change_all_slots(PyTypeObject* cls, const char* name)
|
|
2382
|
+
{
|
|
2383
|
+
if (strcmp(name, "__getattribute__") == 0 || strcmp(name, "__getattr__") == 0) {
|
|
2384
|
+
cls->tp_getattro = PrivateAttr_tp_getattro;
|
|
2385
|
+
::AllData::all_type_getattro[(uintptr_t)cls] = get_need_tp_getattro(cls);
|
|
2386
|
+
} else if (strcmp(name, "__setattr__") == 0 || strcmp(name, "__delattr__") == 0) {
|
|
2387
|
+
cls->tp_setattro = PrivateAttr_tp_setattro;
|
|
2388
|
+
::AllData::all_type_setattro[(uintptr_t)cls] = get_need_tp_setattro(cls);
|
|
2389
|
+
} else if (strcmp(name, "__del__") == 0) {
|
|
2390
|
+
cls->tp_finalize = PrivateAttr_tp_finalize;
|
|
2391
|
+
::AllData::all_type_finalize[(uintptr_t)cls] = get_need_tp_finalize(cls);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
static void
|
|
2396
|
+
subtype_change_all_slots(PyTypeObject* cls, const char* name)
|
|
2397
|
+
{
|
|
2398
|
+
// tp_subclasses: {id(type): weakref.ref(type)}
|
|
2399
|
+
PyObject* tp_subclasses = (PyObject*)cls->tp_subclasses;
|
|
2400
|
+
if (!tp_subclasses) {
|
|
2401
|
+
return;
|
|
2402
|
+
}
|
|
2403
|
+
if (!PyDict_Check(tp_subclasses)) {
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
PyObject* key;
|
|
2407
|
+
PyObject* value;
|
|
2408
|
+
Py_ssize_t pos = 0;
|
|
2409
|
+
while (PyDict_Next(tp_subclasses, &pos, &key, &value)) {
|
|
2410
|
+
if (!PyWeakref_Check(value)) {
|
|
2411
|
+
continue;
|
|
2412
|
+
}
|
|
2413
|
+
#if PY_VERSION_HEX < 0x030D0000
|
|
2414
|
+
PyObject* obj = PyWeakref_GET_OBJECT(value);
|
|
2415
|
+
if (!obj) {
|
|
2416
|
+
continue;
|
|
2417
|
+
}
|
|
2418
|
+
#else
|
|
2419
|
+
PyObject* obj;
|
|
2420
|
+
if (PyWeakref_GetRef(value, &obj) != 0) {
|
|
2421
|
+
continue;
|
|
2422
|
+
}
|
|
2423
|
+
if (!obj) {
|
|
2424
|
+
continue;
|
|
2425
|
+
}
|
|
2426
|
+
#endif
|
|
2427
|
+
if (!PyType_Check(obj)) {
|
|
2428
|
+
continue;
|
|
2429
|
+
}
|
|
2430
|
+
PyTypeObject* sub_cls = (PyTypeObject*)obj;
|
|
2431
|
+
type_change_all_slots(sub_cls, name);
|
|
2432
|
+
#if PY_VERSION_HEX >= 0x030D0000
|
|
2433
|
+
Py_XDECREF(obj);
|
|
2434
|
+
#endif
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2205
2438
|
static int
|
|
2206
2439
|
PrivateAttrType_setattr(PyObject* cls, PyObject* name, PyObject* value)
|
|
2207
2440
|
{
|
|
@@ -2209,8 +2442,14 @@ PrivateAttrType_setattr(PyObject* cls, PyObject* name, PyObject* value)
|
|
|
2209
2442
|
PyErr_SetString(PyExc_TypeError, "cls must be a type");
|
|
2210
2443
|
return -1;
|
|
2211
2444
|
}
|
|
2445
|
+
// check Py_TPFLAGS_IMMUTABLETYPE
|
|
2212
2446
|
uintptr_t typ_id = (uintptr_t)(cls);
|
|
2213
2447
|
std::string name_str = PyUnicode_AsUTF8(name);
|
|
2448
|
+
if (((PyTypeObject*)cls)->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
|
|
2449
|
+
std::string error_message = "cannot set '" + name_str + "' attribute of immutable type '" + ((PyTypeObject*)cls)->tp_name + "'";
|
|
2450
|
+
PyErr_SetString(PyExc_TypeError, error_message.c_str());
|
|
2451
|
+
return -1;
|
|
2452
|
+
}
|
|
2214
2453
|
PyCodeObject* now_code = get_now_code();
|
|
2215
2454
|
if (type_private_attr(typ_id, name_str)) {
|
|
2216
2455
|
if (!now_code || (!is_class_code(typ_id, now_code) && !is_subclass_code(typ_id, now_code))) {
|
|
@@ -2222,6 +2461,28 @@ PrivateAttrType_setattr(PyObject* cls, PyObject* name, PyObject* value)
|
|
|
2222
2461
|
return type_setattr(cls, name_str, value);
|
|
2223
2462
|
}
|
|
2224
2463
|
Py_XDECREF(now_code);
|
|
2464
|
+
// if name in __getattribute__, __setattr__, __delattr__, __del__, just set to tp_dict
|
|
2465
|
+
if (name_str == "__getattribute__" || name_str == "__getattr__" || name_str == "__setattr__" || name_str == "__delattr__" || name_str == "__del__") {
|
|
2466
|
+
PyObject* tp_dict = ((PyTypeObject*)cls)->tp_dict;
|
|
2467
|
+
if (!tp_dict) {
|
|
2468
|
+
PyErr_SetString(PyExc_TypeError, "type has no tp_dict");
|
|
2469
|
+
return -1;
|
|
2470
|
+
}
|
|
2471
|
+
if (!value) {
|
|
2472
|
+
if (PyDict_DelItem(tp_dict, name) < 0) {
|
|
2473
|
+
return -1;
|
|
2474
|
+
}
|
|
2475
|
+
type_change_all_slots((PyTypeObject*)cls, name_str.c_str());
|
|
2476
|
+
subtype_change_all_slots((PyTypeObject*)cls, name_str.c_str());
|
|
2477
|
+
return 0;
|
|
2478
|
+
}
|
|
2479
|
+
if (PyDict_SetItem(tp_dict, name, value) < 0) {
|
|
2480
|
+
return -1;
|
|
2481
|
+
}
|
|
2482
|
+
type_change_all_slots((PyTypeObject*)cls, name_str.c_str());
|
|
2483
|
+
subtype_change_all_slots((PyTypeObject*)cls, name_str.c_str());
|
|
2484
|
+
return 0;
|
|
2485
|
+
}
|
|
2225
2486
|
PyTypeObject* base = Py_TYPE(cls)->tp_base;
|
|
2226
2487
|
while (base && base->tp_base && base->tp_setattro == PrivateAttrType_setattr) {
|
|
2227
2488
|
base = base->tp_base;
|
|
@@ -2307,7 +2568,7 @@ static void
|
|
|
2307
2568
|
PrivateAttrType_del(PyObject* cls)
|
|
2308
2569
|
{
|
|
2309
2570
|
PrivateAttrType_finalize(cls);
|
|
2310
|
-
(
|
|
2571
|
+
PyType_Type.tp_dealloc(cls);
|
|
2311
2572
|
}
|
|
2312
2573
|
|
|
2313
2574
|
static const char* PrivateAttrBase_doc = "The class to help to create private attribute. It does not have any special behavior.";
|
|
@@ -2484,7 +2745,8 @@ prepare_for_PrivateAttr(PyObject* /*self*/, PyObject* args, PyObject* kwargs)
|
|
|
2484
2745
|
}
|
|
2485
2746
|
|
|
2486
2747
|
static PyObject*
|
|
2487
|
-
postprocess_for_PrivateAttr(PyObject* /*self*/, PyObject* args)
|
|
2748
|
+
postprocess_for_PrivateAttr(PyObject* /*self*/, PyObject* args)
|
|
2749
|
+
{
|
|
2488
2750
|
PyObject* type;
|
|
2489
2751
|
PyObject* tmp;
|
|
2490
2752
|
if (!PyArg_ParseTuple(args, "OO", &type, &tmp)) {
|
|
@@ -2765,11 +3027,12 @@ static PyModuleDef def = {
|
|
|
2765
3027
|
PyMODINIT_FUNC
|
|
2766
3028
|
PyInit_private_attribute(void)
|
|
2767
3029
|
{
|
|
2768
|
-
if (
|
|
3030
|
+
if (init_all_slots() <0 ||
|
|
3031
|
+
PyType_Ready(&PrivateWrapType) < 0 ||
|
|
2769
3032
|
PyType_Ready(&PrivateWrapProxyType) < 0 ||
|
|
2770
3033
|
PyType_Ready(&PrivateAttrType) < 0 ||
|
|
2771
3034
|
PyType_Ready(&PrivateModuleType) < 0 ||
|
|
2772
|
-
PyType_Ready(&PrivateTempType)) {
|
|
3035
|
+
PyType_Ready(&PrivateTempType) < 0) {
|
|
2773
3036
|
return NULL;
|
|
2774
3037
|
}
|
|
2775
3038
|
|
{private_attribute_cpp-1.3.5 → private_attribute_cpp-1.3.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.3.
|
|
3
|
+
Version: 1.3.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
|
|
@@ -19,7 +19,7 @@ readme = open('README.md').read()
|
|
|
19
19
|
|
|
20
20
|
setup(
|
|
21
21
|
name='private_attribute_cpp',
|
|
22
|
-
version='1.3.
|
|
22
|
+
version='1.3.7',
|
|
23
23
|
author="HuangHaoHua",
|
|
24
24
|
author_email="13140752715@example.com",
|
|
25
25
|
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
|