private-attribute-cpp 2.1.18__tar.gz → 2.1.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {private_attribute_cpp-2.1.18/private_attribute_cpp.egg-info → private_attribute_cpp-2.1.20}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/private_attribute.cpp +358 -83
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/private_attribute.pyi +13 -2
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/setup.py +1 -1
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/LICENSE +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/MANIFEST.in +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/README.md +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/picosha2.h +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/private_attribute_cpp.egg-info/top_level.txt +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/setup.cfg +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_attr_classify_owner.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_class_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_gc_collect.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_abc.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_attrs.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_func.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_inheritance.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_method.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_wrap.py +0 -0
- {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_slots_cycle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.20
|
|
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
|
|
@@ -931,6 +931,270 @@ type_delattr(PyObject* typ, const std::string& attr_name) noexcept
|
|
|
931
931
|
return 0;
|
|
932
932
|
}
|
|
933
933
|
|
|
934
|
+
// list proxy
|
|
935
|
+
// privatewrap.funcs return this type after 2.1.19
|
|
936
|
+
|
|
937
|
+
typedef struct {
|
|
938
|
+
PyObject_HEAD
|
|
939
|
+
PyObject *list;
|
|
940
|
+
} listproxy;
|
|
941
|
+
|
|
942
|
+
static bool
|
|
943
|
+
listproxy_check(listproxy *obj) noexcept
|
|
944
|
+
{
|
|
945
|
+
if (!obj->list) {
|
|
946
|
+
PyErr_SetString(PyExc_RuntimeError, "listproxy object has no list");
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
if (!PyList_CheckExact(obj->list)) {
|
|
950
|
+
PyErr_Format(PyExc_TypeError, "listproxy object can only proxy list, not '%s'", Py_TYPE(obj->list)->tp_name);
|
|
951
|
+
return false;
|
|
952
|
+
}
|
|
953
|
+
return true;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
static PyObject*
|
|
957
|
+
listproxy_copy(PyObject* self, PyObject* /*args*/) noexcept
|
|
958
|
+
{
|
|
959
|
+
listproxy* obj = (listproxy*)self;
|
|
960
|
+
if (!listproxy_check(obj)) {
|
|
961
|
+
return NULL;
|
|
962
|
+
}
|
|
963
|
+
return PySequence_List(obj->list);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
static PyObject*
|
|
967
|
+
listproxy_count(PyObject* self, PyObject* value) noexcept
|
|
968
|
+
{
|
|
969
|
+
listproxy* obj = (listproxy*)self;
|
|
970
|
+
if (!listproxy_check(obj)) {
|
|
971
|
+
return NULL;
|
|
972
|
+
}
|
|
973
|
+
Py_ssize_t m = PySequence_Count(obj->list, value);
|
|
974
|
+
if (m < 0) {
|
|
975
|
+
return NULL;
|
|
976
|
+
}
|
|
977
|
+
PyObject* result = PyLong_FromSsize_t(m);
|
|
978
|
+
return result;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
static PyObject*
|
|
982
|
+
listproxy_index(PyObject* self, PyObject* args) noexcept
|
|
983
|
+
{
|
|
984
|
+
listproxy* obj = (listproxy*)self;
|
|
985
|
+
if (!listproxy_check(obj)) {
|
|
986
|
+
return NULL;
|
|
987
|
+
}
|
|
988
|
+
PyObject* method = PyObject_GetAttrString(obj->list, "index");
|
|
989
|
+
if (!method) {
|
|
990
|
+
return NULL;
|
|
991
|
+
}
|
|
992
|
+
PyObject* result = PyObject_Call(method, args, NULL);
|
|
993
|
+
Py_DECREF(method);
|
|
994
|
+
return result;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
static Py_ssize_t
|
|
998
|
+
listproxy_length(PyObject* self) noexcept
|
|
999
|
+
{
|
|
1000
|
+
listproxy* obj = (listproxy*)self;
|
|
1001
|
+
if (!listproxy_check(obj)) {
|
|
1002
|
+
return -1;
|
|
1003
|
+
}
|
|
1004
|
+
return PyList_Size(obj->list);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
static PyObject*
|
|
1008
|
+
listproxy_iter(PyObject* self) noexcept
|
|
1009
|
+
{
|
|
1010
|
+
listproxy* obj = (listproxy*)self;
|
|
1011
|
+
if (!listproxy_check(obj)) {
|
|
1012
|
+
return NULL;
|
|
1013
|
+
}
|
|
1014
|
+
return PyObject_GetIter(obj->list);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
static PyObject*
|
|
1018
|
+
listproxy_item(PyObject* self, Py_ssize_t i) noexcept
|
|
1019
|
+
{
|
|
1020
|
+
listproxy* obj = (listproxy*)self;
|
|
1021
|
+
if (!listproxy_check(obj)) {
|
|
1022
|
+
return NULL;
|
|
1023
|
+
}
|
|
1024
|
+
Py_ssize_t size = PyList_Size(obj->list);
|
|
1025
|
+
if (i < 0) {
|
|
1026
|
+
i += size;
|
|
1027
|
+
}
|
|
1028
|
+
if (i < 0 || i >= size) {
|
|
1029
|
+
PyErr_SetString(PyExc_IndexError, "listproxy index out of range");
|
|
1030
|
+
return NULL;
|
|
1031
|
+
}
|
|
1032
|
+
PyObject* item = PyList_GetItem(obj->list, i);
|
|
1033
|
+
if (!item) {
|
|
1034
|
+
return NULL;
|
|
1035
|
+
}
|
|
1036
|
+
Py_INCREF(item);
|
|
1037
|
+
return item;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
static PyObject*
|
|
1041
|
+
listproxy_subscript(PyObject* self, PyObject* key) noexcept
|
|
1042
|
+
{
|
|
1043
|
+
listproxy* obj = (listproxy*)self;
|
|
1044
|
+
if (!listproxy_check(obj)) {
|
|
1045
|
+
return NULL;
|
|
1046
|
+
}
|
|
1047
|
+
return PyObject_GetItem(obj->list, key);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
static int
|
|
1051
|
+
listproxy_contains(PyObject* self, PyObject* value) noexcept
|
|
1052
|
+
{
|
|
1053
|
+
listproxy* obj = (listproxy*)self;
|
|
1054
|
+
if (!listproxy_check(obj)) {
|
|
1055
|
+
return -1;
|
|
1056
|
+
}
|
|
1057
|
+
return PySequence_Contains(obj->list, value);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
static PyObject*
|
|
1061
|
+
listproxy_repr(PyObject* self) noexcept
|
|
1062
|
+
{
|
|
1063
|
+
listproxy* obj = (listproxy*)self;
|
|
1064
|
+
if (!listproxy_check(obj)) {
|
|
1065
|
+
return NULL;
|
|
1066
|
+
}
|
|
1067
|
+
PyObject* inner = PyObject_Repr(obj->list);
|
|
1068
|
+
if (!inner) {
|
|
1069
|
+
return NULL;
|
|
1070
|
+
}
|
|
1071
|
+
PyObject* result = PyUnicode_FromFormat("listproxy(%U)", inner);
|
|
1072
|
+
Py_DECREF(inner);
|
|
1073
|
+
return result;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
static PyObject*
|
|
1077
|
+
listproxy_richcompare(PyObject* self, PyObject* other, int op) noexcept
|
|
1078
|
+
{
|
|
1079
|
+
listproxy* obj = (listproxy*)self;
|
|
1080
|
+
if (!listproxy_check(obj)) {
|
|
1081
|
+
return NULL;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
// If the counterpart is a genuine Python list, compare the underlying
|
|
1085
|
+
// list directly. Otherwise copy the counterpart into a real list first
|
|
1086
|
+
// (so that listproxy == listproxy and listproxy == tuple behave like a
|
|
1087
|
+
// list-to-list comparison), then compare.
|
|
1088
|
+
PyObject* self_list = obj->list;
|
|
1089
|
+
bool decref_self_list = false;
|
|
1090
|
+
if (!PyList_CheckExact(other)) {
|
|
1091
|
+
self_list = PySequence_List(obj->list);
|
|
1092
|
+
if (!self_list) {
|
|
1093
|
+
PyErr_Clear();
|
|
1094
|
+
Py_RETURN_NOTIMPLEMENTED;
|
|
1095
|
+
}
|
|
1096
|
+
decref_self_list = true;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
PyObject* result = PyObject_RichCompare(self_list, other, op);
|
|
1100
|
+
if (decref_self_list) {
|
|
1101
|
+
Py_DECREF(self_list);
|
|
1102
|
+
}
|
|
1103
|
+
return result;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
static void
|
|
1107
|
+
listproxy_dealloc(listproxy* self) noexcept
|
|
1108
|
+
{
|
|
1109
|
+
Py_XDECREF(self->list);
|
|
1110
|
+
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
static PySequenceMethods listproxy_as_sequence = {
|
|
1114
|
+
listproxy_length, // sq_length
|
|
1115
|
+
0, // sq_concat
|
|
1116
|
+
0, // sq_repeat
|
|
1117
|
+
listproxy_item, // sq_item
|
|
1118
|
+
0, // was_sq_slice
|
|
1119
|
+
0, // sq_ass_item
|
|
1120
|
+
0, // was_sq_ass_slice
|
|
1121
|
+
listproxy_contains, // sq_contains
|
|
1122
|
+
0, // sq_inplace_concat
|
|
1123
|
+
0, // sq_inplace_repeat
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
static PyMappingMethods listproxy_as_mapping = {
|
|
1127
|
+
listproxy_length, // mp_length
|
|
1128
|
+
listproxy_subscript, // mp_subscript
|
|
1129
|
+
0, // mp_ass_subscript
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
static PyMethodDef listproxy_methods[] = {
|
|
1133
|
+
{"copy", listproxy_copy, METH_NOARGS, "Return a copy of the proxied list."},
|
|
1134
|
+
{"count", listproxy_count, METH_O, "Return number of occurrences of value."},
|
|
1135
|
+
{"index", listproxy_index, METH_VARARGS, "Return first index of value."},
|
|
1136
|
+
{NULL, NULL, 0, NULL}
|
|
1137
|
+
};
|
|
1138
|
+
|
|
1139
|
+
static int
|
|
1140
|
+
listproxy_traverse(PyObject* self, visitproc visit, void* arg) noexcept
|
|
1141
|
+
{
|
|
1142
|
+
listproxy* obj = (listproxy*)self;
|
|
1143
|
+
Py_VISIT(obj->list);
|
|
1144
|
+
return 0;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
static int
|
|
1148
|
+
listproxy_clear(PyObject* self) noexcept
|
|
1149
|
+
{
|
|
1150
|
+
listproxy* obj = (listproxy*)self;
|
|
1151
|
+
Py_CLEAR(obj->list);
|
|
1152
|
+
return 0;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
static PyTypeObject listproxyType = {
|
|
1156
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1157
|
+
"private_attribute.listproxy", // tp_name
|
|
1158
|
+
sizeof(listproxy), // tp_basicsize
|
|
1159
|
+
0, // tp_itemsize
|
|
1160
|
+
(destructor)listproxy_dealloc, // tp_dealloc
|
|
1161
|
+
0, // tp_print
|
|
1162
|
+
0, // tp_getattr
|
|
1163
|
+
0, // tp_setattr
|
|
1164
|
+
0, // tp_reserved
|
|
1165
|
+
listproxy_repr, // tp_repr
|
|
1166
|
+
0, // tp_as_number
|
|
1167
|
+
&listproxy_as_sequence, // tp_as_sequence
|
|
1168
|
+
&listproxy_as_mapping, // tp_as_mapping
|
|
1169
|
+
0, // tp_hash
|
|
1170
|
+
0, // tp_call
|
|
1171
|
+
0, // tp_str
|
|
1172
|
+
0, // tp_getattro
|
|
1173
|
+
0, // tp_setattro
|
|
1174
|
+
0, // tp_as_buffer
|
|
1175
|
+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags
|
|
1176
|
+
"A read-only proxy of a list.", // tp_doc
|
|
1177
|
+
listproxy_traverse, // tp_traverse
|
|
1178
|
+
listproxy_clear, // tp_clear
|
|
1179
|
+
listproxy_richcompare, // tp_richcompare
|
|
1180
|
+
0, // tp_weaklistoffset
|
|
1181
|
+
listproxy_iter, // tp_iter
|
|
1182
|
+
0, // tp_iternext
|
|
1183
|
+
listproxy_methods, // tp_methods
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
static PyObject*
|
|
1187
|
+
listproxy_new(PyObject* list) noexcept
|
|
1188
|
+
{
|
|
1189
|
+
listproxy* obj = PyObject_GC_New(listproxy, &listproxyType);
|
|
1190
|
+
if (!obj) {
|
|
1191
|
+
return NULL;
|
|
1192
|
+
}
|
|
1193
|
+
obj->list = list;
|
|
1194
|
+
Py_INCREF(list);
|
|
1195
|
+
return (PyObject*)obj;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
934
1198
|
// ================================================================
|
|
935
1199
|
// _PrivateWrap
|
|
936
1200
|
// ================================================================
|
|
@@ -957,7 +1221,7 @@ PrivateWrap_funcs(PyObject *obj, void* /*closure*/) noexcept
|
|
|
957
1221
|
Py_RETURN_NONE;
|
|
958
1222
|
}
|
|
959
1223
|
|
|
960
|
-
return
|
|
1224
|
+
return listproxy_new(((PrivateWrapObject*)obj)->func_list);
|
|
961
1225
|
}
|
|
962
1226
|
|
|
963
1227
|
static PyObject*
|
|
@@ -1148,7 +1412,7 @@ PrivateWrap_clear(PyObject* obj) noexcept
|
|
|
1148
1412
|
|
|
1149
1413
|
static PyTypeObject PrivateWrapType = {
|
|
1150
1414
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
1151
|
-
"_PrivateWrap",
|
|
1415
|
+
"private_attribute._PrivateWrap", // tp_name
|
|
1152
1416
|
sizeof(PrivateWrapObject), // tp_basicsize
|
|
1153
1417
|
0, // tp_itemsize
|
|
1154
1418
|
(destructor)PrivateWrap_dealloc, // tp_dealloc
|
|
@@ -2100,17 +2364,12 @@ PrivateAttrType_tp_clear(PyObject* self) noexcept
|
|
|
2100
2364
|
static void
|
|
2101
2365
|
PrivateAttr_object_init_private_dict(uintptr_t obj_id, uintptr_t type_id) noexcept
|
|
2102
2366
|
{
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
if (::AllData::all_object_mutex[type_id].find(obj_id) == ::AllData::all_object_mutex[type_id].end()) {
|
|
2110
|
-
::AllData::all_object_mutex[type_id][obj_id] = std::make_unique<std::shared_mutex>();
|
|
2111
|
-
}
|
|
2112
|
-
if (::AllData::all_object_attr[type_id].find(obj_id) == ::AllData::all_object_attr[type_id].end()) {
|
|
2113
|
-
::AllData::all_object_attr[type_id][obj_id] = {};
|
|
2367
|
+
object_create_mutex(type_id, obj_id);
|
|
2368
|
+
{
|
|
2369
|
+
std::unique_lock<std::shared_mutex> lock(*::AllData::all_object_mutex[type_id][obj_id]);
|
|
2370
|
+
if (::AllData::all_object_attr[type_id].find(obj_id) == ::AllData::all_object_attr[type_id].end()) {
|
|
2371
|
+
::AllData::all_object_attr[type_id][obj_id] = {};
|
|
2372
|
+
}
|
|
2114
2373
|
}
|
|
2115
2374
|
if (::AllData::all_type_parent_id.find(type_id) != ::AllData::all_type_parent_id.end()) {
|
|
2116
2375
|
for (auto parent_id : ::AllData::all_type_parent_id[type_id]) {
|
|
@@ -2177,7 +2436,7 @@ get_string_hash_tuple(const std::string& name) noexcept
|
|
|
2177
2436
|
std::string name1hash, name2hash;
|
|
2178
2437
|
picosha2::hash256_hex_string(name1, name1hash);
|
|
2179
2438
|
picosha2::hash256_hex_string(name2, name2hash);
|
|
2180
|
-
return
|
|
2439
|
+
return Py_BuildValue("(ss)", name1hash.c_str(), name2hash.c_str());
|
|
2181
2440
|
}
|
|
2182
2441
|
|
|
2183
2442
|
static TwoStringTuple
|
|
@@ -2466,6 +2725,14 @@ real_class_name(const std::string& name, const std::string& class_name) noexcept
|
|
|
2466
2725
|
return name;
|
|
2467
2726
|
}
|
|
2468
2727
|
|
|
2728
|
+
#define PRIVATEATTR_CREATION_DATA_CLEAR(name) do \
|
|
2729
|
+
{ \
|
|
2730
|
+
if (name) { \
|
|
2731
|
+
Py_DECREF(name); \
|
|
2732
|
+
name = nullptr; \
|
|
2733
|
+
} \
|
|
2734
|
+
} while (0)
|
|
2735
|
+
|
|
2469
2736
|
struct PrivateAttrCreationData
|
|
2470
2737
|
{
|
|
2471
2738
|
std::string class_name;
|
|
@@ -2489,34 +2756,13 @@ struct PrivateAttrCreationData
|
|
|
2489
2756
|
if (cleared) {
|
|
2490
2757
|
return;
|
|
2491
2758
|
}
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
}
|
|
2500
|
-
if (attrs) {
|
|
2501
|
-
Py_DECREF(attrs);
|
|
2502
|
-
attrs = nullptr;
|
|
2503
|
-
}
|
|
2504
|
-
if (attrs_copy) {
|
|
2505
|
-
Py_DECREF(attrs_copy);
|
|
2506
|
-
attrs_copy = nullptr;
|
|
2507
|
-
}
|
|
2508
|
-
if (new_hash_private_attrs) {
|
|
2509
|
-
Py_DECREF(new_hash_private_attrs);
|
|
2510
|
-
new_hash_private_attrs = nullptr;
|
|
2511
|
-
}
|
|
2512
|
-
if (private_func) {
|
|
2513
|
-
Py_DECREF(private_func);
|
|
2514
|
-
private_func = nullptr;
|
|
2515
|
-
}
|
|
2516
|
-
if (base_kwds) {
|
|
2517
|
-
Py_DECREF(base_kwds);
|
|
2518
|
-
base_kwds = nullptr;
|
|
2519
|
-
}
|
|
2759
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(name);
|
|
2760
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(bases);
|
|
2761
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(attrs);
|
|
2762
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(attrs_copy);
|
|
2763
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(new_hash_private_attrs);
|
|
2764
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(private_func);
|
|
2765
|
+
PRIVATEATTR_CREATION_DATA_CLEAR(base_kwds);
|
|
2520
2766
|
|
|
2521
2767
|
need_remove_itself.clear();
|
|
2522
2768
|
need_remove_subclass.clear();
|
|
@@ -2747,7 +2993,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2747
2993
|
|
|
2748
2994
|
// forbidden to have "__static_attributes__" in attrs, because it exposes the private attributes name.
|
|
2749
2995
|
if (PyDict_ContainsString(data.attrs_copy, "__static_attributes__")) {
|
|
2750
|
-
PyDict_DelItemString(data.attrs_copy, "__static_attributes__");
|
|
2996
|
+
if (PyDict_DelItemString(data.attrs_copy, "__static_attributes__") < 0) return false;
|
|
2751
2997
|
}
|
|
2752
2998
|
|
|
2753
2999
|
{
|
|
@@ -2772,7 +3018,7 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2772
3018
|
// (PrivateAttrCreationData::clear). No manual INCREF here,
|
|
2773
3019
|
// otherwise the value leaks (+1) when the class is destroyed.
|
|
2774
3020
|
data.need_remove_itself[attr_name] = need_value;
|
|
2775
|
-
PyDict_DelItem(data.attrs_copy, key);
|
|
3021
|
+
if (PyDict_DelItem(data.attrs_copy, key)) return false;
|
|
2776
3022
|
continue;
|
|
2777
3023
|
}
|
|
2778
3024
|
uintptr_t need_remove_subclass_id = need_remove_to_subclass(attr_name);
|
|
@@ -2785,10 +3031,12 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2785
3031
|
}
|
|
2786
3032
|
// PyObjectStorage assignment INCREFs (RAII); no manual INCREF.
|
|
2787
3033
|
data.need_remove_subclass[need_remove_subclass_id][attr_name] = need_value;
|
|
2788
|
-
PyDict_DelItem(data.attrs_copy, key);
|
|
3034
|
+
if (PyDict_DelItem(data.attrs_copy, key)) return false;
|
|
2789
3035
|
continue;
|
|
2790
3036
|
}
|
|
2791
|
-
if (value != need_value)
|
|
3037
|
+
if (value != need_value) {
|
|
3038
|
+
if (PyDict_SetItem(data.attrs_copy, key, need_value) < 0) return false;
|
|
3039
|
+
}
|
|
2792
3040
|
}
|
|
2793
3041
|
Py_DECREF(forward_analyse);
|
|
2794
3042
|
}
|
|
@@ -2804,7 +3052,9 @@ PrivateAttrType_preprocess(PyObject* args, PyObject* kwds, PrivateAttrCreationDa
|
|
|
2804
3052
|
if (!data.base_kwds) {
|
|
2805
3053
|
return false;
|
|
2806
3054
|
}
|
|
2807
|
-
if (has_private_func)
|
|
3055
|
+
if (has_private_func) {
|
|
3056
|
+
if (PyDict_DelItemString(data.base_kwds, "private_func") < 0) return false;
|
|
3057
|
+
}
|
|
2808
3058
|
}
|
|
2809
3059
|
|
|
2810
3060
|
return true;
|
|
@@ -3610,54 +3860,78 @@ static const char* PrivateAttrBase_doc = "The class to help to create private at
|
|
|
3610
3860
|
static PyObject*
|
|
3611
3861
|
create_private_attr_base_simple(void) noexcept
|
|
3612
3862
|
{
|
|
3613
|
-
PyObject* name =
|
|
3614
|
-
|
|
3615
|
-
PyObject*
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
PyObject*
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3863
|
+
PyObject* name = NULL;
|
|
3864
|
+
PyObject* bases = NULL;
|
|
3865
|
+
PyObject* dict = NULL;
|
|
3866
|
+
PyObject* private_attrs = NULL;
|
|
3867
|
+
PyObject* doc = NULL;
|
|
3868
|
+
PyObject* module_name = NULL;
|
|
3869
|
+
PyObject* args = NULL;
|
|
3870
|
+
PyObject* base_type = NULL;
|
|
3871
|
+
|
|
3872
|
+
name = PyUnicode_InternFromString("PrivateAttrBase");
|
|
3873
|
+
if (!name) goto fail;
|
|
3874
|
+
|
|
3875
|
+
bases = PyTuple_New(0);
|
|
3876
|
+
if (!bases) goto fail;
|
|
3877
|
+
|
|
3878
|
+
dict = PyDict_New();
|
|
3879
|
+
if (!dict) goto fail;
|
|
3880
|
+
|
|
3881
|
+
private_attrs = PyTuple_New(0);
|
|
3882
|
+
if (!private_attrs) goto fail;
|
|
3883
|
+
|
|
3884
|
+
doc = PyUnicode_InternFromString(PrivateAttrBase_doc);
|
|
3885
|
+
if (!doc) goto fail;
|
|
3886
|
+
|
|
3887
|
+
module_name = PyUnicode_InternFromString("private_attribute");
|
|
3888
|
+
if (!module_name) goto fail;
|
|
3889
|
+
|
|
3890
|
+
if (PyDict_SetItemString(dict, "__private_attrs__", private_attrs) < 0) goto fail;
|
|
3891
|
+
if (PyDict_SetItemString(dict, "__slots__", private_attrs) < 0) goto fail;
|
|
3892
|
+
if (PyDict_SetItemString(dict, "__doc__", doc) < 0) goto fail;
|
|
3893
|
+
if (PyDict_SetItemString(dict, "__module__", module_name) < 0) goto fail;
|
|
3894
|
+
|
|
3895
|
+
Py_DECREF(doc);
|
|
3896
|
+
doc = NULL;
|
|
3897
|
+
Py_DECREF(module_name);
|
|
3898
|
+
module_name = NULL;
|
|
3899
|
+
|
|
3900
|
+
args = PyTuple_Pack(3, name, bases, dict);
|
|
3901
|
+
if (!args) goto fail;
|
|
3902
|
+
|
|
3903
|
+
{
|
|
3640
3904
|
// RAII: the first heap type created through tp_new (PrivateAttrBase)
|
|
3641
3905
|
// carries CPython's pristine subtype_traverse/subtype_clear in its
|
|
3642
3906
|
// tp_traverse/tp_clear; PrivateAttrType_new captures those pointers
|
|
3643
3907
|
// while this guard is active.
|
|
3644
3908
|
PrivateAttrCaptureGuard capture_guard;
|
|
3645
3909
|
base_type = PrivateAttrType_new((PyTypeObject*)&PrivateAttrType, args, NULL);
|
|
3646
|
-
Py_DECREF(args);
|
|
3647
|
-
} else {
|
|
3648
|
-
Py_DECREF(name);
|
|
3649
|
-
Py_DECREF(bases);
|
|
3650
|
-
Py_DECREF(dict);
|
|
3651
|
-
return NULL;
|
|
3652
3910
|
}
|
|
3911
|
+
Py_DECREF(args);
|
|
3912
|
+
args = NULL;
|
|
3913
|
+
|
|
3653
3914
|
Py_DECREF(name);
|
|
3915
|
+
name = NULL;
|
|
3654
3916
|
Py_DECREF(bases);
|
|
3917
|
+
bases = NULL;
|
|
3655
3918
|
Py_DECREF(dict);
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3919
|
+
dict = NULL;
|
|
3920
|
+
|
|
3921
|
+
if (!base_type) goto fail;
|
|
3922
|
+
|
|
3659
3923
|
((PyTypeObject*)base_type)->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE;
|
|
3660
3924
|
return base_type;
|
|
3925
|
+
|
|
3926
|
+
fail:
|
|
3927
|
+
Py_XDECREF(name);
|
|
3928
|
+
Py_XDECREF(bases);
|
|
3929
|
+
Py_XDECREF(dict);
|
|
3930
|
+
Py_XDECREF(private_attrs);
|
|
3931
|
+
Py_XDECREF(doc);
|
|
3932
|
+
Py_XDECREF(module_name);
|
|
3933
|
+
Py_XDECREF(args);
|
|
3934
|
+
return NULL;
|
|
3661
3935
|
}
|
|
3662
3936
|
|
|
3663
3937
|
typedef struct {
|
|
@@ -4496,6 +4770,7 @@ PyInit_private_attribute(void) noexcept
|
|
|
4496
4770
|
}
|
|
4497
4771
|
if (init_all_slots() <0 ||
|
|
4498
4772
|
atexit_register_clean_func() < 0 ||
|
|
4773
|
+
PyType_Ready(&listproxyType) < 0 ||
|
|
4499
4774
|
PyType_Ready(&PrivateWrapType) < 0 ||
|
|
4500
4775
|
PyType_Ready(&PrivateWrapProxyType) < 0 ||
|
|
4501
4776
|
PyType_Ready(&PrivateAttrType) < 0 ||
|
|
@@ -15,8 +15,9 @@ class MyClass(PrivateAttrBase):
|
|
|
15
15
|
return self._private_attr1
|
|
16
16
|
```
|
|
17
17
|
"""
|
|
18
|
-
from typing import Any, TypeVar, Callable, TypedDict, Sequence, Generic, Optional, cast
|
|
18
|
+
from typing import Any, TypeVar, Callable, TypedDict, Sequence, Generic, Optional, cast, Iterator
|
|
19
19
|
from types import FunctionType
|
|
20
|
+
import sys
|
|
20
21
|
|
|
21
22
|
# define the dict that must have a key "__private_attrs__" and value must be the sequence of strings
|
|
22
23
|
class _PrivateAttrDict(TypedDict):
|
|
@@ -24,6 +25,16 @@ class _PrivateAttrDict(TypedDict):
|
|
|
24
25
|
|
|
25
26
|
_T = TypeVar('_T')
|
|
26
27
|
|
|
28
|
+
class listproxy(Generic[_T]):
|
|
29
|
+
"a read-only proxy of a list"
|
|
30
|
+
def copy(self) -> list[_T]: ...
|
|
31
|
+
def count(self, value: Any, /) -> int: ...
|
|
32
|
+
def index(self, value: Any, start: int = 0, stop: int = sys.maxsize, /) -> int: ...
|
|
33
|
+
def __len__(self) -> int: ...
|
|
34
|
+
def __iter__(self) -> Iterator[_T]: ...
|
|
35
|
+
def __getitem__(self, key: int | slice) -> Any: ...
|
|
36
|
+
def __contains__(self, value: object) -> bool: ...
|
|
37
|
+
|
|
27
38
|
class _PrivateWrap(Generic[_T]):
|
|
28
39
|
@property
|
|
29
40
|
def result(self) -> _T:
|
|
@@ -31,7 +42,7 @@ class _PrivateWrap(Generic[_T]):
|
|
|
31
42
|
...
|
|
32
43
|
|
|
33
44
|
@property
|
|
34
|
-
def funcs(self) ->
|
|
45
|
+
def funcs(self) -> listproxy[FunctionType]:
|
|
35
46
|
"the original functions"
|
|
36
47
|
...
|
|
37
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: private_attribute_cpp
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.20
|
|
4
4
|
Summary: A Python package that provides a way to define private attributes in C++ implementation.
|
|
5
5
|
Home-page: https://github.com/Locked-chess-official/private_attribute_cpp
|
|
6
6
|
Author: HuangHaoHua
|
|
@@ -24,7 +24,7 @@ readme = open('README.md').read()
|
|
|
24
24
|
|
|
25
25
|
setup(
|
|
26
26
|
name='private_attribute_cpp',
|
|
27
|
-
version='2.1.
|
|
27
|
+
version='2.1.20',
|
|
28
28
|
author="HuangHaoHua",
|
|
29
29
|
author_email="13140752715@example.com",
|
|
30
30
|
description='A Python package that provides a way to define private attributes in C++ implementation.',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_attr_classify_owner.py
RENAMED
|
File without changes
|
{private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_class_private_attrs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.20}/tests/test_private_inheritance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|