propcache 0.2.0__tar.gz → 0.2.1__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 (58) hide show
  1. {propcache-0.2.0 → propcache-0.2.1}/.coveragerc +9 -7
  2. {propcache-0.2.0 → propcache-0.2.1}/CHANGES.rst +45 -0
  3. {propcache-0.2.0/src/propcache.egg-info → propcache-0.2.1}/PKG-INFO +48 -4
  4. {propcache-0.2.0 → propcache-0.2.1}/README.rst +1 -1
  5. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/_backend.py +3 -7
  6. {propcache-0.2.0 → propcache-0.2.1}/pyproject.toml +3 -0
  7. {propcache-0.2.0 → propcache-0.2.1}/pytest.ini +5 -4
  8. {propcache-0.2.0 → propcache-0.2.1}/requirements/doc.txt +1 -1
  9. propcache-0.2.1/requirements/lint.txt +1 -0
  10. {propcache-0.2.0 → propcache-0.2.1}/requirements/test.txt +1 -0
  11. {propcache-0.2.0 → propcache-0.2.1}/setup.cfg +1 -2
  12. {propcache-0.2.0 → propcache-0.2.1}/src/propcache/__init__.py +3 -3
  13. {propcache-0.2.0 → propcache-0.2.1}/src/propcache/_helpers_c.pyx +7 -15
  14. {propcache-0.2.0 → propcache-0.2.1}/src/propcache/_helpers_py.py +5 -20
  15. {propcache-0.2.0 → propcache-0.2.1/src/propcache.egg-info}/PKG-INFO +48 -4
  16. {propcache-0.2.0 → propcache-0.2.1}/src/propcache.egg-info/SOURCES.txt +1 -0
  17. {propcache-0.2.0 → propcache-0.2.1}/tests/conftest.py +4 -22
  18. propcache-0.2.1/tests/test_benchmarks.py +87 -0
  19. {propcache-0.2.0 → propcache-0.2.1}/tests/test_cached_property.py +18 -2
  20. {propcache-0.2.0 → propcache-0.2.1}/tests/test_under_cached_property.py +23 -6
  21. propcache-0.2.0/requirements/lint.txt +0 -1
  22. {propcache-0.2.0 → propcache-0.2.1}/CHANGES/.TEMPLATE.rst +0 -0
  23. {propcache-0.2.0 → propcache-0.2.1}/CHANGES/.gitignore +0 -0
  24. {propcache-0.2.0 → propcache-0.2.1}/CHANGES/README.rst +0 -0
  25. {propcache-0.2.0 → propcache-0.2.1}/LICENSE +0 -0
  26. {propcache-0.2.0 → propcache-0.2.1}/MANIFEST.in +0 -0
  27. {propcache-0.2.0 → propcache-0.2.1}/NOTICE +0 -0
  28. {propcache-0.2.0 → propcache-0.2.1}/docs/Makefile +0 -0
  29. {propcache-0.2.0 → propcache-0.2.1}/docs/_static/README.txt +0 -0
  30. {propcache-0.2.0 → propcache-0.2.1}/docs/api.rst +0 -0
  31. {propcache-0.2.0 → propcache-0.2.1}/docs/changes.rst +0 -0
  32. {propcache-0.2.0 → propcache-0.2.1}/docs/conf.py +0 -0
  33. {propcache-0.2.0 → propcache-0.2.1}/docs/contributing/guidelines.rst +0 -0
  34. {propcache-0.2.0 → propcache-0.2.1}/docs/contributing/release_guide.rst +0 -0
  35. {propcache-0.2.0 → propcache-0.2.1}/docs/index.rst +0 -0
  36. {propcache-0.2.0 → propcache-0.2.1}/docs/make.bat +0 -0
  37. {propcache-0.2.0 → propcache-0.2.1}/docs/spelling_wordlist.txt +0 -0
  38. {propcache-0.2.0 → propcache-0.2.1}/packaging/README.md +0 -0
  39. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/__init__.py +0 -0
  40. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/__main__.py +0 -0
  41. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/_compat.py +0 -0
  42. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/_cython_configuration.py +0 -0
  43. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/_transformers.py +0 -0
  44. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/cli.py +0 -0
  45. {propcache-0.2.0 → propcache-0.2.1}/packaging/pep517_backend/hooks.py +0 -0
  46. {propcache-0.2.0 → propcache-0.2.1}/requirements/cython.txt +0 -0
  47. {propcache-0.2.0 → propcache-0.2.1}/requirements/dev.txt +0 -0
  48. {propcache-0.2.0 → propcache-0.2.1}/requirements/doc-spelling.txt +0 -0
  49. {propcache-0.2.0 → propcache-0.2.1}/requirements/towncrier.txt +0 -0
  50. {propcache-0.2.0 → propcache-0.2.1}/src/propcache/_helpers.py +0 -0
  51. {propcache-0.2.0 → propcache-0.2.1}/src/propcache/api.py +0 -0
  52. {propcache-0.2.0 → propcache-0.2.1}/src/propcache/py.typed +0 -0
  53. {propcache-0.2.0 → propcache-0.2.1}/src/propcache.egg-info/dependency_links.txt +0 -0
  54. {propcache-0.2.0 → propcache-0.2.1}/src/propcache.egg-info/not-zip-safe +0 -0
  55. {propcache-0.2.0 → propcache-0.2.1}/src/propcache.egg-info/top_level.txt +0 -0
  56. {propcache-0.2.0 → propcache-0.2.1}/tests/test_api.py +0 -0
  57. {propcache-0.2.0 → propcache-0.2.1}/tests/test_init.py +0 -0
  58. {propcache-0.2.0 → propcache-0.2.1}/towncrier.toml +0 -0
