winipedia-utils 0.6.7__tar.gz → 0.7.8__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 (136) hide show
  1. {winipedia_utils-0.6.7 → winipedia_utils-0.7.8}/PKG-INFO +28 -20
  2. {winipedia_utils-0.6.7 → winipedia_utils-0.7.8}/README.md +26 -19
  3. {winipedia_utils-0.6.7 → winipedia_utils-0.7.8}/pyproject.toml +17 -2
  4. winipedia_utils-0.7.8/winipedia_utils/dev/artifacts/build.py +6 -0
  5. winipedia_utils-0.6.7/winipedia_utils/artifacts/build.py → winipedia_utils-0.7.8/winipedia_utils/dev/artifacts/builder/base/base.py +34 -16
  6. winipedia_utils-0.7.8/winipedia_utils/dev/artifacts/builder/builder.py +17 -0
  7. winipedia_utils-0.6.7/winipedia_utils/text/config.py → winipedia_utils-0.7.8/winipedia_utils/dev/configs/base/base.py +68 -7
  8. winipedia_utils-0.7.8/winipedia_utils/dev/configs/builder.py +30 -0
  9. winipedia_utils-0.7.8/winipedia_utils/dev/configs/configs.py +34 -0
  10. winipedia_utils-0.6.7/winipedia_utils/git/gitignore/config.py → winipedia_utils-0.7.8/winipedia_utils/dev/configs/gitignore.py +2 -2
  11. winipedia_utils-0.6.7/winipedia_utils/git/pre_commit/config.py → winipedia_utils-0.7.8/winipedia_utils/dev/configs/pre_commit.py +4 -4
  12. winipedia_utils-0.6.7/winipedia_utils/projects/poetry/config.py → winipedia_utils-0.7.8/winipedia_utils/dev/configs/pyproject.py +37 -13
  13. winipedia_utils-0.6.7/winipedia_utils/testing/config.py → winipedia_utils-0.7.8/winipedia_utils/dev/configs/testing.py +7 -56
  14. {winipedia_utils-0.6.7/winipedia_utils/git/github → winipedia_utils-0.7.8/winipedia_utils/dev/configs}/workflows/base/base.py +31 -17
  15. {winipedia_utils-0.6.7/winipedia_utils/git/github → winipedia_utils-0.7.8/winipedia_utils/dev/configs}/workflows/health_check.py +1 -1
  16. {winipedia_utils-0.6.7/winipedia_utils/git/github → winipedia_utils-0.7.8/winipedia_utils/dev/configs}/workflows/publish.py +2 -2
  17. {winipedia_utils-0.6.7/winipedia_utils/git/github → winipedia_utils-0.7.8/winipedia_utils/dev/configs}/workflows/release.py +5 -2
  18. winipedia_utils-0.7.8/winipedia_utils/dev/git/__init__.py +1 -0
  19. winipedia_utils-0.7.8/winipedia_utils/dev/git/github/__init__.py +1 -0
  20. winipedia_utils-0.7.8/winipedia_utils/dev/git/github/repo/__init__.py +1 -0
  21. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/git/github/repo/protect.py +5 -5
  22. winipedia_utils-0.7.8/winipedia_utils/dev/git/pre_commit/__init__.py +1 -0
  23. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/git/pre_commit/hooks.py +3 -45
  24. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/git/pre_commit/run_hooks.py +5 -5
  25. winipedia_utils-0.7.8/winipedia_utils/dev/projects/__init__.py +1 -0
  26. winipedia_utils-0.7.8/winipedia_utils/dev/projects/poetry/__init__.py +1 -0
  27. winipedia_utils-0.7.8/winipedia_utils/dev/projects/poetry/dev_deps.py +21 -0
  28. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/projects/poetry/poetry.py +2 -2
  29. winipedia_utils-0.7.8/winipedia_utils/dev/projects/project.py +18 -0
  30. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/setup.py +9 -5
  31. winipedia_utils-0.7.8/winipedia_utils/dev/testing/__init__.py +1 -0
  32. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/convention.py +1 -1
  33. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/create_tests.py +14 -14
  34. winipedia_utils-0.7.8/winipedia_utils/dev/testing/tests/__init__.py +1 -0
  35. winipedia_utils-0.7.8/winipedia_utils/dev/testing/tests/base/__init__.py +1 -0
  36. winipedia_utils-0.7.8/winipedia_utils/dev/testing/tests/base/fixtures/__init__.py +1 -0
  37. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/base/fixtures/fixture.py +1 -1
  38. winipedia_utils-0.7.8/winipedia_utils/dev/testing/tests/base/fixtures/scopes/__init__.py +1 -0
  39. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/base/fixtures/scopes/class_.py +2 -2
  40. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/base/fixtures/scopes/module.py +2 -2
  41. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/base/fixtures/scopes/session.py +48 -10
  42. winipedia_utils-0.7.8/winipedia_utils/dev/testing/tests/base/utils/__init__.py +1 -0
  43. winipedia_utils-0.7.8/winipedia_utils/dev/testing/tests/base/utils/utils.py +1 -0
  44. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/conftest.py +2 -2
  45. {winipedia_utils-0.6.7/winipedia_utils/testing/tests/base/utils → winipedia_utils-0.7.8/winipedia_utils/dev/testing}/utils.py +7 -24
  46. winipedia_utils-0.7.8/winipedia_utils/utils/__init__.py +1 -0
  47. winipedia_utils-0.7.8/winipedia_utils/utils/data/__init__.py +1 -0
  48. winipedia_utils-0.7.8/winipedia_utils/utils/data/dataframe/__init__.py +1 -0
  49. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/data/dataframe/cleaning.py +1 -1
  50. winipedia_utils-0.7.8/winipedia_utils/utils/data/structures/__init__.py +1 -0
  51. winipedia_utils-0.7.8/winipedia_utils/utils/data/structures/text/__init__.py +1 -0
  52. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils/data/structures}/text/string.py +8 -5
  53. winipedia_utils-0.7.8/winipedia_utils/utils/git/__init__.py +1 -0
  54. winipedia_utils-0.7.8/winipedia_utils/utils/git/github/__init__.py +1 -0
  55. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/git/github/github.py +1 -1
  56. winipedia_utils-0.7.8/winipedia_utils/utils/git/github/repo/__init__.py +1 -0
  57. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/git/github/repo/repo.py +1 -1
  58. winipedia_utils-0.7.8/winipedia_utils/utils/git/gitignore/__init__.py +1 -0
  59. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/git/gitignore/gitignore.py +2 -2
  60. winipedia_utils-0.7.8/winipedia_utils/utils/iterating/__init__.py +1 -0
  61. winipedia_utils-0.7.8/winipedia_utils/utils/iterating/concurrent/__init__.py +1 -0
  62. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils/iterating}/concurrent/concurrent.py +4 -4
  63. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils/iterating}/concurrent/multiprocessing.py +2 -2
  64. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils/iterating}/concurrent/multithreading.py +1 -1
  65. winipedia_utils-0.7.8/winipedia_utils/utils/logging/__init__.py +1 -0
  66. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/logging/logger.py +1 -1
  67. winipedia_utils-0.7.8/winipedia_utils/utils/modules/__init__.py +1 -0
  68. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/modules/class_.py +5 -5
  69. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/modules/function.py +2 -2
  70. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/modules/module.py +30 -5
  71. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/modules/package.py +28 -10
  72. winipedia_utils-0.7.8/winipedia_utils/utils/oop/__init__.py +1 -0
  73. winipedia_utils-0.7.8/winipedia_utils/utils/oop/mixins/__init__.py +1 -0
  74. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/oop/mixins/meta.py +4 -4
  75. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/oop/mixins/mixin.py +2 -2
  76. winipedia_utils-0.7.8/winipedia_utils/utils/os/__init__.py +1 -0
  77. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/os/os.py +2 -2
  78. winipedia_utils-0.7.8/winipedia_utils/utils/resources/__init__.py +1 -0
  79. winipedia_utils-0.7.8/winipedia_utils/utils/resources/svgs/__init__.py +1 -0
  80. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/svg.py +1 -1
  81. winipedia_utils-0.7.8/winipedia_utils/utils/security/__init__.py +1 -0
  82. winipedia_utils-0.7.8/winipedia_utils/utils/testing/__init__.py +1 -0
  83. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/testing/assertions.py +18 -0
  84. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/testing/skip.py +1 -1
  85. winipedia_utils-0.6.7/winipedia_utils/concurrent/__init__.py +0 -1
  86. winipedia_utils-0.6.7/winipedia_utils/data/__init__.py +0 -1
  87. winipedia_utils-0.6.7/winipedia_utils/git/__init__.py +0 -1
  88. winipedia_utils-0.6.7/winipedia_utils/git/github/workflows/__init__.py +0 -1
  89. winipedia_utils-0.6.7/winipedia_utils/git/gitignore/__init__.py +0 -1
  90. winipedia_utils-0.6.7/winipedia_utils/git/pre_commit/__init__.py +0 -1
  91. winipedia_utils-0.6.7/winipedia_utils/iterating/__init__.py +0 -1
  92. winipedia_utils-0.6.7/winipedia_utils/logging/__init__.py +0 -1
  93. winipedia_utils-0.6.7/winipedia_utils/modules/__init__.py +0 -1
  94. winipedia_utils-0.6.7/winipedia_utils/oop/__init__.py +0 -1
  95. winipedia_utils-0.6.7/winipedia_utils/oop/mixins/__init__.py +0 -1
  96. winipedia_utils-0.6.7/winipedia_utils/os/__init__.py +0 -1
  97. winipedia_utils-0.6.7/winipedia_utils/projects/__init__.py +0 -1
  98. winipedia_utils-0.6.7/winipedia_utils/projects/poetry/__init__.py +0 -1
  99. winipedia_utils-0.6.7/winipedia_utils/projects/project.py +0 -16
  100. winipedia_utils-0.6.7/winipedia_utils/security/__init__.py +0 -1
  101. winipedia_utils-0.6.7/winipedia_utils/testing/__init__.py +0 -1
  102. winipedia_utils-0.6.7/winipedia_utils/testing/tests/__init__.py +0 -1
  103. winipedia_utils-0.6.7/winipedia_utils/testing/tests/base/__init__.py +0 -1
  104. winipedia_utils-0.6.7/winipedia_utils/testing/tests/base/fixtures/__init__.py +0 -1
  105. winipedia_utils-0.6.7/winipedia_utils/testing/tests/base/fixtures/scopes/__init__.py +0 -1
  106. winipedia_utils-0.6.7/winipedia_utils/testing/tests/base/utils/__init__.py +0 -1
  107. winipedia_utils-0.6.7/winipedia_utils/text/__init__.py +0 -1
  108. {winipedia_utils-0.6.7 → winipedia_utils-0.7.8}/LICENSE +0 -0
  109. {winipedia_utils-0.6.7 → winipedia_utils-0.7.8}/winipedia_utils/__init__.py +0 -0
  110. {winipedia_utils-0.6.7/winipedia_utils/artifacts → winipedia_utils-0.7.8/winipedia_utils/dev}/__init__.py +0 -0
  111. {winipedia_utils-0.6.7/winipedia_utils/data/dataframe → winipedia_utils-0.7.8/winipedia_utils/dev/artifacts}/__init__.py +0 -0
  112. {winipedia_utils-0.6.7/winipedia_utils/data/structures → winipedia_utils-0.7.8/winipedia_utils/dev/artifacts/builder}/__init__.py +0 -0
  113. {winipedia_utils-0.6.7/winipedia_utils/git/github → winipedia_utils-0.7.8/winipedia_utils/dev/artifacts/builder/base}/__init__.py +0 -0
  114. {winipedia_utils-0.6.7/winipedia_utils/git/github/repo → winipedia_utils-0.7.8/winipedia_utils/dev/configs}/__init__.py +0 -0
  115. {winipedia_utils-0.6.7/winipedia_utils/git/github/workflows → winipedia_utils-0.7.8/winipedia_utils/dev/configs}/base/__init__.py +0 -0
  116. {winipedia_utils-0.6.7/winipedia_utils/resources → winipedia_utils-0.7.8/winipedia_utils/dev/configs/workflows}/__init__.py +0 -0
  117. {winipedia_utils-0.6.7/winipedia_utils/resources/svgs → winipedia_utils-0.7.8/winipedia_utils/dev/configs/workflows/base}/__init__.py +0 -0
  118. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/base/fixtures/scopes/function.py +0 -0
  119. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/dev}/testing/tests/base/fixtures/scopes/package.py +0 -0
  120. {winipedia_utils-0.6.7 → winipedia_utils-0.7.8}/winipedia_utils/py.typed +0 -0
  121. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/data/structures/dicts.py +0 -0
  122. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/iterating/iterate.py +0 -0
  123. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/logging/ansi.py +0 -0
  124. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/logging/config.py +0 -0
  125. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/modules/inspection.py +0 -0
  126. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/delete_garbage_can.svg +0 -0
  127. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/download_arrow.svg +0 -0
  128. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/exit_fullscreen_icon.svg +0 -0
  129. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/fullscreen_icon.svg +0 -0
  130. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/menu_icon.svg +0 -0
  131. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/pause_icon.svg +0 -0
  132. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/play_icon.svg +0 -0
  133. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/resources/svgs/plus_icon.svg +0 -0
  134. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/security/cryptography.py +0 -0
  135. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/security/keyring.py +0 -0
  136. {winipedia_utils-0.6.7/winipedia_utils → winipedia_utils-0.7.8/winipedia_utils/utils}/testing/fixtures.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: winipedia-utils
