pyutilkit 0.11.0__tar.gz → 0.11.0.post1__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.
- pyutilkit-0.11.0.post1/PKG-INFO +136 -0
- pyutilkit-0.11.0.post1/docs/README.md +117 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/pyproject.toml +13 -14
- pyutilkit-0.11.0.post1/src/pyutilkit/__version__.py +3 -0
- pyutilkit-0.11.0.post1/src/pyutilkit/classes.py +26 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/files.py +1 -1
- pyutilkit-0.11.0/LICENSE.md +0 -11
- pyutilkit-0.11.0/PKG-INFO +0 -65
- pyutilkit-0.11.0/docs/README.md +0 -46
- pyutilkit-0.11.0/src/pyutilkit/__version__.py +0 -1
- pyutilkit-0.11.0/src/pyutilkit/classes.py +0 -21
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/__init__.py +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/data/__init__.py +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/data/timezones.py +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/date_utils.py +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/py.typed +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/subprocess.py +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/term.py +0 -0
- {pyutilkit-0.11.0 → pyutilkit-0.11.0.post1}/src/pyutilkit/timing.py +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: pyutilkit
|
|
3
|
+
Version: 0.11.0.post1
|
|
4
|
+
Summary: python's missing batteries
|
|
5
|
+
Keywords: utils
|
|
6
|
+
Author: Stephanos Kuma
|
|
7
|
+
Author-email: Stephanos Kuma <stephanos@kuma.ai>
|
|
8
|
+
License: BSD-3-Clause
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Requires-Dist: tzdata ; os_name == 'nt'
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Project-URL: homepage, https://pyutilkit.readthedocs.io/en/stable/
|
|
16
|
+
Project-URL: repository, https://github.com/spapanik/pyutilkit
|
|
17
|
+
Project-URL: documentation, https://pyutilkit.readthedocs.io/en/stable/
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# pyutilkit: python's missing batteries
|
|
21
|
+
|
|
22
|
+
[![build][build_badge]][build_url]
|
|
23
|
+
[![lint][lint_badge]][lint_url]
|
|
24
|
+
[![tests][tests_badge]][tests_url]
|
|
25
|
+
[![license][licence_badge]][licence_url]
|
|
26
|
+
[![codecov][codecov_badge]][codecov_url]
|
|
27
|
+
[![readthedocs][readthedocs_badge]][readthedocs_url]
|
|
28
|
+
[![pypi][pypi_badge]][pypi_url]
|
|
29
|
+
[![downloads][pepy_badge]][pepy_url]
|
|
30
|
+
[![build automation: yam][yam_badge]][yam_url]
|
|
31
|
+
[![Lint: ruff][ruff_badge]][ruff_url]
|
|
32
|
+
|
|
33
|
+
Python has long maintained the philosophy of "batteries included", providing users with a rich
|
|
34
|
+
standard library that avoids the need for third-party tools for most tasks. Some packages are so
|
|
35
|
+
common they have achieved similar status to the standard library. Yet, certain utilities are
|
|
36
|
+
reimplemented across countless projects. This lightweight library, with minimal dependencies,
|
|
37
|
+
aims to eliminate that repetition.
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
Install pyutilkit:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install pyutilkit
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or with uv (recommended for speed):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
uv pip install pyutilkit
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Basic usage example:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from pyutilkit.date_utils import now
|
|
57
|
+
from pyutilkit.timing import Stopwatch
|
|
58
|
+
from pyutilkit.term import SGRString, SGRCodes
|
|
59
|
+
|
|
60
|
+
# Get current time in any timezone
|
|
61
|
+
from zoneinfo import ZoneInfo
|
|
62
|
+
tokyo_time = now(ZoneInfo("Asia/Tokyo"))
|
|
63
|
+
print(f"Current time in Tokyo: {tokyo_time}")
|
|
64
|
+
|
|
65
|
+
# Measure execution time
|
|
66
|
+
stopwatch = Stopwatch()
|
|
67
|
+
with stopwatch:
|
|
68
|
+
# Your code here
|
|
69
|
+
result = sum(range(1000000))
|
|
70
|
+
print(f"Computation took: {stopwatch.elapsed}")
|
|
71
|
+
|
|
72
|
+
# Colorful terminal output
|
|
73
|
+
success = SGRString("✓ Task completed", params=[SGRCodes.GREEN, SGRCodes.BOLD])
|
|
74
|
+
success.print()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Key Features
|
|
78
|
+
|
|
79
|
+
- **🕐 Timezone Utilities**: Robust datetime handling with cross-platform timezone support, ISO parsing (including Zulu timezone), and seamless timezone conversion
|
|
80
|
+
- **⏱️ High-Precision Timing**: Nanosecond-precision timing with human-readable formatting, lap tracking, and stopwatch functionality
|
|
81
|
+
- **🎨 Terminal Formatting**: ANSI color codes with smart TTY detection, automatic style stripping for piped output, and convenient header formatting
|
|
82
|
+
- **🛡️ Error Handling**: Elegant exception handling decorator that logs errors and returns defaults instead of raising exceptions
|
|
83
|
+
- **📁 File Utilities**: Efficient SHA-256 file hashing with buffered reading for large files
|
|
84
|
+
- **🚀 Subprocess Enhancement**: Run shell commands with real-time output streaming, automatic timing, and structured results
|
|
85
|
+
- **🔧 Design Patterns**: Thread-safe Singleton metaclass implementation
|
|
86
|
+
- **✨ Zero Dependencies**: Pure Python using only standard library (except optional tzdata on Windows)
|
|
87
|
+
- **🧪 Fully Tested**: 100% test coverage with comprehensive type annotations
|
|
88
|
+
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
- **[Installation Guide](installation.md)** - Setup instructions and requirements
|
|
92
|
+
- **[Usage Guide](usage/index.md)** - Comprehensive examples and tutorials for all modules
|
|
93
|
+
- [Classes](usage/classes.md) - Singleton pattern implementation
|
|
94
|
+
- [Date Utilities](usage/date_utils.md) - Timezone-aware datetime operations
|
|
95
|
+
- [File Utilities](usage/files.md) - Exception handling and file hashing
|
|
96
|
+
- [Subprocess](usage/subprocess.md) - Enhanced command execution
|
|
97
|
+
- [Terminal](usage/term.md) - Terminal formatting and colors
|
|
98
|
+
- [Timing](usage/timing.md) - Performance measurement and benchmarking
|
|
99
|
+
- **[Changelog](CHANGELOG.md)** - Version history and changes
|
|
100
|
+
- **[Code of Conduct](CODE_OF_CONDUCT.md)** - Community guidelines
|
|
101
|
+
|
|
102
|
+
## Requirements
|
|
103
|
+
|
|
104
|
+
- Python 3.10 or higher
|
|
105
|
+
- No external dependencies (tzdata is automatically installed on Windows)
|
|
106
|
+
|
|
107
|
+
## Links
|
|
108
|
+
|
|
109
|
+
- [Full Documentation](https://pyutilkit.readthedocs.io/en/stable/)
|
|
110
|
+
- [PyPI Package](https://pypi.org/project/pyutilkit)
|
|
111
|
+
- [GitHub Repository](https://github.com/spapanik/pyutilkit)
|
|
112
|
+
- [Changelog](CHANGELOG.md)
|
|
113
|
+
- [Report Issues](https://github.com/spapanik/pyutilkit/issues)
|
|
114
|
+
|
|
115
|
+
[build_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml/badge.svg
|
|
116
|
+
[build_url]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml
|
|
117
|
+
[lint_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml/badge.svg
|
|
118
|
+
[lint_url]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml
|
|
119
|
+
[tests_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml/badge.svg
|
|
120
|
+
[tests_url]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml
|
|
121
|
+
[licence_badge]: https://img.shields.io/pypi/l/pyutilkit
|
|
122
|
+
[licence_url]: https://pyutilkit.readthedocs.io/en/stable/LICENSE/
|
|
123
|
+
[codecov_badge]: https://codecov.io/github/spapanik/pyutilkit/graph/badge.svg?token=Q20F84BW72
|
|
124
|
+
[codecov_url]: https://codecov.io/github/spapanik/pyutilkit
|
|
125
|
+
[readthedocs_badge]: https://readthedocs.org/projects/pyutilkit/badge/?version=latest
|
|
126
|
+
[readthedocs_url]: https://pyutilkit.readthedocs.io/en/latest/
|
|
127
|
+
[pypi_badge]: https://img.shields.io/pypi/v/pyutilkit
|
|
128
|
+
[pypi_url]: https://pypi.org/project/pyutilkit
|
|
129
|
+
[pepy_badge]: https://pepy.tech/badge/pyutilkit
|
|
130
|
+
[pepy_url]: https://pepy.tech/project/pyutilkit
|
|
131
|
+
[yam_badge]: https://img.shields.io/badge/build%20automation-yamk-success
|
|
132
|
+
[yam_url]: https://github.com/spapanik/yamk
|
|
133
|
+
[ruff_badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json
|
|
134
|
+
[ruff_url]: https://github.com/charliermarsh/ruff
|
|
135
|
+
[Documentation]: https://pyutilkit.readthedocs.io/en/stable/
|
|
136
|
+
[Changelog]: https://pyutilkit.readthedocs.io/en/stable/CHANGELOG/
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# pyutilkit: python's missing batteries
|
|
2
|
+
|
|
3
|
+
[![build][build_badge]][build_url]
|
|
4
|
+
[![lint][lint_badge]][lint_url]
|
|
5
|
+
[![tests][tests_badge]][tests_url]
|
|
6
|
+
[![license][licence_badge]][licence_url]
|
|
7
|
+
[![codecov][codecov_badge]][codecov_url]
|
|
8
|
+
[![readthedocs][readthedocs_badge]][readthedocs_url]
|
|
9
|
+
[![pypi][pypi_badge]][pypi_url]
|
|
10
|
+
[![downloads][pepy_badge]][pepy_url]
|
|
11
|
+
[![build automation: yam][yam_badge]][yam_url]
|
|
12
|
+
[![Lint: ruff][ruff_badge]][ruff_url]
|
|
13
|
+
|
|
14
|
+
Python has long maintained the philosophy of "batteries included", providing users with a rich
|
|
15
|
+
standard library that avoids the need for third-party tools for most tasks. Some packages are so
|
|
16
|
+
common they have achieved similar status to the standard library. Yet, certain utilities are
|
|
17
|
+
reimplemented across countless projects. This lightweight library, with minimal dependencies,
|
|
18
|
+
aims to eliminate that repetition.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
Install pyutilkit:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install pyutilkit
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or with uv (recommended for speed):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv pip install pyutilkit
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Basic usage example:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from pyutilkit.date_utils import now
|
|
38
|
+
from pyutilkit.timing import Stopwatch
|
|
39
|
+
from pyutilkit.term import SGRString, SGRCodes
|
|
40
|
+
|
|
41
|
+
# Get current time in any timezone
|
|
42
|
+
from zoneinfo import ZoneInfo
|
|
43
|
+
tokyo_time = now(ZoneInfo("Asia/Tokyo"))
|
|
44
|
+
print(f"Current time in Tokyo: {tokyo_time}")
|
|
45
|
+
|
|
46
|
+
# Measure execution time
|
|
47
|
+
stopwatch = Stopwatch()
|
|
48
|
+
with stopwatch:
|
|
49
|
+
# Your code here
|
|
50
|
+
result = sum(range(1000000))
|
|
51
|
+
print(f"Computation took: {stopwatch.elapsed}")
|
|
52
|
+
|
|
53
|
+
# Colorful terminal output
|
|
54
|
+
success = SGRString("✓ Task completed", params=[SGRCodes.GREEN, SGRCodes.BOLD])
|
|
55
|
+
success.print()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Key Features
|
|
59
|
+
|
|
60
|
+
- **🕐 Timezone Utilities**: Robust datetime handling with cross-platform timezone support, ISO parsing (including Zulu timezone), and seamless timezone conversion
|
|
61
|
+
- **⏱️ High-Precision Timing**: Nanosecond-precision timing with human-readable formatting, lap tracking, and stopwatch functionality
|
|
62
|
+
- **🎨 Terminal Formatting**: ANSI color codes with smart TTY detection, automatic style stripping for piped output, and convenient header formatting
|
|
63
|
+
- **🛡️ Error Handling**: Elegant exception handling decorator that logs errors and returns defaults instead of raising exceptions
|
|
64
|
+
- **📁 File Utilities**: Efficient SHA-256 file hashing with buffered reading for large files
|
|
65
|
+
- **🚀 Subprocess Enhancement**: Run shell commands with real-time output streaming, automatic timing, and structured results
|
|
66
|
+
- **🔧 Design Patterns**: Thread-safe Singleton metaclass implementation
|
|
67
|
+
- **✨ Zero Dependencies**: Pure Python using only standard library (except optional tzdata on Windows)
|
|
68
|
+
- **🧪 Fully Tested**: 100% test coverage with comprehensive type annotations
|
|
69
|
+
|
|
70
|
+
## Documentation
|
|
71
|
+
|
|
72
|
+
- **[Installation Guide](installation.md)** - Setup instructions and requirements
|
|
73
|
+
- **[Usage Guide](usage/index.md)** - Comprehensive examples and tutorials for all modules
|
|
74
|
+
- [Classes](usage/classes.md) - Singleton pattern implementation
|
|
75
|
+
- [Date Utilities](usage/date_utils.md) - Timezone-aware datetime operations
|
|
76
|
+
- [File Utilities](usage/files.md) - Exception handling and file hashing
|
|
77
|
+
- [Subprocess](usage/subprocess.md) - Enhanced command execution
|
|
78
|
+
- [Terminal](usage/term.md) - Terminal formatting and colors
|
|
79
|
+
- [Timing](usage/timing.md) - Performance measurement and benchmarking
|
|
80
|
+
- **[Changelog](CHANGELOG.md)** - Version history and changes
|
|
81
|
+
- **[Code of Conduct](CODE_OF_CONDUCT.md)** - Community guidelines
|
|
82
|
+
|
|
83
|
+
## Requirements
|
|
84
|
+
|
|
85
|
+
- Python 3.10 or higher
|
|
86
|
+
- No external dependencies (tzdata is automatically installed on Windows)
|
|
87
|
+
|
|
88
|
+
## Links
|
|
89
|
+
|
|
90
|
+
- [Full Documentation](https://pyutilkit.readthedocs.io/en/stable/)
|
|
91
|
+
- [PyPI Package](https://pypi.org/project/pyutilkit)
|
|
92
|
+
- [GitHub Repository](https://github.com/spapanik/pyutilkit)
|
|
93
|
+
- [Changelog](CHANGELOG.md)
|
|
94
|
+
- [Report Issues](https://github.com/spapanik/pyutilkit/issues)
|
|
95
|
+
|
|
96
|
+
[build_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml/badge.svg
|
|
97
|
+
[build_url]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml
|
|
98
|
+
[lint_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml/badge.svg
|
|
99
|
+
[lint_url]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml
|
|
100
|
+
[tests_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml/badge.svg
|
|
101
|
+
[tests_url]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml
|
|
102
|
+
[licence_badge]: https://img.shields.io/pypi/l/pyutilkit
|
|
103
|
+
[licence_url]: https://pyutilkit.readthedocs.io/en/stable/LICENSE/
|
|
104
|
+
[codecov_badge]: https://codecov.io/github/spapanik/pyutilkit/graph/badge.svg?token=Q20F84BW72
|
|
105
|
+
[codecov_url]: https://codecov.io/github/spapanik/pyutilkit
|
|
106
|
+
[readthedocs_badge]: https://readthedocs.org/projects/pyutilkit/badge/?version=latest
|
|
107
|
+
[readthedocs_url]: https://pyutilkit.readthedocs.io/en/latest/
|
|
108
|
+
[pypi_badge]: https://img.shields.io/pypi/v/pyutilkit
|
|
109
|
+
[pypi_url]: https://pypi.org/project/pyutilkit
|
|
110
|
+
[pepy_badge]: https://pepy.tech/badge/pyutilkit
|
|
111
|
+
[pepy_url]: https://pepy.tech/project/pyutilkit
|
|
112
|
+
[yam_badge]: https://img.shields.io/badge/build%20automation-yamk-success
|
|
113
|
+
[yam_url]: https://github.com/spapanik/yamk
|
|
114
|
+
[ruff_badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json
|
|
115
|
+
[ruff_url]: https://github.com/charliermarsh/ruff
|
|
116
|
+
[Documentation]: https://pyutilkit.readthedocs.io/en/stable/
|
|
117
|
+
[Changelog]: https://pyutilkit.readthedocs.io/en/stable/CHANGELOG/
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
requires = [
|
|
3
|
-
"
|
|
3
|
+
"uv_build>=0.11.0,<0.12.0",
|
|
4
4
|
]
|
|
5
|
-
build-backend = "
|
|
5
|
+
build-backend = "uv_build"
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "pyutilkit"
|
|
9
|
-
|
|
10
|
-
"version",
|
|
11
|
-
]
|
|
9
|
+
version = "0.11.0.post1"
|
|
12
10
|
|
|
13
11
|
authors = [
|
|
14
12
|
{ name = "Stephanos Kuma", email = "stephanos@kuma.ai" },
|
|
@@ -24,7 +22,7 @@ classifiers = [
|
|
|
24
22
|
"Development Status :: 4 - Beta",
|
|
25
23
|
"Operating System :: OS Independent",
|
|
26
24
|
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
-
"
|
|
25
|
+
"Intended Audience :: Developers",
|
|
28
26
|
]
|
|
29
27
|
|
|
30
28
|
requires-python = ">=3.10"
|
|
@@ -47,8 +45,9 @@ dev = [
|
|
|
47
45
|
{ include-group = "docs" },
|
|
48
46
|
]
|
|
49
47
|
lint = [
|
|
50
|
-
"mypy~=1.
|
|
51
|
-
"ruff~=0.
|
|
48
|
+
"mypy~=1.19",
|
|
49
|
+
"ruff~=0.15",
|
|
50
|
+
"ty~=0.0.26",
|
|
52
51
|
{ include-group = "test_core" },
|
|
53
52
|
]
|
|
54
53
|
test = [
|
|
@@ -67,9 +66,6 @@ docs = [
|
|
|
67
66
|
"pymdown-extensions~=10.15",
|
|
68
67
|
]
|
|
69
68
|
|
|
70
|
-
[tool.phosphorus.dynamic]
|
|
71
|
-
version = { file = "src/pyutilkit/__version__.py" }
|
|
72
|
-
|
|
73
69
|
[tool.mypy]
|
|
74
70
|
check_untyped_defs = true
|
|
75
71
|
disallow_any_decorated = true
|
|
@@ -122,6 +118,7 @@ ignore = [
|
|
|
122
118
|
"FBT001", # Test arguments are handled by pytest
|
|
123
119
|
"PLR2004", # Tests should contain magic number comparisons
|
|
124
120
|
"S101", # Pytest needs assert statements
|
|
121
|
+
"SLF001", # Tests need to access private members for coverage
|
|
125
122
|
]
|
|
126
123
|
|
|
127
124
|
[tool.ruff.lint.flake8-tidy-imports]
|
|
@@ -138,13 +135,15 @@ forced-separate = [
|
|
|
138
135
|
]
|
|
139
136
|
split-on-trailing-comma = false
|
|
140
137
|
|
|
141
|
-
[tool.pytest
|
|
138
|
+
[tool.pytest]
|
|
142
139
|
minversion = "9.0"
|
|
143
140
|
strict = true
|
|
144
|
-
addopts = [
|
|
141
|
+
addopts = [
|
|
142
|
+
"-ra",
|
|
143
|
+
"-v",
|
|
144
|
+
]
|
|
145
145
|
testpaths = [
|
|
146
146
|
"tests",
|
|
147
|
-
"integration",
|
|
148
147
|
]
|
|
149
148
|
|
|
150
149
|
[tool.coverage.run]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import threading
|
|
4
|
+
from typing import TypeVar, cast
|
|
5
|
+
|
|
6
|
+
_T = TypeVar("_T")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Singleton(type):
|
|
10
|
+
instance: object
|
|
11
|
+
_lock: threading.Lock
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
cls, name: str, bases: tuple[type[object], ...], namespace: dict[str, object]
|
|
15
|
+
) -> None:
|
|
16
|
+
super().__init__(name, bases, namespace)
|
|
17
|
+
cls.instance = None
|
|
18
|
+
cls._lock = threading.Lock()
|
|
19
|
+
|
|
20
|
+
def __call__(cls: type[_T]) -> _T:
|
|
21
|
+
mcs = cast("Singleton", cls)
|
|
22
|
+
if mcs.instance is None:
|
|
23
|
+
with mcs._lock:
|
|
24
|
+
if mcs.instance is None:
|
|
25
|
+
mcs.instance = super(Singleton, mcs).__call__()
|
|
26
|
+
return cast("_T", mcs.instance)
|
pyutilkit-0.11.0/LICENSE.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# BSD 3-Clause License
|
|
2
|
-
|
|
3
|
-
Copyright © 2025 Stephanos Kuma.
|
|
4
|
-
|
|
5
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
6
|
-
|
|
7
|
-
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
8
|
-
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
-
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
-
|
|
11
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
pyutilkit-0.11.0/PKG-INFO
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: pyutilkit
|
|
3
|
-
Version: 0.11.0
|
|
4
|
-
Summary: python's missing batteries
|
|
5
|
-
Home-page: https://pyutilkit.readthedocs.io/en/stable/
|
|
6
|
-
License: BSD-3-Clause
|
|
7
|
-
Keywords: utils
|
|
8
|
-
Author: Stephanos Kuma
|
|
9
|
-
Author-email: "Stephanos Kuma" <stephanos@kuma.ai>
|
|
10
|
-
Requires-Python: >=3.10
|
|
11
|
-
Classifier: Development Status :: 4 - Beta
|
|
12
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
-
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
-
Requires-Dist: tzdata ; os_name == 'nt'
|
|
16
|
-
Project-URL: Documentation, https://pyutilkit.readthedocs.io/en/stable/
|
|
17
|
-
Project-URL: Repository, https://github.com/spapanik/pyutilkit
|
|
18
|
-
Description-Content-Type: text/markdown
|
|
19
|
-
|
|
20
|
-
# pyutilkit: python's missing batteries
|
|
21
|
-
|
|
22
|
-
[![build][build_badge]][build_url]
|
|
23
|
-
[![lint][lint_badge]][lint_url]
|
|
24
|
-
[![tests][tests_badge]][tests_url]
|
|
25
|
-
[![license][licence_badge]][licence_url]
|
|
26
|
-
[![codecov][codecov_badge]][codecov_url]
|
|
27
|
-
[![readthedocs][readthedocs_badge]][readthedocs_url]
|
|
28
|
-
[![pypi][pypi_badge]][pypi_url]
|
|
29
|
-
[![downloads][pepy_badge]][pepy_url]
|
|
30
|
-
[![build automation: yam][yam_badge]][yam_url]
|
|
31
|
-
[![Lint: ruff][ruff_badge]][ruff_url]
|
|
32
|
-
|
|
33
|
-
The Python has long maintained the philosophy of "batteries included", giving the user
|
|
34
|
-
a rich standard library, avoiding the need for third party tools for most work. Some packages
|
|
35
|
-
are so common, that the have a similar status to the standard library. Still, some code seems
|
|
36
|
-
to be written time and again, with every project. This small library, with minimal requirements,
|
|
37
|
-
hopes to stop this repetition.
|
|
38
|
-
|
|
39
|
-
## Links
|
|
40
|
-
|
|
41
|
-
- [Documentation]
|
|
42
|
-
- [Changelog]
|
|
43
|
-
|
|
44
|
-
[build_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml/badge.svg
|
|
45
|
-
[build_url]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml
|
|
46
|
-
[lint_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml/badge.svg
|
|
47
|
-
[lint_url]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml
|
|
48
|
-
[tests_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml/badge.svg
|
|
49
|
-
[tests_url]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml
|
|
50
|
-
[licence_badge]: https://img.shields.io/pypi/l/pyutilkit
|
|
51
|
-
[licence_url]: https://pyutilkit.readthedocs.io/en/stable/LICENSE/
|
|
52
|
-
[codecov_badge]: https://codecov.io/github/spapanik/pyutilkit/graph/badge.svg?token=Q20F84BW72
|
|
53
|
-
[codecov_url]: https://codecov.io/github/spapanik/pyutilkit
|
|
54
|
-
[readthedocs_badge]: https://readthedocs.org/projects/pyutilkit/badge/?version=latest
|
|
55
|
-
[readthedocs_url]: https://pyutilkit.readthedocs.io/en/latest/
|
|
56
|
-
[pypi_badge]: https://img.shields.io/pypi/v/pyutilkit
|
|
57
|
-
[pypi_url]: https://pypi.org/project/pyutilkit
|
|
58
|
-
[pepy_badge]: https://pepy.tech/badge/pyutilkit
|
|
59
|
-
[pepy_url]: https://pepy.tech/project/pyutilkit
|
|
60
|
-
[yam_badge]: https://img.shields.io/badge/build%20automation-yamk-success
|
|
61
|
-
[yam_url]: https://github.com/spapanik/yamk
|
|
62
|
-
[ruff_badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json
|
|
63
|
-
[ruff_url]: https://github.com/charliermarsh/ruff
|
|
64
|
-
[Documentation]: https://pyutilkit.readthedocs.io/en/stable/
|
|
65
|
-
[Changelog]: https://pyutilkit.readthedocs.io/en/stable/CHANGELOG/
|
pyutilkit-0.11.0/docs/README.md
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# pyutilkit: python's missing batteries
|
|
2
|
-
|
|
3
|
-
[![build][build_badge]][build_url]
|
|
4
|
-
[![lint][lint_badge]][lint_url]
|
|
5
|
-
[![tests][tests_badge]][tests_url]
|
|
6
|
-
[![license][licence_badge]][licence_url]
|
|
7
|
-
[![codecov][codecov_badge]][codecov_url]
|
|
8
|
-
[![readthedocs][readthedocs_badge]][readthedocs_url]
|
|
9
|
-
[![pypi][pypi_badge]][pypi_url]
|
|
10
|
-
[![downloads][pepy_badge]][pepy_url]
|
|
11
|
-
[![build automation: yam][yam_badge]][yam_url]
|
|
12
|
-
[![Lint: ruff][ruff_badge]][ruff_url]
|
|
13
|
-
|
|
14
|
-
The Python has long maintained the philosophy of "batteries included", giving the user
|
|
15
|
-
a rich standard library, avoiding the need for third party tools for most work. Some packages
|
|
16
|
-
are so common, that the have a similar status to the standard library. Still, some code seems
|
|
17
|
-
to be written time and again, with every project. This small library, with minimal requirements,
|
|
18
|
-
hopes to stop this repetition.
|
|
19
|
-
|
|
20
|
-
## Links
|
|
21
|
-
|
|
22
|
-
- [Documentation]
|
|
23
|
-
- [Changelog]
|
|
24
|
-
|
|
25
|
-
[build_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml/badge.svg
|
|
26
|
-
[build_url]: https://github.com/spapanik/pyutilkit/actions/workflows/build.yml
|
|
27
|
-
[lint_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml/badge.svg
|
|
28
|
-
[lint_url]: https://github.com/spapanik/pyutilkit/actions/workflows/lint.yml
|
|
29
|
-
[tests_badge]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml/badge.svg
|
|
30
|
-
[tests_url]: https://github.com/spapanik/pyutilkit/actions/workflows/tests.yml
|
|
31
|
-
[licence_badge]: https://img.shields.io/pypi/l/pyutilkit
|
|
32
|
-
[licence_url]: https://pyutilkit.readthedocs.io/en/stable/LICENSE/
|
|
33
|
-
[codecov_badge]: https://codecov.io/github/spapanik/pyutilkit/graph/badge.svg?token=Q20F84BW72
|
|
34
|
-
[codecov_url]: https://codecov.io/github/spapanik/pyutilkit
|
|
35
|
-
[readthedocs_badge]: https://readthedocs.org/projects/pyutilkit/badge/?version=latest
|
|
36
|
-
[readthedocs_url]: https://pyutilkit.readthedocs.io/en/latest/
|
|
37
|
-
[pypi_badge]: https://img.shields.io/pypi/v/pyutilkit
|
|
38
|
-
[pypi_url]: https://pypi.org/project/pyutilkit
|
|
39
|
-
[pepy_badge]: https://pepy.tech/badge/pyutilkit
|
|
40
|
-
[pepy_url]: https://pepy.tech/project/pyutilkit
|
|
41
|
-
[yam_badge]: https://img.shields.io/badge/build%20automation-yamk-success
|
|
42
|
-
[yam_url]: https://github.com/spapanik/yamk
|
|
43
|
-
[ruff_badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json
|
|
44
|
-
[ruff_url]: https://github.com/charliermarsh/ruff
|
|
45
|
-
[Documentation]: https://pyutilkit.readthedocs.io/en/stable/
|
|
46
|
-
[Changelog]: https://pyutilkit.readthedocs.io/en/stable/CHANGELOG/
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.11.0"
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import threading
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Singleton(type):
|
|
7
|
-
instance: type | None
|
|
8
|
-
|
|
9
|
-
def __init__(
|
|
10
|
-
cls, name: str, bases: tuple[type[object], ...], namespace: dict[str, object]
|
|
11
|
-
) -> None:
|
|
12
|
-
super().__init__(name, bases, namespace)
|
|
13
|
-
cls.instance = None
|
|
14
|
-
cls._lock = threading.Lock()
|
|
15
|
-
|
|
16
|
-
def __call__(cls) -> type:
|
|
17
|
-
if cls.instance is None:
|
|
18
|
-
with cls._lock:
|
|
19
|
-
if cls.instance is None:
|
|
20
|
-
cls.instance = super().__call__()
|
|
21
|
-
return cls.instance
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|