@@ -3,20 +3,22 @@ show_contexts = true
3
3
  skip_covered = false
4
4
 
5
5
  [paths]
6
- source =
7
- src/propcache
8
- */lib/pypy*/site-packages/propcache
9
- */lib/python*/site-packages/propcache
10
- */Lib/site-packages/propcache
6
+ _site-packages-to-src-mapping =
7
+ src
8
+ */src
9
+ *\src
10
+ */lib/pypy*/site-packages
11
+ */lib/python*/site-packages
12
+ *\Lib\site-packages
11
13
 
12
14
  [report]
15
+ exclude_also =
16
+ ^\s*@pytest\.mark\.xfail
13
17
  # small library, don't fail when running without C-extension
14
18
  fail_under = 50.00
15
19
  skip_covered = true
16
20
  skip_empty = true
17
21
  show_missing = true
18
- exclude_also =
19
- ^\s*@pytest\.mark\.xfail
20
22
 
21
23
  [run]
22
24
  branch = true
@@ -14,6 +14,51 @@ Changelog
14
14
 
15
15
  .. towncrier release notes start
16
16
 
17
+ 0.2.1
18
+ =====
19
+
20
+ *(2024-12-01)*
21
+
22
+
23
+ Bug fixes
24
+ ---------
25
+
26
+ - Stopped implicitly allowing the use of Cython pre-release versions when
27
+ building the distribution package -- by :user:`ajsanchezsanz` and
28
+ :user:`markgreene74`.
29
+
30
+ *Related commits on GitHub:*
31
+ :commit:`64df0a6`.
32
+
33
+ - Fixed ``wrapped`` and ``func`` not being accessible in the Cython versions of :func:`propcache.api.cached_property` and :func:`propcache.api.under_cached_property` decorators -- by :user:`bdraco`.
34
+
35
+ *Related issues and pull requests on GitHub:*
36
+ :issue:`72`.
37
+
38
+
39
+ Removals and backward incompatible breaking changes
40
+ ---------------------------------------------------
41
+
42
+ - Removed support for Python 3.8 as it has reached end of life -- by :user:`bdraco`.
43
+
44
+ *Related issues and pull requests on GitHub:*
45
+ :issue:`57`.
46
+
47
+
48
+ Packaging updates and notes for downstreams
49
+ -------------------------------------------
50
+
51
+ - Stopped implicitly allowing the use of Cython pre-release versions when
52
+ building the distribution package -- by :user:`ajsanchezsanz` and
53
+ :user:`markgreene74`.
54
+
55
+ *Related commits on GitHub:*
56
+ :commit:`64df0a6`.
57
+
58
+
59
+ ----
60
+
61
+
17
62
  0.2.0
18
63
  =====
19
64
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: propcache
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Accelerated property cache
5
5
  Home-page: https://github.com/aio-libs/propcache
6
6
  Author: Andrew Svetlov
@@ -24,7 +24,6 @@ Classifier: License :: OSI Approved :: Apache Software License
24
24
  Classifier: Programming Language :: Cython
25
25
  Classifier: Programming Language :: Python
26
26
  Classifier: Programming Language :: Python :: 3
27
- Classifier: Programming Language :: Python :: 3.8
28
27
  Classifier: Programming Language :: Python :: 3.9
29
28
  Classifier: Programming Language :: Python :: 3.10
