python-utils 2.5.6__py3-none-any.whl → 4.0.0__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.
@@ -0,0 +1,389 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-utils
3
+ Version: 4.0.0
4
+ Summary: Python Utils is a module with some convenient utilities not included with the standard Python install
5
+ Keywords: utils,utilities,helpers,typing,typed,async,lazy-imports
6
+ Author: Rick van Hattem
7
+ Author-email: Rick van Hattem <wolph@wol.ph>
8
+ License-Expression: BSD-3-Clause
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: Implementation :: CPython
21
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
22
+ Classifier: Typing :: Typed
23
+ Requires-Dist: typing-extensions>3.10.0.2
24
+ Requires-Dist: sphinx ; extra == 'docs'
25
+ Requires-Dist: furo ; extra == 'docs'
26
+ Requires-Dist: myst-parser ; extra == 'docs'
27
+ Requires-Dist: loguru ; extra == 'loguru'
28
+ Requires-Dist: pytest ; extra == 'tests'
29
+ Requires-Dist: pytest-cov ; extra == 'tests'
30
+ Requires-Dist: pytest-asyncio ; extra == 'tests'
31
+ Requires-Dist: loguru ; extra == 'tests'
32
+ Requires-Dist: blessings ; extra == 'tests'
33
+ Requires-Python: >=3.10
34
+ Project-URL: Homepage, https://github.com/WoLpH/python-utils
35
+ Project-URL: Documentation, https://python-utils.readthedocs.io/
36
+ Project-URL: Repository, https://github.com/WoLpH/python-utils
37
+ Project-URL: Changelog, https://github.com/WoLpH/python-utils/releases
38
+ Provides-Extra: docs
39
+ Provides-Extra: loguru
40
+ Provides-Extra: tests
41
+ Description-Content-Type: text/markdown
42
+
43
+ <div align="center">
44
+
45
+ <img src="https://raw.githubusercontent.com/WoLpH/python-utils/develop/docs/_static/banner.svg" alt="python-utils" width="720">
46
+
47
+ # ⚡ Python Utils
48
+
49
+ **The fast, fully-typed stdlib helpers you keep rewriting — in one tiny, dependency-light package.**
50
+
51
+ [![PyPI version](https://img.shields.io/pypi/v/python-utils.svg?logo=pypi&logoColor=white)](https://pypi.python.org/pypi/python-utils)
52
+ [![Python versions](https://img.shields.io/pypi/pyversions/python-utils.svg?logo=python&logoColor=white)](https://pypi.python.org/pypi/python-utils)
53
+ [![CI](https://github.com/WoLpH/python-utils/actions/workflows/ci.yml/badge.svg)](https://github.com/WoLpH/python-utils/actions/workflows/ci.yml)
54
+ [![Coverage Status](https://coveralls.io/repos/github/WoLpH/python-utils/badge.svg?branch=develop)](https://coveralls.io/github/WoLpH/python-utils?branch=develop)
55
+ [![Typed](https://img.shields.io/badge/typed-mypy%20%7C%20pyright%20%7C%20pyrefly-blue.svg)](https://github.com/WoLpH/python-utils)
56
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
57
+ [![License](https://img.shields.io/pypi/l/python-utils.svg)](https://github.com/WoLpH/python-utils/blob/develop/LICENSE)
58
+ [![Downloads](https://img.shields.io/pypi/dm/python-utils.svg?logo=pypi&logoColor=white)](https://pypi.python.org/pypi/python-utils)
59
+
60
+ [**Documentation**](https://python-utils.readthedocs.io/en/latest/) ·
61
+ [**PyPI**](https://pypi.python.org/pypi/python-utils) ·
62
+ [**Source**](https://github.com/WoLpH/python-utils) ·
63
+ [**Issues**](https://github.com/WoLpH/python-utils/issues)
64
+
65
+ </div>
66
+
67
+ ---
68
+
69
+ Python Utils is a collection of small, battle-tested functions and classes that
70
+ make everyday Python patterns shorter, safer and faster. No sprawling framework,
71
+ no heavy dependencies — just the helpers you find yourself re-writing in project
72
+ after project, packaged once and typed to the hilt.
73
+
74
+ It has powered production code for years (and is used by libraries such as
75
+ [Django Utils](https://pypi.python.org/pypi/django-utils2) and
76
+ [progressbar2](https://pypi.python.org/pypi/progressbar2)).
77
+
78
+ ## ✨ Highlights
79
+
80
+ - 🪶 **Zero-cost imports** — thanks to [PEP 562][pep562] lazy loading, `import
81
+ python_utils` pulls in *nothing* until you actually touch a helper. No
82
+ `asyncio`, no `typing_extensions`, until you ask for them.
83
+ - ⚡ **Async-native** — `acount`, `abatcher`, and timeout/stall detectors bring
84
+ `itertools`-style ergonomics to `async for`.
85
+ - 📦 **Smart containers** — self-casting dicts, duplicate-proof lists and a
86
+ sliceable deque.
87
+ - 🔢 **Forgiving converters** — pull an `int`/`float` out of *any* messy string,
88
+ scale bytes to KiB/MiB, remap values between ranges (with `Decimal` precision).
89
+ - ⏱️ **Time & retries** — human-readable durations plus timeout generators for
90
+ sampling slow APIs without hanging.
91
+ - 🎯 **Fully typed & 100% covered** — ships `py.typed`, passes **mypy**,
92
+ **basedpyright** *and* **pyrefly** in strict mode, with 100% test coverage.
93
+ - 🐍 **Modern & tiny** — Python 3.10+, a single runtime dependency
94
+ (`typing_extensions`), BSD-3 licensed.
95
+
96
+ ## 🗺️ What's inside
97
+
98
+ | Module | What you get |
99
+ | --- | --- |
100
+ | [`converters`](https://python-utils.readthedocs.io/en/latest/) | `to_int` · `to_float` · `to_str` · `to_unicode` · `scale_1024` · `remap` |
101
+ | [`formatters`](https://python-utils.readthedocs.io/en/latest/) | `camel_to_underscore` · `apply_recursive` · `timesince` |
102
+ | [`time`](https://python-utils.readthedocs.io/en/latest/) | `format_time` · `timeout_generator` · `aio_timeout_generator` · `aio_generator_timeout_detector` |
103
+ | [`generators`](https://python-utils.readthedocs.io/en/latest/) | `batcher` · `abatcher` (batch by size **or** time interval) |
104
+ | [`aio`](https://python-utils.readthedocs.io/en/latest/) | `acount` · `acontainer` — async `itertools` |
105
+ | [`containers`](https://python-utils.readthedocs.io/en/latest/) | `CastedDict` · `LazyCastedDict` · `UniqueList` · `SliceableDeque` |
106
+ | [`decorators`](https://python-utils.readthedocs.io/en/latest/) | `listify` · `set_attributes` · `sample` · `wraps_classmethod` |
107
+ | [`logger`](https://python-utils.readthedocs.io/en/latest/) | `Logged` · `LoggerBase` (+ `Logurud` via the `loguru` extra) |
108
+ | [`import_`](https://python-utils.readthedocs.io/en/latest/) | `import_global` — programmatic `from x import *` |
109
+ | [`exceptions`](https://python-utils.readthedocs.io/en/latest/) | `raise_exception` · `reraise` |
110
+ | [`terminal`](https://python-utils.readthedocs.io/en/latest/) | `get_terminal_size` — works in shells, IPython & Jupyter |
111
+ | [`types`](https://python-utils.readthedocs.io/en/latest/) | handy type aliases (`Number`, `Scope`, `StringTypes`, …) |
112
+
113
+ ## 📦 Installation
114
+
115
+ ```bash
116
+ pip install python-utils
117
+ ```
118
+
119
+ Optional extras:
120
+
121
+ ```bash
122
+ pip install 'python-utils[loguru]' # loguru-backed logging mixin
123
+ ```
124
+
125
+ Python **3.10+** is required. The only runtime dependency is
126
+ `typing_extensions` (and it's imported lazily).
127
+
128
+ ## 🚀 Quickstart
129
+
130
+ ```python
131
+ import python_utils
132
+
133
+ # Pull a number out of any messy string
134
+ python_utils.to_int('listening on port=8080', regexp=True) # 8080
135
+
136
+ # Human-readable sizes: (value, power-of-1024)
137
+ python_utils.scale_1024(1536, 2) # (1.5, 1) -> 1.5 KiB
138
+
139
+ # Remap a value between ranges (46% volume -> dB on an AVR)
140
+ python_utils.remap(46.0, 0.0, 100.0, -80.0, 10.0) # -38.6
141
+
142
+ # "time ago" formatting, Django-style
143
+ import datetime
144
+ python_utils.timesince(datetime.datetime.now() - datetime.timedelta(seconds=61))
145
+ # '1 minute and 1 second ago'
146
+ ```
147
+
148
+ Everything is reachable straight off the top-level package (`python_utils.<name>`)
149
+ or from its submodule (`python_utils.converters.to_int`) — pick whichever reads
150
+ better. Either way, only the modules you touch get imported.
151
+
152
+ ## 🧰 Examples
153
+
154
+ <details open>
155
+ <summary><b>🔢 Converters — numbers out of anything</b></summary>
156
+
157
+ ```python
158
+ from python_utils import converters
159
+
160
+ # Extract digits with a built-in or custom regexp
161
+ converters.to_int('spam15eggs', regexp=True) # 15
162
+ converters.to_int('nope', default=-1) # -1
163
+ converters.to_float('pi is 3.14', regexp=True) # 3.14
164
+
165
+ # Scale bytes to a sensible unit (value, power) -> 2.0 KiB
166
+ converters.scale_1024(2048, 3) # (2.0, 1)
167
+
168
+ # Linear remap; pass a Decimal anywhere to keep full precision
169
+ converters.remap(500, 0, 1000, 0, 100) # 50
170
+ import decimal
171
+ converters.remap(decimal.Decimal('250.0'), 0.0, 1000.0, 0.0, 100.0)
172
+ # Decimal('25.0')
173
+ ```
174
+
175
+ </details>
176
+
177
+ <details>
178
+ <summary><b>📦 Containers — dicts & lists with super-powers</b></summary>
179
+
180
+ ```python
181
+ from python_utils import containers
182
+
183
+ # Keys and values are cast on the way in
184
+ d = containers.CastedDict(int, int)
185
+ d['3'] = '4'
186
+ d.update({'5': '6'})
187
+ d # {3: 4, 5: 6}
188
+
189
+ # A list that silently drops duplicates (or raises, if you prefer)
190
+ u = containers.UniqueList(1, 2, 3)
191
+ u.append(2) # ignored
192
+ u # [1, 2, 3]
193
+
194
+ # A deque you can actually slice
195
+ s = containers.SliceableDeque([1, 2, 3, 4, 5])
196
+ s[1:4] # SliceableDeque([2, 3, 4])
197
+ ```
198
+
199
+ </details>
200
+
201
+ <details>
202
+ <summary><b>⚡ Async helpers — <code>itertools</code> for <code>async for</code></b></summary>
203
+
204
+ ```python
205
+ from python_utils import aio, generators
206
+
207
+ # Async counter (optionally with a delay and a stop value)
208
+ async def demo():
209
+ async for i in aio.acount(stop=3):
210
+ print(i) # 0, 1, 2
211
+
212
+ # Batch an async stream by size OR time interval — whichever comes first.
213
+ # Great for chunking bursty producers without ever stalling a slow loop.
214
+ async def batched():
215
+ async for batch in generators.abatcher(aio.acount(stop=10), batch_size=3):
216
+ print(batch) # [0, 1, 2], [3, 4, 5], [6, 7, 8], [9]
217
+
218
+ # Sync batching too:
219
+ list(generators.batcher(range(9), 3)) # [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
220
+ ```
221
+
222
+ </details>
223
+
224
+ <details>
225
+ <summary><b>⏱️ Time & retries — sample slow APIs, format durations</b></summary>
226
+
227
+ ```python
228
+ import datetime
229
+ from python_utils import time
230
+
231
+ # Loop over a slow operation, but give up after `timeout` seconds
232
+ for i in time.timeout_generator(0.1, interval=0.06):
233
+ ... # yields 0, 1, 2 then stops
234
+
235
+ # Format timedeltas, datetimes and raw seconds uniformly
236
+ time.format_time(1) # '0:00:01'
237
+ time.format_time(datetime.timedelta(seconds=3661)) # '1:01:01'
238
+ time.format_time(datetime.datetime(2000, 1, 2, 3, 4, 5)) # '2000-01-02 03:04:05'
239
+ time.format_time(None) # '--:--:--'
240
+ ```
241
+
242
+ There's also `aio_timeout_generator` (the `async for` twin) and
243
+ `aio_generator_timeout_detector`, which fails fast when an async generator
244
+ stalls instead of hanging forever.
245
+
246
+ </details>
247
+
248
+ <details>
249
+ <summary><b>🔤 Formatters — case conversion & friendly timestamps</b></summary>
250
+
251
+ ```python
252
+ from python_utils import formatters
253
+
254
+ formatters.camel_to_underscore('SpamEggsAndBacon') # 'spam_eggs_and_bacon'
255
+
256
+ # Recursively rewrite every key in a nested dict
257
+ formatters.apply_recursive(
258
+ formatters.camel_to_underscore,
259
+ {'SpamEggs': {'FooBar': 1}},
260
+ ) # {'spam_eggs': {'foo_bar': 1}}
261
+ ```
262
+
263
+ </details>
264
+
265
+ <details>
266
+ <summary><b>🎀 Decorators — collect generators, tag functions, sample calls</b></summary>
267
+
268
+ ```python
269
+ from python_utils import decorators
270
+
271
+ # Turn a generator into a concrete collection automatically
272
+ @decorators.listify()
273
+ def numbers():
274
+ yield 1
275
+ yield 2
276
+ yield 3
277
+
278
+ numbers() # [1, 2, 3]
279
+
280
+ @decorators.listify(collection=dict)
281
+ def pairs():
282
+ yield 'a', 1
283
+ yield 'b', 2
284
+
285
+ pairs() # {'a': 1, 'b': 2}
286
+
287
+ # Attach metadata to a function (handy for the Django admin)
288
+ @decorators.set_attributes(short_description='Name')
289
+ def upper_case_name(self, obj):
290
+ return f'{obj.first_name} {obj.last_name}'.upper()
291
+
292
+ # Only actually run ~10% of the calls
293
+ @decorators.sample(0.1)
294
+ def maybe_log(msg): ...
295
+ ```
296
+
297
+ </details>
298
+
299
+ <details>
300
+ <summary><b>📝 Logging — a correctly-named logger on every class</b></summary>
301
+
302
+ ```python
303
+ from python_utils.logger import Logged
304
+
305
+ class MyClass(Logged):
306
+ def do_work(self):
307
+ self.info('starting %s', 'work') # stdlib %-style logging args
308
+ self.error('something went wrong')
309
+
310
+ MyClass().do_work()
311
+ ```
312
+
313
+ Prefer [loguru](https://github.com/Delgan/loguru)? Install the extra
314
+ (`pip install 'python-utils[loguru]'`) and subclass `Logurud` instead — the same
315
+ `self.info(...)` / `self.error(...)` API, backed by loguru so you keep all its
316
+ configuration and per-instance context.
317
+
318
+ </details>
319
+
320
+ <details>
321
+ <summary><b>🖥️ Terminal & 🧩 misc</b></summary>
322
+
323
+ ```python
324
+ from python_utils import terminal, import_
325
+ from python_utils.exceptions import raise_exception, reraise
326
+
327
+ # Robust terminal size (tries IPython/Jupyter, shutil, blessings, ioctl, tput…)
328
+ terminal.get_terminal_size() # e.g. (80, 24)
329
+
330
+ # Programmatic `from some_module import *`
331
+ import_.import_global('os')
332
+
333
+ # Build a callable that raises — useful as a default/callback
334
+ on_error = raise_exception(ValueError, 'boom')
335
+ ```
336
+
337
+ </details>
338
+
339
+ ## ⚡ Performance: lazy by default
340
+
341
+ `import python_utils` is intentionally *cheap*. Every submodule and every export
342
+ is wired through a [PEP 562][pep562] `__getattr__`, so nothing is imported until
343
+ first access — and then it's cached. In particular:
344
+
345
+ - Need only the synchronous helpers? `asyncio` is never imported.
346
+ - Even `typing_extensions` is deferred, so the import graph stays minimal.
347
+
348
+ ```python
349
+ import sys
350
+ import python_utils # imports basically nothing extra
351
+
352
+ 'asyncio' in sys.modules # False
353
+ python_utils.acount # now `aio` (and asyncio) load, on demand
354
+ ```
355
+
356
+ See the [performance guide](https://python-utils.readthedocs.io/en/latest/) for
357
+ the full story.
358
+
359
+ ## 📚 Documentation
360
+
361
+ Full API reference and guides live at
362
+ **<https://python-utils.readthedocs.io/en/latest/>**.
363
+
364
+ ## 🔗 Links
365
+
366
+ - 📖 Documentation: <https://python-utils.readthedocs.io/en/latest/>
367
+ - 🐙 Source: <https://github.com/WoLpH/python-utils>
368
+ - 📦 PyPI: <https://pypi.python.org/pypi/python-utils>
369
+ - 🐛 Issues: <https://github.com/WoLpH/python-utils/issues>
370
+ - ✍️ Author's blog: <https://wol.ph/>
371
+
372
+ ## 🔒 Security
373
+
374
+ To report a security vulnerability, please use the
375
+ [Tidelift security contact](https://tidelift.com/security). Tidelift will
376
+ coordinate the fix and disclosure.
377
+
378
+ ## 🤝 Contributing
379
+
380
+ Contributions are very welcome! We keep a strict **100% coverage** bar and run
381
+ `ruff`, three type checkers and the full test matrix in CI. See
382
+ [CONTRIBUTING.md](https://github.com/WoLpH/python-utils/blob/develop/CONTRIBUTING.md)
383
+ to get set up.
384
+
385
+ ## 📄 License
386
+
387
+ BSD-3-Clause — see [LICENSE](https://github.com/WoLpH/python-utils/blob/develop/LICENSE).
388
+
389
+ [pep562]: https://peps.python.org/pep-0562/
@@ -0,0 +1,21 @@
1
+ python_utils/__about__.py,sha256=qmqR375psvJc8IPYmLhruuaiouHzhdHu7DozRZG34DM,1343
2
+ python_utils/__init__.py,sha256=atYwTBHh2KNGdPSawwQKYCL9UolHho3L4WFxo901WDg,5958
3
+ python_utils/_aliases.py,sha256=xf_HrYaAa9ZKZAdYYJwIen-OB3nFGI5TTUETH5_ayGY,1641
4
+ python_utils/aio.py,sha256=59Zd-N9gF4jx__mEHlne1UIHFMlmNYuQOIy4_Nb6-QI,3999
5
+ python_utils/containers.py,sha256=FX3naenzdHuNQvNYsB_KdiFXgCXKVklS3GvSkbK95OU,19785
6
+ python_utils/converters.py,sha256=XgGqmtHjQ4czgYOiptTGM38Of5-NMwnDTnxuxPBkl2E,14949
7
+ python_utils/decorators.py,sha256=5r-T7fEBWqbhaWEEdi9NWS7f6uVVlvq1Uk8K0PGC3qA,7124
8
+ python_utils/exceptions.py,sha256=B5wljs3Id6eQ9eRaur-ZMPGGmhHNwh9F08Sfw6fuLX4,1230
9
+ python_utils/formatters.py,sha256=ypKLXAL1t0Z3NJ-hKAbGFrQ18F5aGKh93WVvL_lvwrM,5452
10
+ python_utils/generators.py,sha256=ftkIbx0HQntGfe87rudMZJma5fIfv-xCKMvL_fYaPGQ,3882
11
+ python_utils/import_.py,sha256=0w1jHkRFcAKO0Sr15cY2_Lz4ZZYjP5p5qrl0wRyohm4,3916
12
+ python_utils/logger.py,sha256=Fe0OYGucs-5oPSp4to_PTjaJkfGS2Kflr86Y73ycOrM,11627
13
+ python_utils/loguru.py,sha256=mcUzxk16EDhK2MoAimG3dCVxXQCbImj6MWmtac1h8pg,1476
14
+ python_utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ python_utils/terminal.py,sha256=GL3n2_rT98LBNmxy-amY-hezGKStCo-9_d_pR-TMgv8,6823
16
+ python_utils/time.py,sha256=amOrCsbQuEaVKSKkd35chDJU2_lHh-PCazM_J7hqeGE,15006
17
+ python_utils/types.py,sha256=fDvzdtVTEYgy0KgRmWTaugA9paRe9Y3LbHPUb7RY-Cg,4378
18
+ python_utils-4.0.0.dist-info/licenses/LICENSE,sha256=_Zrs9NZu-G6_aZT2g3Jv5_JREJQfhRNBC61EH6WDH-o,1501
19
+ python_utils-4.0.0.dist-info/WHEEL,sha256=uOqnPWqgFlbov4NeTCercq7cBQ2UN7xh5fiW55lOnAg,81
20
+ python_utils-4.0.0.dist-info/METADATA,sha256=DKsXPwK0DH0l71HBmz3j6C0OQ2OG23cYA7TEdkMvRaM,14910
21
+ python_utils-4.0.0.dist-info/RECORD,,
@@ -1,6 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.34.2)
2
+ Generator: uv 0.11.26
3
3
  Root-Is-Purelib: true
4
- Tag: py2-none-any
5
4
  Tag: py3-none-any
6
-
@@ -1,122 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: python-utils
3
- Version: 2.5.6
4
- Summary: Python Utils is a module with some convenient utilities not included with the standard Python install
5
- Home-page: https://github.com/WoLpH/python-utils
6
- Author: Rick van Hattem
7
- Author-email: Wolph@wol.ph
8
- License: BSD
9
- Platform: UNKNOWN
10
- Classifier: License :: OSI Approved :: BSD License
11
- Requires-Dist: six
12
-
13
- Useful Python Utils
14
- ==============================================================================
15
-
16
- .. image:: https://travis-ci.org/WoLpH/python-utils.svg?branch=master
17
- :target: https://travis-ci.org/WoLpH/python-utils
18
-
19
- .. image:: https://coveralls.io/repos/WoLpH/python-utils/badge.svg?branch=master
20
- :target: https://coveralls.io/r/WoLpH/python-utils?branch=master
21
-
22
- Python Utils is a collection of small Python functions and
23
- classes which make common patterns shorter and easier. It is by no means a
24
- complete collection but it has served me quite a bit in the past and I will
25
- keep extending it.
26
-
27
- One of the libraries using Python Utils is Django Utils.
28
-
29
- Documentation is available at: https://python-utils.readthedocs.org/en/latest/
30
-
31
- Links
32
- -----
33
-
34
- - The source: https://github.com/WoLpH/python-utils
35
- - Project page: https://pypi.python.org/pypi/python-utils
36
- - Reporting bugs: https://github.com/WoLpH/python-utils/issues
37
- - Documentation: https://python-utils.readthedocs.io/en/latest/
38
- - My blog: https://wol.ph/
39
-
40
- Requirements for installing:
41
- ------------------------------------------------------------------------------
42
-
43
- - `six` any recent version
44
-
45
- Installation:
46
- ------------------------------------------------------------------------------
47
-
48
- The package can be installed through `pip` (this is the recommended method):
49
-
50
- pip install python-utils
51
-
52
- Or if `pip` is not available, `easy_install` should work as well:
53
-
54
- easy_install python-utils
55
-
56
- Or download the latest release from Pypi (https://pypi.python.org/pypi/python-utils) or Github.
57
-
58
- Note that the releases on Pypi are signed with my GPG key (https://pgp.mit.edu/pks/lookup?op=vindex&search=0xE81444E9CE1F695D) and can be checked using GPG:
59
-
60
- gpg --verify python-utils-<version>.tar.gz.asc python-utils-<version>.tar.gz
61
-
62
- Quickstart
63
- ------------------------------------------------------------------------------
64
-
65
- This module makes it easy to execute common tasks in Python scripts such as
66
- converting text to numbers and making sure a string is in unicode or bytes
67
- format.
68
-
69
- Examples
70
- ------------------------------------------------------------------------------
71
-
72
- To extract a number from nearly every string:
73
-
74
- .. code-block:: python
75
-
76
- from python_utils import converters
77
-
78
- number = converters.to_int('spam15eggs')
79
- assert number == 15
80
-
81
- number = converters.to_int('spam')
82
- assert number == 0
83
-
84
- number = converters.to_int('spam', default=1)
85
- assert number == 1
86
-
87
- number = converters.to_float('spam1.234')
88
-
89
- To do a global import programmatically you can use the `import_global`
90
- function. This effectively emulates a `from ... import *`
91
-
92
- .. code-block:: python
93
-
94
- from python_utils.import_ import import_global
95
-
96
- # The following is the equivalent of `from some_module import *`
97
- import_global('some_module')
98
-
99
- Or add a correclty named logger to your classes which can be easily accessed:
100
-
101
- .. code-block:: python
102
-
103
- class MyClass(Logged):
104
- def __init__(self):
105
- Logged.__init__(self)
106
-
107
- my_class = MyClass()
108
-
109
- # Accessing the logging method:
110
- my_class.error('error')
111
-
112
- # With formatting:
113
- my_class.error('The logger supports %(formatting)s',
114
- formatting='named parameters')
115
-
116
- # Or to access the actual log function (overwriting the log formatting can
117
- # be done n the log method)
118
- import logging
119
- my_class.log(logging.ERROR, 'log')
120
-
121
-
122
-
@@ -1,15 +0,0 @@
1
- python_utils/__about__.py,sha256=JW1tl3eO-au_q7bocpy6PajRqsTynyq6YqdoNfMgAfw,308
2
- python_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- python_utils/compat.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_utils/converters.py,sha256=wZmtbObSEd-APsEzoHsXgAi-YFmAWMdi1sJN6N_zobk,8318
5
- python_utils/decorators.py,sha256=ClWrOS0xVoqk49FK3QrZLpGo86z46g82fh5WJVDTQLo,948
6
- python_utils/formatters.py,sha256=wQvjN0koIaHWiWUV8BYOspgbKthyn4B5YlWEPrSTb8s,3837
7
- python_utils/import_.py,sha256=sxr6c1TAV3BtV_3M_motYBqlg1wrT4_MLnMHRu2Oz9I,2757
8
- python_utils/logger.py,sha256=9fnYiFtJib-Z-BM1g2OTpsCevxnuGSCxCNkjaBb1EJc,1771
9
- python_utils/terminal.py,sha256=ZKEYu1t_xJrvyZmbdr5NhifIZRlpQADVZvUPQm4kqoI,4286
10
- python_utils/time.py,sha256=RQsfV0WSf5w4T1zdM995Cyxj30R5Xx2t5lX2DfyfUnY,3212
11
- python_utils-2.5.6.dist-info/LICENSE,sha256=_Zrs9NZu-G6_aZT2g3Jv5_JREJQfhRNBC61EH6WDH-o,1501
12
- python_utils-2.5.6.dist-info/METADATA,sha256=mz8Z5sVBmpfCLAluml7OO27itMye1Kd6METwv_ETvCQ,3771
13
- python_utils-2.5.6.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
14
- python_utils-2.5.6.dist-info/top_level.txt,sha256=zAx6OfEsjJs8BEW3okSiG_j9gpkI69xWShzum6oBgKI,13
15
- python_utils-2.5.6.dist-info/RECORD,,
@@ -1 +0,0 @@
1
- python_utils
File without changes