winipedia-utils 0.2.63__tar.gz → 0.3.7__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.
Potentially problematic release.
This version of winipedia-utils might be problematic. Click here for more details.
- winipedia_utils-0.3.7/PKG-INFO +324 -0
- winipedia_utils-0.3.7/README.md +299 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/pyproject.toml +20 -20
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/concurrent/concurrent.py +7 -2
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/concurrent/multiprocessing.py +1 -2
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/concurrent/multithreading.py +2 -2
- winipedia_utils-0.3.7/winipedia_utils/git/gitignore/config.py +54 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/gitignore/gitignore.py +5 -63
- winipedia_utils-0.3.7/winipedia_utils/git/pre_commit/config.py +57 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/pre_commit/hooks.py +13 -13
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/pre_commit/run_hooks.py +2 -2
- winipedia_utils-0.3.7/winipedia_utils/git/workflows/base/base.py +127 -0
- winipedia_utils-0.3.7/winipedia_utils/git/workflows/publish.py +55 -0
- winipedia_utils-0.3.7/winipedia_utils/git/workflows/release.py +65 -0
- winipedia_utils-0.3.7/winipedia_utils/iterating/iterate.py +87 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/modules/class_.py +60 -10
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/modules/function.py +18 -1
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/modules/package.py +16 -7
- winipedia_utils-0.3.7/winipedia_utils/projects/poetry/config.py +129 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/projects/poetry/poetry.py +1 -8
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/projects/project.py +7 -13
- winipedia_utils-0.3.7/winipedia_utils/setup.py +41 -0
- winipedia_utils-0.3.7/winipedia_utils/testing/config.py +95 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/create_tests.py +4 -18
- winipedia_utils-0.3.7/winipedia_utils/testing/skip.py +10 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +3 -3
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/scopes/module.py +6 -4
- winipedia_utils-0.3.7/winipedia_utils/testing/tests/base/fixtures/scopes/session.py +182 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/utils/utils.py +11 -55
- winipedia_utils-0.3.7/winipedia_utils/text/config.py +143 -0
- winipedia_utils-0.2.63/PKG-INFO +0 -738
- winipedia_utils-0.2.63/README.md +0 -713
- winipedia_utils-0.2.63/winipedia_utils/consts.py +0 -21
- winipedia_utils-0.2.63/winipedia_utils/git/pre_commit/config.py +0 -70
- winipedia_utils-0.2.63/winipedia_utils/git/workflows/base/base.py +0 -77
- winipedia_utils-0.2.63/winipedia_utils/git/workflows/publish.py +0 -79
- winipedia_utils-0.2.63/winipedia_utils/git/workflows/release.py +0 -91
- winipedia_utils-0.2.63/winipedia_utils/iterating/iterate.py +0 -29
- winipedia_utils-0.2.63/winipedia_utils/projects/poetry/config.py +0 -117
- winipedia_utils-0.2.63/winipedia_utils/setup.py +0 -59
- winipedia_utils-0.2.63/winipedia_utils/testing/tests/base/fixtures/scopes/session.py +0 -330
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/LICENSE +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/concurrent/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/data/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/data/dataframe/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/data/dataframe/cleaning.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/data/structures/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/data/structures/dicts.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/gitignore/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/pre_commit/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/workflows/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/git/workflows/base/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/iterating/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/logging/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/logging/ansi.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/logging/config.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/logging/logger.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/modules/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/modules/module.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/oop/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/oop/mixins/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/oop/mixins/meta.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/oop/mixins/mixin.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/os/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/os/os.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/projects/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/projects/poetry/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/py.typed +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/delete_garbage_can.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/download_arrow.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/exit_fullscreen_icon.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/fullscreen_icon.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/menu_icon.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/pause_icon.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/play_icon.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/plus_icon.svg +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/resources/svgs/svg.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/security/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/security/cryptography.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/security/keyring.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/assertions.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/convention.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/fixtures.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/fixture.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/scopes/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/scopes/function.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/fixtures/scopes/package.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/base/utils/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/testing/tests/conftest.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/text/__init__.py +0 -0
- {winipedia_utils-0.2.63 → winipedia_utils-0.3.7}/winipedia_utils/text/string.py +0 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: winipedia-utils
|
|
3
|
+
Version: 0.3.7
|
|
4
|
+
Summary: A package with many utility functions
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Winipedia
|
|
8
|
+
Author-email: win.steveker@gmx.de
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Dist: cryptography
|
|
15
|
+
Requires-Dist: defusedxml
|
|
16
|
+
Requires-Dist: keyring
|
|
17
|
+
Requires-Dist: pathspec
|
|
18
|
+
Requires-Dist: polars
|
|
19
|
+
Requires-Dist: pyyaml
|
|
20
|
+
Requires-Dist: setuptools
|
|
21
|
+
Requires-Dist: tomlkit
|
|
22
|
+
Requires-Dist: tqdm
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# Winipedia Utils
|
|
26
|
+
|
|
27
|
+
A comprehensive Python utility package that enforces best practices, automates project setup, and provides a complete testing framework for modern Python projects.
|
|
28
|
+
|
|
29
|
+
> **Note:** Code examples in this README are provided for reference. Please check the source code and docstrings for complete and accurate implementations.
|
|
30
|
+
|
|
31
|
+
[](https://www.python.org/downloads/)
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
[](https://github.com/astral-sh/ruff)
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
- [Overview](#overview)
|
|
38
|
+
- [Key Features](#key-features)
|
|
39
|
+
- [Quick Start](#quick-start)
|
|
40
|
+
- [Setup Process](#setup-process)
|
|
41
|
+
- [Utilities](#utilities)
|
|
42
|
+
- [Configuration Files](#configuration-files)
|
|
43
|
+
- [Important Notes](#important-notes)
|
|
44
|
+
- [Requirements](#requirements)
|
|
45
|
+
|
|
46
|
+
## Overview
|
|
47
|
+
|
|
48
|
+
**Winipedia Utils** is a utility library that serves two primary purposes:
|
|
49
|
+
|
|
50
|
+
1. **Utility Package** - Provides reusable functions across several domains (concurrency, data handling, security, testing, etc.)
|
|
51
|
+
2. **Project Framework** - Automates project setup, testing infrastructure, code quality checks, and best practices enforcement
|
|
52
|
+
|
|
53
|
+
## Key Features
|
|
54
|
+
|
|
55
|
+
- **Automatic Test Generation** - Creates mirror test structure matching your source code
|
|
56
|
+
- **Security First** - Built-in encryption, keyring integration, and security scanning
|
|
57
|
+
- **Concurrent Processing** - Unified interface for multiprocessing and multithreading
|
|
58
|
+
- **Data Handling** - Polars-based dataframe utilities with cleaning pipelines
|
|
59
|
+
- **Strict Type Checking** - mypy in strict mode with full type annotations
|
|
60
|
+
- **Code Quality** - Automated linting, formatting, and security checks
|
|
61
|
+
- **Comprehensive Logging** - Automatic method instrumentation and performance tracking
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
### Installation
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Add winipedia-utils to your project
|
|
69
|
+
poetry add winipedia-utils
|
|
70
|
+
|
|
71
|
+
# Run the automated setup
|
|
72
|
+
poetry run python -m winipedia_utils.setup
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The setup script will automatically configure your project with all necessary files and standards.
|
|
76
|
+
|
|
77
|
+
## Setup Process
|
|
78
|
+
|
|
79
|
+
The `winipedia_utils.setup` command automates the entire project initialization in three main steps:
|
|
80
|
+
|
|
81
|
+
1. **Initialize Configuration Files** - Creates all necessary config files with standard configurations
|
|
82
|
+
2. **Create Project Root** - Sets up the project root directory with __init__.py files
|
|
83
|
+
3. **Run Pre-commit Hooks** - Executes all pre-commit hooks to validate the setup
|
|
84
|
+
|
|
85
|
+
### Generated Configuration Files
|
|
86
|
+
|
|
87
|
+
The setup creates the following configuration files:
|
|
88
|
+
- `.pre-commit-config.yaml` - Pre-commit hook configuration
|
|
89
|
+
- `.gitignore` - Git ignore rules (assumes you added one on GitHub before.)
|
|
90
|
+
- `pyproject.toml` - Project configuration with Poetry settings
|
|
91
|
+
- `.github/workflows/release.yaml` - Release workflow
|
|
92
|
+
- `.github/workflows/publish.yaml` - Publishing workflow
|
|
93
|
+
- `py.typed` - PEP 561 marker for type hints
|
|
94
|
+
- `experiment.py` - For experimentation (ignored by git)
|
|
95
|
+
- `test0.py` - Test file with one empyt test (so that initial tests pass)
|
|
96
|
+
- `conftest.py` - Pytest configuration file
|
|
97
|
+
|
|
98
|
+
### Pre-commit Hook Workflow
|
|
99
|
+
|
|
100
|
+
When you commit code using `poetry run git commit`, the following checks run automatically:
|
|
101
|
+
|
|
102
|
+
1. Patch version
|
|
103
|
+
2. Add version patch to git
|
|
104
|
+
3. Update package manager
|
|
105
|
+
4. Install packages
|
|
106
|
+
5. Update packages
|
|
107
|
+
6. Lock dependencies
|
|
108
|
+
7. Check package manager configs
|
|
109
|
+
8. Create tests
|
|
110
|
+
9. Lint code
|
|
111
|
+
10. Format code
|
|
112
|
+
11. Check static types
|
|
113
|
+
12. Check security
|
|
114
|
+
13. Run tests
|
|
115
|
+
|
|
116
|
+
### Auto-generated Test Structure
|
|
117
|
+
|
|
118
|
+
The test generation creates a **mirror structure** of your source code:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
my_project/
|
|
122
|
+
├── my_project/
|
|
123
|
+
│ ├── module_a.py
|
|
124
|
+
│ └── package_b/
|
|
125
|
+
│ └── module_c.py
|
|
126
|
+
└── tests/
|
|
127
|
+
├── test_module_a.py
|
|
128
|
+
└── test_package_b/
|
|
129
|
+
└── test_module_c.py
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
For each function, class, and method, skeleton tests are created with `NotImplementedError` placeholders for you to implement.
|
|
133
|
+
|
|
134
|
+
## Configuration Files
|
|
135
|
+
|
|
136
|
+
Configuration files are managed automatically by the setup system:
|
|
137
|
+
|
|
138
|
+
- **Deleted files** - If you delete a config file, it will be recreated with standard configurations
|
|
139
|
+
- **Empty files** - If you want to disable a config file, make it empty. This signals that the file is unwanted and won't be modified
|
|
140
|
+
- **Custom additions** - You can add custom configurations as long as the standard configurations remain intact
|
|
141
|
+
- **Modified standards** - If you modify the standard configurations, they will be restored on the next setup run
|
|
142
|
+
|
|
143
|
+
## Utilities
|
|
144
|
+
|
|
145
|
+
Winipedia Utils provides comprehensive utility modules for common development tasks:
|
|
146
|
+
|
|
147
|
+
### Concurrent Processing
|
|
148
|
+
|
|
149
|
+
Unified interface for multiprocessing and multithreading:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
|
|
153
|
+
from winipedia_utils.concurrent.multithreading import multithread_loop
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Data Cleaning & Handling
|
|
157
|
+
|
|
158
|
+
Build data cleaning pipelines using Polars:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from winipedia_utils.data.dataframe.cleaning import CleaningDF
|
|
162
|
+
import polars as pl
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Logging Utilities
|
|
166
|
+
|
|
167
|
+
Simple, standardized logging setup with automatic method instrumentation:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from winipedia_utils.logging.logger import get_logger
|
|
171
|
+
|
|
172
|
+
logger = get_logger(__name__)
|
|
173
|
+
logger.info("Application started")
|
|
174
|
+
logger.warning("This is a warning")
|
|
175
|
+
logger.error("An error occurred")
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Features:**
|
|
179
|
+
- Pre-configured logging levels
|
|
180
|
+
- ANSI color support for terminal output
|
|
181
|
+
- Automatic method logging via metaclasses
|
|
182
|
+
|
|
183
|
+
### Object-Oriented Programming Utilities
|
|
184
|
+
|
|
185
|
+
Advanced metaclasses and mixins for class composition and behavior extension:
|
|
186
|
+
|
|
187
|
+
```python
|
|
188
|
+
from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Security Utilities
|
|
192
|
+
|
|
193
|
+
Encryption and secure credential storage using keyring:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from winipedia_utils.security.keyring import (
|
|
197
|
+
get_or_create_fernet,
|
|
198
|
+
get_or_create_aes_gcm
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Testing Utilities
|
|
203
|
+
|
|
204
|
+
Comprehensive testing framework with automatic test generation:
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
from winipedia_utils.testing.assertions import assert_with_msg
|
|
208
|
+
from winipedia_utils.testing.convention import (
|
|
209
|
+
make_test_obj_name,
|
|
210
|
+
get_test_obj_from_obj,
|
|
211
|
+
make_test_obj_importpath_from_obj
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# Custom assertions
|
|
215
|
+
assert_with_msg(result == expected, "Result does not match expected value")
|
|
216
|
+
|
|
217
|
+
# Test naming conventions
|
|
218
|
+
test_name = make_test_obj_name(my_function) # "test_my_function"
|
|
219
|
+
|
|
220
|
+
# Get corresponding test object
|
|
221
|
+
test_obj = get_test_obj_from_obj(my_function)
|
|
222
|
+
|
|
223
|
+
# Get test import path
|
|
224
|
+
test_path = make_test_obj_importpath_from_obj(my_function)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Features:**
|
|
228
|
+
- Automatic test file generation
|
|
229
|
+
- Mirror test structure matching source code
|
|
230
|
+
- Test naming conventions
|
|
231
|
+
- Fixture management with scopes (function, class, module, package, session)
|
|
232
|
+
|
|
233
|
+
### Module Introspection Utilities
|
|
234
|
+
|
|
235
|
+
Tools for working with Python modules, packages, classes, and functions:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
from winipedia_utils.modules.package import find_packages, walk_package
|
|
239
|
+
from winipedia_utils.modules.module import create_module, import_obj_from_importpath
|
|
240
|
+
from winipedia_utils.modules.class_ import get_all_cls_from_module, get_all_methods_from_cls
|
|
241
|
+
from winipedia_utils.modules.function import get_all_functions_from_module
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Text and String Utilities
|
|
245
|
+
|
|
246
|
+
String manipulation and configuration file handling:
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
from winipedia_utils.text.string import value_to_truncated_string
|
|
250
|
+
from winipedia_utils.text.config import ConfigFile
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### OS and System Utilities
|
|
254
|
+
|
|
255
|
+
Operating system and subprocess utilities:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from winipedia_utils.os.os import run_subprocess
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Iteration Utilities
|
|
262
|
+
|
|
263
|
+
Utilities for working with iterables and nested structures:
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
from winipedia_utils.iterating.iterate import get_len_with_default, nested_structure_is_subset
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Git Utilities
|
|
270
|
+
|
|
271
|
+
Git-related utilities including .gitignore handling and pre-commit hooks:
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
from winipedia_utils.git.gitignore.gitignore import path_is_in_gitignore
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Project Management Utilities
|
|
278
|
+
|
|
279
|
+
Tools for managing Poetry projects and project structure:
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
from winipedia_utils.projects.project import create_project_root
|
|
283
|
+
from winipedia_utils.projects.poetry.config import PyProjectTomlConfig
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Important Notes
|
|
287
|
+
|
|
288
|
+
### Git Commit Workflow
|
|
289
|
+
|
|
290
|
+
When using winipedia-utils, you **must** use Poetry to run git commit:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Correct - Uses Python environment for pre-commit hook
|
|
294
|
+
poetry run git commit -m "Your commit message"
|
|
295
|
+
|
|
296
|
+
# Incorrect - Pre-commit hook won't run properly
|
|
297
|
+
git commit -m "Your commit message"
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
This is necessary because the pre-commit hook needs access to the Python environment and installed packages.
|
|
301
|
+
|
|
302
|
+
### Philosophy
|
|
303
|
+
|
|
304
|
+
The core philosophy of Winipedia Utils is to:
|
|
305
|
+
|
|
306
|
+
> **Enforce good habits, ensure clean code, and save time when starting new projects**
|
|
307
|
+
|
|
308
|
+
By automating setup, testing, linting, formatting, and type checking, you can focus on writing business logic instead of configuring tools.
|
|
309
|
+
|
|
310
|
+
## Requirements
|
|
311
|
+
|
|
312
|
+
- **Python:** 3.12 or higher
|
|
313
|
+
- **Poetry:** For dependency management
|
|
314
|
+
- **Git:** For version control and pre-commit hooks
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
MIT License - See [LICENSE](LICENSE) file for details
|
|
319
|
+
|
|
320
|
+
## Contributing
|
|
321
|
+
|
|
322
|
+
Contributions are welcome! Please ensure all code follows the project's quality standards.
|
|
323
|
+
|
|
324
|
+
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Winipedia Utils
|
|
2
|
+
|
|
3
|
+
A comprehensive Python utility package that enforces best practices, automates project setup, and provides a complete testing framework for modern Python projects.
|
|
4
|
+
|
|
5
|
+
> **Note:** Code examples in this README are provided for reference. Please check the source code and docstrings for complete and accurate implementations.
|
|
6
|
+
|
|
7
|
+
[](https://www.python.org/downloads/)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://github.com/astral-sh/ruff)
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Overview](#overview)
|
|
14
|
+
- [Key Features](#key-features)
|
|
15
|
+
- [Quick Start](#quick-start)
|
|
16
|
+
- [Setup Process](#setup-process)
|
|
17
|
+
- [Utilities](#utilities)
|
|
18
|
+
- [Configuration Files](#configuration-files)
|
|
19
|
+
- [Important Notes](#important-notes)
|
|
20
|
+
- [Requirements](#requirements)
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
**Winipedia Utils** is a utility library that serves two primary purposes:
|
|
25
|
+
|
|
26
|
+
1. **Utility Package** - Provides reusable functions across several domains (concurrency, data handling, security, testing, etc.)
|
|
27
|
+
2. **Project Framework** - Automates project setup, testing infrastructure, code quality checks, and best practices enforcement
|
|
28
|
+
|
|
29
|
+
## Key Features
|
|
30
|
+
|
|
31
|
+
- **Automatic Test Generation** - Creates mirror test structure matching your source code
|
|
32
|
+
- **Security First** - Built-in encryption, keyring integration, and security scanning
|
|
33
|
+
- **Concurrent Processing** - Unified interface for multiprocessing and multithreading
|
|
34
|
+
- **Data Handling** - Polars-based dataframe utilities with cleaning pipelines
|
|
35
|
+
- **Strict Type Checking** - mypy in strict mode with full type annotations
|
|
36
|
+
- **Code Quality** - Automated linting, formatting, and security checks
|
|
37
|
+
- **Comprehensive Logging** - Automatic method instrumentation and performance tracking
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
### Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Add winipedia-utils to your project
|
|
45
|
+
poetry add winipedia-utils
|
|
46
|
+
|
|
47
|
+
# Run the automated setup
|
|
48
|
+
poetry run python -m winipedia_utils.setup
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The setup script will automatically configure your project with all necessary files and standards.
|
|
52
|
+
|
|
53
|
+
## Setup Process
|
|
54
|
+
|
|
55
|
+
The `winipedia_utils.setup` command automates the entire project initialization in three main steps:
|
|
56
|
+
|
|
57
|
+
1. **Initialize Configuration Files** - Creates all necessary config files with standard configurations
|
|
58
|
+
2. **Create Project Root** - Sets up the project root directory with __init__.py files
|
|
59
|
+
3. **Run Pre-commit Hooks** - Executes all pre-commit hooks to validate the setup
|
|
60
|
+
|
|
61
|
+
### Generated Configuration Files
|
|
62
|
+
|
|
63
|
+
The setup creates the following configuration files:
|
|
64
|
+
- `.pre-commit-config.yaml` - Pre-commit hook configuration
|
|
65
|
+
- `.gitignore` - Git ignore rules (assumes you added one on GitHub before.)
|
|
66
|
+
- `pyproject.toml` - Project configuration with Poetry settings
|
|
67
|
+
- `.github/workflows/release.yaml` - Release workflow
|
|
68
|
+
- `.github/workflows/publish.yaml` - Publishing workflow
|
|
69
|
+
- `py.typed` - PEP 561 marker for type hints
|
|
70
|
+
- `experiment.py` - For experimentation (ignored by git)
|
|
71
|
+
- `test0.py` - Test file with one empyt test (so that initial tests pass)
|
|
72
|
+
- `conftest.py` - Pytest configuration file
|
|
73
|
+
|
|
74
|
+
### Pre-commit Hook Workflow
|
|
75
|
+
|
|
76
|
+
When you commit code using `poetry run git commit`, the following checks run automatically:
|
|
77
|
+
|
|
78
|
+
1. Patch version
|
|
79
|
+
2. Add version patch to git
|
|
80
|
+
3. Update package manager
|
|
81
|
+
4. Install packages
|
|
82
|
+
5. Update packages
|
|
83
|
+
6. Lock dependencies
|
|
84
|
+
7. Check package manager configs
|
|
85
|
+
8. Create tests
|
|
86
|
+
9. Lint code
|
|
87
|
+
10. Format code
|
|
88
|
+
11. Check static types
|
|
89
|
+
12. Check security
|
|
90
|
+
13. Run tests
|
|
91
|
+
|
|
92
|
+
### Auto-generated Test Structure
|
|
93
|
+
|
|
94
|
+
The test generation creates a **mirror structure** of your source code:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
my_project/
|
|
98
|
+
├── my_project/
|
|
99
|
+
│ ├── module_a.py
|
|
100
|
+
│ └── package_b/
|
|
101
|
+
│ └── module_c.py
|
|
102
|
+
└── tests/
|
|
103
|
+
├── test_module_a.py
|
|
104
|
+
└── test_package_b/
|
|
105
|
+
└── test_module_c.py
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
For each function, class, and method, skeleton tests are created with `NotImplementedError` placeholders for you to implement.
|
|
109
|
+
|
|
110
|
+
## Configuration Files
|
|
111
|
+
|
|
112
|
+
Configuration files are managed automatically by the setup system:
|
|
113
|
+
|
|
114
|
+
- **Deleted files** - If you delete a config file, it will be recreated with standard configurations
|
|
115
|
+
- **Empty files** - If you want to disable a config file, make it empty. This signals that the file is unwanted and won't be modified
|
|
116
|
+
- **Custom additions** - You can add custom configurations as long as the standard configurations remain intact
|
|
117
|
+
- **Modified standards** - If you modify the standard configurations, they will be restored on the next setup run
|
|
118
|
+
|
|
119
|
+
## Utilities
|
|
120
|
+
|
|
121
|
+
Winipedia Utils provides comprehensive utility modules for common development tasks:
|
|
122
|
+
|
|
123
|
+
### Concurrent Processing
|
|
124
|
+
|
|
125
|
+
Unified interface for multiprocessing and multithreading:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
|
|
129
|
+
from winipedia_utils.concurrent.multithreading import multithread_loop
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Data Cleaning & Handling
|
|
133
|
+
|
|
134
|
+
Build data cleaning pipelines using Polars:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from winipedia_utils.data.dataframe.cleaning import CleaningDF
|
|
138
|
+
import polars as pl
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Logging Utilities
|
|
142
|
+
|
|
143
|
+
Simple, standardized logging setup with automatic method instrumentation:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from winipedia_utils.logging.logger import get_logger
|
|
147
|
+
|
|
148
|
+
logger = get_logger(__name__)
|
|
149
|
+
logger.info("Application started")
|
|
150
|
+
logger.warning("This is a warning")
|
|
151
|
+
logger.error("An error occurred")
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Features:**
|
|
155
|
+
- Pre-configured logging levels
|
|
156
|
+
- ANSI color support for terminal output
|
|
157
|
+
- Automatic method logging via metaclasses
|
|
158
|
+
|
|
159
|
+
### Object-Oriented Programming Utilities
|
|
160
|
+
|
|
161
|
+
Advanced metaclasses and mixins for class composition and behavior extension:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Security Utilities
|
|
168
|
+
|
|
169
|
+
Encryption and secure credential storage using keyring:
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from winipedia_utils.security.keyring import (
|
|
173
|
+
get_or_create_fernet,
|
|
174
|
+
get_or_create_aes_gcm
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Testing Utilities
|
|
179
|
+
|
|
180
|
+
Comprehensive testing framework with automatic test generation:
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from winipedia_utils.testing.assertions import assert_with_msg
|
|
184
|
+
from winipedia_utils.testing.convention import (
|
|
185
|
+
make_test_obj_name,
|
|
186
|
+
get_test_obj_from_obj,
|
|
187
|
+
make_test_obj_importpath_from_obj
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Custom assertions
|
|
191
|
+
assert_with_msg(result == expected, "Result does not match expected value")
|
|
192
|
+
|
|
193
|
+
# Test naming conventions
|
|
194
|
+
test_name = make_test_obj_name(my_function) # "test_my_function"
|
|
195
|
+
|
|
196
|
+
# Get corresponding test object
|
|
197
|
+
test_obj = get_test_obj_from_obj(my_function)
|
|
198
|
+
|
|
199
|
+
# Get test import path
|
|
200
|
+
test_path = make_test_obj_importpath_from_obj(my_function)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Features:**
|
|
204
|
+
- Automatic test file generation
|
|
205
|
+
- Mirror test structure matching source code
|
|
206
|
+
- Test naming conventions
|
|
207
|
+
- Fixture management with scopes (function, class, module, package, session)
|
|
208
|
+
|
|
209
|
+
### Module Introspection Utilities
|
|
210
|
+
|
|
211
|
+
Tools for working with Python modules, packages, classes, and functions:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from winipedia_utils.modules.package import find_packages, walk_package
|
|
215
|
+
from winipedia_utils.modules.module import create_module, import_obj_from_importpath
|
|
216
|
+
from winipedia_utils.modules.class_ import get_all_cls_from_module, get_all_methods_from_cls
|
|
217
|
+
from winipedia_utils.modules.function import get_all_functions_from_module
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Text and String Utilities
|
|
221
|
+
|
|
222
|
+
String manipulation and configuration file handling:
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from winipedia_utils.text.string import value_to_truncated_string
|
|
226
|
+
from winipedia_utils.text.config import ConfigFile
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### OS and System Utilities
|
|
230
|
+
|
|
231
|
+
Operating system and subprocess utilities:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
from winipedia_utils.os.os import run_subprocess
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Iteration Utilities
|
|
238
|
+
|
|
239
|
+
Utilities for working with iterables and nested structures:
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from winipedia_utils.iterating.iterate import get_len_with_default, nested_structure_is_subset
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Git Utilities
|
|
246
|
+
|
|
247
|
+
Git-related utilities including .gitignore handling and pre-commit hooks:
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
from winipedia_utils.git.gitignore.gitignore import path_is_in_gitignore
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Project Management Utilities
|
|
254
|
+
|
|
255
|
+
Tools for managing Poetry projects and project structure:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from winipedia_utils.projects.project import create_project_root
|
|
259
|
+
from winipedia_utils.projects.poetry.config import PyProjectTomlConfig
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Important Notes
|
|
263
|
+
|
|
264
|
+
### Git Commit Workflow
|
|
265
|
+
|
|
266
|
+
When using winipedia-utils, you **must** use Poetry to run git commit:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# Correct - Uses Python environment for pre-commit hook
|
|
270
|
+
poetry run git commit -m "Your commit message"
|
|
271
|
+
|
|
272
|
+
# Incorrect - Pre-commit hook won't run properly
|
|
273
|
+
git commit -m "Your commit message"
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
This is necessary because the pre-commit hook needs access to the Python environment and installed packages.
|
|
277
|
+
|
|
278
|
+
### Philosophy
|
|
279
|
+
|
|
280
|
+
The core philosophy of Winipedia Utils is to:
|
|
281
|
+
|
|
282
|
+
> **Enforce good habits, ensure clean code, and save time when starting new projects**
|
|
283
|
+
|
|
284
|
+
By automating setup, testing, linting, formatting, and type checking, you can focus on writing business logic instead of configuring tools.
|
|
285
|
+
|
|
286
|
+
## Requirements
|
|
287
|
+
|
|
288
|
+
- **Python:** 3.12 or higher
|
|
289
|
+
- **Poetry:** For dependency management
|
|
290
|
+
- **Git:** For version control and pre-commit hooks
|
|
291
|
+
|
|
292
|
+
## License
|
|
293
|
+
|
|
294
|
+
MIT License - See [LICENSE](LICENSE) file for details
|
|
295
|
+
|
|
296
|
+
## Contributing
|
|
297
|
+
|
|
298
|
+
Contributions are welcome! Please ensure all code follows the project's quality standards.
|
|
299
|
+
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Project section
|
|
2
2
|
[project]
|
|
3
3
|
name = "winipedia-utils"
|
|
4
|
-
version = "0.
|
|
4
|
+
version = "0.3.7"
|
|
5
5
|
description = "A package with many utility functions"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
requires-python = ">=3.12"
|
|
@@ -21,27 +21,27 @@ build-backend = "poetry.core.masonry.api"
|
|
|
21
21
|
include = "winipedia_utils"
|
|
22
22
|
|
|
23
23
|
[tool.poetry.dependencies]
|
|
24
|
-
tqdm = "
|
|
25
|
-
setuptools = "
|
|
26
|
-
defusedxml = "
|
|
27
|
-
tomlkit = "
|
|
28
|
-
pathspec = "
|
|
29
|
-
pyyaml = "
|
|
30
|
-
keyring = "
|
|
31
|
-
cryptography = "
|
|
32
|
-
polars = "
|
|
24
|
+
tqdm = "*"
|
|
25
|
+
setuptools = "*"
|
|
26
|
+
defusedxml = "*"
|
|
27
|
+
tomlkit = "*"
|
|
28
|
+
pathspec = "*"
|
|
29
|
+
pyyaml = "*"
|
|
30
|
+
keyring = "*"
|
|
31
|
+
cryptography = "*"
|
|
32
|
+
polars = "*"
|
|
33
33
|
|
|
34
34
|
[tool.poetry.group.dev.dependencies]
|
|
35
|
-
ruff = "
|
|
36
|
-
pre-commit = "
|
|
37
|
-
mypy = "
|
|
38
|
-
pytest = "
|
|
39
|
-
bandit = "
|
|
40
|
-
types-setuptools = "
|
|
41
|
-
types-tqdm = "
|
|
42
|
-
types-defusedxml = "
|
|
43
|
-
types-pyyaml = "
|
|
44
|
-
pytest-mock = "
|
|
35
|
+
ruff = "*"
|
|
36
|
+
pre-commit = "*"
|
|
37
|
+
mypy = "*"
|
|
38
|
+
pytest = "*"
|
|
39
|
+
bandit = "*"
|
|
40
|
+
types-setuptools = "*"
|
|
41
|
+
types-tqdm = "*"
|
|
42
|
+
types-defusedxml = "*"
|
|
43
|
+
types-pyyaml = "*"
|
|
44
|
+
pytest-mock = "*"
|
|
45
45
|
|
|
46
46
|
[tool.ruff]
|
|
47
47
|
exclude = [ ".*", "**/migrations/*.py",]
|
|
@@ -20,8 +20,6 @@ from typing import TYPE_CHECKING, Any, cast
|
|
|
20
20
|
|
|
21
21
|
from tqdm import tqdm
|
|
22
22
|
|
|
23
|
-
from winipedia_utils.concurrent.multiprocessing import get_spwan_pool
|
|
24
|
-
from winipedia_utils.concurrent.multithreading import imap_unordered
|
|
25
23
|
from winipedia_utils.iterating.iterate import get_len_with_default
|
|
26
24
|
from winipedia_utils.logging.logger import get_logger
|
|
27
25
|
|
|
@@ -210,6 +208,13 @@ def concurrent_loop( # noqa: PLR0913
|
|
|
210
208
|
Returns:
|
|
211
209
|
list[Any]: Results from the process_function executions
|
|
212
210
|
"""
|
|
211
|
+
from winipedia_utils.concurrent.multiprocessing import ( # noqa: PLC0415 # avoid circular import
|
|
212
|
+
get_spwan_pool,
|
|
213
|
+
)
|
|
214
|
+
from winipedia_utils.concurrent.multithreading import ( # noqa: PLC0415 # avoid circular import
|
|
215
|
+
imap_unordered,
|
|
216
|
+
)
|
|
217
|
+
|
|
213
218
|
process_args_len = get_len_with_default(process_args, process_args_len)
|
|
214
219
|
process_args = generate_process_args(
|
|
215
220
|
process_function=process_function,
|