enum-properties 2.7.0__tar.gz → 2.8.0__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 (95) hide show
  1. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/dependabot.yml +0 -12
  2. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/workflows/lint.yml +5 -5
  3. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/workflows/release.yml +10 -11
  4. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/workflows/scorecard.yml +7 -3
  5. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/workflows/test.yml +31 -30
  6. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/workflows/zizmor.yml +4 -4
  7. {enum_properties-2.7.0 → enum_properties-2.8.0}/.gitignore +1 -0
  8. {enum_properties-2.7.0 → enum_properties-2.8.0}/PKG-INFO +1 -1
  9. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/changelog.rst +6 -0
  10. {enum_properties-2.7.0 → enum_properties-2.8.0}/justfile +2 -2
  11. {enum_properties-2.7.0 → enum_properties-2.8.0}/pyproject.toml +2 -1
  12. {enum_properties-2.7.0 → enum_properties-2.8.0}/src/enum_properties/__init__.py +58 -54
  13. {enum_properties-2.7.0 → enum_properties-2.8.0}/src/enum_properties/__init__.pyi +4 -5
  14. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test.py +1 -1
  15. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test.py +2 -2
  16. enum_properties-2.7.0/uv.lock +0 -1977
  17. {enum_properties-2.7.0 → enum_properties-2.8.0}/.codecov.yml +0 -0
  18. {enum_properties-2.7.0 → enum_properties-2.8.0}/.github/CODEOWNERS +0 -0
  19. {enum_properties-2.7.0 → enum_properties-2.8.0}/.pre-commit-config.yaml +0 -0
  20. {enum_properties-2.7.0 → enum_properties-2.8.0}/CODE_OF_CONDUCT.md +0 -0
  21. {enum_properties-2.7.0 → enum_properties-2.8.0}/CONTRIBUTING.md +0 -0
  22. {enum_properties-2.7.0 → enum_properties-2.8.0}/LICENSE +0 -0
  23. {enum_properties-2.7.0 → enum_properties-2.8.0}/README.md +0 -0
  24. {enum_properties-2.7.0 → enum_properties-2.8.0}/SECURITY.md +0 -0
  25. {enum_properties-2.7.0 → enum_properties-2.8.0}/conftest.py +0 -0
  26. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/.readthedocs.yaml +0 -0
  27. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/_static/style.css +0 -0
  28. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/conf.py +0 -0
  29. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/howto.rst +0 -0
  30. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/index.rst +0 -0
  31. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/reference.rst +0 -0
  32. {enum_properties-2.7.0 → enum_properties-2.8.0}/doc/source/tutorial.rst +0 -0
  33. {enum_properties-2.7.0 → enum_properties-2.8.0}/src/enum_properties/py.typed +0 -0
  34. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/__init__.py +0 -0
  35. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_aliases.py +0 -0
  36. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_flags.py +0 -0
  37. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_future_annotations.py +0 -0
  38. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_interface_eq.py +0 -0
  39. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_nestedclass.py +0 -0
  40. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_none_coercion.py +0 -0
  41. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_perf.py +0 -0
  42. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_pickle.py +0 -0
  43. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_specialize.py +0 -0
  44. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_symmetric.py +0 -0
  45. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/annotations/test_type_hints.py +0 -0
  46. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/big_enum.py +0 -0
  47. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/big_enum_annotations.py +0 -0
  48. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/__init__.py +0 -0
  49. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/address.py +0 -0
  50. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/color_example.py +0 -0
  51. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/hash_equiv_def.py +0 -0
  52. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_add_props.py +0 -0
  53. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_dataclass.py +0 -0
  54. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_dataclass_integration.py +0 -0
  55. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_flag.py +0 -0
  56. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_flag_boundaries.py +0 -0
  57. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_flags_no_iterable.py +0 -0
  58. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_functional.py +0 -0
  59. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_hash_equiv.py +0 -0
  60. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_hash_equiv_def.py +0 -0
  61. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_legacy.py +0 -0
  62. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_members_and_aliases.py +0 -0
  63. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_metaclass.py +0 -0
  64. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_nested_classes.py +0 -0
  65. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_nested_classes_313.py +0 -0
  66. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_specialized.py +0 -0
  67. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_specialized_default.py +0 -0
  68. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_specialized_list.py +0 -0
  69. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_specialized_missing.py +0 -0
  70. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_symmetric_builtins.py +0 -0
  71. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_symmetric_decorator.py +0 -0
  72. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_symmetric_metaclass.py +0 -0
  73. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_symmetric_overload.py +0 -0
  74. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_symmetry.py +0 -0
  75. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/howto_verify_unique.py +0 -0
  76. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/mapbox.py +0 -0
  77. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/specialization_example.py +0 -0
  78. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/symmetric_example.py +0 -0
  79. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/examples/test_examples.py +0 -0
  80. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/__init__.py +0 -0
  81. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_flags.py +0 -0
  82. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_interface_eq.py +0 -0
  83. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_multi_primitives.py +0 -0
  84. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_nestedclass.py +0 -0
  85. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_none_coercion.py +0 -0
  86. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_perf.py +0 -0
  87. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_pickle.py +0 -0
  88. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_specialize.py +0 -0
  89. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/legacy/test_type_hints.py +0 -0
  90. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/pickle_enums.py +0 -0
  91. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/pickle_enums_annotations.py +0 -0
  92. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/test_functional.py +0 -0
  93. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/type_hints/__init__.py +0 -0
  94. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/type_hints/pyright.json +0 -0
  95. {enum_properties-2.7.0 → enum_properties-2.8.0}/tests/type_hints/test.py +0 -0
