private-attribute-cpp 2.1.18__tar.gz → 2.1.19__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.
Files changed (24) hide show
  1. {private_attribute_cpp-2.1.18/private_attribute_cpp.egg-info → private_attribute_cpp-2.1.19}/PKG-INFO +1 -1
  2. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/private_attribute.cpp +267 -2
  3. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/private_attribute.pyi +13 -2
  4. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19/private_attribute_cpp.egg-info}/PKG-INFO +1 -1
  5. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/setup.py +1 -1
  6. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/LICENSE +0 -0
  7. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/MANIFEST.in +0 -0
  8. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/README.md +0 -0
  9. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/picosha2.h +0 -0
  10. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/private_attribute_cpp.egg-info/SOURCES.txt +0 -0
  11. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/private_attribute_cpp.egg-info/dependency_links.txt +0 -0
  12. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/private_attribute_cpp.egg-info/not-zip-safe +0 -0
  13. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/private_attribute_cpp.egg-info/top_level.txt +0 -0
  14. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/setup.cfg +0 -0
  15. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_attr_classify_owner.py +0 -0
  16. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_class_private_attrs.py +0 -0
  17. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_gc_collect.py +0 -0
  18. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_private_abc.py +0 -0
  19. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_private_attrs.py +0 -0
  20. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_private_func.py +0 -0
  21. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_private_inheritance.py +0 -0
  22. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_private_method.py +0 -0
  23. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/tests/test_private_wrap.py +0 -0
  24. {private_attribute_cpp-2.1.18 → private_attribute_cpp-2.1.19}/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.18
3
+ Version: 2.1.19
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_FromLong(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 PySequence_Tuple(((PrivateWrapObject*)obj)->func_list);
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", // tp_name
1415
+ "private_attribute._PrivateWrap", // tp_name
1152
1416
  sizeof(PrivateWrapObject), // tp_basicsize
1153
1417
  0, // tp_itemsize
1154
1418
  (destructor)PrivateWrap_dealloc, // tp_dealloc
@@ -4496,6 +4760,7 @@ PyInit_private_attribute(void) noexcept
4496
4760
  }
4497
4761
  if (init_all_slots() <0 ||
4498
4762
  atexit_register_clean_func() < 0 ||
4763
+ PyType_Ready(&listproxyType) < 0 ||
4499
4764
  PyType_Ready(&PrivateWrapType) < 0 ||
4500
4765
  PyType_Ready(&PrivateWrapProxyType) < 0 ||
4501
4766
  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) -> tuple[FunctionType]:
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.18
3
+ Version: 2.1.19
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.18',
27
+ version='2.1.19',
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.',