30
29
  Classifier: Programming Language :: Python :: 3.11
@@ -32,7 +31,7 @@ Classifier: Programming Language :: Python :: 3.12
32
31
  Classifier: Programming Language :: Python :: 3.13
33
32
  Classifier: Topic :: Internet :: WWW/HTTP
34
33
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
35
- Requires-Python: >=3.8
34
+ Requires-Python: >=3.9
36
35
  Description-Content-Type: text/x-rst
37
36
  License-File: LICENSE
38
37
  License-File: NOTICE
@@ -40,7 +39,7 @@ License-File: NOTICE
40
39
  propcache
41
40
  =========
42
41
 
43
- The module provides a fast implementation of cached properties for Python 3.8+.
42
+ The module provides a fast implementation of cached properties for Python 3.9+.
44
43
 
45
44
  .. image:: https://github.com/aio-libs/propcache/actions/workflows/ci-cd.yml/badge.svg
46
45
  :target: https://github.com/aio-libs/propcache/actions?query=workflow%3ACI
@@ -152,6 +151,51 @@ Changelog
152
151
 
153
152
  .. towncrier release notes start
154
153
 
154
+ 0.2.1
155
+ =====
156
+
157
+ *(2024-12-01)*
158
+
159
+
160
+ Bug fixes
161
+ ---------
162
+
163
+ - Stopped implicitly allowing the use of Cython pre-release versions when
164
+ building the distribution package -- by `@ajsanchezsanz <https://github.com/sponsors/ajsanchezsanz>`__ and
165
+ `@markgreene74 <https://github.com/sponsors/markgreene74>`__.
166
+
167
+ *Related commits on GitHub:*
168
+ `64df0a6 <https://github.com/aio-libs/propcache/commit/64df0a6>`__.
169
+
170
+ - Fixed ``wrapped`` and ``func`` not being accessible in the Cython versions of ``propcache.api.cached_property`` and ``propcache.api.under_cached_property`` decorators -- by `@bdraco <https://github.com/sponsors/bdraco>`__.
171
+
172
+ *Related issues and pull requests on GitHub:*
173
+ `#72 <https://github.com/aio-libs/propcache/issues/72>`__.
174
+
175
+
176
+ Removals and backward incompatible breaking changes
177
+ ---------------------------------------------------
178
+
179
+ - Removed support for Python 3.8 as it has reached end of life -- by `@bdraco <https://github.com/sponsors/bdraco>`__.
180
+
181
+ *Related issues and pull requests on GitHub:*
182
+ `#57 <https://github.com/aio-libs/propcache/issues/57>`__.
183
+
184
+
185
+ Packaging updates and notes for downstreams
186
+ -------------------------------------------
187
+
188
+ - Stopped implicitly allowing the use of Cython pre-release versions when
189
+ building the distribution package -- by `@ajsanchezsanz <https://github.com/sponsors/ajsanchezsanz>`__ and
190
+ `@markgreene74 <https://github.com/sponsors/markgreene74>`__.
191
+
192
+ *Related commits on GitHub:*
193
+ `64df0a6 <https://github.com/aio-libs/propcache/commit/64df0a6>`__.
194
+
195
+
196
+ ----
197
+
198
+
155
199
  0.2.0
156
200
  =====
157
201
 
@@ -1,7 +1,7 @@
1
1
  propcache
2
2
  =========
3
3
 
4
- The module provides a fast implementation of cached properties for Python 3.8+.
4
+ The module provides a fast implementation of cached properties for Python 3.9+.
5
5
 
6
6
  .. image:: https://github.com/aio-libs/propcache/actions/workflows/ci-cd.yml/badge.svg
7
7
  :target: https://github.com/aio-libs/propcache/actions?query=workflow%3ACI
@@ -11,7 +11,6 @@ from pathlib import Path
11
11
  from shutil import copytree
12
12
  from sys import implementation as _system_implementation
13
13
  from sys import stderr as _standard_error_stream
14
- from sys import version_info as _python_version_tuple
15
14
  from tempfile import TemporaryDirectory
16
15
  from warnings import warn as _warn_that
17
16
 
@@ -82,9 +81,6 @@ PURE_PYTHON_CONFIG_SETTING = 'pure-python'
82
81
  PURE_PYTHON_ENV_VAR = 'PROPCACHE_NO_EXTENSIONS'
83
82
  """Environment variable name toggle used to opt out of making C-exts."""
84
83
 