@@ -15,15 +15,3 @@ updates:
15
15
  gha-updates:
16
16
  patterns:
17
17
  - "*"
18
-
19
- # Python
20
- - package-ecosystem: "uv"
21
- directory: "/"
22
- schedule:
23
- interval: "monthly"
24
- commit-message:
25
- prefix: ⬆
26
- groups:
27
- uv-updates:
28
- patterns:
29
- - "*"
@@ -26,21 +26,21 @@ jobs:
26
26
  # run static analysis on bleeding and trailing edges
27
27
  python-version: [ '3.10', '3.14' ]
28
28
  steps:
29
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
29
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
30
30
  with:
31
31
  persist-credentials: false
32
32
  - name: Set up Python ${{ matrix.python-version }}
33
33
  id: sp
34
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
34
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
35
35
  with:
36
36
  python-version: ${{ matrix.python-version }}
37
37
  allow-prereleases: true
38
38
  - name: Install uv
39
- uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098
39
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
40
40
  with:
41
41
  enable-cache: true
42
42
  - name: Install Just
43
- uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b
43
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3
44
44
  - name: Install Dependencies
45
45
  env:
46
46
  PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
@@ -52,7 +52,7 @@ jobs:
52
52
  sudo apt install emacs
53
53
  - name: Setup tmate session
54
54
  if: ${{ github.event.inputs.debug == 'true' }}
55
- uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101
55
+ uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113
56
56
  with:
57
57
  detached: true
58
58
  timeout-minutes: 60
@@ -25,9 +25,8 @@ jobs:
25
25
  permissions:
26
26
  contents: read
27
27
  actions: write
28
+ id-token: write
28
29
  uses: ./.github/workflows/test.yml
29
- secrets:
30
- CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
31
30
 
32
31
  build:
33
32
  name: Build Package
@@ -39,21 +38,21 @@ jobs:
39
38
  PACKAGE_NAME: ${{ steps.set-package.outputs.package_name }}
40
39
  RELEASE_VERSION: ${{ steps.set-package.outputs.release_version }}
41
40
  steps:
42
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
41
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
43
42
  with:
44
43
  persist-credentials: true
45
44
  - name: Set up Python
46
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
45
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
47
46
  with:
48
47
  python-version: ">=3.11" # for tomlib
49
48
  - name: Install uv
50
- uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098
49
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
51
50
  with:
52
51
  enable-cache: false
53
52
  restore-cache: false
54
53
  save-cache: false
55
54
  - name: Setup Just
56
- uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b
55
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3
57
56
  - name: Verify Tag
58
57
  run: |
