classcore 1.8__tar.gz → 1.10__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. {classcore-1.8 → classcore-1.10}/.gitignore +3 -0
  2. {classcore-1.8 → classcore-1.10}/PKG-INFO +2 -2
  3. {classcore-1.8 → classcore-1.10}/README.rst +1 -1
  4. {classcore-1.8 → classcore-1.10}/pyproject.toml +37 -4
  5. {classcore-1.8 → classcore-1.10}/sources/classcore/__init__.py +1 -1
  6. {classcore-1.8 → classcore-1.10}/sources/classcore/exceptions.py +9 -1
  7. {classcore-1.8 → classcore-1.10}/sources/classcore/nomina.py +5 -0
  8. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/__.py +3 -5
  9. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/classes.py +35 -4
  10. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/nomina.py +1 -2
  11. {classcore-1.8 → classcore-1.10}/sources/classcore/utilities.py +1 -1
  12. {classcore-1.8 → classcore-1.10}/LICENSE.txt +0 -0
  13. {classcore-1.8 → classcore-1.10}/sources/classcore/__/__init__.py +0 -0
  14. {classcore-1.8 → classcore-1.10}/sources/classcore/__/doctab.py +0 -0
  15. {classcore-1.8 → classcore-1.10}/sources/classcore/__/imports.py +0 -0
  16. {classcore-1.8 → classcore-1.10}/sources/classcore/__/nomina.py +0 -0
  17. {classcore-1.8 → classcore-1.10}/sources/classcore/decorators.py +0 -0
  18. {classcore-1.8 → classcore-1.10}/sources/classcore/factories.py +0 -0
  19. {classcore-1.8 → classcore-1.10}/sources/classcore/py.typed +0 -0
  20. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/__init__.py +0 -0
  21. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/behaviors.py +0 -0
  22. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/decorators.py +0 -0
  23. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/dynadoc.py +0 -0
  24. {classcore-1.8 → classcore-1.10}/sources/classcore/standard/modules.py +0 -0
@@ -2,11 +2,14 @@
2
2
  .claude
3
3
  .gemini
4
4
  .mcp.json
5
+ .opencode
5
6
  .*.swp
6
7
  AGENTS.md
7
8
  CLAUDE.md
8
9
  CONVENTIONS.md
9
10
  GEMINI.md
11
+ opencode.jsonc
10
12
  __pycache__/
11
13
  bugs/
12
14
  build/
15
+ dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: classcore
3
- Version: 1.8
3
+ Version: 1.10
4
4
  Summary: Foundational class factories and decorators.
5
5
  Project-URL: Homepage, https://github.com/emcd/python-classcore
6
6
  Project-URL: Documentation, https://emcd.github.io/python-classcore
@@ -237,7 +237,7 @@ For development guidance and standards, please see the `development guide
237
237
  <https://emcd.github.io/python-classcore/stable/sphinx-html/contribution.html#development>`_.
238
238
 
239
239
 
240
- `More Flair <https://www.imdb.com/title/tt0151804/characters/nm0431918>`_
240
+ Additional Indicia
241
241
  ===============================================================================
242
242
 
243
243
  .. image:: https://img.shields.io/github/last-commit/emcd/python-classcore
@@ -208,7 +208,7 @@ For development guidance and standards, please see the `development guide
208
208
  <https://emcd.github.io/python-classcore/stable/sphinx-html/contribution.html#development>`_.
209
209
 
210
210
 
211
- `More Flair <https://www.imdb.com/title/tt0151804/characters/nm0431918>`_
211
+ Additional Indicia
212
212
  ===============================================================================
213
213
 
214
214
  .. image:: https://img.shields.io/github/last-commit/emcd/python-classcore