3
- Version: 0.6.7
3
+ Version: 0.7.8
4
4
  Summary: A package with many utility functions
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -16,6 +16,7 @@ Requires-Dist: defusedxml
16
16
  Requires-Dist: dotenv
17
17
  Requires-Dist: keyring
18
18
  Requires-Dist: networkx
19
+ Requires-Dist: packaging
19
20
  Requires-Dist: pathspec
20
21
  Requires-Dist: polars
21
22
  Requires-Dist: pygithub
@@ -86,10 +87,11 @@ poetry init # or poetry new
86
87
  poetry add winipedia-utils
87
88
 
88
89
  # 6: Run the automated setup
89
- poetry run python -m winipedia_utils.setup
90
+ poetry run python -m winipedia_utils.dev.setup
90
91
  ```
91
92
 
92
93
  The setup script will automatically configure your project with all necessary files and standards.
94
+ If you wish to use winipedia_utils without its dev framework then just skip the setup step and you can access the utils via `winipedia_utils.utils`
93
95
 
94
96
  ## Setup Process
95
97
 
@@ -126,8 +128,14 @@ The health check and release workflows test your code across:
126
128
 
127
129
  This matrix strategy ensures your code works reliably across different environments before merging or releasing.
128
130
 
131
+ #### Configuration File Structure
132
+ Config Files are autogenerated via ConfigFile non-abstract subclasses.
133
+ All nonabstract subclasses of ConfigFile are automatically created and managed when you commit or run pytest. winipedia_utils automatically discovers the pkg your_pkg.dev.configs and calls them. This way you can adjust or add some settings by subclassing. It is however important the parent class stays a subset of the child class according to the description in the function `nested_structure_is_subset` in `winipedia_utils.iterating.iterate` bc parents are still initialized and the order is not guaranteed.
134
+
129
135
  #### Workflow Structure
130
136
 
137
+ Worklfows are a type of ConfigFile.
138
+
131
139
  The health check workflow consists of two jobs:
132
140
 
133
141
  1. **Matrix Job** (`health_check_matrix`) - Runs all checks in parallel across the matrix of OS and Python versions:
@@ -145,7 +153,7 @@ The health check workflow consists of two jobs:
145
153
  - Provides a single status check that can be marked as required in branch protection rules
146
154
 
147
155
  The release workflow extends the health check workflow and adds a release job that runs after all health checks pass.
148
- A build job is added before the release job if a script src/artifacts/build.py exists. This script is created by the setup command and can be modified to create build artifacts for your project. This script then just needs to create artifacts in a folder called artifacts and those will be uploaded as artifacts to the release.
156
+ A build job is added before the release job if a src/dev/artifacts/builder exists with Builder subclasses. This script is created by the setup command and can be modified to create build artifacts for your project. Winipedia Utils automatically discovers all subclasses of Builder (dev.artifacts.builder.base.base) and calls them if the artifacts folder contains any files.
149
157
 
150
158
  ### Pre-commit Hook Workflow
151
159
 
@@ -162,7 +170,7 @@ Hooks run in the following order:
162
170
  - Update packages (poetry update --with dev (winipedia_utils forces all dependencies with * to be updated to latest compatible version))
163
171
  - Lock dependencies (poetry lock)
164
172
  - Check package manager configs (poetry check --strict)
165
- - Create tests (python -m winipedia_utils.testing.create_tests)
173
+ - Create tests (python -m winipedia_utils.dev.testing.create_tests)
166
174
  - Lint code (ruff check --fix)
167
175
  - Format code (ruff format)
168
176
  - Check static types (mypy)
@@ -203,7 +211,7 @@ Configuration files are managed automatically by the setup system:
203
211
 
204
212
  ## Branch Protection
205
213
 
206
- As soon as you push to `main` on GitHub (provided the `REPO_TOKEN` secret is set up correctly), the `health_check.yaml` workflow will run and execute `winipedia_utils.git.github.repo.protect`, which uses PyGithub to protect the repository.
214
+ As soon as you push to `main` on GitHub (provided the `REPO_TOKEN` secret is set up correctly), the `health_check.yaml` workflow will run and execute `winipedia_utils.dev.git.github.repo.protect`, which uses PyGithub to protect the repository.
207
215
 
208
216
  ### Repository Settings
209
217
 
@@ -249,8 +257,8 @@ Winipedia Utils provides comprehensive utility modules for common development ta
249
257
  Unified interface for multiprocessing and multithreading:
250
258
 
251
259
  ```python
