private-attribute-cpp 1.3.6__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.6/private_attribute_cpp.egg-info → private_attribute_cpp-1.3.7}/PKG-INFO +1 -1
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/private_attribute.cpp +282 -29
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/setup.py +1 -1
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/LICENSE +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/MANIFEST.in +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/README.md +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/picosha2.h +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/private_attribute.pyi +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-1.3.6 → private_attribute_cpp-1.3.7}/setup.cfg +0 -0
{private_attribute_cpp-1.3.6/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
|
|
@@ -128,6 +128,12 @@ namespace {
|
|
|
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
|
+
|
|
131
137
|
struct FinalObject
|
|
132
138
|
{
|
|
133
139
|
PyObject* result = NULL;
|
|
@@ -1191,6 +1197,8 @@ typedef struct {
|
|
|
1191
1197
|
static void PrivateAttr_object_init_private_dict(uintptr_t obj_id, uintptr_t type_id);
|
|
1192
1198
|
static void ensure_tp(PyTypeObject* type_instance);
|
|
1193
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);
|
|
1194
1202
|
|
|
1195
1203
|
static PyObject*
|
|
1196
1204
|
PrivateAttr_tp_getattro(PyObject* self, PyObject* name)
|
|
@@ -1212,8 +1220,11 @@ PrivateAttr_tp_getattro(PyObject* self, PyObject* name)
|
|
|
1212
1220
|
}
|
|
1213
1221
|
Py_XDECREF(code);
|
|
1214
1222
|
if (::AllData::all_type_getattro.find(type_id) != ::AllData::all_type_getattro.end()){
|
|
1215
|
-
|
|
1216
|
-
|
|
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
|
+
}
|
|
1217
1228
|
}
|
|
1218
1229
|
return PyObject_GenericGetAttr(self, name);
|
|
1219
1230
|
}
|
|
@@ -1245,6 +1256,7 @@ PrivateAttr_tp_setattro(PyObject* self, PyObject* name, PyObject* value)
|
|
|
1245
1256
|
Py_XDECREF(code);
|
|
1246
1257
|
if (::AllData::all_type_setattro.find(typ_id) != ::AllData::all_type_setattro.end()){
|
|
1247
1258
|
int result = ::AllData::all_type_setattro[typ_id](self, name, value);
|
|
1259
|
+
ensure_tp(typ);
|
|
1248
1260
|
return result;
|
|
1249
1261
|
}
|
|
1250
1262
|
return PyObject_GenericSetAttr(self, name, value);
|
|
@@ -1258,7 +1270,10 @@ PrivateAttr_tp_finalize(PyObject* self)
|
|
|
1258
1270
|
uintptr_t typ_id = (uintptr_t)typ;
|
|
1259
1271
|
Py_ssize_t original_ref = Py_REFCNT(self);
|
|
1260
1272
|
if (::AllData::all_type_finalize.find(typ_id) != ::AllData::all_type_finalize.end()){
|
|
1261
|
-
::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
|
+
}
|
|
1262
1277
|
}
|
|
1263
1278
|
if (original_ref != Py_REFCNT(self)) {
|
|
1264
1279
|
return;
|
|
@@ -1743,6 +1758,21 @@ need_analyse_type(PyObject* type)
|
|
|
1743
1758
|
return false;
|
|
1744
1759
|
}
|
|
1745
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
|
+
|
|
1746
1776
|
static bool
|
|
1747
1777
|
PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationData& data)
|
|
1748
1778
|
{
|
|
@@ -1809,7 +1839,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1809
1839
|
}
|
|
1810
1840
|
|
|
1811
1841
|
if (!PyUnicode_Check(attr)) {
|
|
1812
|
-
|
|
1842
|
+
PyErr_Format(PyExc_TypeError, "all items in '__private_attrs__' must be 'str', not '%.200s'", Py_TYPE(attr)->tp_name);
|
|
1813
1843
|
return false;
|
|
1814
1844
|
}
|
|
1815
1845
|
|
|
@@ -1821,7 +1851,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1821
1851
|
std::string attr_str = real_class_name(attr_cstr, data.class_name);
|
|
1822
1852
|
|
|
1823
1853
|
for (const char** p = invalid_name; *p != NULL; p++) {
|
|
1824
|
-
if (attr_str
|
|
1854
|
+
if (strcmp(attr_str.c_str(), *p) == 0) {
|
|
1825
1855
|
std::string error_msg = "invalid attribute name: '" + std::string(*p) + "'";
|
|
1826
1856
|
PyErr_SetString(PyExc_TypeError, error_msg.c_str());
|
|
1827
1857
|
return false;
|
|
@@ -1842,10 +1872,10 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1842
1872
|
return false;
|
|
1843
1873
|
}
|
|
1844
1874
|
|
|
1845
|
-
|
|
1846
|
-
bool has_slots = (all_slots != NULL);
|
|
1875
|
+
int has_slots = PyDict_ContainsString(data.attrs_copy, "__slots__");
|
|
1847
1876
|
|
|
1848
1877
|
if (has_slots) {
|
|
1878
|
+
PyObject* all_slots = PyDict_GetItemString(data.attrs_copy, "__slots__");
|
|
1849
1879
|
PyObject* slot_seq = PySequence_Fast(all_slots, "__slots__ must be a sequence");
|
|
1850
1880
|
if (!slot_seq) {
|
|
1851
1881
|
return false;
|
|
@@ -1866,8 +1896,6 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1866
1896
|
}
|
|
1867
1897
|
}
|
|
1868
1898
|
Py_DECREF(slot_seq);
|
|
1869
|
-
} else {
|
|
1870
|
-
PyErr_Clear();
|
|
1871
1899
|
}
|
|
1872
1900
|
|
|
1873
1901
|
Py_ssize_t bases_len = PyTuple_GET_SIZE(data.bases);
|
|
@@ -1927,16 +1955,16 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
1927
1955
|
|
|
1928
1956
|
// get "private_func" from kwds
|
|
1929
1957
|
if (kwds && PyDict_Check(kwds)) {
|
|
1930
|
-
|
|
1931
|
-
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");
|
|
1932
1961
|
Py_INCREF(data.private_func);
|
|
1933
1962
|
}
|
|
1934
1963
|
data.base_kwds = PyDict_Copy(kwds);
|
|
1935
1964
|
if (!data.base_kwds) {
|
|
1936
1965
|
return false;
|
|
1937
1966
|
}
|
|
1938
|
-
PyDict_DelItemString(data.base_kwds, "private_func");
|
|
1939
|
-
PyErr_Clear();
|
|
1967
|
+
if (has_private_func) PyDict_DelItemString(data.base_kwds, "private_func");
|
|
1940
1968
|
}
|
|
1941
1969
|
|
|
1942
1970
|
return true;
|
|
@@ -1968,13 +1996,21 @@ PrivateAttrType_create(PyTypeObject* type, PrivateAttrCreationData& data)
|
|
|
1968
1996
|
return new_type;
|
|
1969
1997
|
}
|
|
1970
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
|
+
|
|
1971
2003
|
static void
|
|
1972
2004
|
ensure_tp(PyTypeObject* type_instance)
|
|
1973
2005
|
{
|
|
1974
2006
|
uintptr_t type_id = (uintptr_t)(type_instance);
|
|
1975
|
-
|
|
2007
|
+
{
|
|
1976
2008
|
if (type_instance->tp_getattro != PrivateAttr_tp_getattro) {
|
|
1977
|
-
|
|
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
|
+
}
|
|
1978
2014
|
type_instance->tp_getattro = PrivateAttr_tp_getattro;
|
|
1979
2015
|
} else {
|
|
1980
2016
|
PyTypeObject* base = type_instance->tp_base;
|
|
@@ -1986,9 +2022,13 @@ ensure_tp(PyTypeObject* type_instance)
|
|
|
1986
2022
|
}
|
|
1987
2023
|
}
|
|
1988
2024
|
}
|
|
1989
|
-
|
|
2025
|
+
{
|
|
1990
2026
|
if (type_instance->tp_setattro != PrivateAttr_tp_setattro) {
|
|
1991
|
-
|
|
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
|
+
}
|
|
1992
2032
|
type_instance->tp_setattro = PrivateAttr_tp_setattro;
|
|
1993
2033
|
} else {
|
|
1994
2034
|
PyTypeObject* base = type_instance->tp_base;
|
|
@@ -2000,9 +2040,13 @@ ensure_tp(PyTypeObject* type_instance)
|
|
|
2000
2040
|
}
|
|
2001
2041
|
}
|
|
2002
2042
|
}
|
|
2003
|
-
|
|
2043
|
+
{
|
|
2004
2044
|
if (type_instance->tp_finalize != PrivateAttr_tp_finalize) {
|
|
2005
|
-
|
|
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
|
+
}
|
|
2006
2050
|
type_instance->tp_finalize = PrivateAttr_tp_finalize;
|
|
2007
2051
|
} else {
|
|
2008
2052
|
PyTypeObject* base = type_instance->tp_base;
|
|
@@ -2022,23 +2066,37 @@ ensure_subclass_tp(PyTypeObject* type_instance)
|
|
|
2022
2066
|
// type.__subclasses__
|
|
2023
2067
|
PyObject* type_subclasses = (PyObject*)type_instance->tp_subclasses;
|
|
2024
2068
|
if (!type_subclasses) {
|
|
2025
|
-
PyErr_Clear();
|
|
2026
2069
|
return;
|
|
2027
2070
|
}
|
|
2028
|
-
if (!
|
|
2029
|
-
Py_DECREF(type_subclasses);
|
|
2071
|
+
if (!PyDict_Check(type_subclasses)) {
|
|
2030
2072
|
return;
|
|
2031
2073
|
}
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
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);
|
|
2035
2084
|
if (!subclass || !PyType_Check(subclass)) {
|
|
2036
2085
|
continue;
|
|
2037
2086
|
}
|
|
2038
2087
|
ensure_tp((PyTypeObject*)subclass);
|
|
2039
|
-
|
|
2088
|
+
#else
|
|
2089
|
+
PyObject* subclass;
|
|
2090
|
+
if (PyWeakref_GetRef(value, (PyObject**)&subclass) != 0) {
|
|
2091
|
+
continue;
|
|
2092
|
+
}
|
|
2093
|
+
if (!subclass || !PyType_Check(subclass)) {
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
ensure_tp((PyTypeObject*)subclass);
|
|
2097
|
+
Py_XDECREF(subclass);
|
|
2098
|
+
#endif
|
|
2040
2099
|
}
|
|
2041
|
-
Py_DECREF(type_subclasses);
|
|
2042
2100
|
}
|
|
2043
2101
|
|
|
2044
2102
|
static bool
|
|
@@ -2205,6 +2263,178 @@ PrivateAttrType_getattr(PyObject* cls, PyObject* name)
|
|
|
2205
2263
|
return result;
|
|
2206
2264
|
}
|
|
2207
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
|
+
|
|
2208
2438
|
static int
|
|
2209
2439
|
PrivateAttrType_setattr(PyObject* cls, PyObject* name, PyObject* value)
|
|
2210
2440
|
{
|
|
@@ -2231,6 +2461,28 @@ PrivateAttrType_setattr(PyObject* cls, PyObject* name, PyObject* value)
|
|
|
2231
2461
|
return type_setattr(cls, name_str, value);
|
|
2232
2462
|
}
|
|
2233
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
|
+
}
|
|
2234
2486
|
PyTypeObject* base = Py_TYPE(cls)->tp_base;
|
|
2235
2487
|
while (base && base->tp_base && base->tp_setattro == PrivateAttrType_setattr) {
|
|
2236
2488
|
base = base->tp_base;
|
|
@@ -2316,7 +2568,7 @@ static void
|
|
|
2316
2568
|
PrivateAttrType_del(PyObject* cls)
|
|
2317
2569
|
{
|
|
2318
2570
|
PrivateAttrType_finalize(cls);
|
|
2319
|
-
(
|
|
2571
|
+
PyType_Type.tp_dealloc(cls);
|
|
2320
2572
|
}
|
|
2321
2573
|
|
|
2322
2574
|
static const char* PrivateAttrBase_doc = "The class to help to create private attribute. It does not have any special behavior.";
|
|
@@ -2775,7 +3027,8 @@ static PyModuleDef def = {
|
|
|
2775
3027
|
PyMODINIT_FUNC
|
|
2776
3028
|
PyInit_private_attribute(void)
|
|
2777
3029
|
{
|
|
2778
|
-
if (
|
|
3030
|
+
if (init_all_slots() <0 ||
|
|
3031
|
+
PyType_Ready(&PrivateWrapType) < 0 ||
|
|
2779
3032
|
PyType_Ready(&PrivateWrapProxyType) < 0 ||
|
|
2780
3033
|
PyType_Ready(&PrivateAttrType) < 0 ||
|
|
2781
3034
|
PyType_Ready(&PrivateModuleType) < 0 ||
|
{private_attribute_cpp-1.3.6 → 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
|