private-attribute-cpp 2.2.1__tar.gz → 2.2.3__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 (35) hide show
  1. private_attribute_cpp-2.2.3/CMakeLists.txt +89 -0
  2. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/PKG-INFO +7 -5
  3. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/README.md +6 -4
  4. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/private_attribute.cpp +28 -5
  5. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/private_attribute.pyi +15 -12
  6. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/pyproject.toml +1 -1
  7. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_private_abc.py +6 -6
  8. private_attribute_cpp-2.2.1/CMakeLists.txt +0 -34
  9. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.github/dependabot.yml +0 -0
  10. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.github/workflows/build-android.yml +0 -0
  11. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.github/workflows/lint.yml +0 -0
  12. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.github/workflows/python-publish.yml +0 -0
  13. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.github/workflows/test.yml +0 -0
  14. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.github/workflows/update-bot.yml +0 -0
  15. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.gitignore +0 -0
  16. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.pre-commit-config.yaml +0 -0
  17. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/.update-bot/update_picosha2.py +0 -0
  18. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/LICENSE +0 -0
  19. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/ci/android/build_python.sh +0 -0
  20. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/ci/android/common.sh +0 -0
  21. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/ci/android/pydroid3.sh +0 -0
  22. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/ci/android/run.sh +0 -0
  23. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/ci/android/termux.sh +0 -0
  24. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/picosha2.h +0 -0
  25. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_attr_classify_owner.py +0 -0
  26. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_class_private_attrs.py +0 -0
  27. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_gc_collect.py +0 -0
  28. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_init_subclass.py +0 -0
  29. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_private_attrs.py +0 -0
  30. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_private_func.py +0 -0
  31. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_private_inheritance.py +0 -0
  32. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_private_method.py +0 -0
  33. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_private_wrap.py +0 -0
  34. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_slots_cycle.py +0 -0
  35. {private_attribute_cpp-2.2.1 → private_attribute_cpp-2.2.3}/tests/test_use_parents.py +0 -0