252
- from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
253
- from winipedia_utils.concurrent.multithreading import multithread_loop
260
+ from winipedia_utils.utils.iterating.concurrent.multiprocessing import multiprocess_loop
261
+ from winipedia_utils.utils.iterating.concurrent.multithreading import multithread_loop
254
262
  ```
255
263
 
256
264
  ### Data Cleaning & Handling
@@ -258,7 +266,7 @@ from winipedia_utils.concurrent.multithreading import multithread_loop
258
266
  Build data cleaning pipelines using Polars:
259
267
 
260
268
  ```python
261
- from winipedia_utils.data.dataframe.cleaning import CleaningDF
269
+ from winipedia_utils.utils.data.dataframe.cleaning import CleaningDF
262
270
  import polars as pl
263
271
  ```
264
272
 
@@ -267,7 +275,7 @@ import polars as pl
267
275
  Simple, standardized logging setup with automatic method instrumentation:
268
276
 
269
277
  ```python
270
- from winipedia_utils.logging.logger import get_logger
278
+ from winipedia_utils.utils.logging.logger import get_logger
271
279
 
272
280
  logger = get_logger(__name__)
273
281
  logger.info("Application started")
@@ -285,7 +293,7 @@ logger.error("An error occurred")
285
293
  Advanced metaclasses and mixins for class composition and behavior extension:
