kalib 0.17.13__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.
kalib-0.17.13/PKG-INFO ADDED
@@ -0,0 +1,522 @@
1
+ Metadata-Version: 2.1
2
+ Name: kalib
3
+ Version: 0.17.13
4
+ Summary: A comprehensive set of advanced utilities for Python programming, e.g. HTTP communication, string handling, logging enhancements, introspection, dynamic importing, property caching descriptors, data class extensions, serialization, etc.
5
+ Home-page: https://kalaver.in
6
+ License: MIT
7
+ Keywords: dataclasses,decorators,descriptors,http,import,introspection,logging,python,serialization,string,utilities
8
+ Author: Alex Kalaverin
9
+ Author-email: alex@kalaver.in
10
+ Requires-Python: >=3.10,<4.0
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Provides-Extra: all
22
+ Provides-Extra: data
23
+ Provides-Extra: deploy
24
+ Provides-Extra: pydantic
25
+ Provides-Extra: pyyaml
26
+ Provides-Extra: web
27
+ Requires-Dist: base2048 (>=0.1.3,<0.2.0) ; extra == "all" or extra == "data"
28
+ Requires-Dist: charset-normalizer (>=3.3.2,<4.0.0) ; extra == "all" or extra == "data"
29
+ Requires-Dist: fake_useragent (>=1.5.1,<2.0.0) ; extra == "all" or extra == "web"
30
+ Requires-Dist: feedparser (>=6.0.11,<7.0.0) ; extra == "all" or extra == "web"
31
+ Requires-Dist: gitpython (>=3.1.43,<4.0.0)
32
+ Requires-Dist: lxml (>=5.3.0,<6.0.0) ; extra == "all" or extra == "web"
33
+ Requires-Dist: msgpack (>=1.1.0,<2.0.0) ; extra == "all" or extra == "web"
34
+ Requires-Dist: natsort (>=8.4.0,<9.0.0)
35
+ Requires-Dist: orjson (>=3.10.7,<4.0.0)
36
+ Requires-Dist: pre-commit (>=3.7.1,<4.0.0) ; extra == "all" or extra == "deploy"
37
+ Requires-Dist: pydantic (>=2.7.4,<3.0.0) ; extra == "all" or extra == "pydantic"
38
+ Requires-Dist: python-magic (>=0.4.27,<0.5.0) ; extra == "all" or extra == "data"
39
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0) ; extra == "all" or extra == "pyyaml"
40
+ Requires-Dist: tomli (>=2.0.1,<3.0.0)
41
+ Requires-Dist: versioneer (>=0.29,<0.30) ; extra == "all" or extra == "deploy"
42
+ Requires-Dist: xxhash (>=3.5.0,<4.0.0)
43
+ Requires-Dist: yarl (>=1.13.1,<2.0.0) ; extra == "all" or extra == "web"
44
+ Requires-Dist: zstd (>=1.5.5.1,<2.0.0.0)
45
+ Description-Content-Type: text/markdown
46
+
47
+ # Advanced Python Utilities Module
48
+
49
+ This module provides a comprehensive set of utilities for advanced Python programming, including HTTP communication, string handling, logging enhancements, introspection, dynamic importing, property descriptors, data class extensions, and serialization. It is designed to facilitate complex application development by offering robust tools that extend Python's standard capabilities.
50
+
51
+ ## Table of Contents
52
+
53
+ - [HTTP Communication Utilities](#http-communication-utilities)
54
+ - [String Handling Enhancements](#string-handling-enhancements)
55
+ - [Advanced Logging System](#advanced-logging-system)
56
+ - [Introspection and Reflection Utilities](#introspection-and-reflection-utilities)
57
+ - [Dynamic Importing Tools](#dynamic-importing-tools)
58
+ - [Advanced Property Descriptors](#advanced-property-descriptors)
59
+ - [Data Class Extensions and Configuration Handling](#data-class-extensions-and-configuration-handling)
60
+ - [Serialization and Deserialization Utilities](#serialization-and-deserialization-utilities)
61
+
62
+ ## HTTP Communication Utilities
63
+
64
+ ### Overview
65
+
66
+ This component provides a robust toolkit for handling HTTP communication. It includes advanced features for error handling, response parsing, cookie management, and URL processing. The utilities streamline building HTTP clients and services by abstracting common patterns and offering flexible, extensible components.
67
+
68
+ ### Key Features
69
+
70
+ - **HTTPException Hierarchy**: A comprehensive set of exception classes for handling HTTP errors, based on status codes and error types.
71
+ - **Response Handling**: Utilities for parsing and processing HTTP responses, including automatic JSON decoding and error checking.
72
+ - **Cookie Management**: Tools for managing HTTP cookies, including parsing and formatting.
73
+ - **URL Processing**: Classes and functions for manipulating URLs, including query parameters and path components.
74
+ - **Serialization Decorators**: Decorators to facilitate serialization and deserialization of complex objects within the HTTP context.
75
+ - **Namespace Augmentation**: Enhancements to the HTTP namespace for convenient access to common utilities like `HTTP.URL`, `HTTP.Agent`, and `HTTP.Exception`.
76
+
77
+ ## String Handling Enhancements
78
+
79
+ ### Overview
80
+
81
+ Provides advanced string handling utilities focused on character encoding detection, conversion, and manipulation. It defines the `Str` class, acting as a wrapper around string or bytes objects, offering methods to handle various encoding scenarios and to facilitate text processing.
82
+
83
+ ### Key Features
84
+
85
+ - **Encoding and Decoding**: Convert between bytes and string representations, handling different character encodings.
86
+ - **Charset Detection**: Automatically detects the character encoding of input data using custom logic and libraries.
87
+ - **Lazy Proxying**: Proxies common string methods to the underlying string representation, allowing `Str` instances to behave like regular strings.
88
+ - **Tokenization**: Methods to split strings into tokens based on regular expression patterns.
89
+
90
+ ## Advanced Logging System
91
+
92
+ ### Overview
93
+
94
+ Enhances the standard Python logging system by introducing custom log levels, additional logging utilities, and a more flexible logger configuration. It provides advanced logging capabilities suitable for complex applications that require detailed logging and traceability.
95
+
96
+ ### Key Features
97
+
98
+ - **Custom Log Levels**: Defines additional log levels like `NOTICE`, `DEPRECATE`, and `VERBOSE` for finer-grained logging.
99
+ - **Logger Configuration**: Supports configuration from files (e.g., `logging.toml`), environment variables, or default settings.
100
+ - **Logger Extensions**: Provides a `Logger` class with enhanced methods for logging, including context-aware logging and deduplication of messages.
101
+ - **Integration with Modules**: Automatically injects the custom logger into modules, ensuring consistent logging behavior across the application.
102
+
103
+ ## Introspection and Reflection Utilities
104
+
105
+ ### Overview
106
+
107
+ Offers a collection of utility functions and classes for introspection, type checking, and reflection. It includes functions to analyze objects, their types, inheritance hierarchies, and modules.
108
+
109
+ ### Key Features
110
+
111
+ - **Type Checking Functions**: Utilities like `is_callable`, `is_collection`, and `is_iterable` for checking object types.
112
+ - **Inheritance Utilities**: Functions to iterate over an object's MRO, get attributes from superclasses, and analyze class hierarchies.
113
+ - **Module and Object Inspection**: Tools to get the module of an object, its fully qualified name, source file, and other metadata.
114
+ - **Stack Inspection**: Functions to analyze the call stack, filter stack traces, and determine stack frame offsets.
115
+
116
+ ## Dynamic Importing Tools
117
+
118
+ ### Overview
119
+
120
+ Provides utilities for dynamic importing of modules and objects, with support for caching, handling optional dependencies, and enhanced error reporting.
121
+
122
+ ### Key Features
123
+
124
+ - **Dynamic Importing**: Functions like `import_object` to import modules or objects by name at runtime.
125
+ - **Caching Imports**: `cached_import` function to memoize imports and improve performance.
126
+ - **Optional Dependencies**: `optional` function to handle optional imports gracefully, returning `None` or a default value if the module is not available.
127
+ - **Error Handling**: Detailed logging and error messages to aid in debugging import issues, including suggestions for missing packages.
128
+
129
+ ## Advanced Property Descriptors
130
+
131
+ ### Overview
132
+
133
+ Provides advanced property descriptors for Python classes, allowing the creation of instance, class, and mixed properties with optional caching capabilities. It includes decorators and base classes to facilitate the definition of properties that can behave differently depending on access context.
134
+
135
+ ### Key Features
136
+
137
+ - **Custom Property Decorators**: Decorators like `@prop` and `@pin` to define properties with custom behaviors.
138
+ - **Caching Support**: Ability to cache property results, optimizing performance for expensive computations.
139
+ - **Context-Aware Properties**: Properties that can differentiate between being accessed from an instance or a class.
140
+ - **Async Support**: Supports both synchronous and asynchronous property methods.
141
+
142
+ ## Data Class Extensions and Configuration Handling
143
+
144
+ ### Overview
145
+
146
+ Extends the standard `dataclasses` module with additional features such as validation, serialization, dynamic class creation, and integration with custom logging mechanisms.
147
+
148
+ ### Key Features
149
+
150
+ - **Custom Data Classes**: Enhanced `dataclass` decorator that supports extra parameters, memoization, and custom initialization.
151
+ - **Validation**: Automatic validation of field types and default values against the defined schema.
152
+ - **Serialization Methods**: Methods like `as_dict`, `as_json`, and `as_sql` for converting instances to different formats.
153
+ - **Dynamic Class Creation**: Utilities like `autoclass` and `simple` to generate classes dynamically based on configuration schemas.
154
+ - **Operator Overloading**: Overloaded operators (`&`, `|`, `^`, `-`, `+`) for combining and comparing data class instances.
155
+
156
+ ## Serialization and Deserialization Utilities
157
+
158
+ ### Overview
159
+
160
+ Provides advanced serialization and deserialization utilities, supporting multiple serialization backends, compression algorithms, and encoding schemes. It allows custom serialization of complex objects, automatic detection of serialization formats, and flexible data encoding and decoding options.
161
+
162
+ ### Key Features
163
+
164
+ - **Multiple Backends**: Supports serialization backends like `orjson` and standard `json`, with automatic selection.
165
+ - **Custom Serialization**: Ability to register custom serialization functions for specific classes.
166
+ - **Compression Support**: Utilizes compression libraries like `zstd` or `gzip` to compress serialized data.
167
+ - **Flexible Encoding**: Supports multiple encoding schemes such as Base16, Base32, Base64, Base85, and Base2048.
168
+ - **Automatic Backend Detection**: Deserialization functions automatically detect the serialization backend used.
169
+ - **Error Handling**: Robust exception handling and context-aware suppression of errors.
170
+
171
+ # Tasks
172
+
173
+ ## publish
174
+
175
+ Run: once
176
+ Requires: environment
177
+
178
+ Input: mode
179
+ Environment: mode=patch
180
+
181
+ Bumps project new version, build and publish the package to repository.
182
+
183
+ ```bash
184
+
185
+ xc bump-version "$mode"
186
+
187
+ .venv/bin/poetry build
188
+ .venv/bin/poetry publish
189
+
190
+ ```
191
+
192
+ ## bump-version
193
+
194
+ Run: once
195
+ Requires: environment
196
+
197
+ Inputs: mode
198
+ Environment: mode=patch
199
+
200
+ Prepare and commit a version update in a Git repository. Checks for uncommitted changes, ensures the current branch is master, verifies if there are any changes since the last tag, and bumps the version number.
201
+
202
+ After validating the readiness for an update, it prompts to proceed. Once confirmed, the script updates the pyproject.toml and .pre-commit-config.yaml files if necessary, commits the changes, tags the new version, and pushes the updates to the remote repository.
203
+
204
+ ```bash
205
+ #!/bin/zsh
206
+
207
+ uncommited="$(git diff --cached --name-only | sort -u | tr '\n' ' ' | xargs)"
208
+ if [ -n "$uncommited" ]; then
209
+ echo "uncommited changes found"
210
+ exit 1
211
+ fi
212
+
213
+ #
214
+
215
+ branch="$(git rev-parse --quiet --abbrev-ref HEAD 2>/dev/null)"
216
+ if [ -z "$branch" ]; then
217
+ exit 1
218
+ elif [ "$branch" == "master" ]; then
219
+ echo "using main master mode"
220
+ else
221
+ exit 1
222
+ fi
223
+
224
+ #
225
+
226
+ changes="$(git ls-files --deleted --modified --exclude-standard)"
227
+ changes="$(printf "$changes" | sort -u | tr '\n' ' ' | xargs)"
228
+
229
+ if [ "$changes" == "README.md" ]; then
230
+ echo "pipeline development mode"
231
+ elif [ -n "$changes" ]; then
232
+ echo "uncommited changes found"
233
+ exit 1
234
+ fi
235
+
236
+ current="$(git describe --tags --abbrev=0)"
237
+ [ -z "$current" ] && exit 1
238
+
239
+
240
+ amount="$(git rev-list --count $current..HEAD)"
241
+ uncommited="$(git diff --cached --name-only | sort -u | tr '\n' ' ' | xargs)"
242
+
243
+ if [ "$amount" -eq 0 ] && [ -z "$uncommited" ]; then
244
+ echo "no changes since $current"
245
+ exit 1
246
+ fi
247
+
248
+ version="$(bump "$mode" "$current")"
249
+ [ -z "$version" ] && exit 1
250
+
251
+ # non destructive stop here
252
+
253
+ git-restore-mtime --skip-missing || echo "datetime restoration failed, return: $?, skip"
254
+
255
+ ls -la
256
+
257
+ echo "we ready for upgrade $current -> ${version}, press ENTER twice to proceed or ESC+ENTER to exit"
258
+
259
+ counter=0
260
+ while : ; do
261
+ read -r key
262
+
263
+ if [[ $key == $'\e' ]]; then
264
+ exit 1
265
+
266
+ elif [ -z "$key" ]; then
267
+ counter=$((counter + 1))
268
+ if [ "$counter" -eq 2 ]; then
269
+ break
270
+ fi
271
+ fi
272
+ done
273
+
274
+ # actions starts here
275
+
276
+ xc update-pyproject "$current" "$version"
277
+
278
+ uncommited="$(git diff --cached --name-only | sort -u | tr '\n' ' ' | xargs)"
279
+ changes="$(git ls-files --deleted --modified --exclude-standard)"
280
+ changes="$(printf "$changes" | sort -u | tr '\n' ' ' | xargs)"
281
+
282
+ if [[ "$uncommited" =~ "\bpyproject\.toml\b" ]] || [[ "$changes" =~ "\bpyproject\.toml\b" ]]; then
283
+ xc add-pyproject
284
+ fi
285
+
286
+ if [[ "$uncommited" =~ "\bci/\.pre-commit-config\.yaml\b" ]] || [[ "$changes" =~ "\bci/\.pre-commit-config\.yaml\b" ]]; then
287
+ xc add-precommit
288
+ fi
289
+
290
+ uncommited="$(git diff --cached --name-only | sort -u | tr '\n' ' ' | xargs)"
291
+ if [ -n "$uncommited" ]; then
292
+ git commit -m "$branch: $version"
293
+ fi
294
+
295
+ git tag -a "$version" -m "$version" && \
296
+ git push --tags && \
297
+ git fetch --tags --force && \
298
+ git push origin $branch
299
+
300
+ echo "version update to ${version}"
301
+ ```
302
+
303
+ ## environment
304
+
305
+ Run: once
306
+
307
+ Make virtualenv for project build & test tools, install pre-push hook.
308
+
309
+ ```bash
310
+
311
+ if [ ! -d ".venv" ]; then
312
+ virtualenv --python python3.11 ".venv" && \
313
+ source ".venv/bin/activate" && \
314
+ .venv/bin/pip install --upgrade pip && \
315
+ .venv/bin/pip install --upgrade poetry pre-commit tomli tomli_w docformatter rstcheck
316
+
317
+ else
318
+ [ -f ".venv/bin/activate" ]
319
+
320
+ fi
321
+ pre-commit install --config ci/.pre-commit-config.yaml --install-hooks --hook-type pre-push
322
+ ```
323
+
324
+ ## autoupdate
325
+
326
+ Run: once
327
+
328
+ Autoupdate pre-commit hooks if the last update was more than 7 days ago.
329
+
330
+ ```bash
331
+
332
+ ctime="$(date +%s)"
333
+ mtime="$(git log -1 --format=%ct ci/.pre-commit-config.yaml)"
334
+
335
+ result=$(((7*86400) - (ctime - mtime)))
336
+
337
+ if [ "$result" -le 0 ]; then
338
+ update
339
+ fi
340
+
341
+ ```
342
+
343
+ ## update
344
+
345
+ Run: once
346
+ Requires: environment
347
+
348
+ Update all pre-commit hook versions to latest releases.
349
+
350
+ ```bash
351
+
352
+ .venv/bin/pre-commit autoupdate --config ci/.pre-commit-config.yaml --color always
353
+
354
+ ```
355
+
356
+ ## check
357
+
358
+ Requires: environment, autoupdate
359
+
360
+ Runs all defined pre-commit hooks.
361
+
362
+ ```bash
363
+ .venv/bin/pre-commit run --config ci/.pre-commit-config.yaml --color always --all
364
+ ```
365
+
366
+ ## clean
367
+
368
+ Run: once
369
+
370
+ Clean up the project working directory: remove build/, .venv/, and .ruff_cache/ directories, as well as all .pyc files and __pycache__ directories.
371
+
372
+ ```bash
373
+
374
+ rm -rf build/ || true
375
+ rm -rf .venv/ || true
376
+ rm -rf .ruff_cache/ || true
377
+
378
+ find . -name "*.pyc" -delete || true
379
+ find . -name "__pycache__" -type d -exec rm -rf {} + || true
380
+
381
+ ```
382
+
383
+ ## update-pyproject
384
+
385
+ Run: once
386
+ Requires: environment, autoupdate
387
+
388
+ Update version in pyproject.toml file based on provided old and new version tags. It validates the version format and ensures the current tag matches the project's version before writing the new version.
389
+
390
+ ```python
391
+ #!.venv/bin/python
392
+ from os import environ
393
+ from sys import argv, exit
394
+ from re import match
395
+ from pathlib import Path
396
+
397
+ import tomli_w
398
+ import tomllib
399
+
400
+ ROOT = Path(environ['PWD'])
401
+
402
+ def get_version(string):
403
+ try:
404
+ return match(r'^(\d+\.\d+\.\d+)$', string).group(1)
405
+ except Exception:
406
+ print(f'could not parse version from {string}')
407
+ exit(3)
408
+
409
+ if __name__ == '__main__':
410
+ try:
411
+ current_tag = get_version(argv[1])
412
+ version_tag = get_version(argv[2])
413
+ except IndexError:
414
+ print('usage: xc setver <old_tag> <new_tag>')
415
+ exit(1)
416
+
417
+ path = ROOT / 'pyproject.toml'
418
+ try:
419
+ with open(path, 'rb') as fd:
420
+ data = tomllib.load(fd)
421
+
422
+ except Exception:
423
+ print(f'could not load {path}')
424
+ exit(2)
425
+
426
+ try:
427
+ current_ver = get_version(data['tool']['poetry']['version'])
428
+ print(f'project version: {current_ver}')
429
+
430
+ except KeyError:
431
+ print(f'could not find version in {data}')
432
+ exit(2)
433
+
434
+ if current_tag != current_ver:
435
+ if current_ver == version_tag:
436
+ print(f'current version {current_ver} == {version_tag}, no update needed')
437
+ exit(0)
438
+
439
+ print(f'current tag {current_tag} != {current_ver} current version')
440
+ exit(4)
441
+
442
+ data['tool']['poetry']['version'] = version_tag
443
+
444
+ try:
445
+ with open(path, 'wb') as fd:
446
+ tomli_w.dump(data, fd)
447
+
448
+ print(f'project version -> {version_tag}')
449
+
450
+ except Exception:
451
+ print(f'could not write {path} with {data=}')
452
+ exit(5)
453
+ ```
454
+
455
+ ## add-precommit
456
+
457
+ Requires: environment, autoupdate
458
+
459
+ Check and format ci/.pre-commit-config.yaml. If any changes are made, it stages the file for the next commit.
460
+
461
+ ```bash
462
+
463
+ .venv/bin/pre-commit run check-yaml --config ci/.pre-commit-config.yaml --color always --file ci/.pre-commit-config.yaml || value="$?"
464
+
465
+ while true; do
466
+ value="0"
467
+ .venv/bin/pre-commit run yamlfix --config ci/.pre-commit-config.yaml --color always --file ci/.pre-commit-config.yaml || value="$?"
468
+
469
+ if [ "$value" -eq 0 ]; then
470
+ break
471
+
472
+ elif [ "$value" -eq 1 ]; then
473
+ continue
474
+
475
+ else
476
+ exit "$value"
477
+
478
+ fi
479
+ done
480
+
481
+ changes="$(git diff pyproject.toml)" || exit "$?"
482
+ changes="$(printf "$changes" | wc -l)"
483
+ if [ "$changes" -ne 0 ]; then
484
+ git add ci/.pre-commit-config.yaml
485
+ fi
486
+
487
+ ```
488
+
489
+ ## add-pyproject
490
+
491
+ Requires: environment, autoupdate
492
+
493
+ Check and format pyproject.toml. If any changes are made, it stages the file for the next commit.
494
+
495
+ ```bash
496
+
497
+ .venv/bin/pre-commit run check-toml --config ci/.pre-commit-config.yaml --color always --file pyproject.toml || value="$?"
498
+
499
+ while true; do
500
+ value="0"
501
+ .venv/bin/pre-commit run pretty-format-toml --config ci/.pre-commit-config.yaml --color always --file pyproject.toml || value="$?"
502
+
503
+ if [ "$value" -eq 0 ]; then
504
+ break
505
+
506
+ elif [ "$value" -eq 1 ]; then
507
+ continue
508
+
509
+ else
510
+ exit "$value"
511
+
512
+ fi
513
+ done
514
+
515
+ changes="$(git diff pyproject.toml)" || exit "$?"
516
+ changes="$(printf "$changes" | wc -l)"
517
+ if [ "$changes" -ne 0 ]; then
518
+ git add pyproject.toml
519
+ fi
520
+
521
+ ```
522
+