@@ -0,0 +1,89 @@
1
+ cmake_minimum_required(VERSION 3.15...3.31)
2
+
3
+ project(private_attribute_cpp LANGUAGES CXX)
4
+
5
+ # Locate the running interpreter and its development headers/module support.
6
+ find_package(
7
+ Python
8
+ COMPONENTS Interpreter Development.Module
9
+ REQUIRED)
10
+
11
+ # Build the `private_attribute` extension module with a proper SOABI suffix
12
+ # (private_attribute.cpython-3XX[-t]-<plat>.so), importable from site-packages.
13
+ # Detect whether the running Python was built with --enable-shared.
14
+ execute_process(
15
+ COMMAND "${Python_EXECUTABLE}" -c
16
+ "import sysconfig; print(sysconfig.get_config_var('Py_ENABLE_SHARED') or 0)"
17
+ OUTPUT_VARIABLE PYTHON_ENABLE_SHARED
18
+ OUTPUT_STRIP_TRAILING_WHITESPACE
19
+ RESULT_VARIABLE PYTHON_CONFIG_RESULT
20
+ )
21
+
22
+ if(NOT PYTHON_CONFIG_RESULT EQUAL 0)
23
+ message(FATAL_ERROR "Failed to query Python build configuration")
24
+ endif()
25
+
26
+ if(WIN32)
27
+ # Windows: keep Python::Module to obtain the required import library.
28
+ Python_add_library(
29
+ private_attribute MODULE WITH_SOABI
30
+ private_attribute.cpp
31
+ )
32
+ elseif(PYTHON_ENABLE_SHARED STREQUAL "1")
33
+ # Keep the standard CMake Python extension-module behavior.
34
+ Python_add_library(
35
+ private_attribute MODULE WITH_SOABI
36
+ private_attribute.cpp
37
+ )
38
+ else()
39
+ # Match the usual Unix setuptools.Extension behavior:
40
+ # do not link the static libpython into the extension module.
41
+ add_library(
42
+ private_attribute MODULE
43
+ private_attribute.cpp
44
+ )
45
+
46
+ if(APPLE)
47
+ target_link_options(
48
+ private_attribute PRIVATE
49
+ "-undefined" "dynamic_lookup"
50
+ )
51
+ endif()
52
+
53
+ target_include_directories(
54
+ private_attribute PRIVATE
55
+ ${Python_INCLUDE_DIRS}
56
+ )
57
+
58
+ set_target_properties(
59
+ private_attribute PROPERTIES
60
+ PREFIX ""
61
+ SUFFIX ".${Python_SOABI}${CMAKE_SHARED_MODULE_SUFFIX}"
62
+ )
63
+
64
+ message(STATUS
65
+ "Python was built without --enable-shared; "
66
+ "building the extension without linking libpython"
67
+ )
68
+ endif()
69
+
70
+ # picosha2.h is a header-only dependency living next to the .cpp.
71
+ target_include_directories(private_attribute PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
72
+
73
+ # C++17, matching the original setup.py flags.
74
+ if(MSVC)
75
+ target_compile_options(private_attribute PRIVATE /std:c++17 /GR-)
76
+ else()
77
+ target_compile_options(private_attribute PRIVATE -std=c++17 -fno-exceptions -fno-rtti)
78
+ # Strip debug info unless the caller explicitly opts in to keeping it.
79
+ # (This is the conditional that a static pyproject.toml cannot express,
80
+ # hence it lives here in CMake instead of setup.py.)
81
+ if(NOT "$ENV{PRIVATE_ATTR_KEEP_DEBUG}" STREQUAL "1")
82
+ target_compile_options(private_attribute PRIVATE -g0)
83
+ endif()
84
+ endif()
85
+
86
+ # Install both the compiled module and its PEP 561 type stub at the
87
+ # site-packages root, side by side.
88
+ install(TARGETS private_attribute LIBRARY DESTINATION .)
89
+ install(FILES private_attribute.pyi DESTINATION .)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: private_attribute_cpp
3
- Version: 2.2.1
3
+ Version: 2.2.3
4
4
  Summary: A Python package that provides a way to define private attributes in C++ implementation.
5
5
  Author-Email: HuangHaoHua <13140752715@example.com>
6
6
  License-Expression: MIT
@@ -184,10 +184,10 @@ import private_attribute
184
184
 
185
185
  class PrivateAbcMeta(ABCMeta):
186
186
  def __new__(cls, name, bases, attrs, **kwargs):
187
- temp = private_attribute.prepare(name, bases, attrs, **kwargs)
188
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
189
- private_attribute.postprocess(typ, temp)
190
- return typ
187
+ with private_attribute.prepare(name, bases, attrs, **kwargs) as tmp: # In 2.2.3 it support using "with"
188
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
189
+ private_attribute.postprocess(typ, temp) # or tmp.postprocess(typ)
190
+ return typ
191
191
 
192
192
  private_attribute.register_metaclass(PrivateAbcMeta)
193
193
  ```
@@ -248,6 +248,8 @@ TypeError: Can't instantiate abstract class MyClass without an implementation fo
248
248
  - CPython may change "tp_getattro", "tp_setattro" and so on when you change the attribute "\_\_getattribute\_\_", "\_\_setattr\_\_" and so on. If you are fear about it, you can use `ensure_type` to reset those tp slots. For the other metaclasses, you can use `ensure_metaclass` to reset those tp slots. Also, don't set those methods on these classes in your code.
249
249
  - `private_attribute.register_metaclass` must be called with the metaclass which supports weakref.
250
250
  - Don't set `__static_attributes__` in private attribute class, or it will be removed.
251
+ - After 2.2.1, when `prepare` was called, it will lock the creation of new private attribute type. There will be only one private attribute type in building (type.\_\_new\_\_) at the same time. Call `postprocess` to unlock it. If build failed, the lock will be released automatically.
252
+ - After 2.2.3, it is recommend to use "with" on `private_attribute.prepare` and `private_attribute.postprocess` to ensure the lock is released.
251
253
 
252
254
  ## License
253
255
 
@@ -174,10 +174,10 @@ import private_attribute
174
174
 
175
175
  class PrivateAbcMeta(ABCMeta):
176
176
  def __new__(cls, name, bases, attrs, **kwargs):
177
- temp = private_attribute.prepare(name, bases, attrs, **kwargs)
178
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
179
- private_attribute.postprocess(typ, temp)
180
- return typ
177
+ with private_attribute.prepare(name, bases, attrs, **kwargs) as tmp: # In 2.2.3 it support using "with"
178
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
179
+ private_attribute.postprocess(typ, temp) # or tmp.postprocess(typ)
180
+ return typ
181
181
 
182
182
  private_attribute.register_metaclass(PrivateAbcMeta)
183
183
  ```
@@ -238,6 +238,8 @@ TypeError: Can't instantiate abstract class MyClass without an implementation fo
238
238
  - CPython may change "tp_getattro", "tp_setattro" and so on when you change the attribute "\_\_getattribute\_\_", "\_\_setattr\_\_" and so on. If you are fear about it, you can use `ensure_type` to reset those tp slots. For the other metaclasses, you can use `ensure_metaclass` to reset those tp slots. Also, don't set those methods on these classes in your code.
239
239
  - `private_attribute.register_metaclass` must be called with the metaclass which supports weakref.
240
240
  - Don't set `__static_attributes__` in private attribute class, or it will be removed.
241
+ - After 2.2.1, when `prepare` was called, it will lock the creation of new private attribute type. There will be only one private attribute type in building (type.\_\_new\_\_) at the same time. Call `postprocess` to unlock it. If build failed, the lock will be released automatically.
242
+ - After 2.2.3, it is recommend to use "with" on `private_attribute.prepare` and `private_attribute.postprocess` to ensure the lock is released.
241
243
 
242
244
  ## License
243
245
 
@@ -4060,8 +4060,27 @@ PrivateTempObject_postprocess(PyObject* self, PyObject* type) noexcept
4060
4060
  Py_RETURN_NONE;
4061
4061
  }
