winipedia-utils 0.2.10__py3-none-any.whl → 0.2.17__py3-none-any.whl

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.

Files changed (69) hide show
  1. winipedia_utils/concurrent/concurrent.py +245 -245
  2. winipedia_utils/concurrent/multiprocessing.py +130 -130
  3. winipedia_utils/concurrent/multithreading.py +93 -93
  4. winipedia_utils/consts.py +21 -21
  5. winipedia_utils/data/__init__.py +1 -1
  6. winipedia_utils/data/dataframe/__init__.py +1 -1
  7. winipedia_utils/data/dataframe/cleaning.py +378 -378
  8. winipedia_utils/data/structures/__init__.py +1 -1
  9. winipedia_utils/data/structures/dicts.py +16 -16
  10. winipedia_utils/git/__init__.py +1 -1
  11. winipedia_utils/git/gitignore/__init__.py +1 -1
  12. winipedia_utils/git/gitignore/gitignore.py +136 -136
  13. winipedia_utils/git/pre_commit/__init__.py +1 -1
  14. winipedia_utils/git/pre_commit/config.py +70 -70
  15. winipedia_utils/git/pre_commit/hooks.py +127 -109
  16. winipedia_utils/git/pre_commit/run_hooks.py +49 -49
  17. winipedia_utils/iterating/__init__.py +1 -1
  18. winipedia_utils/iterating/iterate.py +29 -29
  19. winipedia_utils/logging/ansi.py +6 -6
  20. winipedia_utils/logging/config.py +64 -64
  21. winipedia_utils/logging/logger.py +26 -26
  22. winipedia_utils/modules/class_.py +119 -119
  23. winipedia_utils/modules/function.py +101 -101
  24. winipedia_utils/modules/module.py +379 -379
  25. winipedia_utils/modules/package.py +390 -390
  26. winipedia_utils/oop/mixins/meta.py +333 -333
  27. winipedia_utils/oop/mixins/mixin.py +37 -37
  28. winipedia_utils/os/__init__.py +1 -1
  29. winipedia_utils/os/os.py +63 -63
  30. winipedia_utils/projects/__init__.py +1 -1
  31. winipedia_utils/projects/poetry/__init__.py +1 -1
  32. winipedia_utils/projects/poetry/config.py +117 -117
  33. winipedia_utils/projects/poetry/poetry.py +31 -31
  34. winipedia_utils/projects/project.py +48 -48
  35. winipedia_utils/resources/__init__.py +1 -1
  36. winipedia_utils/resources/svgs/__init__.py +1 -1
  37. winipedia_utils/resources/svgs/download_arrow.svg +2 -2
  38. winipedia_utils/resources/svgs/exit_fullscreen_icon.svg +5 -5
  39. winipedia_utils/resources/svgs/fullscreen_icon.svg +2 -2
  40. winipedia_utils/resources/svgs/menu_icon.svg +3 -3
  41. winipedia_utils/resources/svgs/pause_icon.svg +3 -3
  42. winipedia_utils/resources/svgs/play_icon.svg +16 -16
  43. winipedia_utils/resources/svgs/plus_icon.svg +23 -23
  44. winipedia_utils/resources/svgs/svg.py +15 -15
  45. winipedia_utils/security/__init__.py +1 -1
  46. winipedia_utils/security/cryptography.py +29 -29
  47. winipedia_utils/security/keyring.py +70 -70
  48. winipedia_utils/setup.py +47 -47
  49. winipedia_utils/testing/assertions.py +23 -23
  50. winipedia_utils/testing/convention.py +177 -177
  51. winipedia_utils/testing/create_tests.py +297 -297
  52. winipedia_utils/testing/fixtures.py +28 -28
  53. winipedia_utils/testing/tests/base/fixtures/__init__.py +1 -1
  54. winipedia_utils/testing/tests/base/fixtures/fixture.py +6 -6
  55. winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +33 -33
  56. winipedia_utils/testing/tests/base/fixtures/scopes/function.py +7 -7
  57. winipedia_utils/testing/tests/base/fixtures/scopes/module.py +33 -33
  58. winipedia_utils/testing/tests/base/fixtures/scopes/package.py +7 -7
  59. winipedia_utils/testing/tests/base/fixtures/scopes/session.py +296 -296
  60. winipedia_utils/testing/tests/base/utils/utils.py +111 -111
  61. winipedia_utils/testing/tests/conftest.py +32 -32
  62. winipedia_utils/text/string.py +126 -126
  63. winipedia_utils-0.2.17.dist-info/METADATA +716 -0
  64. winipedia_utils-0.2.17.dist-info/RECORD +80 -0
  65. {winipedia_utils-0.2.10.dist-info → winipedia_utils-0.2.17.dist-info}/licenses/LICENSE +21 -21
  66. winipedia_utils/testing/tests/test_0.py +0 -8
  67. winipedia_utils-0.2.10.dist-info/METADATA +0 -355
  68. winipedia_utils-0.2.10.dist-info/RECORD +0 -81
  69. {winipedia_utils-0.2.10.dist-info → winipedia_utils-0.2.17.dist-info}/WHEEL +0 -0
