pythonwrench 0.6.2__tar.gz → 0.6.4__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 (139) hide show
  1. pythonwrench-0.6.4/.github/workflows/test.yaml +194 -0
  2. pythonwrench-0.6.4/.gitignore +182 -0
  3. pythonwrench-0.6.4/.pre-commit-config.yaml +32 -0
  4. pythonwrench-0.6.4/.readthedocs.yaml +26 -0
  5. pythonwrench-0.6.4/CHANGELOG.md +201 -0
  6. pythonwrench-0.6.4/CITATION.cff +21 -0
  7. {pythonwrench-0.6.2/src/pythonwrench.egg-info → pythonwrench-0.6.4}/PKG-INFO +31 -28
  8. pythonwrench-0.6.4/docs/Makefile +20 -0
  9. pythonwrench-0.6.4/docs/conf.py +117 -0
  10. pythonwrench-0.6.4/docs/index.rst +174 -0
  11. pythonwrench-0.6.4/docs/make.bat +35 -0
  12. pythonwrench-0.6.4/docs/modules.rst +7 -0
  13. pythonwrench-0.6.4/docs/pythonwrench.abc.rst +7 -0
  14. pythonwrench-0.6.4/docs/pythonwrench.argparse.dataclass_.rst +7 -0
  15. pythonwrench-0.6.4/docs/pythonwrench.argparse.parsers.rst +7 -0
  16. pythonwrench-0.6.4/docs/pythonwrench.argparse.rst +16 -0
  17. pythonwrench-0.6.4/docs/pythonwrench.cast.rst +7 -0
  18. pythonwrench-0.6.4/docs/pythonwrench.checksum.rst +7 -0
  19. pythonwrench-0.6.4/docs/pythonwrench.collections.collections.rst +7 -0
  20. pythonwrench-0.6.4/docs/pythonwrench.collections.prop.rst +7 -0
  21. pythonwrench-0.6.4/docs/pythonwrench.collections.reducers.rst +7 -0
  22. pythonwrench-0.6.4/docs/pythonwrench.collections.rst +17 -0
  23. pythonwrench-0.6.4/docs/pythonwrench.concurrent.rst +7 -0
  24. pythonwrench-0.6.4/docs/pythonwrench.csv.rst +7 -0
  25. pythonwrench-0.6.4/docs/pythonwrench.dataclasses.rst +7 -0
  26. pythonwrench-0.6.4/docs/pythonwrench.datetime.rst +7 -0
  27. pythonwrench-0.6.4/docs/pythonwrench.difflib.rst +7 -0
  28. pythonwrench-0.6.4/docs/pythonwrench.disk_cache.rst +7 -0
  29. pythonwrench-0.6.4/docs/pythonwrench.enum.rst +7 -0
  30. pythonwrench-0.6.4/docs/pythonwrench.functools.rst +7 -0
  31. pythonwrench-0.6.4/docs/pythonwrench.hashlib.rst +7 -0
  32. pythonwrench-0.6.4/docs/pythonwrench.importlib.rst +7 -0
  33. pythonwrench-0.6.4/docs/pythonwrench.inspect.rst +7 -0
  34. pythonwrench-0.6.4/docs/pythonwrench.json.rst +7 -0
  35. pythonwrench-0.6.4/docs/pythonwrench.jsonl.rst +7 -0
  36. pythonwrench-0.6.4/docs/pythonwrench.logging.rst +7 -0
  37. pythonwrench-0.6.4/docs/pythonwrench.math.rst +7 -0
  38. pythonwrench-0.6.4/docs/pythonwrench.os.rst +7 -0
  39. pythonwrench-0.6.4/docs/pythonwrench.pickle.rst +7 -0
  40. pythonwrench-0.6.4/docs/pythonwrench.random.rst +7 -0
  41. pythonwrench-0.6.4/docs/pythonwrench.re.rst +7 -0
  42. pythonwrench-0.6.4/docs/pythonwrench.rst +50 -0
  43. pythonwrench-0.6.4/docs/pythonwrench.semver.rst +7 -0
  44. pythonwrench-0.6.4/docs/pythonwrench.serialization.csv.rst +7 -0
  45. pythonwrench-0.6.4/docs/pythonwrench.serialization.json.rst +7 -0
  46. pythonwrench-0.6.4/docs/pythonwrench.serialization.jsonl.rst +7 -0
  47. pythonwrench-0.6.4/docs/pythonwrench.serialization.pickle.rst +7 -0
  48. pythonwrench-0.6.4/docs/pythonwrench.serialization.rst +18 -0
  49. pythonwrench-0.6.4/docs/pythonwrench.time.rst +7 -0
  50. pythonwrench-0.6.4/docs/pythonwrench.typing.checks.rst +7 -0
  51. pythonwrench-0.6.4/docs/pythonwrench.typing.classes.rst +7 -0
  52. pythonwrench-0.6.4/docs/pythonwrench.typing.rst +16 -0
  53. pythonwrench-0.6.4/docs/pythonwrench.warnings.rst +7 -0
  54. pythonwrench-0.6.4/docs/update.bash +23 -0
  55. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/pyproject.toml +28 -21
  56. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/__init__.py +27 -1
  57. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/_core.py +49 -29
  58. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/abc.py +1 -0
  59. pythonwrench-0.6.4/src/pythonwrench/argparse/__init__.py +81 -0
  60. pythonwrench-0.6.4/src/pythonwrench/argparse/dataclass_.py +284 -0
  61. pythonwrench-0.6.4/src/pythonwrench/argparse/parsers.py +619 -0
  62. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/cast.py +49 -13
  63. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/checksum.py +55 -12
  64. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/collections/collections.py +92 -25
  65. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/collections/prop.py +7 -2
  66. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/collections/reducers.py +70 -23
  67. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/concurrent.py +3 -0
  68. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/dataclasses.py +8 -0
  69. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/disk_cache.py +29 -8
  70. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/entrypoints/safe_rmdir.py +2 -0
  71. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/entrypoints/tree.py +5 -4
  72. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/enum.py +6 -0
  73. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/functools.py +30 -10
  74. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/hashlib.py +35 -14
  75. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/importlib.py +11 -1
  76. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/logging.py +8 -0
  77. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/math.py +11 -1
  78. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/os.py +4 -2
  79. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/random.py +6 -2
  80. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/re.py +66 -45
  81. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/semver.py +36 -5
  82. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/serialization/_core.py +9 -3
  83. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/serialization/csv.py +20 -5
  84. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/serialization/json.py +9 -1
  85. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/serialization/jsonl.py +9 -1
  86. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/serialization/pickle.py +5 -1
  87. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/typing/checks.py +48 -6
  88. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/typing/classes.py +31 -0
  89. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/warnings.py +14 -4
  90. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_argparse.py +105 -24
  91. pythonwrench-0.6.4/tests/test_core.py +30 -0
  92. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_importlib.py +1 -2
  93. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_typing.py +10 -2
  94. pythonwrench-0.6.4/uv.lock +4376 -0
  95. pythonwrench-0.6.2/PKG-INFO +0 -239
  96. pythonwrench-0.6.2/setup.cfg +0 -4
  97. pythonwrench-0.6.2/src/pythonwrench/argparse.py +0 -563
  98. pythonwrench-0.6.2/src/pythonwrench.egg-info/SOURCES.txt +0 -79
  99. pythonwrench-0.6.2/src/pythonwrench.egg-info/dependency_links.txt +0 -1
  100. pythonwrench-0.6.2/src/pythonwrench.egg-info/entry_points.txt +0 -10
  101. pythonwrench-0.6.2/src/pythonwrench.egg-info/requires.txt +0 -18
  102. pythonwrench-0.6.2/src/pythonwrench.egg-info/top_level.txt +0 -1
  103. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/LICENSE +0 -0
  104. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/README.md +0 -0
  105. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/setup.py +0 -0
  106. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/__main__.py +0 -0
  107. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/collections/__init__.py +0 -0
  108. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/csv.py +0 -0
  109. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/datetime.py +0 -0
  110. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/difflib.py +0 -0
  111. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/entrypoints/info.py +0 -0
  112. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/inspect.py +0 -0
  113. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/json.py +0 -0
  114. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/jsonl.py +0 -0
  115. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/pickle.py +0 -0
  116. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/serialization/__init__.py +0 -0
  117. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/time.py +0 -0
  118. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/src/pythonwrench/typing/__init__.py +0 -0
  119. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_abc.py +0 -0
  120. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_cast.py +0 -0
  121. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_checksum.py +0 -0
  122. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_collections.py +0 -0
  123. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_csv.py +0 -0
  124. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_dataclasses.py +0 -0
  125. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_difflib.py +0 -0
  126. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_disk_cache.py +0 -0
  127. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_entrypoints.py +0 -0
  128. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_enum.py +0 -0
  129. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_functools.py +0 -0
  130. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_hashlib.py +0 -0
  131. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_inspect.py +0 -0
  132. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_json.py +0 -0
  133. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_jsonl.py +0 -0
  134. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_logging.py +0 -0
  135. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_math.py +0 -0
  136. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_os.py +0 -0
  137. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_random.py +0 -0
  138. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_readme.py +0 -0
  139. {pythonwrench-0.6.2 → pythonwrench-0.6.4}/tests/test_semver.py +0 -0