59
58
  TAG_NAME=${GITHUB_REF#refs/tags/}
@@ -74,7 +73,7 @@ jobs:
74
73
  - name: Build the binary wheel and a source tarball
75
74
  run: just build
76
75
  - name: Store the distribution packages
77
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
76
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
78
77
  with:
79
78
  name: python-package-distributions
80
79
  path: dist/
@@ -98,12 +97,12 @@ jobs:
98
97
  id-token: write # IMPORTANT: mandatory for trusted publishing
99
98
  steps:
100
99
  - name: Download all the dists
101
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
100
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
102
101
  with:
103
102
  name: python-package-distributions
104
103
  path: dist/
105
104
  - name: Publish distribution 📦 to PyPI
106
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e
105
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b
107
106
 
108
107
  github-release:
109
108
  name: Publish GitHub Release
@@ -118,12 +117,12 @@ jobs:
118
117
 
119
118
  steps:
120
119
  - name: Download all the dists
121
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
120
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
122
121
  with:
123
122
  name: python-package-distributions
124
123
  path: dist/
125
124
  - name: Sign the dists with Sigstore
126
- uses: sigstore/gh-action-sigstore-python@a5caf349bc536fbef3668a10ed7f5cd309a4b53d
125
+ uses: sigstore/gh-action-sigstore-python@5b79a39c381910c090341a2c9b0bf022c8b387e1
127
126
  with:
128
127
  inputs: >-
129
128
  ./dist/*.tar.gz
@@ -15,13 +15,17 @@ jobs:
15
15
  analysis:
16
16
  name: Scorecard analysis
17
17
  runs-on: ubuntu-latest
18
+ environment:
19
+ name: scorecard
20
+ deployment: false # Prevents creating a GitHub deployment object
21
+
18
22
  permissions:
19
23
  security-events: write
20
24
  id-token: write
21
25
 
22
26
  steps:
23
27
  - name: "Checkout code"
24
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
28
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
25
29
  with:
26
30
  persist-credentials: false
27
31
 
@@ -48,7 +52,7 @@ jobs:
48
52
  # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
49
53
  # format to the repository Actions tab.
50
54
  - name: "Upload artifact"
51
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
55
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
52
56
  with:
53
57
  name: SARIF file
54
58
  path: results.sarif
@@ -57,6 +61,6 @@ jobs:
57
61
  # Upload the results to GitHub's code scanning dashboard (optional).
58
62
  # Commenting out will disable upload of results to your repo's Code Scanning dashboard
59
63
  - name: "Upload to code-scanning"
60
- uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e
64
+ uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e
61
65
  with:
62
66
  sarif_file: results.sarif
@@ -10,9 +10,6 @@ on:
10
10
  pull_request:
11
11
  merge_group:
12
12
  workflow_call:
13
- secrets:
14
- CODECOV_TOKEN:
15
- required: true
16
13
  workflow_dispatch:
17
14
  inputs:
18
15
  debug:
@@ -42,19 +39,19 @@ jobs:
42
39
  if: ${{ github.event.inputs.clear_cache == 'true' }}
43
40
  run: sudo rm -rf /opt/hostedtoolcache
44
41
 
45
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
42
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
46
43
  with:
47
44
  persist-credentials: false
48
45
  - name: Set up Python ${{ matrix.python-version }}
49
46
  id: sp
50
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
47
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
51
48
  with:
52
49
  python-version: ${{ matrix.python-version }}
53
50
  allow-prereleases: true
54
51
  - name: Install Just
55
- uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b
52
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3
56
53
  - name: Install uv
57
- uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098
54
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
58
55
  with:
59
56
  enable-cache: true
60
57
  - name: Install Emacs
@@ -63,7 +60,7 @@ jobs:
63
60
  sudo apt install emacs
64
61
  - name: Setup tmate session
65
62
  if: ${{ github.event.inputs.debug == 'true' }}
66
- uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101
63
+ uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113
67
64
  with:
68
65
  detached: true
69
66
  - name: Install Dependencies
@@ -76,7 +73,7 @@ jobs:
76
73
  just test
77
74
 
78
75
  - name: Store coverage files
79
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
76
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
80
77
  with:
81
78
  name: ${{ env.COVERAGE_FILE }}
82
79
  path: ${{ env.COVERAGE_FILE }}
@@ -97,19 +94,19 @@ jobs:
97
94
  if: ${{ github.event.inputs.clear_cache == 'true' }}
98
95
  run: sudo rm -rf /Users/runner/hostedtoolcache
99
96
 
100
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
97
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
101
98
  with:
102
99
  persist-credentials: false
103
100
  - name: Set up Python ${{ matrix.python-version }}
104
101
  id: sp
105
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
102
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
106
103
  with:
107
104
  python-version: ${{ matrix.python-version }}
108
105
  allow-prereleases: true
109
106
  - name: Install Just
110
- uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b
107
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3
111
108
  - name: Install uv
112
- uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098
109
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
113
110
  with:
114
111
  enable-cache: true
115
112
  - name: install-emacs-macos
@@ -118,7 +115,7 @@ jobs:
118
115
  brew install emacs
119
116
  - name: Setup tmate session
120
117
  if: ${{ github.event.inputs.debug == 'true' }}
121
- uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101
118
+ uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113
122
119
  with:
123
120
  detached: true
124
121
  - name: Install Dependencies
@@ -131,7 +128,7 @@ jobs:
131
128
  just test
132
129
 
133
130
  - name: Store coverage files
134
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
131
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
135
132
  with:
136
133
  name: ${{ env.COVERAGE_FILE }}
137
134
  path: ${{ env.COVERAGE_FILE }}
@@ -151,27 +148,27 @@ jobs:
151
148
  - name: Clear GitHub Actions cache
152
149
  if: ${{ github.event.inputs.clear_cache == 'true' }}
153
150
  run: Remove-Item -Recurse -Force C:\hostedtoolcache
154
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
151
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
155
152
  with:
156
153
  persist-credentials: false
157
154
  - name: Set up Python ${{ matrix.python-version }}
158
155
  id: sp
159
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
156
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
160
157
  with:
161
158
  python-version: ${{ matrix.python-version }}
162
159
  allow-prereleases: true
163
160
  - name: Install Just
164
- uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b
161
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3
165
162
  - name: Install uv
166
- uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098
163
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
167
164
  with:
168
165
  enable-cache: true
169
166
  - name: install-vim-windows
170
167
  if: ${{ github.event.inputs.debug == 'true' }}
171
- uses: rhysd/action-setup-vim@19e3dd31a84dbc2c5445d65e9b363f616cab96c1
168
+ uses: rhysd/action-setup-vim@febef33995d6649302e9d88dda81e071b68f16a7
172
169
  - name: Setup tmate session
173
170
  if: ${{ github.event.inputs.debug == 'true' }}
174
- uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101
171
+ uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113
175
172
  with:
176
173
  detached: true
177
174
  - name: Install Dependencies
@@ -184,7 +181,7 @@ jobs:
184
181
  just test
185
182
 
186
183
  - name: Store coverage files
187
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
184
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
188
185
  with:
189
186
  name: ${{ env.COVERAGE_FILE }}
190
187
  path: ${{ env.COVERAGE_FILE }}
@@ -192,22 +189,25 @@ jobs:
192
189
  coverage-combine:
193
190
  needs: [linux, macos, windows]
194
191
  runs-on: ubuntu-latest
192
+ permissions:
193
+ contents: read
194
+ id-token: write
195
195
 
196
196
  steps:
197
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
197
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
198
198
  with:
199
199
  persist-credentials: false
200
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
200
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1
201
201
  id: sp
202
202
  with:
203
203
  python-version: '3.14'
204
204
 
205
205
  - name: Install uv
206
- uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098
206
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39
207
207
  with:
208
208
  enable-cache: true
209
209
  - name: Setup Just
210
- uses: extractions/setup-just@f8a3cce218d9f83db3a2ecd90e41ac3de6cdfd9b
210
+ uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3
211
211
  - name: Install Release Dependencies
212
212
  env:
213
213
  PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
@@ -215,7 +215,7 @@ jobs:
215
215
  just setup "$PYTHON_PATH"
216
216
 
217
217
  - name: Get coverage files
218
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3
218
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
219
219
  with:
220
220
  pattern: "*.coverage"
221
221
  merge-multiple: true
@@ -223,7 +223,8 @@ jobs:
223
223
  - run: just coverage
224
224
 
225
225
  - name: Upload coverage to Codecov
226
- uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de
226
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
227
227
  with:
228
- token: ${{ secrets.CODECOV_TOKEN }}
229
- file: ./coverage.xml
228
+ use_oidc: true
229
+ files:
230
+ ./coverage.xml
@@ -22,12 +22,12 @@ jobs:
22
22
 
23
23
  steps:
24
24
  - name: Checkout repository
25
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
25
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
26
26
  with:
27
27
  persist-credentials: false
28
28
 
29
29
  - name: Set up Rust
30
- uses: actions-rust-lang/setup-rust-toolchain@a0b538fa0b742a6aa35d6e2c169b4bd06d225a98
30
+ uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659
31
31
  - name: Install jq
32
32
  run: |
33
33
  sudo apt-get update
@@ -41,14 +41,14 @@ jobs:
41
41
  zizmor --format sarif .github/workflows/ > results.sarif
42
42
 
43
43
  - name: Upload analysis results
44
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
44
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
45
45
  with:
46
46
  name: zizmor-results
47
47
  path: results.sarif
48
48
  retention-days: 7
49
49
 
50
50
  - name: Upload to code-scanning
51
- uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e
51
+ uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e
52
52
  with:
53
53
  sarif_file: results.sarif
54
54
 
@@ -134,3 +134,4 @@ dmypy.json
134
134
  .idea
135
135
  .ruff_cache
136
136
  CLAUDE.md
137
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enum-properties
3
- Version: 2.7.0
3
+ Version: 2.8.0
4
4
  Summary: Add properties and method specializations to Python enumeration values with a simple declarative syntax.
5
5
  Project-URL: Homepage, https://github.com/bckohan/enum-properties
6
6
  Project-URL: Documentation, https://enum-properties.readthedocs.io
@@ -2,6 +2,12 @@
2
2
  Change Log
3
3
  ==========
4
4
 
5
+ v2.8.0 (2026-08-03)
6
+ ===================
7
+
8
+ * Throw TypeError instead of ValueError when wrong types are encountered in enum class definitions.
9
+ * Fix linting issues with latest versions of ruff.
10
+
5
11
  v2.7.0 (2026-03-04)
6
12
  ===================
7
13
 
@@ -1,6 +1,6 @@
1
1
  set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]
2
- set unstable := true
3
- set script-interpreter := ['uv', 'run', '--script']
2
+ set unstable
3
+ set script-interpreter := ['uv', 'run', '--project', '.', '--script']
4
4
 
5
5
  export PYTHONPATH := source_directory()
6
6
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "enum-properties"
7
- version = "2.7.0"
7
+ version = "2.8.0"
8
8
  description = "Add properties and method specializations to Python enumeration values with a simple declarative syntax."
9
9
  requires-python = ">=3.10,<4.0"
10
10
  authors = [
@@ -139,6 +139,7 @@ exclude = [
139
139
  "examples",
140
140
  "tests/resources/bad_code.py"
141
141
  ]
142
+ extend-exclude = ["*.md"]
142
143
 
143
144
  [tool.ruff.lint]
144
145
  exclude = [
@@ -19,6 +19,8 @@ Metaprogramming and mixin tools that implement property tuple and method
19
19
  specialization support for python enumeration classes.
20
20
  """
21
21
 
22
+ from __future__ import annotations
23
+
22
24
  import enum
23
25
  import sys
24
26
  import typing as t
@@ -27,7 +29,7 @@ from collections.abc import Generator, Hashable, Iterable, Mapping
27
29
  from dataclasses import dataclass
28
30
  from functools import cached_property
29
31
 
30
- VERSION = (2, 7, 0)
32
+ VERSION = (2, 8, 0)
31
33
 
32
34
  __title__ = "Enum Properties"
33
35
  __version__ = ".".join(str(i) for i in VERSION)
@@ -37,19 +39,19 @@ __copyright__ = "Copyright 2022-2026 Brian Kohan"
37
39
 
38
40
  __all__ = [
39
41
  "VERSION",
42
+ "DecomposeMixin",
40
43
  "EnumProperties",
41
- "IntEnumProperties",
42
- "StrEnumProperties",
44
+ "EnumPropertiesMeta",
43
45
  "FlagProperties",
46
+ "IntEnumProperties",
44
47
  "IntFlagProperties",
45
- "EnumPropertiesMeta",
46
- "symmetric",
48
+ "StrEnumProperties",
47
49
  "Symmetric",
48
50
  "SymmetricMixin",
49
- "DecomposeMixin",
50
- "specialize",
51
51
  "p",
52
52
  "s",
53
+ "specialize",
54
+ "symmetric",
53
55
  ]
54
56
 
55
57
 
@@ -284,7 +286,7 @@ class SymmetricMixin(_SymmetricMixinBase):
284
286
  overridden.
285
287
  """
286
288
 
287
- def __eq__(self, value: t.Any) -> bool:
289
+ def __eq__(self, value: object) -> bool:
288
290
  """Symmetric equality - try to coerce value before failure"""
289
291
  if isinstance(value, self.__class__):
290
292
  return self.value == value.value
@@ -293,7 +295,7 @@ class SymmetricMixin(_SymmetricMixinBase):
293
295
  except (ValueError, TypeError):
294
296
  return False
295
297
 
296
- def __ne__(self, value: t.Any) -> bool:
298
+ def __ne__(self, value: object) -> bool:
297
299
  """Symmetric inequality is the inverse of symmetric equality"""
298
300
  return not self.__eq__(value)
299
301
 
@@ -352,7 +354,7 @@ class SymmetricMixin(_SymmetricMixinBase):
352
354
  if isinstance(val, str):
353
355
  return cls._ep_isymmetric_map_[_do_casenorm(val)]
354
356
 
355
- except Exception:
357
+ except Exception: # noqa: BLE001, S110
356
358
  pass
357
359
 
358
360
  return super()._missing_(value)
@@ -395,10 +397,10 @@ class EnumPropertiesMeta(enum.EnumMeta):
395
397
  """
396
398
 
397
399
  # members expected to be supplied by inheriting classes
398
- EXPECTED = ["_symmetric_builtins_"]
400
+ EXPECTED: t.ClassVar[list[str]] = ["_symmetric_builtins_"]
399
401
 
400
402
  # members reserved for use by EnumProperties
401
- RESERVED = [
403
+ RESERVED: t.ClassVar[list[str]] = [
402
404
  "_properties_",
403
405
  "_num_sym_props_",
404
406
  "_ep_coerce_types_",
@@ -583,7 +585,9 @@ class EnumPropertiesMeta(enum.EnumMeta):
583
585
  else:
584
586
  real_bases.append(base)
585
587
 
586
- class_dict = super().__prepare__(cls, tuple(real_bases), **kwds)
588
+ class_dict: _PropertyEnumDict = super().__prepare__(
589
+ cls, tuple(real_bases), **kwds
590
+ )
587
591
 
588
592
  class _PropertyEnumDict(class_dict.__class__): # type: ignore[name-defined]
589
593
  """
@@ -597,61 +601,61 @@ class EnumPropertiesMeta(enum.EnumMeta):
597
601
  _ep_properties_ = properties
598
602
 
599
603
  # lazy properties in annotation declaration order
600
- _lazy_properties_: list[_Prop] = []
604
+ _lazy_properties_: list[_Prop]
601
605
 
602
606
  # member -> value tuple
603
- _lazy_property_values_: dict[str, t.Any] = {}
604
- _specialized_: dict[str, dict[str, _Specialized]] = {}
605
- _ids_: dict[int, str] = {}
607
+ _lazy_property_values_: dict[str, t.Any]
608
+ _specialized_: dict[str, dict[str, _Specialized]]
609
+ _ids_: dict[int, str]
606
610
  _member_names: list[str] | dict[str, t.Any]
607
611
  _create_properties_: bool = False
608
- __first_class_members__: list[str] = []
612
+ __first_class_members__: list[str]
609
613
 
610
614
  class AnnotationPropertyRecorder(dict):
611
- class_dict: "_PropertyEnumDict"
615
+ class_dict: _PropertyEnumDict
612
616
  create_properties: bool
613
617
 
614
- def __init__(self, class_dict: "_PropertyEnumDict"):
618
+ def __init__(self, class_dict: _PropertyEnumDict):
615
619
  self.class_dict = class_dict
616
620
  # we only use annotations to create properties if p/s value
617
621
  # inheritance is not used
618
622
  super().__init__()
619
623
 
620
624
  def __setitem__(self, key, value):
621
- if self.class_dict._create_properties_:
622
- if (
623
- key not in EnumPropertiesMeta.RESERVED
624
- and key not in EnumPropertiesMeta.EXPECTED
625
+ if self.class_dict._create_properties_ and (
626
+ key not in EnumPropertiesMeta.RESERVED
627
+ and key not in EnumPropertiesMeta.EXPECTED
628
+ ):
629
+ prop: type[_Prop]
630
+ if getattr(value, "__metadata__", None) and isinstance(
631
+ value.__metadata__[0], Symmetric
625
632
  ):
626
- prop: type[_Prop]
627
- if getattr(value, "__metadata__", None) and isinstance(
628
- value.__metadata__[0], Symmetric
629
- ):
630
- prop = s(
631
- key,
632
- case_fold=value.__metadata__[0].case_fold,
633
- match_none=value.__metadata__[0].match_none,
634
- )
635
- else:
636
- prop = p(key)
637
- if key == "name" or key == "value":
638
- if issubclass(prop, _SProp):
639
- if self.class_dict.__contains__(
640
- "_symmetric_builtins_"
641
- ):
642
- self.class_dict["_symmetric_builtins_"].append(
643
- prop
644
- )
645
- else:
646
- self.class_dict["_symmetric_builtins_"] = [prop]
647
- else:
648
- if _lazy_annotations_:
649
- self.class_dict._lazy_properties_.append(prop())
633
+ prop = s(
634
+ key,
635
+ case_fold=value.__metadata__[0].case_fold,
636
+ match_none=value.__metadata__[0].match_none,
637
+ )
638
+ else:
639
+ prop = p(key)
640
+ if key == "name" or key == "value":
641
+ if issubclass(prop, _SProp):
642
+ if self.class_dict.__contains__("_symmetric_builtins_"):
643
+ self.class_dict["_symmetric_builtins_"].append(prop)
650
644
  else:
651
- self.class_dict._ep_properties_[prop()] = []
645
+ self.class_dict["_symmetric_builtins_"] = [prop]
646
+ else:
647
+ if _lazy_annotations_:
648
+ self.class_dict._lazy_properties_.append(prop())
649
+ else:
650
+ self.class_dict._ep_properties_[prop()] = []
652
651
  super().__setitem__(key, value)
653
652
 
654
653
  def __init__(self):
654
+ self._lazy_properties_ = []
655
+ self._lazy_property_values_ = {}
656
+ self._specialized_ = {}
657
+ self._ids_ = {}
658
+ self.__first_class_members__ = []
655
659
  super().__init__()
656
660
  for attr in set(dir(class_dict)).difference(set(dir(self))):
657
661
  setattr(self, attr, getattr(class_dict, attr))
@@ -703,7 +707,7 @@ class EnumPropertiesMeta(enum.EnumMeta):
703
707
  elif self._ep_properties_ or (
704
708
  _lazy_annotations_ and isinstance(value, tuple)
705
709
  ):
706
- member_names = getattr(class_dict, "_member_names")
710
+ member_names = class_dict._member_names
707
711
  # are we an enum value? - just kick this up to parent class
708
712
  # logic, this code runs once on load - its fine that it's
709
713
  # doing a little redundant work and doing it this way
@@ -781,7 +785,7 @@ class EnumPropertiesMeta(enum.EnumMeta):
781
785
  4) Add casefolded symmetric maps for any symmetric properties
782
786
  5) Add any symmetric builtin properties to our symmetric maps
783
787
 
784
- :raises ValueError: if ``_symmetric_builtins_`` is specified
788
+ :raises TypeError: if ``_symmetric_builtins_`` is specified
785
789
  incorrectly, or if non-hashable values are provided for a
786
790
  symmetric property.
787
791
  """
@@ -850,7 +854,7 @@ class EnumPropertiesMeta(enum.EnumMeta):
850
854
  if p_val is None and not prop.match_none:
851
855
  return
852
856
  if not isinstance(p_val, Hashable):
853
- raise ValueError(
857
+ raise TypeError(
854
858
  f"{cls}.{prop}:{p_val} is not hashable. Symmetrical "
855
859
  f"enumeration properties must be hashable or a list of "
856
860
  f"hashable values."
@@ -911,7 +915,7 @@ class EnumPropertiesMeta(enum.EnumMeta):
911
915
  elif issubclass(sym_builtin, _SProp):
912
916
  sym_builtin = sym_builtin()
913
917
  else:
914
- raise ValueError(
918
+ raise TypeError(
915
919
  f"_symmetric_builtins_ contained {type(sym_builtin)}, "
916
920
  f"expected string or s() property."
917
921
  )
@@ -1017,7 +1021,7 @@ class DecomposeMixin(_DecomposeMixinBase):
1017
1021
  """
1018
1022
  Returns the list of flags that are active.
1019
1023
  """
1020
- return list(flag for flag in iter(self))
1024
+ return list(iter(self))
1021
1025
 
1022
1026
  def __iter__(self):
1023
1027
  """