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.
@@ -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
- "phosphorus>=0.10",
3
+ "uv_build>=0.11.0,<0.12.0",
4
4
  ]
5
- build-backend = "phosphorus.construction.api"
5
+ build-backend = "uv_build"
6
6
 
7
7
  [project]
8
8
  name = "pyutilkit"
9
- dynamic = [
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
- "License :: OSI Approved :: BSD License",
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.18",
51
- "ruff~=0.13",
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.ini_options]
138
+ [tool.pytest]
142
139
  minversion = "9.0"
143
140
  strict = true
144
- addopts = ["-ra", "-v"]
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,3 @@
1
+ from importlib.metadata import version
2
+
3
+ __version__ = version("pyutilkit")
@@ -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)
@@ -29,7 +29,7 @@ def handle_exceptions(
29
29
  except exceptions as exc:
30
30
  getattr(logger, log_level)(
31
31
  INGEST_ERROR,
32
- func.__name__,
32
+ func.__name__, # ty: ignore[unresolved-attribute]
33
33
  exc.__class__.__name__,
34
34
  args,
35
35
  kwargs,
@@ -1,11 +0,0 @@
1
- # BSD 3-Clause License
2
-
3
- Copyright &copy; 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/
@@ -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