@@ -0,0 +1,716 @@
1
+ Metadata-Version: 2.4
2
+ Name: winipedia-utils
3
+ Version: 0.2.17
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 (>=45.0.5,<46.0.0)
15
+ Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
16
+ Requires-Dist: keyring (>=25.6.0,<26.0.0)
17
+ Requires-Dist: pathspec (>=0.12.1,<0.13.0)
18
+ Requires-Dist: polars (>=1.34.0,<2.0.0)
19
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
20
+ Requires-Dist: setuptools (>=80.3.1,<81.0.0)
21
+ Requires-Dist: tomlkit (>=0.13.2,<0.14.0)
22
+ Requires-Dist: tqdm (>=4.67.1,<5.0.0)
23
+ Description-Content-Type: text/markdown
24
+
25
+ # 🚀 Winipedia Utils
26
+ (Some of the README is AI generated, so code examples might have bugs, please check the source code directly on problems. Every functions has a docstring.)
27
+
28
+ > A comprehensive Python utility package that enforces best practices, automates project setup, and provides a complete testing framework for modern Python projects.
29
+
30
+ [![Python Version](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/downloads/)
31
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
32
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
33
+
34
+ ---
35
+
36
+ ## 📋 Table of Contents
37
+
38
+ - [Overview](#overview)
39
+ - [Quick Start](#quick-start)
40
+ - [Setup Process](#setup-process)
41
+ - [Utilities](#utilities)
42
+ - [Usage Examples](#usage-examples)
43
+ - [Important Notes](#important-notes)
44
+
45
+ ---
46
+
47
+ ## Overview
48
+
49
+ **Winipedia Utils** is a utility library that serves two primary purposes:
50
+
51
+ 1. **🛠️ Utility Package** - Provides reusable functions across several domains (concurrency, data handling, security, testing, etc.)
52
+ 2. **🏗️ Project Framework** - Automates project setup, testing infrastructure, code quality checks, and best practices enforcement
53
+
54
+ ### Key Features
55
+
56
+ ✨ **Automatic Test Generation** - Creates mirror test structure matching your source code
57
+ 🔒 **Security First** - Built-in encryption, keyring integration, and security scanning
58
+ ⚡ **Concurrent Processing** - Unified interface for multiprocessing and multithreading
59
+ 📊 **Data Handling** - Polars-based dataframe utilities with cleaning pipelines
60
+ 🎯 **Strict Type Checking** - mypy in strict mode with full type annotations
61
+ 🧹 **Code Quality** - Automated linting, formatting, and security checks
62
+ 📝 **Comprehensive Logging** - Automatic method instrumentation and performance tracking
63
+
64
+ > **Note:** Functions starting with `_` are for internal use only and should not be called directly by package users.
65
+
66
+ ---
67
+
68
+ ## Quick Start
69
+
70
+ ### Installation
71
+
72
+ ```bash
73
+ # clone from github
74
+ git clone https://github.com/user/your-repo.git
75
+
76
+ # Initialize a new Poetry project
77
+ poetry init
78
+
79
+ # Add winipedia-utils to your project
80
+ poetry add winipedia-utils
81
+
82
+ # Run the automated setup
83
+ poetry run python -m winipedia_utils.setup
84
+ ```
85
+
86
+ That's it! The setup script will configure everything for you.
87
+
88
+ ---
89
+
90
+ ## Setup Process
91
+
92
+ The `winipedia_utils.setup` command automates the entire project initialization in a few steps:
93
+
94
+ ### Step 1️⃣ - Install Dev Dependencies
95
+ Installs all development tools needed for code quality like:
96
+ - `ruff` - Fast Python linter and formatter
97
+ - `mypy` - Static type checker
98
+ - `pytest` - Testing framework
99
+ - `bandit` - Security scanner
100
+ - `pre-commit` - Git hooks framework
101
+
102
+ ### Step 2️⃣ - Create Pre-commit Configuration
103
+ Sets up `.pre-commit-config.yaml` with the winipedia-utils hook that runs on every commit.
104
+
105
+ ### Step 3️⃣ - Install Pre-commit Framework
106
+ Installs git hooks so checks run automatically before commits.
107
+
108
+ ### Step 4️⃣ - Update .gitignore
109
+ Adds standard patterns for Python projects:
110
+ ```
111
+ __pycache__/
112
+ .idea/
113
+ .mypy_cache/
114
+ .pytest_cache/
115
+ .ruff_cache/
116
+ .vscode/
117
+ dist/
118
+ test.py
119
+ .git/
120
+ ```
121
+
122
+ ### Step 5️⃣ - Configure pyproject.toml
123
+ Adds tool configurations in pyproject.toml for e.g.:
124
+ - **mypy** - Strict type checking
125
+ - **ruff** - Linting and formatting rules
126
+ - **pytest** - Test discovery and execution
127
+ - **bandit** - Security scanning
128
+
129
+ ### Step 6️⃣ - Create Project Root
130
+ Creates your project's root package directory with `py.typed` marker for type hint support.
131
+
132
+ ### Step 7️⃣ - Run Pre-commit Hook
133
+ Executes the complete quality pipeline (see below).
134
+
135
+ ---
136
+
137
+ ## Pre-commit Hook Workflow
138
+
139
+ When you commit code, the winipedia-utils hook automatically runs a few quality checks e.g.:
140
+
141
+ ```
142
+ ┌─────────────────────────────────────────────────────────┐
143
+ │ Pre-commit Hook Execution Pipeline │
144
+ ├─────────────────────────────────────────────────────────┤
145
+ │ 1. Patch Version (poetry version patch, git add toml) │
146
+ │ 2. Update Poetry │
147
+ │ 3. Install Dependencies (poetry install) │
148
+ │ 4. Update All Dependencies (poetry update) │
149
+ │ 5. Lock Dependencies (poetry lock) │
150
+ │ 6. Validate Configuration (poetry check) │
151
+ │ 7. Generate Tests (auto-create test files) │
152
+ │ 8. Lint Code (ruff check --fix) │
153
+ │ 9. Format Code (ruff format) │
154
+ │ 10. Type Check (mypy) │
155
+ │ 11. Security Scan (bandit) │
156
+ │ 12. Run Tests (pytest) │
157
+ └─────────────────────────────────────────────────────────┘
158
+ ```
159
+
160
+ ### Auto-generated Test Structure
161
+
162
+ The test generation creates a **mirror structure** of your source code:
163
+
164
+ ```
165
+ my_project/
166
+ ├── my_project/
167
+ │ ├── module_a.py
168
+ │ └── package_b/
169
+ │ └── module_c.py
170
+ └── tests/
171
+ ├── test_module_a.py
172
+ └── test_package_b/
173
+ └── test_module_c.py
174
+ ```
175
+
176
+ For each function, class, and method, skeleton tests are created with `NotImplementedError` placeholders for you to implement.
177
+
178
+ ---
179
+
180
+ ## Utilities
181
+
182
+ Winipedia Utils provides comprehensive utility modules:
183
+
184
+ ### 1. 🔄 Concurrent Processing
185
+
186
+ Execute functions in parallel with automatic worker pool management.
187
+
188
+ **Use Cases:** CPU-bound tasks, I/O-bound operations, batch processing
189
+
190
+ ```python
191
+ from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
192
+ from winipedia_utils.concurrent.multithreading import multithread_loop
193
+
194
+ # CPU-bound: Process data in parallel
195
+ def expensive_computation(x):
196
+ return x ** 2
197
+
198
+ data = [[i] for i in range(100)]
199
+ results = multiprocess_loop(expensive_computation, data)
200
+
201
+ # I/O-bound: Fetch URLs concurrently
202
+ def fetch_url(url):
203
+ return requests.get(url).text
204
+
205
+ urls = [["https://example.com"], ["https://google.com"]]
206
+ results = multithread_loop(fetch_url, urls)
207
+ ```
208
+
209
+ **Key Functions:**
210
+ - `multiprocess_loop()` - Parallel execution for CPU-bound tasks
211
+ - `multithread_loop()` - Parallel execution for I/O-bound tasks
212
+ - `cancel_on_timeout()` - Decorator to timeout long-running functions
213
+ - `find_max_pools()` - Automatically determine optimal worker count
214
+
215
+ ---
216
+
217
+ ### 2. 📊 Data Cleaning & Handling
218
+
219
+ Build data cleaning pipelines using Polars (not Pandas).
220
+
221
+ **Use Cases:** ETL pipelines, data validation, dataframe transformations
222
+
223
+ ```python
224
+ from winipedia_utils.data.dataframe.cleaning import CleaningDF
225
+ import polars as pl
226
+
227
+ class MyDataCleaner(CleaningDF):
228
+ COL_NAME = "name"
229
+ COL_VALUE = "value"
230
+
231
+ @classmethod
232
+ def get_rename_map(cls):
233
+ return {cls.COL_NAME: "original_name", cls.COL_VALUE: "original_value"}
234
+
235
+ @classmethod
236
+ def get_col_dtype_map(cls):
237
+ return {cls.COL_NAME: pl.Utf8, cls.COL_VALUE: pl.Float64}
238
+
239
+ @classmethod
240
+ def get_fill_null_map(cls):
241
+ return {cls.COL_NAME: "Unknown", cls.COL_VALUE: 0.0}
242
+
243
+ @classmethod
244
+ def get_drop_null_subsets(cls):
245
+ return ((cls.COL_NAME,),)
246
+
247
+ @classmethod
248
+ def get_sort_cols(cls):
249
+ return ((cls.COL_NAME, False),)
250
+
251
+ @classmethod
252
+ def get_unique_subsets(cls):
253
+ return ((cls.COL_NAME,),)
254
+
255
+ @classmethod
256
+ def get_no_null_cols(cls):
257
+ return (cls.COL_NAME,)
258
+
259
+ @classmethod
260
+ def get_col_converter_map(cls):
261
+ return {cls.COL_NAME: cls.lower_col}
262
+
263
+ @classmethod
264
+ def get_add_on_duplicate_cols(cls):
265
+ return (cls.COL_VALUE,)
266
+
267
+ @classmethod
268
+ def get_col_precision_map(cls):
269
+ return {cls.COL_VALUE: 2}
270
+
271
+ # Usage
272
+ data = MyDataCleaner({"original_name": ["Alice", "bob"], "original_value": [1.5, 2.7]})
273
+ print(data.df) # Cleaned and validated dataframe
274
+ ```
275
+
276
+ **Key Features:**
277
+ - Automatic column renaming
278
+ - Type conversion and validation
279
+ - Null value handling
280
+ - Deduplication with aggregation
281
+ - Sorting and precision rounding
282
+ - Comprehensive data validation
283
+
284
+ ---
285
+
286
+ ### 3. 🔧 Git Utilities
287
+
288
+ Manage gitignore patterns and pre-commit configuration.
289
+
290
+ **Use Cases:** Project setup, git workflow automation
291
+
292
+ ```python
293
+ from winipedia_utils.git.gitignore.gitignore import (
294
+ path_is_in_gitignore,
295
+ walk_os_skipping_gitignore_patterns,
296
+ add_patterns_to_gitignore
297
+ )
298
+
299
+ # Check if path is ignored
300
+ if path_is_in_gitignore("dist/"):
301
+ print("This path is in .gitignore")
302
+
303
+ # Walk directory respecting gitignore
304
+ for root, dirs, files in walk_os_skipping_gitignore_patterns("."):
305
+ print(f"Processing: {root}")
306
+
307
+ # Add patterns to gitignore
308
+ add_patterns_to_gitignore(["*.log", "temp/"])
309
+ ```
310
+
311
+ **Key Functions:**
312
+ - `path_is_in_gitignore()` - Check if path matches gitignore patterns
313
+ - `walk_os_skipping_gitignore_patterns()` - Directory traversal respecting gitignore
314
+ - `add_patterns_to_gitignore()` - Add patterns to .gitignore file
315
+ - Pre-commit configuration management
316
+
317
+ ---
318
+
319
+ ### 4. 🔁 Iterating Utilities
320
+
321
+ Handle iterables with sensible defaults.
322
+
323
+ **Use Cases:** Working with generators, unknown-length iterables
324
+
325
+ ```python
326
+ from winipedia_utils.iterating.iterate import get_len_with_default
327
+
328
+ # Get length with fallback
329
+ length = get_len_with_default(some_generator, default=100)
330
+ print(f"Length: {length}")
331
+ ```
332
+
333
+ ---
334
+
335
+ ### 5. 📝 Logging Utilities
336
+
337
+ Simple, standardized logging setup with automatic method instrumentation.
338
+
339
+ **Use Cases:** Application logging, debugging, performance tracking
340
+
341
+ ```python
342
+ from winipedia_utils.logging.logger import get_logger
343
+
344
+ logger = get_logger(__name__)
345
+ logger.info("Application started")
346
+ logger.warning("This is a warning")
347
+ logger.error("An error occurred")
348
+ ```
349
+
350
+ **Features:**
351
+ - Pre-configured logging levels
352
+ - ANSI color support for terminal output
353
+ - Automatic method logging via metaclasses
354
+
355
+ ---
356
+
357
+ ### 6. 📦 Module/Package Utilities
358
+
359
+ Introspect and manipulate Python modules and packages dynamically.
360
+
361
+ **Use Cases:** Testing frameworks, code generation, dynamic imports
362
+
363
+ ```python
364
+ from winipedia_utils.modules.module import (
365
+ to_module_name,
366
+ to_path,
367
+ create_module,
368
+ import_obj_from_importpath,
369
+ make_obj_importpath
370
+ )
371
+ from winipedia_utils.modules.class_ import get_all_cls_from_module
372
+ from winipedia_utils.modules.function import get_all_functions_from_module
373
+ from winipedia_utils.modules.package import find_packages, walk_package
374
+
375
+ # Convert between paths and module names
376
+ module_name = to_module_name("src/package/module.py") # "src.package.module"
377
+ path = to_path("src.package.module", is_package=False) # Path("src/package/module.py")
378
+
379
+ # Create modules dynamically
380
+ new_module = create_module("my_package.new_module", is_package=False)
381
+
382
+ # Import objects by path
383
+ obj = import_obj_from_importpath("my_package.MyClass")
384
+
385
+ # Get all classes in a module
386
+ classes = get_all_cls_from_module("my_package.module")
387
+
388
+ # Get all functions in a module
389
+ functions = get_all_functions_from_module("my_package.module")
390
+
391
+ # Find all packages
392
+ packages = find_packages(depth=1)
393
+
394
+ # Walk package hierarchy
395
+ for package, modules in walk_package(my_package):
396
+ print(f"Package: {package.__name__}, Modules: {len(modules)}")
397
+ ```
398
+
399
+ ---
400
+
401
+ ### 7. 🎯 Object-Oriented Programming Utilities
402
+
403
+ Advanced metaclasses and mixins for class composition and behavior extension.
404
+
405
+ **Use Cases:** Framework development, enforcing design patterns, automatic instrumentation
406
+
407
+ ```python
408
+ from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
409
+ from abc import abstractmethod
410
+ from typing import final
411
+
412
+ # Automatic logging + ABC functionality
413
+ class MyService(ABCLoggingMixin):
414
+ def process_data(self, data):
415
+ # Automatically logged with timing
416
+ return data * 2
417
+
418
+ # Strict implementation enforcement + logging
419
+ class StrictService(StrictABCLoggingMixin):
420
+ @abstractmethod
421
+ def required_method(self):
422
+ pass
423
+
424
+ @final
425
+ def final_method(self):
426
+ return "Cannot be overridden"
427
+
428
+ # Usage
429
+ service = MyService()
430
+ result = service.process_data(42) # Automatically logged
431
+ ```
432
+
433
+ **Features:**
434
+ - `ABCLoggingMixin` - Automatic method logging with performance tracking
435
+ - `StrictABCLoggingMixin` - Enforces implementation + logging
436
+ - Rate-limited logging to prevent log flooding
437
+ - Automatic timing of method execution
438
+
439
+ ---
440
+
441
+ ### 8. 🖥️ OS Utilities
442
+
443
+ Operating system utilities for command execution and path management.
444
+
445
+ **Use Cases:** Subprocess management, command discovery
446
+
447
+ ```python
448
+ from winipedia_utils.os.os import which_with_raise, run_subprocess
449
+
450
+ # Find command path
451
+ python_path = which_with_raise("python")
452
+
453
+ # Run subprocess with timeout
454
+ result = run_subprocess(
455
+ ["python", "-c", "print('hello')"],
456
+ timeout=5,
457
+ capture_output=True
458
+ )
459
+ print(result.stdout)
460
+ ```
461
+
462
+ ---
463
+
464
+ ### 9. 🏗️ Projects Utilities
465
+
466
+ Poetry and project setup utilities.
467
+
468
+ **Use Cases:** Project initialization, configuration management
469
+
470
+ ```python
471
+ from winipedia_utils.projects.project import make_name_from_package
472
+ from winipedia_utils.projects.poetry.config import get_poetry_package_name
473
+
474
+ # Get project name from pyproject.toml
475
+ project_name = get_poetry_package_name()
476
+
477
+ # Convert package name to human-readable format
478
+ readable_name = make_name_from_package(my_package)
479
+ # "my_package" -> "My-Package"
480
+ ```
481
+
482
+ ---
483
+
484
+ ### 10. 🔐 Security Utilities
485
+
486
+ Encryption and secure credential storage using keyring.
487
+
488
+ **Use Cases:** API key management, secure data encryption
489
+
490
+ ```python
491
+ from winipedia_utils.security.keyring import (
492
+ get_or_create_fernet,
493
+ get_or_create_aes_gcm
494
+ )
495
+
496
+ # Get or create Fernet encryption key
497
+ fernet, key_bytes = get_or_create_fernet("my_app", "user@example.com")
498
+ encrypted = fernet.encrypt(b"secret data")
499
+ decrypted = fernet.decrypt(encrypted)
500
+
501
+ # Get or create AES-GCM key
502
+ aes_gcm, key_bytes = get_or_create_aes_gcm("my_app", "user@example.com")
503
+ ```
504
+
505
+ **Features:**
506
+ - Automatic key generation and storage
507
+ - Keyring integration for secure storage
508
+ - Support for Fernet and AES-GCM encryption
509
+
510
+ ---
511
+
512
+ ### 11. 🧪 Testing Utilities
513
+
514
+ Comprehensive testing framework with automatic test generation.
515
+
516
+ **Use Cases:** Test infrastructure, test discovery, custom assertions
517
+
518
+ ```python
519
+ from winipedia_utils.testing.assertions import assert_with_msg
520
+ from winipedia_utils.testing.convention import (
521
+ make_test_obj_name,
522
+ get_test_obj_from_obj,
523
+ make_test_obj_importpath_from_obj
524
+ )
525
+
526
+ # Custom assertions
527
+ assert_with_msg(result == expected, "Result does not match expected value")
528
+
529
+ # Test naming conventions
530
+ test_name = make_test_obj_name(my_function) # "test_my_function"
531
+
532
+ # Get corresponding test object
533
+ test_obj = get_test_obj_from_obj(my_function)
534
+
535
+ # Get test import path
536
+ test_path = make_test_obj_importpath_from_obj(my_function)
537
+ ```
538
+
539
+ **Features:**
540
+ - Automatic test file generation
541
+ - Mirror test structure matching source code
542
+ - Test naming conventions
543
+ - Fixture management with scopes (function, class, module, package, session)
544
+
545
+ ---
546
+
547
+ ### 12. 📄 Text Utilities
548
+
549
+ String manipulation and text processing utilities.
550
+
551
+ **Use Cases:** String processing, XML parsing, hashing, user input
552
+
553
+ ```python
554
+ from winipedia_utils.text.string import (
555
+ ask_for_input_with_timeout,
556
+ find_xml_namespaces,
557
+ value_to_truncated_string,
558
+ get_reusable_hash,
559
+ split_on_uppercase
560
+ )
561
+
562
+ # Get user input with timeout
563
+ user_input = ask_for_input_with_timeout("Enter value: ", timeout=10)
564
+
565
+ # Extract XML namespaces
566
+ namespaces = find_xml_namespaces("<root xmlns:ns='http://example.com'/>")
567
+
568
+ # Truncate values for logging
569
+ truncated = value_to_truncated_string(large_object, max_length=50)
570
+
571
+ # Generate consistent hash
572
+ hash_value = get_reusable_hash({"key": "value"})
573
+
574
+ # Split on uppercase
575
+ parts = split_on_uppercase("HelloWorld") # ["Hello", "World"]
576
+ ```
577
+
578
+ ---
579
+
580
+ ### 13. 🎨 Resources Utilities
581
+
582
+ SVG and resource utilities (minimal, may be removed in future versions).
583
+
584
+ ---
585
+
586
+ ## Usage Examples
587
+
588
+ ### Example 1: Setting Up a New Project
589
+
590
+ ```bash
591
+ # Create new project
592
+ mkdir my_project
593
+ cd my_project
594
+
595
+ # Initialize Poetry
596
+ poetry init
597
+
598
+ # Add winipedia-utils
599
+ poetry add winipedia-utils
600
+
601
+ # Run setup (this does everything!)
602
+ poetry run python -m winipedia_utils.setup
603
+
604
+ # Start coding
605
+ poetry run python -m my_project
606
+ ```
607
+
608
+ ### Example 2: Using Concurrent Processing
609
+
610
+ ```python
611
+ from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
612
+
613
+ def process_item(item_id, multiplier):
614
+ return item_id * multiplier
615
+
616
+ # Process 1000 items in parallel
617
+ items = [[i] for i in range(1000)]
618
+ results = multiprocess_loop(
619
+ process_item,
620
+ items,
621
+ process_args_static=[2], # multiplier = 2
622
+ process_args_len=1000
623
+ )
624
+ ```
625
+
626
+ ### Example 3: Building a Data Pipeline
627
+
628
+ ```python
629
+ from winipedia_utils.data.dataframe.cleaning import CleaningDF
630
+ import polars as pl
631
+
632
+ class SalesDataCleaner(CleaningDF):
633
+ COL_PRODUCT = "product"
634
+ COL_AMOUNT = "amount"
635
+
636
+ @classmethod
637
+ def get_rename_map(cls):
638
+ return {cls.COL_PRODUCT: "product_name", cls.COL_AMOUNT: "sale_amount"}
639
+
640
+ @classmethod
641
+ def get_col_dtype_map(cls):
642
+ return {cls.COL_PRODUCT: pl.Utf8, cls.COL_AMOUNT: pl.Float64}
643
+
644
+ # ... implement other required methods ...
645
+
646
+ # Usage
647
+ raw_data = {"product_name": ["A", "B"], "sale_amount": [100.5, 200.7]}
648
+ cleaned = SalesDataCleaner(raw_data)
649
+ print(cleaned.df)
650
+ ```
651
+
652
+ ---
653
+
654
+ ## Important Notes
655
+
656
+ ### ⚠️ Git Commit Workflow
657
+
658
+ When using winipedia-utils, you **must** use Poetry to run git commit:
659
+
660
+ ```bash
661
+ # ✅ Correct - Uses Python environment for pre-commit hook
662
+ poetry run git commit -m "Your commit message"
663
+
664
+ # ❌ Wrong - Pre-commit hook won't run properly
665
+ git commit -m "Your commit message"
666
+ ```
667
+
668
+ This is necessary because the pre-commit hook needs access to the Python environment and installed packages.
669
+
670
+ ### 📌 Internal Functions
671
+
672
+ Functions and methods starting with `_` are for **internal use only**:
673
+
674
+ ```python
675
+ # ❌ Don't use these
676
+ from winipedia_utils.git.gitignore.gitignore import _get_gitignore_patterns
677
+
678
+ # ✅ Use public API instead
679
+ from winipedia_utils.git.gitignore.gitignore import add_patterns_to_gitignore
680
+ ```
681
+
682
+ ### 🎯 Philosophy
683
+
684
+ The core philosophy of Winipedia Utils is to:
685
+
686
+ > **Enforce good habits, ensure clean code, and save time when starting new projects**
687
+
688
+ By automating setup, testing, linting, formatting, and type checking, you can focus on writing business logic instead of configuring tools.
689
+
690
+ ---
691
+
692
+ ## Requirements
693
+
694
+ - **Python:** 3.12 or higher
695
+ - **Poetry:** For dependency management
696
+ - **Git:** For version control and pre-commit hooks
697
+
698
+ ---
699
+
700
+ ## License
701
+
702
+ MIT License - See [LICENSE](LICENSE) file for details
703
+
704
+ ---
705
+
706
+ ## Contributing
707
+
708
+ Contributions are welcome! Please ensure all code follows the project's quality standards:
709
+
710
+ - Type hints on all functions
711
+ - Comprehensive docstrings (Google style)
712
+ - Full test coverage
713
+ - Pass all linting and security checks
714
+
715
+ ---
716
+