85
- IS_PY3_12_PLUS = _python_version_tuple[:2] >= (3, 12)
86
- """A flag meaning that the current runtime is Python 3.12 or higher."""
87
-
88
84
  IS_CPYTHON = _system_implementation.name == "cpython"
89
85
  """A flag meaning that the current interpreter implementation is CPython."""
90
86
 
@@ -205,7 +201,7 @@ def _exclude_dir_path(
205
201
  """Prevent recursive directory traversal."""
206
202
  # This stops the temporary directory from being copied
207
203
  # into self recursively forever.
208
- # Ref: https://github.com/aio-libs/propcache/issues/992
204
+ # Ref: https://github.com/aio-libs/yarl/issues/992
209
205
  visited_directory_subdirs_to_ignore = [
210
206
  subdir
211
207
  for subdir in _visited_dir_contents
@@ -378,8 +374,8 @@ def get_requires_for_build_wheel(
378
374
  )
379
375
 
380
376
  c_ext_build_deps = [] if is_pure_python_build else [
381
- 'Cython >= 3.0.0b3' if IS_PY3_12_PLUS # Only Cython 3+ is compatible
382
- else 'Cython',
377
+ 'Cython ~= 3.0.0; python_version >= "3.12"',
378
+ 'Cython; python_version < "3.12"',
383
379
  ]
384
380
 
385
381
  return _setuptools_get_requires_for_build_wheel(
@@ -91,3 +91,6 @@ pure-python = "false"
91
91
 
92
92
  [tool.cibuildwheel.windows]
93
93
  before-test = [] # Windows cmd has different syntax and pip chooses wheels
94
+
95
+ [tool.cibuildwheel.linux]
96
+ before-all = "yum install -y libffi-devel || apk add --upgrade libffi-dev || apt-get install libffi-dev"
@@ -2,6 +2,8 @@
2
2
  addopts =
3
3
  # `pytest-xdist`:
4
4
  --numprocesses=auto
5
+ # NOTE: the plugin disabled because it's slower with so few tests
6
+ --numprocesses=0
5
7
 
6
8
  # Show 10 slowest invocations:
7
9
  --durations=10
@@ -16,16 +18,14 @@ addopts =
16
18
  # https://docs.pytest.org/en/stable/doctest.html
17
19
  --doctest-modules
18
20
 
19
- # Dump the test results in junit format:
20
- # --junitxml=.test-results/pytest/results.xml
21
-
22
21
  # Pre-load the `pytest-cov` plugin early:
23
22
  -p pytest_cov
24
23
 
25
24
  # `pytest-cov`:
26
25
  --cov
27
- --cov-context=test
28
26
  --cov-config=.coveragerc
27
+ --cov-context=test
28
+ --no-cov-on-fail
29
29
 
30
30
  # Fail on config parsing warnings:
31
31
  # --strict-config
@@ -73,6 +73,7 @@ norecursedirs =
73
73
  build
74
74
  dist
75
75
  docs
76
+ requirements
76
77
  venv
77
78
  virtualenv
78
79
  propcache.egg-info
@@ -1,4 +1,4 @@
1
1
  -r towncrier.txt
2
2
  myst-parser >= 0.10.0
3
- sphinx==8.0.2
3
+ sphinx==8.1.3
4
4
  sphinxcontrib-towncrier
@@ -0,0 +1 @@
1
+ pre-commit==4.0.1
@@ -1,5 +1,6 @@
1
1
  -r cython.txt
2
2
  covdefaults
3
3
  pytest==8.3.3
4
+ pytest-codspeed==3.0.0
4
5
  pytest-cov>=2.3.1
5
6
  pytest-xdist
@@ -36,7 +36,6 @@ classifiers =
36
36
  Programming Language :: Cython
37
37
  Programming Language :: Python
38
38
  Programming Language :: Python :: 3
39
- Programming Language :: Python :: 3.8
40
39
  Programming Language :: Python :: 3.9
41
40
  Programming Language :: Python :: 3.10
42
41
  Programming Language :: Python :: 3.11
@@ -51,7 +50,7 @@ keywords =
51
50
  propcache
52
51
 
53
52
  [options]
54
- python_requires = >=3.8
53
+ python_requires = >=3.9
55
54
  package_dir =
56
55
  =src
57
56
  packages =
@@ -1,10 +1,10 @@
1
1
  """propcache: An accelerated property cache for Python classes."""
2
2
 
3
- from typing import TYPE_CHECKING, List
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  _PUBLIC_API = ("cached_property", "under_cached_property")
6
6
 
7
- __version__ = "0.2.0"
7
+ __version__ = "0.2.1"
8
8
  __all__ = ()
9
9
 
10
10
  # Imports have moved to `propcache.api` in 0.2.0+.
@@ -23,7 +23,7 @@ def _import_facade(attr: str) -> object:
23
23
  raise AttributeError(f"module '{__package__}' has no attribute '{attr}'")
24
24
 
25
25
 
26
- def _dir_facade() -> List[str]:
26
+ def _dir_facade() -> list[str]:
27
27
  """Include the public API in the module's dir() output."""
28
28
  return [*_PUBLIC_API, *globals().keys()]
29
29
 
@@ -1,13 +1,5 @@
1
1
  # cython: language_level=3
2
- import sys
3
- import types
4
-
5
- if sys.version_info >= (3, 9):
6
- GenericAlias = types.GenericAlias
7
- else:
8
-
9
- def GenericAlias(cls):
10
- return cls
2
+ from types import GenericAlias
11
3
 
12
4
 
13
5
  cdef _sentinel = object()
@@ -21,7 +13,7 @@ cdef class under_cached_property:
21
13
 
22
14
  """
23
15
 
24
- cdef object wrapped
16
+ cdef readonly object wrapped
25
17
  cdef object name
26
18
 
27
19
  def __init__(self, wrapped):
@@ -55,16 +47,16 @@ cdef class cached_property:
55
47
 
56
48
  """
57
49
 
58
- cdef object wrapped
50
+ cdef readonly object func
59
51
  cdef object name
60
52
 
61
- def __init__(self, wrapped):
62
- self.wrapped = wrapped
53
+ def __init__(self, func):
54
+ self.func = func
63
55
  self.name = None
64
56
 
65
57
  @property
66
58
  def __doc__(self):
67
- return self.wrapped.__doc__
59
+ return self.func.__doc__
68
60
 
69
61
  def __set_name__(self, owner, name):
70
62
  if self.name is None:
@@ -85,7 +77,7 @@ cdef class cached_property:
85
77
  cdef dict cache = inst.__dict__
86
78
  val = cache.get(self.name, _sentinel)
87
79
  if val is _sentinel:
88
- val = self.wrapped(inst)
80
+ val = self.func(inst)
89
81
  cache[self.name] = val
90
82
  return val
91
83
 
@@ -2,18 +2,7 @@
2
2
 
3
3
  import sys
4
4
  from functools import cached_property
5
- from typing import (
6
- Any,
7
- Callable,
8
- Dict,
9
- Generic,
10
- Optional,
11
- Protocol,
12
- Type,
13
- TypeVar,
14
- Union,
15
- overload,
16
- )
5
+ from typing import Any, Callable, Generic, Optional, Protocol, TypeVar, Union, overload
17
6
 
18
7
  __all__ = ("under_cached_property", "cached_property")
19
8
 
@@ -27,7 +16,7 @@ _T = TypeVar("_T")
27
16
 
28
17
 
29
18
  class _TSelf(Protocol, Generic[_T]):
30
- _cache: Dict[str, _T]
19
+ _cache: dict[str, _T]
31
20
 
32
21
 
33
22
  class under_cached_property(Generic[_T]):
@@ -46,17 +35,13 @@ class under_cached_property(Generic[_T]):
46
35
  self.name = wrapped.__name__
47
36
 
48
37
  @overload
49
- def __get__( # pragma: no cover
50
- self, inst: None, owner: Optional[Type[Any]] = None
51
- ) -> Self: ... # pragma: no cover
38
+ def __get__(self, inst: None, owner: Optional[type[object]] = None) -> Self: ...
52
39
 
53
40
  @overload
54
- def __get__( # pragma: no cover
55
- self, inst: _TSelf[_T], owner: Optional[Type[Any]] = None
56
- ) -> _T: ... # pragma: no cover
41
+ def __get__(self, inst: _TSelf[_T], owner: Optional[type[object]] = None) -> _T: ...
57
42
 
58
43
  def __get__(
59
- self, inst: Optional[_TSelf[_T]], owner: Optional[Type[Any]] = None
44
+ self, inst: Optional[_TSelf[_T]], owner: Optional[type[object]] = None
60
45
  ) -> Union[_T, Self]:
61
46
  if inst is None:
62
47
  return self
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: propcache
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Accelerated property cache
5
5
  Home-page: https://github.com/aio-libs/propcache
6
6
  Author: Andrew Svetlov
@@ -24,7 +24,6 @@ Classifier: License :: OSI Approved :: Apache Software License
24
24
  Classifier: Programming Language :: Cython
25
25
  Classifier: Programming Language :: Python
26
26
  Classifier: Programming Language :: Python :: 3
27
- Classifier: Programming Language :: Python :: 3.8
28
27
  Classifier: Programming Language :: Python :: 3.9
29
28
  Classifier: Programming Language :: Python :: 3.10
30
29
  Classifier: Programming Language :: Python :: 3.11
@@ -32,7 +31,7 @@ Classifier: Programming Language :: Python :: 3.12
32
31
  Classifier: Programming Language :: Python :: 3.13
33
32
  Classifier: Topic :: Internet :: WWW/HTTP
34
33
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
35
- Requires-Python: >=3.8
34
+ Requires-Python: >=3.9
36
35
  Description-Content-Type: text/x-rst
37
36
  License-File: LICENSE
38
37
  License-File: NOTICE
@@ -40,7 +39,7 @@ License-File: NOTICE
40
39
  propcache
41
40
  =========
42
41
 
43
- The module provides a fast implementation of cached properties for Python 3.8+.
42
+ The module provides a fast implementation of cached properties for Python 3.9+.
44
43
 
45
44
  .. image:: https://github.com/aio-libs/propcache/actions/workflows/ci-cd.yml/badge.svg
46
45
  :target: https://github.com/aio-libs/propcache/actions?query=workflow%3ACI
@@ -152,6 +151,51 @@ Changelog
152
151
 
153
152
  .. towncrier release notes start
154
153
 
154
+ 0.2.1
155
+ =====
156
+
157
+ *(2024-12-01)*
158
+
159
+
160
+ Bug fixes
161
+ ---------
162
+
163
+ - Stopped implicitly allowing the use of Cython pre-release versions when
164
+ building the distribution package -- by `@ajsanchezsanz <https://github.com/sponsors/ajsanchezsanz>`__ and
165
+ `@markgreene74 <https://github.com/sponsors/markgreene74>`__.
166
+
167
+ *Related commits on GitHub:*
168
+ `64df0a6 <https://github.com/aio-libs/propcache/commit/64df0a6>`__.
169
+
170
+ - Fixed ``wrapped`` and ``func`` not being accessible in the Cython versions of ``propcache.api.cached_property`` and ``propcache.api.under_cached_property`` decorators -- by `@bdraco <https://github.com/sponsors/bdraco>`__.
171
+
172
+ *Related issues and pull requests on GitHub:*
173
+ `#72 <https://github.com/aio-libs/propcache/issues/72>`__.
174
+
175
+
176
+ Removals and backward incompatible breaking changes
177
+ ---------------------------------------------------
178
+
179
+ - Removed support for Python 3.8 as it has reached end of life -- by `@bdraco <https://github.com/sponsors/bdraco>`__.
180
+
181
+ *Related issues and pull requests on GitHub:*
182
+ `#57 <https://github.com/aio-libs/propcache/issues/57>`__.
183
+
184
+
185
+ Packaging updates and notes for downstreams
186
+ -------------------------------------------
187
+
188
+ - Stopped implicitly allowing the use of Cython pre-release versions when
189
+ building the distribution package -- by `@ajsanchezsanz <https://github.com/sponsors/ajsanchezsanz>`__ and
190
+ `@markgreene74 <https://github.com/sponsors/markgreene74>`__.
191
+
192
+ *Related commits on GitHub:*
193
+ `64df0a6 <https://github.com/aio-libs/propcache/commit/64df0a6>`__.
194
+
195
+
196
+ ----
197
+
198
+
155
199
  0.2.0
156
200
  =====
157
201
 
@@ -50,6 +50,7 @@ src/propcache.egg-info/not-zip-safe
50
50
  src/propcache.egg-info/top_level.txt
51
51
  tests/conftest.py
52
52
  tests/test_api.py
53
+ tests/test_benchmarks.py
53
54
  tests/test_cached_property.py
54
55
  tests/test_init.py
55
56
  tests/test_under_cached_property.py
@@ -2,14 +2,11 @@ import argparse
2
2
  from dataclasses import dataclass
3
3
  from functools import cached_property
4
4
  from importlib import import_module
5
- from sys import version_info as _version_info
6
5
  from types import ModuleType
7
- from typing import List, Type, Union
8
6
 
9
7
  import pytest
10
8
 
11
9
  C_EXT_MARK = pytest.mark.c_extension
12
- PY_38_AND_BELOW = _version_info < (3, 9)
13
10
 
14
11
 
15
12
  @dataclass(frozen=True)
@@ -77,34 +74,19 @@ def pytest_addoption(
77
74
  version of the ``propcache`` implementation.
78
75
  """
79
76
  del pluginmanager
80
-
81
- arg_parse_action: Union[str, Type[argparse.Action]]
82
- if PY_38_AND_BELOW:
83
- arg_parse_action = "store_true"
84
- else:
85
- arg_parse_action = argparse.BooleanOptionalAction # type: ignore[attr-defined, unused-ignore] # noqa
86
-
87
77
  parser.addoption(
88
78
  "--c-extensions", # disabled with `--no-c-extensions`
89
- action=arg_parse_action,
79
+ action=argparse.BooleanOptionalAction,
90
80
  default=True,
91
81
  dest="c_extensions",
92
82
  help="Test C-extensions (on by default)",
93
83
  )
94
84
 
95
- if PY_38_AND_BELOW:
96
- parser.addoption(
97
- "--no-c-extensions",
98
- action="store_false",
99
- dest="c_extensions",
100
- help="Skip testing C-extensions (on by default)",
101
- )
102
-
103
85
 
104
86
  def pytest_collection_modifyitems(
105
87
  session: pytest.Session,
106
88
  config: pytest.Config,
107
- items: List[pytest.Item],
89
+ items: list[pytest.Item],
108
90
  ) -> None:
109
91
  """Deselect tests against C-extensions when requested via CLI."""
110
92
  test_c_extensions = config.getoption("--c-extensions") is True
@@ -112,8 +94,8 @@ def pytest_collection_modifyitems(
112
94
  if test_c_extensions:
113
95
  return
114
96
 
115
- selected_tests: List[pytest.Item] = []
116
- deselected_tests: List[pytest.Item] = []
97
+ selected_tests: list[pytest.Item] = []
98
+ deselected_tests: list[pytest.Item] = []
117
99
 
118
100
  for item in items:
119
101
  c_ext = item.get_closest_marker(C_EXT_MARK.name) is not None
@@ -0,0 +1,87 @@
1
+ """codspeed benchmarks for propcache."""
2
+
3
+ from pytest_codspeed import BenchmarkFixture
4
+
5
+ from propcache import cached_property, under_cached_property
6
+
7
+
8
+ def test_under_cached_property_cache_hit(benchmark: BenchmarkFixture) -> None:
9
+ """Benchmark for under_cached_property cache hit."""
10
+
11
+ class Test:
12
+ def __init__(self) -> None:
13
+ self._cache = {"prop": 42}
14
+
15
+ @under_cached_property
16
+ def prop(self) -> int:
17
+ """Return the value of the property."""
18
+ raise NotImplementedError
19
+
20
+ t = Test()
21
+
22
+ @benchmark
23
+ def _run() -> None:
24
+ for _ in range(100):
25
+ t.prop
26
+
27
+
28
+ def test_cached_property_cache_hit(benchmark: BenchmarkFixture) -> None:
29
+ """Benchmark for cached_property cache hit."""
30
+
31
+ class Test:
32
+ def __init__(self) -> None:
33
+ self.__dict__["prop"] = 42
34
+
35
+ @cached_property
36
+ def prop(self) -> int:
37
+ """Return the value of the property."""
38
+ raise NotImplementedError
39
+
40
+ t = Test()
41
+
42
+ @benchmark
43
+ def _run() -> None:
44
+ for _ in range(100):
45
+ t.prop
46
+
47
+
48
+ def test_under_cached_property_cache_miss(benchmark: BenchmarkFixture) -> None:
49
+ """Benchmark for under_cached_property cache miss."""
50
+
51
+ class Test:
52
+ def __init__(self) -> None:
53
+ self._cache: dict[str, int] = {}
54
+
55
+ @under_cached_property
56
+ def prop(self) -> int:
57
+ """Return the value of the property."""
58
+ return 42
59
+
60
+ t = Test()
61
+ cache = t._cache
62
+
63
+ @benchmark
64
+ def _run() -> None:
65
+ for _ in range(100):
66
+ cache.pop("prop", None)
67
+ t.prop
68
+
69
+
70
+ def test_cached_property_cache_miss(benchmark: BenchmarkFixture) -> None:
71
+ """Benchmark for cached_property cache miss."""
72
+
73
+ class Test:
74
+
75
+ @cached_property
76
+ def prop(self) -> int:
77
+ """Return the value of the property."""
78
+ return 42
79
+
80
+ t = Test()
81
+ cache = t.__dict__
82
+
83
+ @benchmark
84
+ def _run() -> None:
85
+ for _ in range(100):
86
+ cache.pop("prop", None)
87
+ t.prop
@@ -1,5 +1,5 @@
1
1
  from operator import not_
2
- from typing import Protocol, Type
2
+ from typing import Protocol
3
3
 
4
4
  import pytest
5
5
 
@@ -8,7 +8,7 @@ from propcache.api import cached_property
8
8
 
9
9
  class APIProtocol(Protocol):
10
10
 
11
- cached_property: Type[cached_property]
11
+ cached_property: type[cached_property]
12
12
 
13
13
 
14
14
  def test_cached_property(propcache_module: APIProtocol) -> None:
@@ -127,3 +127,19 @@ def test_get_without_set_name(propcache_module: APIProtocol) -> None:
127
127
  match = r"Cannot use cached_property instance "
128
128
  with pytest.raises(TypeError, match=match):
129
129
  _ = A().cp # type: ignore[attr-defined]
130
+
131
+
132
+ def test_ensured_wrapped_function_is_accessible(propcache_module: APIProtocol) -> None:
133
+ """Test that the wrapped function can be accessed from python."""
134
+
135
+ class A:
136
+ def __init__(self) -> None:
137
+ """Init."""
138
+
139
+ @propcache_module.cached_property
140
+ def prop(self) -> int:
141
+ """Docstring."""
142
+ return 1
143
+
144
+ a = A()
145
+ assert A.prop.func(a) == 1
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, Protocol, Type
1
+ from typing import Any, Protocol
2
2
 
3
3
  import pytest
4
4
 
@@ -7,13 +7,13 @@ from propcache.api import under_cached_property
7
7
 
8
8
  class APIProtocol(Protocol):
9
9
 
10
- under_cached_property: Type[under_cached_property]
10
+ under_cached_property: type[under_cached_property]
11
11
 
12
12
 
13
13
  def test_under_cached_property(propcache_module: APIProtocol) -> None:
14
14
  class A:
15
15
  def __init__(self) -> None:
16
- self._cache: Dict[str, int] = {}
16
+ self._cache: dict[str, int] = {}
17
17
 
18
18
  @propcache_module.under_cached_property
19
19
  def prop(self) -> int:
@@ -39,7 +39,7 @@ def test_under_cached_property_class(propcache_module: APIProtocol) -> None:
39
39
  def test_under_cached_property_assignment(propcache_module: APIProtocol) -> None:
40
40
  class A:
41
41
  def __init__(self) -> None:
42
- self._cache: Dict[str, Any] = {}
42
+ self._cache: dict[str, Any] = {}
43
43
 
44
44
  @propcache_module.under_cached_property
45
45
  def prop(self) -> None:
@@ -55,7 +55,7 @@ def test_under_cached_property_without_cache(propcache_module: APIProtocol) -> N
55
55
  class A:
56
56
  def __init__(self) -> None:
57
57
  """Init."""
58
- self._cache: Dict[str, int] = {}
58
+ self._cache: dict[str, int] = {}
59
59
 
60
60
  @propcache_module.under_cached_property
61
61
  def prop(self) -> None:
@@ -88,7 +88,7 @@ def test_under_cached_property_check_without_cache(
88
88
  def test_under_cached_property_caching(propcache_module: APIProtocol) -> None:
89
89
  class A:
90
90
  def __init__(self) -> None:
91
- self._cache: Dict[str, int] = {}
91
+ self._cache: dict[str, int] = {}
92
92
 
93
93
  @propcache_module.under_cached_property
94
94
  def prop(self) -> int:
@@ -110,3 +110,20 @@ def test_under_cached_property_class_docstring(propcache_module: APIProtocol) ->
110
110
 
111
111
  assert isinstance(A.prop, propcache_module.under_cached_property)
112
112
  assert "Docstring." == A.prop.__doc__
113
+
114
+
115
+ def test_ensured_wrapped_function_is_accessible(propcache_module: APIProtocol) -> None:
116
+ """Test that the wrapped function can be accessed from python."""
117
+
118
+ class A:
119
+ def __init__(self) -> None:
120
+ """Init."""
121
+ self._cache: dict[str, int] = {}
122
+
123
+ @propcache_module.under_cached_property
124
+ def prop(self) -> int:
125
+ """Docstring."""
126
+ return 1
127
+
128
+ a = A()
129
+ assert A.prop.wrapped(a) == 1
@@ -1 +0,0 @@
1
- pre-commit==4.0.0
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
File without changes
File without changes
File without changes
File without changes
File without changes