pythonwrench 0.5.1__tar.gz → 0.5.2__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.
- {pythonwrench-0.5.1/src/pythonwrench.egg-info → pythonwrench-0.5.2}/PKG-INFO +6 -3
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/README.md +3 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/pyproject.toml +0 -1
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/__init__.py +5 -1
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/argparse.py +0 -2
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/cast.py +4 -2
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/functools.py +21 -1
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/inspect.py +1 -20
- {pythonwrench-0.5.1 → pythonwrench-0.5.2/src/pythonwrench.egg-info}/PKG-INFO +6 -3
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench.egg-info/requires.txt +0 -1
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_cast.py +12 -4
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/LICENSE +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/docs/requirements.txt +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/setup.cfg +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/setup.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/__main__.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/_core.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/abc.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/checksum.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/collections/__init__.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/collections/collections.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/collections/prop.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/collections/reducers.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/concurrent.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/csv.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/dataclasses.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/datetime.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/difflib.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/disk_cache.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/entries.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/enum.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/hashlib.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/importlib.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/json.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/jsonl.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/logging.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/math.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/os.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/pickle.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/random.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/re.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/semver.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/time.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/typing/__init__.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/typing/checks.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/typing/classes.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench/warnings.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench.egg-info/SOURCES.txt +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench.egg-info/dependency_links.txt +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench.egg-info/entry_points.txt +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/src/pythonwrench.egg-info/top_level.txt +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_abc.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_argparse.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_checksum.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_collections.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_csv.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_dataclasses.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_difflib.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_disk_cache.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_entries.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_enum.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_functools.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_hashlib.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_importlib.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_inspect.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_json.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_jsonl.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_logging.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_math.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_os.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_random.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_readme.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_semver.py +0 -0
- {pythonwrench-0.5.1 → pythonwrench-0.5.2}/tests/test_typing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonwrench
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Python library with tools for typing, manipulating collections, and more!
|
|
5
5
|
Author-email: "Étienne Labbé (Labbeti)" <labbeti.pub@gmail.com>
|
|
6
6
|
Maintainer-email: "Étienne Labbé (Labbeti)" <labbeti.pub@gmail.com>
|
|
@@ -50,11 +50,11 @@ Classifier: Operating System :: POSIX
|
|
|
50
50
|
Requires-Python: <3.15,>=3.8
|
|
51
51
|
Description-Content-Type: text/markdown
|
|
52
52
|
License-File: LICENSE
|
|
53
|
-
Requires-Dist: lazy-loader>=0.4
|
|
54
53
|
Requires-Dist: typing-extensions>=4.10.0
|
|
55
54
|
Provides-Extra: dev
|
|
56
55
|
Provides-Extra: lazy
|
|
57
56
|
Requires-Dist: lazy-loader>=0.4; extra == "lazy"
|
|
57
|
+
Dynamic: license-file
|
|
58
58
|
|
|
59
59
|
# pythonwrench
|
|
60
60
|
|
|
@@ -219,6 +219,9 @@ Easely converts common python structures like list of dicts to dict of lists :
|
|
|
219
219
|
... True
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
+
## Lazy loading
|
|
223
|
+
To speed up this package loading, you can install it with `uv add pythonwrench[lazy]`, so `import pythonwrench as pw` will be faster.
|
|
224
|
+
|
|
222
225
|
## Contact
|
|
223
226
|
Maintainer:
|
|
224
227
|
- [Étienne Labbé](https://labbeti.github.io/) "Labbeti": labbeti.pub@gmail.com
|
|
@@ -161,6 +161,9 @@ Easely converts common python structures like list of dicts to dict of lists :
|
|
|
161
161
|
... True
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
+
## Lazy loading
|
|
165
|
+
To speed up this package loading, you can install it with `uv add pythonwrench[lazy]`, so `import pythonwrench as pw` will be faster.
|
|
166
|
+
|
|
164
167
|
## Contact
|
|
165
168
|
Maintainer:
|
|
166
169
|
- [Étienne Labbé](https://labbeti.github.io/) "Labbeti": labbeti.pub@gmail.com
|
|
@@ -9,7 +9,7 @@ __author_email__ = "labbeti.pub@gmail.com"
|
|
|
9
9
|
__license__ = "MIT"
|
|
10
10
|
__maintainer__ = "Étienne Labbé (Labbeti)"
|
|
11
11
|
__status__ = "Development"
|
|
12
|
-
__version__ = "0.5.
|
|
12
|
+
__version__ = "0.5.2"
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
from typing import TYPE_CHECKING
|
|
@@ -114,10 +114,12 @@ if TYPE_CHECKING or lazy is None:
|
|
|
114
114
|
)
|
|
115
115
|
from .hashlib import hash_file
|
|
116
116
|
from .importlib import (
|
|
117
|
+
Placeholder,
|
|
117
118
|
is_available_package,
|
|
118
119
|
is_editable_package,
|
|
119
120
|
reload_editable_packages,
|
|
120
121
|
reload_submodules,
|
|
122
|
+
requires_packages,
|
|
121
123
|
search_submodules,
|
|
122
124
|
)
|
|
123
125
|
from .inspect import get_argnames, get_current_fn_name, get_fullname
|
|
@@ -325,7 +327,9 @@ else:
|
|
|
325
327
|
"is_editable_package",
|
|
326
328
|
"reload_editable_packages",
|
|
327
329
|
"reload_submodules",
|
|
330
|
+
"requires_packages",
|
|
328
331
|
"search_submodules",
|
|
332
|
+
"Placeholder",
|
|
329
333
|
],
|
|
330
334
|
"inspect": ["get_argnames", "get_current_fn_name", "get_fullname"],
|
|
331
335
|
"json": [
|
|
@@ -119,8 +119,6 @@ def str_to_optional_bool(
|
|
|
119
119
|
x: str,
|
|
120
120
|
*,
|
|
121
121
|
case_sensitive: bool = False,
|
|
122
|
-
true_values: Union[str, Iterable[str]] = DEFAULT_TRUE_VALUES,
|
|
123
|
-
false_values: Union[str, Iterable[str]] = DEFAULT_FALSE_VALUES,
|
|
124
122
|
none_values: Union[str, Iterable[str]] = DEFAULT_NONE_VALUES,
|
|
125
123
|
) -> Optional[bool]:
|
|
126
124
|
"""Convert string values to optional bool safely. Intended for argparse arguments.
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
from argparse import Namespace
|
|
5
5
|
from collections import Counter
|
|
6
|
-
from dataclasses import asdict
|
|
7
6
|
from datetime import date
|
|
8
7
|
from enum import Enum
|
|
9
8
|
from functools import partial
|
|
@@ -119,7 +118,10 @@ def _namespace_to_builtin(x: Namespace, **kwargs) -> Any:
|
|
|
119
118
|
|
|
120
119
|
@register_as_builtin_fn(DataclassInstance)
|
|
121
120
|
def _dataclass_to_builtin(x: DataclassInstance, **kwargs) -> Any:
|
|
122
|
-
|
|
121
|
+
# IMPORTANT note : we do not use dataclasses.asdict() because it also converts attributes like Counter, but not do dicts
|
|
122
|
+
field_names = x.__dataclass_fields__.keys()
|
|
123
|
+
xdict = {name: as_builtin(getattr(x, name), **kwargs) for name in field_names}
|
|
124
|
+
return xdict
|
|
123
125
|
|
|
124
126
|
|
|
125
127
|
@register_as_builtin_fn(NamedTupleInstance)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
+
import inspect
|
|
5
|
+
from types import CodeType
|
|
4
6
|
from typing import (
|
|
5
7
|
Any,
|
|
6
8
|
Callable,
|
|
@@ -14,7 +16,7 @@ from typing import (
|
|
|
14
16
|
from typing_extensions import ParamSpec
|
|
15
17
|
|
|
16
18
|
from pythonwrench._core import _decorator_factory, return_none # noqa: F401
|
|
17
|
-
from pythonwrench.inspect import
|
|
19
|
+
from pythonwrench.inspect import get_argnames
|
|
18
20
|
from pythonwrench.typing import isinstance_generic
|
|
19
21
|
|
|
20
22
|
T = TypeVar("T")
|
|
@@ -162,3 +164,21 @@ def identity(x: T, **kwargs) -> T:
|
|
|
162
164
|
def repeat_fn(f: Callable[[T], T], n: int) -> Callable[[T], T]:
|
|
163
165
|
"""Creates wrapper which call a function n items."""
|
|
164
166
|
return Compose([f] * n)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _get_code_and_start(fn: Callable) -> Tuple[CodeType, int]:
|
|
170
|
+
if inspect.isfunction(fn):
|
|
171
|
+
code = fn.__code__
|
|
172
|
+
start = 0
|
|
173
|
+
elif inspect.ismethod(fn):
|
|
174
|
+
code = fn.__code__
|
|
175
|
+
start = 1 # If method, remove 'self' arg
|
|
176
|
+
elif inspect.isclass(fn):
|
|
177
|
+
# If init, remove 'self' arg
|
|
178
|
+
code = fn.__init__.__code__
|
|
179
|
+
start = 1 # If init, remove 'self' arg
|
|
180
|
+
else:
|
|
181
|
+
code = fn.__call__.__code__
|
|
182
|
+
start = 0
|
|
183
|
+
|
|
184
|
+
return code, start
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
import inspect
|
|
5
|
-
from
|
|
6
|
-
from typing import Any, Callable, List, Tuple, TypeVar, Union, get_args
|
|
5
|
+
from typing import Any, Callable, List, TypeVar, Union, get_args
|
|
7
6
|
|
|
8
7
|
T = TypeVar("T")
|
|
9
8
|
|
|
@@ -68,21 +67,3 @@ def get_fullname(x: Any, *, inst_suffix: str = "(...)") -> str:
|
|
|
68
67
|
name = f"{name}[{argsnames_str}]"
|
|
69
68
|
|
|
70
69
|
return name
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def _get_code_and_start(fn: Callable) -> Tuple[CodeType, int]:
|
|
74
|
-
if inspect.isfunction(fn):
|
|
75
|
-
code = fn.__code__
|
|
76
|
-
start = 0
|
|
77
|
-
elif inspect.ismethod(fn):
|
|
78
|
-
code = fn.__code__
|
|
79
|
-
start = 1 # If method, remove 'self' arg
|
|
80
|
-
elif inspect.isclass(fn):
|
|
81
|
-
# If init, remove 'self' arg
|
|
82
|
-
code = fn.__init__.__code__
|
|
83
|
-
start = 1 # If init, remove 'self' arg
|
|
84
|
-
else:
|
|
85
|
-
code = fn.__call__.__code__
|
|
86
|
-
start = 0
|
|
87
|
-
|
|
88
|
-
return code, start
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonwrench
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Python library with tools for typing, manipulating collections, and more!
|
|
5
5
|
Author-email: "Étienne Labbé (Labbeti)" <labbeti.pub@gmail.com>
|
|
6
6
|
Maintainer-email: "Étienne Labbé (Labbeti)" <labbeti.pub@gmail.com>
|
|
@@ -50,11 +50,11 @@ Classifier: Operating System :: POSIX
|
|
|
50
50
|
Requires-Python: <3.15,>=3.8
|
|
51
51
|
Description-Content-Type: text/markdown
|
|
52
52
|
License-File: LICENSE
|
|
53
|
-
Requires-Dist: lazy-loader>=0.4
|
|
54
53
|
Requires-Dist: typing-extensions>=4.10.0
|
|
55
54
|
Provides-Extra: dev
|
|
56
55
|
Provides-Extra: lazy
|
|
57
56
|
Requires-Dist: lazy-loader>=0.4; extra == "lazy"
|
|
57
|
+
Dynamic: license-file
|
|
58
58
|
|
|
59
59
|
# pythonwrench
|
|
60
60
|
|
|
@@ -219,6 +219,9 @@ Easely converts common python structures like list of dicts to dict of lists :
|
|
|
219
219
|
... True
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
+
## Lazy loading
|
|
223
|
+
To speed up this package loading, you can install it with `uv add pythonwrench[lazy]`, so `import pythonwrench as pw` will be faster.
|
|
224
|
+
|
|
222
225
|
## Contact
|
|
223
226
|
Maintainer:
|
|
224
227
|
- [Étienne Labbé](https://labbeti.github.io/) "Labbeti": labbeti.pub@gmail.com
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import unittest
|
|
5
5
|
from collections import Counter
|
|
6
|
+
from dataclasses import dataclass, field
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from unittest import TestCase
|
|
8
9
|
|
|
@@ -14,8 +15,17 @@ class CustomClass:
|
|
|
14
15
|
b: str = ""
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
@dataclass
|
|
19
|
+
class CustomDataclass:
|
|
20
|
+
counts: Counter = field(default_factory=Counter)
|
|
21
|
+
|
|
22
|
+
|
|
17
23
|
class TestCast(TestCase):
|
|
18
24
|
def test_example_1(self) -> None:
|
|
25
|
+
@register_as_builtin_fn(CustomClass)
|
|
26
|
+
def customclass_to_builtin(x: CustomClass) -> dict:
|
|
27
|
+
return {"a": x.a, "b": x.b, "added_prop": None}
|
|
28
|
+
|
|
19
29
|
examples = [
|
|
20
30
|
("a", "a"),
|
|
21
31
|
((), []),
|
|
@@ -25,12 +35,10 @@ class TestCast(TestCase):
|
|
|
25
35
|
(CustomClass(), {"a": 0, "b": "", "added_prop": None}),
|
|
26
36
|
({"a": (1, 2)}, {"a": [1, 2]}),
|
|
27
37
|
(Counter(a=2, b=1, c=3), {"a": 2, "b": 1, "c": 3}),
|
|
38
|
+
(Counter(["a", "b", "a"]), {"a": 2, "b": 1}),
|
|
39
|
+
(CustomDataclass(Counter(["a", "b", "a"])), {"counts": {"a": 2, "b": 1}}),
|
|
28
40
|
]
|
|
29
41
|
|
|
30
|
-
@register_as_builtin_fn(CustomClass)
|
|
31
|
-
def customclass_to_builtin(x: CustomClass) -> dict:
|
|
32
|
-
return {"a": x.a, "b": x.b, "added_prop": None}
|
|
33
|
-
|
|
34
42
|
for x, expected in examples:
|
|
35
43
|
result = as_builtin(x)
|
|
36
44
|
assert result == expected
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|