286
294
 
287
295
  ```python
288
- from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
296
+ from winipedia_utils.utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
289
297
  ```
290
298
 
291
299
  ### Security Utilities
@@ -293,7 +301,7 @@ from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMi
293
301
  Encryption and secure credential storage using keyring:
294
302
 
295
303
  ```python
296
- from winipedia_utils.security.keyring import (
304
+ from winipedia_utils.utils.security.keyring import (
297
305
  get_or_create_fernet,
298
306
  get_or_create_aes_gcm
299
307
  )
@@ -304,8 +312,8 @@ from winipedia_utils.security.keyring import (
304
312
  Comprehensive testing framework with automatic test generation:
305
313
 
306
314
  ```python
307
- from winipedia_utils.testing.assertions import assert_with_msg
308
- from winipedia_utils.testing.convention import (
315
+ from winipedia_utils.utils.testing.assertions import assert_with_msg
316
+ from winipedia_utils.dev.testing.convention import (
309
317
  make_test_obj_name,
310
318
  get_test_obj_from_obj,
311
319
  make_test_obj_importpath_from_obj
@@ -335,10 +343,10 @@ test_path = make_test_obj_importpath_from_obj(my_function)
335
343
  Tools for working with Python modules, packages, classes, and functions:
336
344
 
337
345
  ```python
338
- from winipedia_utils.modules.package import find_packages, walk_package
339
- from winipedia_utils.modules.module import create_module, import_obj_from_importpath
340
- from winipedia_utils.modules.class_ import get_all_cls_from_module, get_all_methods_from_cls
341
- from winipedia_utils.modules.function import get_all_functions_from_module
346
+ from winipedia_utils.utils.modules.package import find_packages, walk_package
347
+ from winipedia_utils.utils.modules.module import create_module, import_obj_from_importpath
348
+ from winipedia_utils.utils.modules.class_ import get_all_cls_from_module, get_all_methods_from_cls
349
+ from winipedia_utils.utils.modules.function import get_all_functions_from_module
342
350
  ```
343
351
 
344
352
  ### Text and String Utilities
@@ -346,7 +354,7 @@ from winipedia_utils.modules.function import get_all_functions_from_module
346
354
  String manipulation and configuration file handling:
347
355
 
348
356
  ```python
349
- from winipedia_utils.text.string import value_to_truncated_string
357
+ from winipedia_utils.utils.data.structures.text.string import value_to_truncated_string
350
358
  ```
351
359
 
352
360
  ### OS and System Utilities
@@ -354,7 +362,7 @@ from winipedia_utils.text.string import value_to_truncated_string
354
362
  Operating system and subprocess utilities:
355
363
 
356
364
  ```python
357
- from winipedia_utils.os.os import run_subprocess
365
+ from winipedia_utils.utils.os.os import run_subprocess
358
366
  ```
359
367
 
360
368
  ### Iteration Utilities
@@ -362,7 +370,7 @@ from winipedia_utils.os.os import run_subprocess
362
370
  Utilities for working with iterables and nested structures:
363
371
 
364
372
  ```python
365
- from winipedia_utils.iterating.iterate import get_len_with_default, nested_structure_is_subset
373
+ from winipedia_utils.utils.iterating.iterate import get_len_with_default, nested_structure_is_subset
366
374
  ```
367
375
 
368
376
  ### Philosophy
@@ -59,10 +59,11 @@ poetry init # or poetry new
59
59
  poetry add winipedia-utils
60
60
 
61
61
  # 6: Run the automated setup
62
- poetry run python -m winipedia_utils.setup
62
+ poetry run python -m winipedia_utils.dev.setup
63
63
  ```
64
64
 
65
65
  The setup script will automatically configure your project with all necessary files and standards.
66
+ If you wish to use winipedia_utils without its dev framework then just skip the setup step and you can access the utils via `winipedia_utils.utils`
66
67
 
67
68
  ## Setup Process
68
69
 
@@ -99,8 +100,14 @@ The health check and release workflows test your code across:
99
100
 
100
101
  This matrix strategy ensures your code works reliably across different environments before merging or releasing.
101
102
 
103
+ #### Configuration File Structure
104
+ Config Files are autogenerated via ConfigFile non-abstract subclasses.
105
+ All nonabstract subclasses of ConfigFile are automatically created and managed when you commit or run pytest. winipedia_utils automatically discovers the pkg your_pkg.dev.configs and calls them. This way you can adjust or add some settings by subclassing. It is however important the parent class stays a subset of the child class according to the description in the function `nested_structure_is_subset` in `winipedia_utils.iterating.iterate` bc parents are still initialized and the order is not guaranteed.
106
+
102
107
  #### Workflow Structure
103
108
 
109
+ Worklfows are a type of ConfigFile.
110
+
104
111
  The health check workflow consists of two jobs:
105
112
 
106
113
  1. **Matrix Job** (`health_check_matrix`) - Runs all checks in parallel across the matrix of OS and Python versions:
@@ -118,7 +125,7 @@ The health check workflow consists of two jobs:
118
125
  - Provides a single status check that can be marked as required in branch protection rules
119
126
 
120
127
  The release workflow extends the health check workflow and adds a release job that runs after all health checks pass.
121
- A build job is added before the release job if a script src/artifacts/build.py exists. This script is created by the setup command and can be modified to create build artifacts for your project. This script then just needs to create artifacts in a folder called artifacts and those will be uploaded as artifacts to the release.
128
+ A build job is added before the release job if a src/dev/artifacts/builder exists with Builder subclasses. This script is created by the setup command and can be modified to create build artifacts for your project. Winipedia Utils automatically discovers all subclasses of Builder (dev.artifacts.builder.base.base) and calls them if the artifacts folder contains any files.
122
129
 
123
130
  ### Pre-commit Hook Workflow
124
131
 
@@ -135,7 +142,7 @@ Hooks run in the following order:
135
142
  - Update packages (poetry update --with dev (winipedia_utils forces all dependencies with * to be updated to latest compatible version))
136
143
  - Lock dependencies (poetry lock)
137
144
  - Check package manager configs (poetry check --strict)
138
- - Create tests (python -m winipedia_utils.testing.create_tests)
145
+ - Create tests (python -m winipedia_utils.dev.testing.create_tests)
139
146
  - Lint code (ruff check --fix)
140
147
  - Format code (ruff format)
141
148
  - Check static types (mypy)
@@ -176,7 +183,7 @@ Configuration files are managed automatically by the setup system:
176
183
 
177
184
  ## Branch Protection
178
185
 
179
- As soon as you push to `main` on GitHub (provided the `REPO_TOKEN` secret is set up correctly), the `health_check.yaml` workflow will run and execute `winipedia_utils.git.github.repo.protect`, which uses PyGithub to protect the repository.
186
+ As soon as you push to `main` on GitHub (provided the `REPO_TOKEN` secret is set up correctly), the `health_check.yaml` workflow will run and execute `winipedia_utils.dev.git.github.repo.protect`, which uses PyGithub to protect the repository.
180
187
 
181
188
  ### Repository Settings
182
189
 
@@ -222,8 +229,8 @@ Winipedia Utils provides comprehensive utility modules for common development ta
222
229
  Unified interface for multiprocessing and multithreading:
223
230
 
224
231
  ```python
225
- from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
226
- from winipedia_utils.concurrent.multithreading import multithread_loop
232
+ from winipedia_utils.utils.iterating.concurrent.multiprocessing import multiprocess_loop
233
+ from winipedia_utils.utils.iterating.concurrent.multithreading import multithread_loop
227
234
  ```
228
235
 
229
236
  ### Data Cleaning & Handling
@@ -231,7 +238,7 @@ from winipedia_utils.concurrent.multithreading import multithread_loop
231
238
  Build data cleaning pipelines using Polars:
232
239
 
233
240
  ```python
234
- from winipedia_utils.data.dataframe.cleaning import CleaningDF
241
+ from winipedia_utils.utils.data.dataframe.cleaning import CleaningDF
235
242
  import polars as pl
236
243
  ```
237
244
 
@@ -240,7 +247,7 @@ import polars as pl
240
247
  Simple, standardized logging setup with automatic method instrumentation:
241
248
 
242
249
  ```python
243
- from winipedia_utils.logging.logger import get_logger
250
+ from winipedia_utils.utils.logging.logger import get_logger
244
251
 
245
252
  logger = get_logger(__name__)
246
253
  logger.info("Application started")
@@ -258,7 +265,7 @@ logger.error("An error occurred")
258
265
  Advanced metaclasses and mixins for class composition and behavior extension:
259
266
 
260
267
  ```python
261
- from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
268
+ from winipedia_utils.utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
262
269
  ```
263
270
 
264
271
  ### Security Utilities
@@ -266,7 +273,7 @@ from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMi
266
273
  Encryption and secure credential storage using keyring:
267
274
 
268
275
  ```python
269
- from winipedia_utils.security.keyring import (
276
+ from winipedia_utils.utils.security.keyring import (
270
277
  get_or_create_fernet,
271
278
  get_or_create_aes_gcm
272
279
  )
@@ -277,8 +284,8 @@ from winipedia_utils.security.keyring import (
277
284
  Comprehensive testing framework with automatic test generation:
278
285
 
279
286
  ```python
280
- from winipedia_utils.testing.assertions import assert_with_msg
281
- from winipedia_utils.testing.convention import (
287
+ from winipedia_utils.utils.testing.assertions import assert_with_msg
288
+ from winipedia_utils.dev.testing.convention import (
282
289
  make_test_obj_name,
283
290
  get_test_obj_from_obj,
284
291
  make_test_obj_importpath_from_obj
@@ -308,10 +315,10 @@ test_path = make_test_obj_importpath_from_obj(my_function)
308
315
  Tools for working with Python modules, packages, classes, and functions:
309
316
 
310
317
  ```python
311
- from winipedia_utils.modules.package import find_packages, walk_package
312
- from winipedia_utils.modules.module import create_module, import_obj_from_importpath
313
- from winipedia_utils.modules.class_ import get_all_cls_from_module, get_all_methods_from_cls
314
- from winipedia_utils.modules.function import get_all_functions_from_module
318
+ from winipedia_utils.utils.modules.package import find_packages, walk_package
319
+ from winipedia_utils.utils.modules.module import create_module, import_obj_from_importpath
320
+ from winipedia_utils.utils.modules.class_ import get_all_cls_from_module, get_all_methods_from_cls
321
+ from winipedia_utils.utils.modules.function import get_all_functions_from_module
315
322
  ```
316
323
 
317
324
  ### Text and String Utilities
@@ -319,7 +326,7 @@ from winipedia_utils.modules.function import get_all_functions_from_module
319
326
  String manipulation and configuration file handling:
320
327
 
321
328
  ```python
322
- from winipedia_utils.text.string import value_to_truncated_string
329
+ from winipedia_utils.utils.data.structures.text.string import value_to_truncated_string
323
330
  ```
324
331
 
325
332
  ### OS and System Utilities
@@ -327,7 +334,7 @@ from winipedia_utils.text.string import value_to_truncated_string
327
334
  Operating system and subprocess utilities:
328
335
 
329
336
  ```python
330
- from winipedia_utils.os.os import run_subprocess
337
+ from winipedia_utils.utils.os.os import run_subprocess
331
338
  ```
332
339
 
333
340
  ### Iteration Utilities
@@ -335,7 +342,7 @@ from winipedia_utils.os.os import run_subprocess
335
342
  Utilities for working with iterables and nested structures:
336
343
 
337
344
  ```python
338
- from winipedia_utils.iterating.iterate import get_len_with_default, nested_structure_is_subset
345
+ from winipedia_utils.utils.iterating.iterate import get_len_with_default, nested_structure_is_subset
339
346
  ```
340
347
 
341
348
  ### Philosophy
@@ -1,7 +1,7 @@
1
1
  # Project section
2
2
  [project]
3
3
  name = "winipedia-utils"
4
- version = "0.6.7"
4
+ version = "0.7.8"
5
5
  description = "A package with many utility functions"
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.12"
@@ -9,7 +9,7 @@ authors = [
9
9
  { name = "Winipedia", email = "win.steveker@gmx.de"}
10
10
  ]
11
11
  license = "MIT"
12
- dependencies = ["polars", "pyyaml", "keyring", "pygithub", "pathspec", "networkx", "setuptools", "tqdm", "defusedxml", "cryptography", "tomlkit", "dotenv"]
12
+ dynamic = ["dependencies"]
13
13
 
14
14
  # Build system section[build-system]
15
15
  [build-system]
@@ -20,6 +20,21 @@ build-backend = "poetry.core.masonry.api"
20
20
  [[tool.poetry.packages]]
21
21
  include = "winipedia_utils"
22
22
 
23
+ [tool.poetry.dependencies]
24
+ networkx = "*"
25
+ setuptools = "*"
26
+ pyyaml = "*"
27
+ packaging = "*"
28
+ polars = "*"
29
+ tomlkit = "*"
30
+ cryptography = "*"
31
+ tqdm = "*"
32
+ pygithub = "*"
33
+ dotenv = "*"
34
+ pathspec = "*"
35
+ defusedxml = "*"
36
+ keyring = "*"
37
+
23
38
  [tool.poetry.group.dev.dependencies]
24
39
  ruff = "*"
25
40
  pre-commit = "*"
@@ -0,0 +1,6 @@
1
+ """Build artifacts for the project."""
2
+
3
+ from winipedia_utils.dev.artifacts.builder.base.base import Builder
4
+
5
+ if __name__ == "__main__":
6
+ Builder.init_all_non_abstract_subclasses()
@@ -8,13 +8,18 @@ distribution of project code.
8
8
 
9
9
  import platform
10
10
  from abc import abstractmethod
11
+ from importlib import import_module
11
12
  from pathlib import Path
12
13
 
13
- from winipedia_utils.git.github.workflows.base.base import Workflow
14
- from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin
14
+ from winipedia_utils.dev.configs.builder import BuilderConfigFile
15
+ from winipedia_utils.utils.modules.class_ import (
16
+ get_all_nonabstract_subclasses,
17
+ )
18
+ from winipedia_utils.utils.modules.module import to_module_name, to_path
19
+ from winipedia_utils.utils.oop.mixins.mixin import ABCLoggingMixin
15
20
 
16
21
 
17
- class Build(ABCLoggingMixin):
22
+ class Builder(ABCLoggingMixin):
18
23
  """Base class for build scripts.
19
24
 
20
25
  Subclass this class and implement the get_artifacts method to create
@@ -24,15 +29,18 @@ class Build(ABCLoggingMixin):
24
29
  YourBuildClass()
25
30
  """
26
31
 
27
- ARTIFACTS_PATH = Workflow.ARTIFACTS_PATH
32
+ ARTIFACTS_DIR_NAME = "artifacts"
33
+ ARTIFACTS_PATH = Path(ARTIFACTS_DIR_NAME)
28
34
 
29
35
  @classmethod
30
36
  @abstractmethod
31
- def get_artifacts(cls) -> list[Path]:
37
+ def create_artifacts(cls) -> None:
32
38
  """Build the project.
33
39
 
40
+ This method should create all artifacts in the ARTIFACTS_PATH folder.
41
+
34
42
  Returns:
35
- list[Path]: List of paths to the built artifacts
43
+ None
36
44
  """
37
45
 
38
46
  @classmethod
@@ -49,6 +57,7 @@ class Build(ABCLoggingMixin):
49
57
  and puts them in the artifacts folder.
50
58
  """
51
59
  cls.ARTIFACTS_PATH.mkdir(parents=True, exist_ok=True)
60
+ cls.create_artifacts()
52
61
  artifacts = cls.get_artifacts()
53
62
  for artifact in artifacts:
54
63
  parent = artifact.parent
@@ -61,18 +70,27 @@ class Build(ABCLoggingMixin):
61
70
  new_path = cls.ARTIFACTS_PATH / new_name
62
71
  artifact.rename(new_path)
63
72
 
64
-
65
- class WinipediaUtilsBuild(Build):
66
- """Build script for winipedia_utils."""
67
-
68
73
  @classmethod
69
74
  def get_artifacts(cls) -> list[Path]:
70
- """Build the project."""
71
- paths = [cls.ARTIFACTS_PATH / "build.txt"]
72
- for path in paths:
73
- path.write_text("Hello World!")
75
+ """Get the built artifacts."""
76
+ paths = list(cls.ARTIFACTS_PATH.glob("*"))
77
+ if not paths:
78
+ msg = f"Expected {cls.ARTIFACTS_PATH} to contain files"
79
+ raise FileNotFoundError(msg)
74
80
  return paths
75
81
 
82
+ @classmethod
83
+ def get_non_abstract_subclasses(cls) -> set[type["Builder"]]:
84
+ """Get all non-abstract subclasses of Builder."""
85
+ path = BuilderConfigFile.get_parent_path()
86
+ module_name = to_module_name(path)
87
+ if not to_path(module_name, is_package=True).exists():
88
+ return set()
89
+ builds_pkg = import_module(module_name)
90
+ return get_all_nonabstract_subclasses(cls, load_package_before=builds_pkg)
76
91
 
77
- if __name__ == "__main__":
78
- WinipediaUtilsBuild()
92
+ @classmethod
93
+ def init_all_non_abstract_subclasses(cls) -> None:
94
+ """Build all artifacts."""
95
+ for builder in cls.get_non_abstract_subclasses():
96
+ builder()
@@ -0,0 +1,17 @@
1
+ """Build script.
2
+
3
+ All subclasses of Builder in the builds package are automatically called.
4
+ """
5
+
6
+ from winipedia_utils.dev.artifacts.builder.base.base import Builder
7
+
8
+
9
+ class WinipediaUtilsBuilder(Builder):
10
+ """Build script for winipedia_utils."""
11
+
12
+ @classmethod
13
+ def create_artifacts(cls) -> None:
14
+ """Build the project."""
15
+ paths = [cls.ARTIFACTS_PATH / "build.txt"]
16
+ for path in paths:
17
+ path.write_text("Hello World!")
@@ -3,19 +3,23 @@
3
3
  import inspect
4
4
  from abc import ABC, abstractmethod
5
5
  from pathlib import Path
6
+ from types import ModuleType
6
7
  from typing import Any
7
8
 
8
9
  import tomlkit
9
10
  import yaml
10
11
  from dotenv import dotenv_values
11
12
 
12
- from winipedia_utils.iterating.iterate import nested_structure_is_subset
13
- from winipedia_utils.modules.class_ import init_all_nonabstract_subclasses
14
- from winipedia_utils.modules.package import DependencyGraph, get_src_package
15
- from winipedia_utils.projects.poetry.poetry import (
13
+ import winipedia_utils
14
+ from winipedia_utils.dev import configs
15
+ from winipedia_utils.dev.projects.poetry.poetry import (
16
16
  get_poetry_run_module_script,
17
17
  )
18
- from winipedia_utils.text.string import split_on_uppercase
18
+ from winipedia_utils.utils.data.structures.text.string import split_on_uppercase
19
+ from winipedia_utils.utils.iterating.iterate import nested_structure_is_subset
20
+ from winipedia_utils.utils.modules.class_ import init_all_nonabstract_subclasses
21
+ from winipedia_utils.utils.modules.module import import_module_with_default
22
+ from winipedia_utils.utils.modules.package import DependencyGraph, get_src_package
19
23
 
20
24
 
21
25
  class ConfigFile(ABC):
@@ -153,14 +157,21 @@ class ConfigFile(ABC):
153
157
  include_winipedia_utils=True
154
158
  )
155
159
  )
160
+
156
161
  pkgs_depending_on_winipedia_utils.add(get_src_package())
157
162
  for pkg in pkgs_depending_on_winipedia_utils:
158
- init_all_nonabstract_subclasses(cls, load_package_before=pkg)
163
+ configs_pkg_name = configs.__name__.replace(
164
+ winipedia_utils.__name__, pkg.__name__, 1
165
+ )
166
+ configs_pkg = import_module_with_default(configs_pkg_name)
167
+ if not isinstance(configs_pkg, ModuleType):
168
+ continue
169
+ init_all_nonabstract_subclasses(cls, load_package_before=configs_pkg)
159
170
 
160
171
  @staticmethod
161
172
  def get_poetry_run_setup_script() -> str:
162
173
  """Get the poetry run setup script."""
163
- from winipedia_utils import setup # noqa: PLC0415 # avoid circular import
174
+ from winipedia_utils.dev import setup # noqa: PLC0415 # avoid circular import
164
175
 
165
176
  return get_poetry_run_module_script(setup)
166
177
 
@@ -248,3 +259,53 @@ class DotEnvConfigFile(ConfigFile):
248
259
  def is_correct(cls) -> bool:
249
260
  """Check if the config is correct."""
250
261
  return super().is_correct() or cls.get_path().exists()
262
+
263
+
264
+ class PythonConfigFile(ConfigFile):
265
+ """Base class for python config files."""
266
+
267
+ CONTENT_KEY = "content"
268
+
269
+ @classmethod
270
+ @abstractmethod
271
+ def get_content_str(cls) -> str:
272
+ """Get the content."""
273
+
274
+ @classmethod
275
+ def load(cls) -> dict[str, str]:
276
+ """Load the config file."""
277
+ return {cls.CONTENT_KEY: cls.get_path().read_text()}
278
+
279
+ @classmethod
280
+ def dump(cls, config: dict[str, Any] | list[Any]) -> None:
281
+ """Dump the config file."""
282
+ if not isinstance(config, dict):
283
+ msg = f"Cannot dump {config} to python file."
284
+ raise TypeError(msg)
285
+ cls.get_path().write_text(config[cls.CONTENT_KEY])
286
+
287
+ @classmethod
288
+ def get_file_extension(cls) -> str:
289
+ """Get the file extension of the config file."""
290
+ return "py"
291
+
292
+ @classmethod
293
+ def get_configs(cls) -> dict[str, Any]:
294
+ """Get the config."""
295
+ return {cls.CONTENT_KEY: cls.get_content_str()}
296
+
297
+ @classmethod
298
+ def get_file_content(cls) -> str:
299
+ """Get the file content."""
300
+ return cls.load()[cls.CONTENT_KEY]
301
+
302
+ @classmethod
303
+ def is_correct(cls) -> bool:
304
+ """Check if the config is correct.
305
+
306
+ Python files are correct if they exist and contain the correct content.
307
+ """
308
+ return (
309
+ super().is_correct()
310
+ or cls.get_content_str().strip() in cls.load()[cls.CONTENT_KEY]
311
+ )
@@ -0,0 +1,30 @@
1
+ """Config File subclass that creates the builds dir and a build.py."""
2
+
3
+ from pathlib import Path
4
+
5
+ import winipedia_utils
6
+ from winipedia_utils.dev.artifacts import builder
7
+ from winipedia_utils.dev.configs.base.base import PythonConfigFile
8
+ from winipedia_utils.dev.configs.pyproject import PyprojectConfigFile
9
+ from winipedia_utils.utils.modules.module import to_path
10
+
11
+
12
+ class BuilderConfigFile(PythonConfigFile):
13
+ """Config File subclass that creates the dirs folder."""
14
+
15
+ @classmethod
16
+ def get_parent_path(cls) -> Path:
17
+ """Get the path to the config file."""
18
+ src_package = PyprojectConfigFile.get_package_name()
19
+ builds_package = builder.__name__.replace(
20
+ winipedia_utils.__name__, src_package, 1
21
+ )
22
+ return to_path(builds_package, is_package=True)
23
+
24
+ @classmethod
25
+ def get_content_str(cls) -> str:
26
+ """Get the content."""
27
+ return '''"""Build script.
28
+
29
+ All subclasses of Builder in the builds package are automatically called.
30
+ """'''
@@ -0,0 +1,34 @@
1
+ """Configs for winipedia_utils.
2
+
3
+ All subclasses of ConfigFile in the configs package are automatically called.
4
+ """
5
+
6
+ from pathlib import Path
7
+
8
+ import winipedia_utils
9
+ from winipedia_utils.dev import configs
10
+ from winipedia_utils.dev.configs.base.base import PythonConfigFile
11
+ from winipedia_utils.dev.configs.pyproject import PyprojectConfigFile
12
+ from winipedia_utils.utils.modules.module import to_path
13
+
14
+
15
+ class ConfigsConfigFile(PythonConfigFile):
16
+ """Config file for configs.py."""
17
+
18
+ @classmethod
19
+ def get_parent_path(cls) -> Path:
20
+ """Get the path to the config file."""
21
+ src_package = PyprojectConfigFile.get_package_name()
22
+ builds_package = configs.__name__.replace(
23
+ winipedia_utils.__name__, src_package, 1
24
+ )
25
+ return to_path(builds_package, is_package=True)
26
+
27
+ @classmethod
28
+ def get_content_str(cls) -> str:
29
+ """Get the content."""
30
+ return '''"""Configs for winipedia_utils.
31
+
32
+ All subclasses of ConfigFile in the configs package are automatically called.
33
+ """
34
+ '''
@@ -5,8 +5,8 @@ from typing import Any
5
5
 
6
6
  import requests
7
7
 
8
- from winipedia_utils.testing.config import ExperimentConfigFile
9
- from winipedia_utils.text.config import ConfigFile, DotEnvConfigFile
8
+ from winipedia_utils.dev.configs.base.base import ConfigFile, DotEnvConfigFile
9
+ from winipedia_utils.dev.configs.testing import ExperimentConfigFile
10
10
 
11
11
 
12
12
  class GitIgnoreConfigFile(ConfigFile):