@@ -97,6 +97,7 @@ dependencies = [
97
97
  'Jinja2',
98
98
  'coverage[toml]',
99
99
  'furo',
100
+ 'isort',
100
101
  'packaging',
101
102
  'pre-commit',
102
103
  'pyright',
@@ -106,6 +107,7 @@ dependencies = [
106
107
  'sphinx-copybutton',
107
108
  'sphinx-inline-tabs',
108
109
  'towncrier',
110
+ 'vulture',
109
111
  # --- BEGIN: Injected by Copier ---
110
112
  # --- END: Injected by Copier ---
111
113
  ]
@@ -119,15 +121,17 @@ PYTHONUNBUFFERED = 'TRUE' # TODO: Only for coverage/pytest.
119
121
  # --- END: Injected by Copier ---
120
122
  [tool.hatch.envs.develop.scripts]
121
123
  docsgen = [
122
- """sphinx-build -E -b linkcheck -d .auxiliary/caches/sphinx \
124
+ """sphinx-build -E -b linkcheck -d .auxiliary/caches/sphinx --quiet \
123
125
  documentation .auxiliary/artifacts/sphinx-linkcheck""",
124
- """sphinx-build -a -d .auxiliary/caches/sphinx \
126
+ """sphinx-build -a -d .auxiliary/caches/sphinx --quiet \
125
127
  documentation .auxiliary/artifacts/sphinx-html""",
126
128
  ]
127
129
  linters = [
128
130
  """ruff check --quiet sources documentation tests""",
129
131
  # --- BEGIN: Injected by Copier ---
130
132
  # --- END: Injected by Copier ---
133
+ """isort --check-only --diff sources tests""",
134
+ """vulture""",
131
135
  """pyright sources""",
132
136
  ]
133
137
  packagers = [
@@ -137,7 +141,7 @@ packagers = [
137
141
  ]
138
142
  testers-documentation = [
139
143
  """coverage run -m sphinx.cmd.build \
140
- -E -b doctest -d .auxiliary/caches/sphinx \
144
+ -E -b doctest -d .auxiliary/caches/sphinx --quiet \
141
145
  documentation .auxiliary/artifacts/sphinx-doctest""",
142
146
  ]
143
147
  testers-serotine = [ """coverage run -m pytest -m slow""" ]
@@ -176,6 +180,25 @@ python = [
176
180
  [tool.hatch.version]
177
181
  path = 'sources/classcore/__init__.py'
178
182
 
183
+ # https://pycqa.github.io/isort/docs/configuration/config_files.html
184
+ [tool.isort]
185
+ # profile = 'black'
186
+ src_paths = [ 'sources', 'tests' ]
187
+ case_sensitive = true
188
+ # ensure_newline_before_comments = true
189
+ # force_sort_within_sections = true
190
+ ignore_whitespace = true
191
+ include_trailing_comma = true
192
+ known_first_party = [ 'classcore' ]
193
+ lines_between_types = 1
194
+ line_length = 79
195
+ multi_line_output = 3
196
+ quiet = true
197
+ # skip_gitignore = true
198
+ skip_glob = [ '*/__/imports.py', '*/__init__.py' ]
199
+ split_on_trailing_comma = true
200
+ use_parentheses = true
201
+
179
202
  # https://mypy.readthedocs.io/en/stable/config_file.html
180
203
  [tool.mypy]
181
204
  # Note: Due to repeated painful experiences with Mypy, we use Pyright instead.
@@ -222,7 +245,7 @@ stubPath = 'sources/classcore/_typedecls'
222
245
  # Note: Cannot run doctests from Pytest, because Pytest tries to update '_'
223
246
  # attribute on protected modules. Instead, we use Sphinx to run doctests.
224
247
  minversion = '8.1'
225
- addopts = """--capture=no --exitfirst -rfE -m 'not slow'""" # TODO? '--fail-under'
248
+ addopts = """--capture=no --exitfirst --quiet -rfE -m 'not slow'""" # TODO? '--fail-under'
226
249
  testpaths = [ 'tests' ]
227
250
  python_files = [ 'test_*.py' ]
228
251
  python_functions = [ 'test_[0-9][0-9][0-9]_*' ]
@@ -234,6 +257,7 @@ markers = [
234
257
  [tool.ruff]
235
258
  #builtins = [ 'ic' ]
236
259
  cache-dir = '.auxiliary/caches/ruff'
260
+ extend-exclude = [ 'vulturefood.py' ]
237
261
  indent-width = 4
238
262
  line-length = 79
239
263
  [tool.ruff.lint]
@@ -323,3 +347,12 @@ showcontent = true
323
347
  directory = 'repair'
324
348
  name = 'Repairs'
325
349
  showcontent = true
350
+
351
+ [tool.vulture]
352
+ paths = [ '.auxiliary/configuration/vulturefood.py', 'sources' ]
353
+ min_confidence = 60
354
+ exclude = [
355
+ '*/imports.py',
356
+ ]
357
+ ignore_decorators = [ '@__.abc.abstractmethod', '@__.typx.overload' ]
358
+ ignore_names = [ 'main' ]
@@ -62,7 +62,7 @@ from .factories import *
62
62
 
63
63
 
64
64
  __version__: __.typx.Annotated[ str, __.ddoc.Visibilities.Reveal ]
65
- __version__ = '1.8'
65
+ __version__ = '1.10'
66
66
 
67
67
 
68
68
  standard.finalize_module(
@@ -22,12 +22,20 @@
22
22
 
23
23
 
24
24
  from . import __
25
+ from . import nomina as _nomina
25
26
  from . import standard as _standard
26
27
 
27
28
 
29
+ exception_mutables_default = (
30
+ '__cause__', '__context__', '__suppress_context__', '__traceback__' )
31
+ exception_visibles_default = (
32
+ *exception_mutables_default, _nomina.is_public_identifier )
33
+
34
+
28
35
  class Omniexception(
29
36
  _standard.Object, BaseException,
30
- instances_visibles = ( '__cause__', '__context__' ),
37
+ instances_mutables = exception_mutables_default,
38
+ instances_visibles = exception_visibles_default,
31
39
  ):
32
40
  ''' Base exception for package. '''
33
41
 
@@ -204,3 +204,8 @@ ClassInitializer: __.typx.TypeAlias = __.typx.Annotated[
204
204
  ],
205
205
  __.ddoc.Doc( ''' Initializer to use with metaclass. ''' ),
206
206
  ]
207
+
208
+
209
+ def is_public_identifier( name: str ) -> bool:
210
+ ''' Is Python identifier public? '''
211
+ return not name.startswith( '_' )
@@ -20,13 +20,11 @@
20
20
 
21
21
  ''' Common constants, imports, and utilities. '''
22
22
 
23
+ # ruff: noqa: F403
23
24
 
24
- from ..__ import * # noqa: F403
25
25
 
26
-
27
- def is_public_identifier( name: str ) -> bool:
28
- ''' Is Python identifier public? '''
29
- return not name.startswith( '_' )
26
+ from ..__ import *
27
+ from ..nomina import is_public_identifier
30
28
 
31
29
 
32
30
  def provide_error_class( name: str ) -> type[ Exception ]:
@@ -205,7 +205,16 @@ class DataclassObjectMutable( metaclass = DataclassMutable ):
205
205
  'class instance conceal' )
206
206
 
207
207
 
208
- class Protocol( __.typx.Protocol, metaclass = ProtocolClass ):
208
+ class Protocol(
209
+ __.typx.Protocol,
210
+ metaclass = ProtocolClass,
211
+ class_mutables = (
212
+ '_abc_cache',
213
+ '_abc_negative_cache',
214
+ '_abc_negative_cache_version',
215
+ '_abc_registry',
216
+ ),
217
+ ):
209
218
  ''' Standard base protocol class. '''
210
219
 
211
220
  _dynadoc_fragments_ = (
@@ -215,7 +224,15 @@ class Protocol( __.typx.Protocol, metaclass = ProtocolClass ):
215
224
 
216
225
 
217
226
  class ProtocolMutable(
218
- __.typx.Protocol, metaclass = ProtocolClass, instances_mutables = '*'
227
+ __.typx.Protocol,
228
+ metaclass = ProtocolClass,
229
+ class_mutables = (
230
+ '_abc_cache',
231
+ '_abc_negative_cache',
232
+ '_abc_negative_cache_version',
233
+ '_abc_registry',
234
+ ),
235
+ instances_mutables = '*',
219
236
  ):
220
237
  ''' Base protocol class with mutable instance attributes. '''
221
238
 
@@ -226,7 +243,14 @@ class ProtocolMutable(
226
243
 
227
244
 
228
245
  class DataclassProtocol(
229
- __.typx.Protocol, metaclass = ProtocolDataclass,
246
+ __.typx.Protocol,
247
+ metaclass = ProtocolDataclass,
248
+ class_mutables = (
249
+ '_abc_cache',
250
+ '_abc_negative_cache',
251
+ '_abc_negative_cache_version',
252
+ '_abc_registry',
253
+ ),
230
254
  ):
231
255
  ''' Standard base protocol dataclass. '''
232
256
 
@@ -237,7 +261,14 @@ class DataclassProtocol(
237
261
 
238
262
 
239
263
  class DataclassProtocolMutable(
240
- __.typx.Protocol, metaclass = ProtocolDataclassMutable,
264
+ __.typx.Protocol,
265
+ metaclass = ProtocolDataclassMutable,
266
+ class_mutables = (
267
+ '_abc_cache',
268
+ '_abc_negative_cache',
269
+ '_abc_negative_cache_version',
270
+ '_abc_registry',
271
+ ),
241
272
  ):
242
273
  ''' Base protocol dataclass with mutable instance attributes. '''
243
274
 
@@ -22,9 +22,8 @@
22
22
  # ruff: noqa: F403,F405
23
23
 
24
24
 
25
- from . import __
26
25
  from ..nomina import *
27
-
26
+ from . import __
28
27
 
29
28
  concealment_label = 'concealment'
30
29
  immutability_label = 'immutability'
@@ -114,7 +114,7 @@ def qualify_class_name( cls: type ) -> str:
114
114
  def repair_class_reproduction( original: type, reproduction: type ) -> None:
115
115
  ''' Repairs a class reproduction, if necessary. '''
116
116
  match __.platform.python_implementation( ):
117
- case 'CPython': # pragma: no branch
117
+ case 'CPython' | 'PyPy': # pragma: no branch
118
118
  _repair_cpython_class_closures( original, reproduction )
119
119
  case _: pass # pragma: no cover
120
120
 
File without changes