winipedia-utils 0.2.10__py3-none-any.whl → 0.2.18__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.18.dist-info/METADATA +715 -0
  64. winipedia_utils-0.2.18.dist-info/RECORD +80 -0
  65. {winipedia_utils-0.2.10.dist-info → winipedia_utils-0.2.18.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.18.dist-info}/WHEEL +0 -0
@@ -0,0 +1,715 @@
1
+ Metadata-Version: 2.4
2
+ Name: winipedia-utils
3
+ Version: 0.2.18
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
+ │ Pre-commit Hook Execution Pipeline │
143
+ ├─────────────────────────────────────────────────────────┤
144
+ │ 1. Patch Version (poetry version patch, git add toml) │
145
+ │ 2. Update Poetry │
146
+ │ 3. Install Dependencies (poetry install) │
147
+ │ 4. Update All Dependencies (poetry update) │
148
+ │ 5. Lock Dependencies (poetry lock) │
149
+ │ 6. Validate Configuration (poetry check) │
150
+ │ 7. Generate Tests (auto-create test files) │
151
+ │ 8. Lint Code (ruff check --fix) │
152
+ │ 9. Format Code (ruff format) │
153
+ │ 10. Type Check (mypy) │
154
+ │ 11. Security Scan (bandit) │
155
+ │ 12. Run Tests (pytest) │
156
+ └─────────────────────────────────────────────────────────┘
157
+ ```
158
+
159
+ ### Auto-generated Test Structure
160
+
161
+ The test generation creates a **mirror structure** of your source code:
162
+
163
+ ```
164
+ my_project/
165
+ ├── my_project/
166
+ │ ├── module_a.py
167
+ │ └── package_b/
168
+ │ └── module_c.py
169
+ └── tests/
170
+ ├── test_module_a.py
171
+ └── test_package_b/
172
+ └── test_module_c.py
173
+ ```
174
+
175
+ For each function, class, and method, skeleton tests are created with `NotImplementedError` placeholders for you to implement.
176
+
177
+ ---
178
+
179
+ ## Utilities
180
+
181
+ Winipedia Utils provides comprehensive utility modules:
182
+
183
+ ### 1. 🔄 Concurrent Processing
184
+
185
+ Execute functions in parallel with automatic worker pool management.
186
+
187
+ **Use Cases:** CPU-bound tasks, I/O-bound operations, batch processing
188
+
189
+ ```python
190
+ from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
191
+ from winipedia_utils.concurrent.multithreading import multithread_loop
192
+
193
+ # CPU-bound: Process data in parallel
194
+ def expensive_computation(x):
195
+ return x ** 2
196
+
197
+ data = [[i] for i in range(100)]
198
+ results = multiprocess_loop(expensive_computation, data)
199
+
200
+ # I/O-bound: Fetch URLs concurrently
201
+ def fetch_url(url):
202
+ return requests.get(url).text
203
+
204
+ urls = [["https://example.com"], ["https://google.com"]]
205
+ results = multithread_loop(fetch_url, urls)
206
+ ```
207
+
208
+ **Key Functions:**
209
+ - `multiprocess_loop()` - Parallel execution for CPU-bound tasks
210
+ - `multithread_loop()` - Parallel execution for I/O-bound tasks
211
+ - `cancel_on_timeout()` - Decorator to timeout long-running functions
212
+ - `find_max_pools()` - Automatically determine optimal worker count
213
+
214
+ ---
215
+
216
+ ### 2. 📊 Data Cleaning & Handling
217
+
218
+ Build data cleaning pipelines using Polars (not Pandas).
219
+
220
+ **Use Cases:** ETL pipelines, data validation, dataframe transformations
221
+
222
+ ```python
223
+ from winipedia_utils.data.dataframe.cleaning import CleaningDF
224
+ import polars as pl
225
+
226
+ class MyDataCleaner(CleaningDF):
227
+ COL_NAME = "name"
228
+ COL_VALUE = "value"
229
+
230
+ @classmethod
231
+ def get_rename_map(cls):
232
+ return {cls.COL_NAME: "original_name", cls.COL_VALUE: "original_value"}
233
+
234
+ @classmethod
235
+ def get_col_dtype_map(cls):
236
+ return {cls.COL_NAME: pl.Utf8, cls.COL_VALUE: pl.Float64}
237
+
238
+ @classmethod
239
+ def get_fill_null_map(cls):
240
+ return {cls.COL_NAME: "Unknown", cls.COL_VALUE: 0.0}
241
+
242
+ @classmethod
243
+ def get_drop_null_subsets(cls):
244
+ return ((cls.COL_NAME,),)
245
+
246
+ @classmethod
247
+ def get_sort_cols(cls):
248
+ return ((cls.COL_NAME, False),)
249
+
250
+ @classmethod
251
+ def get_unique_subsets(cls):
252
+ return ((cls.COL_NAME,),)
253
+
254
+ @classmethod
255
+ def get_no_null_cols(cls):
256
+ return (cls.COL_NAME,)
257
+
258
+ @classmethod
259
+ def get_col_converter_map(cls):
260
+ return {cls.COL_NAME: cls.lower_col}
261
+
262
+ @classmethod
263
+ def get_add_on_duplicate_cols(cls):
264
+ return (cls.COL_VALUE,)
265
+
266
+ @classmethod
267
+ def get_col_precision_map(cls):
268
+ return {cls.COL_VALUE: 2}
269
+
270
+ # Usage
271
+ data = MyDataCleaner({"original_name": ["Alice", "bob"], "original_value": [1.5, 2.7]})
272
+ print(data.df) # Cleaned and validated dataframe
273
+ ```
274
+
275
+ **Key Features:**
276
+ - Automatic column renaming
277
+ - Type conversion and validation
278
+ - Null value handling
279
+ - Deduplication with aggregation
280
+ - Sorting and precision rounding
281
+ - Comprehensive data validation
282
+
283
+ ---
284
+
285
+ ### 3. 🔧 Git Utilities
286
+
287
+ Manage gitignore patterns and pre-commit configuration.
288
+
289
+ **Use Cases:** Project setup, git workflow automation
290
+
291
+ ```python
292
+ from winipedia_utils.git.gitignore.gitignore import (
293
+ path_is_in_gitignore,
294
+ walk_os_skipping_gitignore_patterns,
295
+ add_patterns_to_gitignore
296
+ )
297
+
298
+ # Check if path is ignored
299
+ if path_is_in_gitignore("dist/"):
300
+ print("This path is in .gitignore")
301
+
302
+ # Walk directory respecting gitignore
303
+ for root, dirs, files in walk_os_skipping_gitignore_patterns("."):
304
+ print(f"Processing: {root}")
305
+
306
+ # Add patterns to gitignore
307
+ add_patterns_to_gitignore(["*.log", "temp/"])
308
+ ```
309
+
310
+ **Key Functions:**
311
+ - `path_is_in_gitignore()` - Check if path matches gitignore patterns
312
+ - `walk_os_skipping_gitignore_patterns()` - Directory traversal respecting gitignore
313
+ - `add_patterns_to_gitignore()` - Add patterns to .gitignore file
314
+ - Pre-commit configuration management
315
+
316
+ ---
317
+
318
+ ### 4. 🔁 Iterating Utilities
319
+
320
+ Handle iterables with sensible defaults.
321
+
322
+ **Use Cases:** Working with generators, unknown-length iterables
323
+
324
+ ```python
325
+ from winipedia_utils.iterating.iterate import get_len_with_default
326
+
327
+ # Get length with fallback
328
+ length = get_len_with_default(some_generator, default=100)
329
+ print(f"Length: {length}")
330
+ ```
331
+
332
+ ---
333
+
334
+ ### 5. 📝 Logging Utilities
335
+
336
+ Simple, standardized logging setup with automatic method instrumentation.
337
+
338
+ **Use Cases:** Application logging, debugging, performance tracking
339
+
340
+ ```python
341
+ from winipedia_utils.logging.logger import get_logger
342
+
343
+ logger = get_logger(__name__)
344
+ logger.info("Application started")
345
+ logger.warning("This is a warning")
346
+ logger.error("An error occurred")
347
+ ```
348
+
349
+ **Features:**
350
+ - Pre-configured logging levels
351
+ - ANSI color support for terminal output
352
+ - Automatic method logging via metaclasses
353
+
354
+ ---
355
+
356
+ ### 6. 📦 Module/Package Utilities
357
+
358
+ Introspect and manipulate Python modules and packages dynamically.
359
+
360
+ **Use Cases:** Testing frameworks, code generation, dynamic imports
361
+
362
+ ```python
363
+ from winipedia_utils.modules.module import (
364
+ to_module_name,
365
+ to_path,
366
+ create_module,
367
+ import_obj_from_importpath,
368
+ make_obj_importpath
369
+ )
370
+ from winipedia_utils.modules.class_ import get_all_cls_from_module
371
+ from winipedia_utils.modules.function import get_all_functions_from_module
372
+ from winipedia_utils.modules.package import find_packages, walk_package
373
+
374
+ # Convert between paths and module names
375
+ module_name = to_module_name("src/package/module.py") # "src.package.module"
376
+ path = to_path("src.package.module", is_package=False) # Path("src/package/module.py")
377
+
378
+ # Create modules dynamically
379
+ new_module = create_module("my_package.new_module", is_package=False)
380
+
381
+ # Import objects by path
382
+ obj = import_obj_from_importpath("my_package.MyClass")
383
+
384
+ # Get all classes in a module
385
+ classes = get_all_cls_from_module("my_package.module")
386
+
387
+ # Get all functions in a module
388
+ functions = get_all_functions_from_module("my_package.module")
389
+
390
+ # Find all packages
391
+ packages = find_packages(depth=1)
392
+
393
+ # Walk package hierarchy
394
+ for package, modules in walk_package(my_package):
395
+ print(f"Package: {package.__name__}, Modules: {len(modules)}")
396
+ ```
397
+
398
+ ---
399
+
400
+ ### 7. 🎯 Object-Oriented Programming Utilities
401
+
402
+ Advanced metaclasses and mixins for class composition and behavior extension.
403
+
404
+ **Use Cases:** Framework development, enforcing design patterns, automatic instrumentation
405
+
406
+ ```python
407
+ from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
408
+ from abc import abstractmethod
409
+ from typing import final
410
+
411
+ # Automatic logging + ABC functionality
412
+ class MyService(ABCLoggingMixin):
413
+ def process_data(self, data):
414
+ # Automatically logged with timing
415
+ return data * 2
416
+
417
+ # Strict implementation enforcement + logging
418
+ class StrictService(StrictABCLoggingMixin):
419
+ @abstractmethod
420
+ def required_method(self):
421
+ pass
422
+
423
+ @final
424
+ def final_method(self):
425
+ return "Cannot be overridden"
426
+
427
+ # Usage
428
+ service = MyService()
429
+ result = service.process_data(42) # Automatically logged
430
+ ```
431
+
432
+ **Features:**
433
+ - `ABCLoggingMixin` - Automatic method logging with performance tracking
434
+ - `StrictABCLoggingMixin` - Enforces implementation + logging
435
+ - Rate-limited logging to prevent log flooding
436
+ - Automatic timing of method execution
437
+
438
+ ---
439
+
440
+ ### 8. 🖥️ OS Utilities
441
+
442
+ Operating system utilities for command execution and path management.
443
+
444
+ **Use Cases:** Subprocess management, command discovery
445
+
446
+ ```python
447
+ from winipedia_utils.os.os import which_with_raise, run_subprocess
448
+
449
+ # Find command path
450
+ python_path = which_with_raise("python")
451
+
452
+ # Run subprocess with timeout
453
+ result = run_subprocess(
454
+ ["python", "-c", "print('hello')"],
455
+ timeout=5,
456
+ capture_output=True
457
+ )
458
+ print(result.stdout)
459
+ ```
460
+
461
+ ---
462
+
463
+ ### 9. 🏗️ Projects Utilities
464
+
465
+ Poetry and project setup utilities.
466
+
467
+ **Use Cases:** Project initialization, configuration management
468
+
469
+ ```python
470
+ from winipedia_utils.projects.project import make_name_from_package
471
+ from winipedia_utils.projects.poetry.config import get_poetry_package_name
472
+
473
+ # Get project name from pyproject.toml
474
+ project_name = get_poetry_package_name()
475
+
476
+ # Convert package name to human-readable format
477
+ readable_name = make_name_from_package(my_package)
478
+ # "my_package" -> "My-Package"
479
+ ```
480
+
481
+ ---
482
+
483
+ ### 10. 🔐 Security Utilities
484
+
485
+ Encryption and secure credential storage using keyring.
486
+
487
+ **Use Cases:** API key management, secure data encryption
488
+
489
+ ```python
490
+ from winipedia_utils.security.keyring import (
491
+ get_or_create_fernet,
492
+ get_or_create_aes_gcm
493
+ )
494
+
495
+ # Get or create Fernet encryption key
496
+ fernet, key_bytes = get_or_create_fernet("my_app", "user@example.com")
497
+ encrypted = fernet.encrypt(b"secret data")
498
+ decrypted = fernet.decrypt(encrypted)
499
+
500
+ # Get or create AES-GCM key
501
+ aes_gcm, key_bytes = get_or_create_aes_gcm("my_app", "user@example.com")
502
+ ```
503
+
504
+ **Features:**
505
+ - Automatic key generation and storage
506
+ - Keyring integration for secure storage
507
+ - Support for Fernet and AES-GCM encryption
508
+
509
+ ---
510
+
511
+ ### 11. 🧪 Testing Utilities
512
+
513
+ Comprehensive testing framework with automatic test generation.
514
+
515
+ **Use Cases:** Test infrastructure, test discovery, custom assertions
516
+
517
+ ```python
518
+ from winipedia_utils.testing.assertions import assert_with_msg
519
+ from winipedia_utils.testing.convention import (
520
+ make_test_obj_name,
521
+ get_test_obj_from_obj,
522
+ make_test_obj_importpath_from_obj
523
+ )
524
+
525
+ # Custom assertions
526
+ assert_with_msg(result == expected, "Result does not match expected value")
527
+
528
+ # Test naming conventions
529
+ test_name = make_test_obj_name(my_function) # "test_my_function"
530
+
531
+ # Get corresponding test object
532
+ test_obj = get_test_obj_from_obj(my_function)
533
+
534
+ # Get test import path
535
+ test_path = make_test_obj_importpath_from_obj(my_function)
536
+ ```
537
+
538
+ **Features:**
539
+ - Automatic test file generation
540
+ - Mirror test structure matching source code
541
+ - Test naming conventions
542
+ - Fixture management with scopes (function, class, module, package, session)
543
+
544
+ ---
545
+
546
+ ### 12. 📄 Text Utilities
547
+
548
+ String manipulation and text processing utilities.
549
+
550
+ **Use Cases:** String processing, XML parsing, hashing, user input
551
+
552
+ ```python
553
+ from winipedia_utils.text.string import (
554
+ ask_for_input_with_timeout,
555
+ find_xml_namespaces,
556
+ value_to_truncated_string,
557
+ get_reusable_hash,
558
+ split_on_uppercase
559
+ )
560
+
561
+ # Get user input with timeout
562
+ user_input = ask_for_input_with_timeout("Enter value: ", timeout=10)
563
+
564
+ # Extract XML namespaces
565
+ namespaces = find_xml_namespaces("<root xmlns:ns='http://example.com'/>")
566
+
567
+ # Truncate values for logging
568
+ truncated = value_to_truncated_string(large_object, max_length=50)
569
+
570
+ # Generate consistent hash
571
+ hash_value = get_reusable_hash({"key": "value"})
572
+
573
+ # Split on uppercase
574
+ parts = split_on_uppercase("HelloWorld") # ["Hello", "World"]
575
+ ```
576
+
577
+ ---
578
+
579
+ ### 13. 🎨 Resources Utilities
580
+
581
+ SVG and resource utilities (minimal, may be removed in future versions).
582
+
583
+ ---
584
+
585
+ ## Usage Examples
586
+
587
+ ### Example 1: Setting Up a New Project
588
+
589
+ ```bash
590
+ # Create new project
591
+ mkdir my_project
592
+ cd my_project
593
+
594
+ # Initialize Poetry
595
+ poetry init
596
+
597
+ # Add winipedia-utils
598
+ poetry add winipedia-utils
599
+
600
+ # Run setup (this does everything!)
601
+ poetry run python -m winipedia_utils.setup
602
+
603
+ # Start coding
604
+ poetry run python -m my_project
605
+ ```
606
+
607
+ ### Example 2: Using Concurrent Processing
608
+
609
+ ```python
610
+ from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
611
+
612
+ def process_item(item_id, multiplier):
613
+ return item_id * multiplier
614
+
615
+ # Process 1000 items in parallel
616
+ items = [[i] for i in range(1000)]
617
+ results = multiprocess_loop(
618
+ process_item,
619
+ items,
620
+ process_args_static=[2], # multiplier = 2
621
+ process_args_len=1000
622
+ )
623
+ ```
624
+
625
+ ### Example 3: Building a Data Pipeline
626
+
627
+ ```python
628
+ from winipedia_utils.data.dataframe.cleaning import CleaningDF
629
+ import polars as pl
630
+
631
+ class SalesDataCleaner(CleaningDF):
632
+ COL_PRODUCT = "product"
633
+ COL_AMOUNT = "amount"
634
+
635
+ @classmethod
636
+ def get_rename_map(cls):
637
+ return {cls.COL_PRODUCT: "product_name", cls.COL_AMOUNT: "sale_amount"}
638
+
639
+ @classmethod
640
+ def get_col_dtype_map(cls):
641
+ return {cls.COL_PRODUCT: pl.Utf8, cls.COL_AMOUNT: pl.Float64}
642
+
643
+ # ... implement other required methods ...
644
+
645
+ # Usage
646
+ raw_data = {"product_name": ["A", "B"], "sale_amount": [100.5, 200.7]}
647
+ cleaned = SalesDataCleaner(raw_data)
648
+ print(cleaned.df)
649
+ ```
650
+
651
+ ---
652
+
653
+ ## Important Notes
654
+
655
+ ### ⚠️ Git Commit Workflow
656
+
657
+ When using winipedia-utils, you **must** use Poetry to run git commit:
658
+
659
+ ```bash
660
+ # ✅ Correct - Uses Python environment for pre-commit hook
661
+ poetry run git commit -m "Your commit message"
662
+
663
+ # ❌ Wrong - Pre-commit hook won't run properly
664
+ git commit -m "Your commit message"
665
+ ```
666
+
667
+ This is necessary because the pre-commit hook needs access to the Python environment and installed packages.
668
+
669
+ ### 📌 Internal Functions
670
+
671
+ Functions and methods starting with `_` are for **internal use only**:
672
+
673
+ ```python
674
+ # ❌ Don't use these
675
+ from winipedia_utils.git.gitignore.gitignore import _get_gitignore_patterns
676
+
677
+ # ✅ Use public API instead
678
+ from winipedia_utils.git.gitignore.gitignore import add_patterns_to_gitignore
679
+ ```
680
+
681
+ ### 🎯 Philosophy
682
+
683
+ The core philosophy of Winipedia Utils is to:
684
+
685
+ > **Enforce good habits, ensure clean code, and save time when starting new projects**
686
+
687
+ By automating setup, testing, linting, formatting, and type checking, you can focus on writing business logic instead of configuring tools.
688
+
689
+ ---
690
+
691
+ ## Requirements
692
+
693
+ - **Python:** 3.12 or higher
694
+ - **Poetry:** For dependency management
695
+ - **Git:** For version control and pre-commit hooks
696
+
697
+ ---
698
+
699
+ ## License
700
+
701
+ MIT License - See [LICENSE](LICENSE) file for details
702
+
703
+ ---
704
+
705
+ ## Contributing
706
+
707
+ Contributions are welcome! Please ensure all code follows the project's quality standards:
708
+
709
+ - Type hints on all functions
710
+ - Comprehensive docstrings (Google style)
711
+ - Full test coverage
712
+ - Pass all linting and security checks
713
+
714
+ ---
715
+