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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: private_attribute_cpp
3
- Version: 1.3.5
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
- struct FinalObject {
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
- PyObject* result = ::AllData::all_type_getattro[type_id](self, name);
1214
- return result;
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](self);
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
- PyErr_SetString(PyExc_TypeError, "all items in '__private_attrs__' must be strings");
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 == *p) {
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
- PyObject* all_slots = PyDict_GetItemString(data.attrs_copy, "__slots__");
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
- data.private_func = PyDict_GetItemString(kwds, "private_func");
1928
- if (data.private_func) {
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
- if (type_instance->tp_getattro) {
2007
+ {
1973
2008
  if (type_instance->tp_getattro != PrivateAttr_tp_getattro) {
1974
- ::AllData::all_type_getattro[type_id] = type_instance->tp_getattro;
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
- if (type_instance->tp_setattro) {
2025
+ {
1987
2026
  if (type_instance->tp_setattro != PrivateAttr_tp_setattro) {
1988
- ::AllData::all_type_setattro[type_id] = type_instance->tp_setattro;
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
- if (type_instance->tp_finalize) {
2043
+ {
2001
2044
  if (type_instance->tp_finalize != PrivateAttr_tp_finalize) {
2002
- ::AllData::all_type_finalize[type_id] = type_instance->tp_finalize;
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 (!PyList_Check(type_subclasses)) {
2026
- Py_DECREF(type_subclasses);
2071
+ if (!PyDict_Check(type_subclasses)) {
2027
2072
  return;
2028
2073
  }
2029
- Py_ssize_t subclasses_size = PyList_GET_SIZE(type_subclasses);
2030
- for (Py_ssize_t i = 0; i < subclasses_size; i++) {
2031
- PyObject* subclass = PyList_GET_ITEM(type_subclasses, i);
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
- ensure_subclass_tp((PyTypeObject*)subclass);
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
- (Py_TYPE(cls))->tp_free(cls);
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 (PyType_Ready(&PrivateWrapType) < 0 ||
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: private_attribute_cpp
3
- Version: 1.3.5
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.5',
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.',