4062
4062
 
4063
+ static PyObject*
4064
+ PrivateTempObject_enter(PyObject* self, PyObject* /*args*/) noexcept
4065
+ {
4066
+ Py_INCREF(self);
4067
+ return self;
4068
+ }
4069
+
4070
+
4071
+ static PyObject*
4072
+ PrivateTempObject_exit(PyObject* self, PyObject* /*args*/) noexcept
4073
+ {
4074
+ PrivateTempObject* obj = (PrivateTempObject*)self;
4075
+ if (!obj->tmp->cleared) {
4076
+ obj->tmp->clear();
4077
+ }
4078
+ Py_RETURN_NONE;
4079
+ }
4063
4080
  static PyMethodDef PrivateTempObject_methods[] = {
4064
4081
  {"postprocess", (PyCFunction)PrivateTempObject_postprocess, METH_O, "postprocess the temp object"},
4082
+ {"__enter__", (PyCFunction)PrivateTempObject_enter, METH_NOARGS, NULL},
4083
+ {"__exit__", (PyCFunction)PrivateTempObject_exit, METH_VARARGS, NULL},
4065
4084
  {NULL}
4066
4085
  };
4067
4086
 
@@ -4147,7 +4166,11 @@ postprocess_for_PrivateAttr(PyObject* /*self*/, PyObject* args) noexcept
4147
4166
  {
4148
4167
  PyObject* type;
4149
4168
  PyObject* tmp;
4150
- if (!PyArg_ParseTuple(args, "OO", &type, &tmp)) {
4169
+ if (!PyArg_ParseTuple(args, "OO:private_attribute.postprocess", &type, &tmp)) {
4170
+ return NULL;
4171
+ }
4172
+ if (!PyObject_IsInstance(tmp, (PyObject*)&PrivateTempType)) {
4173
+ PyErr_SetString(PyExc_TypeError, "tmp must be a PrivateTempObject");
4151
4174
  return NULL;
4152
4175
  }
4153
4176
  return PrivateTempObject_postprocess(tmp, type);
@@ -4506,10 +4529,10 @@ import private_attribute
4506
4529
 
4507
4530
  class PrivateAbcMeta(ABCMeta):
4508
4531
  def __new__(cls, *args, **kwargs):
4509
- temp = private_attribute.prepare(*args, **kwargs)
4510
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
4511
- private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
4512
- return typ
4532
+ with private_attribute.prepare(*args, **kwargs) as temp:
4533
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
4534
+ private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
4535
+ return typ
4513
4536
 
4514
4537
  private_attribute.register_metaclass(PrivateAbcMeta)
4515
4538
  ```
@@ -119,6 +119,9 @@ class _PrivateTemp:
119
119
  def kwds(self) -> dict[str, Any]: ...
120
120
  def postprocess(self, typ: type, /) -> None: ... # add in 2.1.17
121
121
 
122
+ def __enter__(self) -> "_PrivateTemp": ...
123
+ def __exit__(self, exc_type: type, exc_val: Exception, exc_tb: Any) -> None: ...
124
+
122
125
  def prepare(name: str, bases: tuple, attrs: _PrivateAttrDict, /, **kwds) -> _PrivateTemp:
123
126
  """
124
127
  function for custom metaclass to create private attributes class.
@@ -140,10 +143,10 @@ def prepare(name: str, bases: tuple, attrs: _PrivateAttrDict, /, **kwds) -> _Pri
140
143
 
141
144
  class PrivateAbcMeta(ABCMeta):
142
145
  def __new__(cls, *args, **kwargs):
143
- temp = private_attribute.prepare(*args, **kwargs)
144
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
145
- private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
146
- return typ
146
+ with private_attribute.prepare(*args, **kwargs) as temp:
147
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
148
+ private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
149
+ return typ
147
150
 
148
151
  private_attribute.register_metaclass(PrivateAbcMeta)
149
152
  ```
@@ -178,10 +181,10 @@ def postprocess(typ: type, temp: _PrivateTemp, /) -> None:
178
181
 
179
182
  class PrivateAbcMeta(ABCMeta):
180
183
  def __new__(cls, *args, **kwargs):
181
- temp = private_attribute.prepare(*args, **kwargs)
182
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
183
- private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
184
- return typ
184
+ with private_attribute.prepare(*args, **kwargs) as temp:
185
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
186
+ private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
187
+ return typ
185
188
 
186
189
  private_attribute.register_metaclass(PrivateAbcMeta)
187
190
  ```
@@ -208,10 +211,10 @@ def register_metaclass(typ: type, /) -> None:
208
211
 
209
212
  class PrivateAbcMeta(ABCMeta):
210
213
  def __new__(cls, *args, **kwargs):
211
- temp = private_attribute.prepare(*args, **kwargs)
212
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
213
- private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
214
- return typ
214
+ with private_attribute.prepare(*args, **kwargs) as temp:
215
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
216
+ private_attribute.postprocess(typ, temp) # or temp.postprocess(typ)
217
+ return typ
215
218
 
216
219
  private_attribute.register_metaclass(PrivateAbcMeta)
217
220
  ```
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "private_attribute_cpp"
7
- version = "2.2.1"
7
+ version = "2.2.3"
8
8
  description = "A Python package that provides a way to define private attributes in C++ implementation."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -5,10 +5,10 @@ import unittest
5
5
 
6
6
  class PrivateAbcMeta(ABCMeta):
7
7
  def __new__(cls, *args, **kwargs):
8
- temp = private_attribute.prepare(*args, **kwargs)
9
- typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
10
- private_attribute.postprocess(typ, temp)
11
- return typ
8
+ with private_attribute.prepare(*args, **kwargs) as temp:
9
+ typ = super().__new__(cls, temp.name, temp.bases, temp.attrs, **temp.kwds)
10
+ private_attribute.postprocess(typ, temp)
11
+ return typ
12
12
 
13
13
 
14
14
  private_attribute.register_metaclass(PrivateAbcMeta)
@@ -34,7 +34,7 @@ class ConcreteClass(MyClass):
34
34
  self._secret1 = secret1
35
35
  self._secret2 = secret2
36
36
 
37
- def public_method(self):
37
+ def public_method(self): # type: ignore
38
38
  return self._secret1, self._secret2
39
39
 
40
40
 
@@ -47,7 +47,7 @@ class TestPrivateAbc(unittest.TestCase):
47
47
  with self.assertRaises(AttributeError):
48
48
  c._secret2
49
49
  with self.assertRaises(TypeError):
50
- MyClass()
50
+ MyClass() # type: ignore
51
51
  with self.assertRaises(AttributeError):
52
52
  MyClass._secret1
53
53
  self.assertEqual(MyClass.get_secret1(), 10)
@@ -1,34 +0,0 @@
1
- cmake_minimum_required(VERSION 3.15...3.31)
2
-
3
- project(private_attribute_cpp LANGUAGES CXX)
4
-
5
- # Locate the running interpreter and its development headers/module support.
6
- find_package(
7
- Python
8
- COMPONENTS Interpreter Development.Module
9
- REQUIRED)
10
-
11
- # Build the `private_attribute` extension module with a proper SOABI suffix
12
- # (private_attribute.cpython-3XX[-t]-<plat>.so), importable from site-packages.
13
- Python_add_library(private_attribute MODULE WITH_SOABI private_attribute.cpp)
14
-
15
- # picosha2.h is a header-only dependency living next to the .cpp.
16
- target_include_directories(private_attribute PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
17
-
18
- # C++17, matching the original setup.py flags.
19
- if(MSVC)
20
- target_compile_options(private_attribute PRIVATE /std:c++17 /GR-)
21
- else()
22
- target_compile_options(private_attribute PRIVATE -std=c++17 -fno-exceptions -fno-rtti)
23
- # Strip debug info unless the caller explicitly opts in to keeping it.
24
- # (This is the conditional that a static pyproject.toml cannot express,
25
- # hence it lives here in CMake instead of setup.py.)
26
- if(NOT "$ENV{PRIVATE_ATTR_KEEP_DEBUG}" STREQUAL "1")
27
- target_compile_options(private_attribute PRIVATE -g0)
28
- endif()
29
- endif()
30
-
31
- # Install both the compiled module and its PEP 561 type stub at the
32
- # site-packages root, side by side.
33
- install(TARGETS private_attribute LIBRARY DESTINATION .)
34
- install(FILES private_attribute.pyi DESTINATION .)