@@ -0,0 +1,194 @@
1
+ # Template: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
2
+
3
+ name: Python package using Pip
4
+
5
+ on:
6
+ push:
7
+ branches: [ main, dev** ]
8
+ pull_request:
9
+ branches: [ main, dev** ]
10
+
11
+ env:
12
+ CACHE_NUMBER: 0 # increase to reset cache manually
13
+ UV_NO_SYNC: 1
14
+
15
+ # Cancel workflow if a new push occurs
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
18
+ # Never interrupt a main-branch publication between PyPI and GitHub.
19
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
20
+
21
+ jobs:
22
+ build-and-test:
23
+ runs-on: ${{ matrix.os }}
24
+
25
+ strategy:
26
+ matrix:
27
+ os: [ubuntu-24.04]
28
+ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
29
+ include:
30
+ - os: windows-2022
31
+ python-version: "3.8"
32
+ - os: windows-latest
33
+ python-version: "3.14"
34
+ - os: macos-15
35
+ python-version: "3.8"
36
+ - os: macos-latest
37
+ python-version: "3.14"
38
+
39
+ steps:
40
+ # --- INSTALLATIONS ---
41
+ - name: Checkout repository
42
+ uses: actions/checkout@v5
43
+
44
+ - name: Install uv and set Python ${{ matrix.python-version }}
45
+ uses: astral-sh/setup-uv@v9.0.0
46
+ with:
47
+ python-version: ${{ matrix.python-version }}
48
+ enable-cache: true
49
+ cache-dependency-glob: "pyproject.toml"
50
+
51
+ - name: Install the project
52
+ run: |
53
+ uv sync --extra tests
54
+
55
+ # --- TESTS ---
56
+ - name: Print install info
57
+ run: |
58
+ uv run pythonwrench-info
59
+
60
+ - name: Check format with Ruff
61
+ run: |
62
+ uv run ruff check
63
+
64
+ - name: Test with coverage + pytest
65
+ run: |
66
+ uv run coverage run -m pytest -v
67
+
68
+ - name: Show coverage results
69
+ run: |
70
+ uv run coverage report -m
71
+
72
+ release-check:
73
+ name: Check whether a release is needed
74
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
75
+ needs: build-and-test
76
+ runs-on: ubuntu-24.04
77
+ permissions:
78
+ contents: read
79
+ outputs:
80
+ version: ${{ steps.release.outputs.version }}
81
+ should-publish: ${{ steps.release.outputs.should-publish }}
82
+
83
+ steps:
84
+ - name: Checkout repository and tags
85
+ uses: actions/checkout@v5
86
+ with:
87
+ fetch-depth: 0
88
+
89
+ - name: Validate release metadata
90
+ id: release
91
+ shell: python
92
+ run: |
93
+ import os
94
+ import pathlib
95
+ import re
96
+
97
+ init_text = pathlib.Path("src/pythonwrench/__init__.py").read_text(encoding="utf-8")
98
+ version_match = re.search(
99
+ r'^__version__\s*=\s*["\'](\d+\.\d+\.\d+)["\']\s*$',
100
+ init_text,
101
+ flags=re.MULTILINE,
102
+ )
103
+ if version_match is None:
104
+ raise SystemExit(
105
+ "__version__ must be a stable X.Y.Z release in "
106
+ "src/pythonwrench/__init__.py"
107
+ )
108
+
109
+ version = version_match.group(1)
110
+ changelog = pathlib.Path("CHANGELOG.md").read_text(encoding="utf-8")
111
+ heading = rf"^## \[{re.escape(version)}\](?:[ \t]+[^\r\n]*)?$"
112
+ if re.search(heading, changelog, flags=re.MULTILINE) is None:
113
+ raise SystemExit(f"CHANGELOG.md has no release section for {version}")
114
+
115
+ tag_ref = pathlib.Path(".git/refs/tags") / f"v{version}"
116
+ tag_exists = tag_ref.exists()
117
+ if not tag_exists:
118
+ import subprocess
119
+
120
+ tag_exists = subprocess.run(
121
+ ["git", "rev-parse", "--verify", "--quiet", f"refs/tags/v{version}"],
122
+ check=False,
123
+ ).returncode == 0
124
+
125
+ with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
126
+ print(f"version={version}", file=output)
127
+ print(f"should-publish={'false' if tag_exists else 'true'}", file=output)
128
+
129
+ if tag_exists:
130
+ print(f"v{version} already exists; publication will be skipped.")
131
+ else:
132
+ print(f"v{version} is ready to publish.")
133
+
134
+ publish:
135
+ name: Publish to PyPI and GitHub Releases
136
+ if: needs.release-check.outputs.should-publish == 'true'
137
+ needs: release-check
138
+ runs-on: ubuntu-24.04
139
+ environment:
140
+ name: pypi
141
+ url: https://pypi.org/project/pythonwrench/${{ needs.release-check.outputs.version }}/
142
+ permissions:
143
+ contents: write
144
+ id-token: write
145
+ env:
146
+ RELEASE_VERSION: ${{ needs.release-check.outputs.version }}
147
+
148
+ steps:
149
+ - name: Checkout tested commit
150
+ uses: actions/checkout@v5
151
+
152
+ - name: Install uv
153
+ uses: astral-sh/setup-uv@v9.0.0
154
+
155
+ - name: Build distributions
156
+ run: uv build
157
+
158
+ - name: Validate distributions
159
+ run: uvx twine check dist/*
160
+
161
+ - name: Extract release notes from changelog
162
+ shell: python
163
+ run: |
164
+ import os
165
+ import pathlib
166
+ import re
167
+
168
+ version = os.environ["RELEASE_VERSION"]
169
+ changelog = pathlib.Path("CHANGELOG.md").read_text(encoding="utf-8")
170
+ section = re.search(
171
+ rf"^## \[{re.escape(version)}\](?:[ \t]+[^\r\n]*)?\n(.*?)(?=^## \[|\Z)",
172
+ changelog,
173
+ flags=re.MULTILINE | re.DOTALL,
174
+ )
175
+ if section is None:
176
+ raise SystemExit(f"Could not extract changelog notes for {version}")
177
+ pathlib.Path("release-notes.md").write_text(
178
+ section.group(1).strip() + "\n",
179
+ encoding="utf-8",
180
+ )
181
+
182
+ - name: Publish distributions to PyPI
183
+ uses: pypa/gh-action-pypi-publish@release/v1
184
+ with:
185
+ skip-existing: true
186
+
187
+ - name: Create GitHub Release and tag
188
+ env:
189
+ GH_TOKEN: ${{ github.token }}
190
+ run: |
191
+ gh release create "v${RELEASE_VERSION}" dist/* \
192
+ --target "${GITHUB_SHA}" \
193
+ --title "v${RELEASE_VERSION}" \
194
+ --notes-file release-notes.md
@@ -0,0 +1,182 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # Ruff stuff:
171
+ .ruff_cache/
172
+
173
+ # PyPI configuration file
174
+ .pypirc
175
+
176
+ # Custom files/dirs
177
+ local_data
178
+ *.ows.swp*
179
+ results
180
+ scripts/cache/
181
+ .nfs0*
182
+ .vscode
@@ -0,0 +1,32 @@
1
+ # exclude: ""
2
+
3
+ repos:
4
+ # Formatting, Whitespace, etc
5
+ - repo: https://github.com/pre-commit/pre-commit-hooks
6
+ rev: v2.2.3
7
+ hooks:
8
+ - id: trailing-whitespace
9
+ - id: check-added-large-files
10
+ args: ['--maxkb=1000']
11
+ - id: check-ast
12
+ - id: check-json
13
+ - id: check-merge-conflict
14
+ - id: check-xml
15
+ - id: check-yaml
16
+ args: ['--unsafe'] # required because hyperpyyaml has specific constructor not supported by pyyaml (i.e. !apply)
17
+ - id: debug-statements
18
+ - id: end-of-file-fixer
19
+ - id: requirements-txt-fixer
20
+ - id: mixed-line-ending
21
+ args: ['--fix=no']
22
+
23
+ - repo: https://github.com/astral-sh/ruff-pre-commit
24
+ rev: v0.14.9
25
+ hooks:
26
+ - id: ruff
27
+ types_or: [python, pyi]
28
+ args: [--select, I, --fix]
29
+ - id: ruff-format
30
+ types_or: [python, pyi]
31
+ - id: ruff-check
32
+ args: [ --fix ]
@@ -0,0 +1,26 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ # Required
6
+ version: 2
7
+
8
+ # Set the version of Python and other tools you might need
9
+ build:
10
+ os: ubuntu-24.04
11
+ tools:
12
+ python: "3.13"
13
+
14
+ # Build documentation in the docs/ directory with Sphinx
15
+ sphinx:
16
+ configuration: docs/conf.py
17
+
18
+ # If using Sphinx, optionally build your docs in additional formats such as PDF
19
+ # formats:
20
+ # - pdf
21
+ python:
22
+ install:
23
+ - method: pip
24
+ path: .
25
+ extra_requirements:
26
+ - docs
@@ -0,0 +1,201 @@
1
+ # Change log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.6.4] 2026-08-17
6
+ ### Added
7
+ - Function `parse_args_using_dataclass` can now handle multiple dataclass at once.
8
+ - Function `parse_args_using_dataclass` now has option `bool_action`.
9
+
10
+
11
+ ## [0.6.3] 2026-08-06
12
+ ### Added
13
+ - Handle `Enum`, `Path`, and add `register_parser_fn` decorator for `parse_to_type`.
14
+ - `isinstance_generic` now supports parametrized `Callable`.
15
+
16
+ ### Modified
17
+ - Replace build backend `setuptools` by `hatchling`.
18
+
19
+
20
+ ## [0.6.2] 2026-07-30
21
+ ### Added
22
+ - `dataclassdict` decorator and `add_dict_method` function to create dataclass+dict classes.
23
+
24
+ ### Modified
25
+ - `add_dataclass_fields_to_parser` now supports mixed union and literals types.
26
+
27
+ ### Fixed
28
+ - Typing for `function_alias`, `deprecated_alias` and `deprecated_function` decorators.
29
+
30
+
31
+ ## [0.6.1] 2026-07-25
32
+ ### Added
33
+ - `list_parsing` argument value `"brackets"` to `add_dataclass_fields_to_parser`.
34
+ - `pre_fn` and `post_fn` args to `function_alias`, `deprecated_alias` and `deprecated_function`.
35
+ - `ModulePlacerholder` and `import_if_available`
36
+
37
+ ### Fixed
38
+ - Minor compatibilities with python 3.8.
39
+
40
+
41
+ ## [0.6.0] 2026-07-24
42
+ ### Added
43
+ - Add `_fill_all_arguments` option to `filter_and_call`.
44
+ - Add `parse_args_using_dataclass` function to parse program arguments using dataclass.
45
+
46
+ ### Modified
47
+ - Move CSV, JSON, JSONL and PICKLE functions to new `serialization` module.
48
+ - Default value for `key_mode` in `dict_list_to_list_dict` is now `"same"` to match `list_dict_to_dict_list`.
49
+
50
+ ### Fixed
51
+ - `Ticker` class in global context.
52
+ - `is_special_form` and `is_parametrized` now supports objects with custom `__contains__`, like ndarray or DataFrames.
53
+
54
+
55
+ ## [0.5.2] 2026-07-02
56
+ ### Modified
57
+ - `lazy-loader` package is now optional.
58
+
59
+ ### Fixed
60
+ - `Placeholder` and `requires_packages` in global context.
61
+ - `as_builtin` now support conversions of dataclasses attributes, without converting to dict with `dataclasses.asdict`.
62
+
63
+
64
+ ## [0.5.1] 2026-06-19
65
+ ### Added
66
+ - Argument `by` to `sorted_dict` function.
67
+ - `Ticker` class.
68
+ - `SupportsIter` alias of `Iterable`.
69
+ - `is_parameterized`, `is_collection_alias`, `is_special_form` functions.
70
+
71
+ ### Modified
72
+ - Checksum can apply to `date`, `datetime`, parametrized types, collections aliases and special forms.
73
+
74
+
75
+ ## [0.5.0] 2026-03-05
76
+ ### Modified
77
+ - Change default store mode to `"outputs_only"` in disk cache.
78
+ - Change default `fn_name` to function name instead of fully qualified name in disk cache.
79
+ - Lazily load imports if `lazy_loader` package is available.
80
+
81
+
82
+ ## [0.4.10] 2026-02-09
83
+ ### Fixed
84
+ - Disk cache custom keywords arguments for cache filename.
85
+
86
+
87
+ ## [0.4.9] 2026-02-06
88
+ ### Fixed
89
+ - `Version` now ignores buildmetadata when comparing versions.
90
+
91
+
92
+ ## [0.4.8] 2026-02-06
93
+ ### Added
94
+ - `checksum_any` now supports `Enum` instances.
95
+
96
+
97
+ ### Fixed
98
+ - Missing global typing imports.
99
+
100
+
101
+ ## [0.4.7] 2026-02-01
102
+ ### Modified
103
+ - Disk cache functions now detect saving backend when custom load/dump functions are provided.
104
+
105
+ ### Fixed
106
+ - `Callable` in `isinstance_generic` check.
107
+
108
+
109
+ ## [0.4.6] 2026-01-09
110
+ ### Added
111
+ - `cache_fname_fmt` can now be a custom callable formatter.
112
+
113
+
114
+ ## [0.4.5] 2026-01-09
115
+ ### Fixed
116
+ - Documentation build with constraint `sphinx<9.0.0`.
117
+
118
+
119
+ ## [0.4.4] 2026-01-09
120
+ ### Added
121
+ - `SizedGenerator` class wrapper.
122
+ - `executor_kwds` argument to `ThreadPoolExecutorHelper` class.
123
+ - `cache_fname_fmt` argument in `disk_cache` now supports inputs arguments values to name the cache file.
124
+
125
+
126
+ ## [0.4.3] 2025-12-13
127
+ ### Added
128
+ - `as_builtin` now supports `datetime.date` instances.
129
+ - `check_only_first` argument in `isinstance_generic` function.
130
+ - `filter_with_patterns` function.
131
+ - `skipfiles`, `include` and `sort` to `tree_iter` function.
132
+ - `SupportsGetitem` protocols now has `T_Index` typevar set to `Any` instead of `int` by default.
133
+ - `SupportsGetitem2`, `SupportsGetitemLen2` and `SupportsGetitemIterLen2` protocols with generic parameters in reversed order to match `Mapping[key, value]` order.
134
+ - `ThreadPoolExecutorHelper` class.
135
+ - `SupportsMatmul` typing class.
136
+ - `reduce_matmul` function.
137
+
138
+
139
+ ## [0.4.2] 2025-10-16
140
+ ### Fixed
141
+ - `get_argnames` and `filter_and_call` functions when argument `fn` contains arguments with default values.
142
+
143
+
144
+ ## [0.4.1] 2025-09-11
145
+ ### Added
146
+ - `SupportsGetitem` protocol.
147
+ - All `SupportGetitem`-based protocols now accept a second generic to specify idx type.
148
+ - `seed` option to `randstr` function.
149
+
150
+ ### Modified
151
+ - `checksum_any` computation with `set` and `frozenset` objects no longer require to sort elements.
152
+
153
+ ### Fixed
154
+ - Default value for `T_Index` typevar for protocol that specify `__getitem__` method.
155
+ - `reload_editable_submodules` when no editable submodule is imported.
156
+
157
+
158
+ ## [0.4.0] 2025-07-18
159
+ ### Added
160
+ - `duplicate_list` function to duplicate elements in a list.
161
+ - `loads`, `save`, `read` functions for CSV, JSON and PICKLE.
162
+ - JSONL file format support.
163
+ - `str_to_type` and `parse_to` functions to convert any argparse argument to builtin value.
164
+ - `requires_packages` decorator to avoid calling a function that requires an optional dependency.
165
+
166
+ ### Modified
167
+ - `deprecated_function` decorator can be used without parenthesis.
168
+
169
+ ### Fixed
170
+ - `disk_cache_decorator` typing.
171
+ - `priority` argument in `register` method of `_FunctionRegistry` class.
172
+ - `get_argnames` returns when function contains local variables.
173
+
174
+
175
+ ## [0.3.0] 2025-06-29
176
+ ### Added
177
+ - `check_args_type` decorator.
178
+
179
+ ### Modified
180
+ - `as_builtin` now converts `collections.Counter` instances.
181
+
182
+ ### Fixed
183
+ - `as_builtin` now converts correctly `Mapping` instances.
184
+ - `register_checksum_fn` now accepts `priority` arg.
185
+
186
+
187
+ ## [0.2.0] 2025-06-25
188
+ ### Added
189
+ - Python 3.8 support.
190
+ - `T_BuiltinNumber` and `T_BuiltinScalar` are covariant by default.
191
+ - `SupportsLen` protocol.
192
+ - `randstr` now support a range of sizes.
193
+ - `as_builtin` function to convert object to built-in equivalent recursively.
194
+
195
+ ### Modified
196
+ - `disk_cache_decorator` now supports custom saving backend fns.
197
+
198
+
199
+ ## [0.1.0] 2025-06-21
200
+ ### Added
201
+ - Initial modules from `pyoutil` module contained in [torchoutil](https://github.com/Labbeti/torchoutil) project.
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ cff-version: 1.2.0
4
+ title: pythonwrench
5
+ message: 'If you use this software, please cite it as below.'
6
+ type: software
7
+ authors:
8
+ - given-names: Étienne
9
+ family-names: Labbé
10
+ email: labbeti.pub@gmail.com
11
+ affiliation: IRIT
12
+ orcid: 'https://orcid.org/0000-0002-7219-5463'
13
+ repository-code: 'https://github.com/Labbeti/pythonwrench/'
14
+ abstract: Python library with tools for typing, manipulating collections, and more!
15
+ keywords:
16
+ - python
17
+ - tools
18
+ - utilities
19
+ license: MIT
20
+ version: 0.6.4
21
+ date-released: '2026-08-17'