swizzle 2.1.0__py3-none-any.whl → 2.2.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.
- swizzle/__init__.py +25 -41
- {swizzle-2.1.0.dist-info → swizzle-2.2.0.dist-info}/METADATA +6 -6
- swizzle-2.2.0.dist-info/RECORD +6 -0
- {swizzle-2.1.0.dist-info → swizzle-2.2.0.dist-info}/WHEEL +1 -1
- swizzle-2.1.0.dist-info/RECORD +0 -6
- {swizzle-2.1.0.dist-info → swizzle-2.2.0.dist-info}/LICENSE +0 -0
- {swizzle-2.1.0.dist-info → swizzle-2.2.0.dist-info}/top_level.txt +0 -0
swizzle/__init__.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# Copyright (c) 2024 Jan T. Müller <mail@jantmueller.com>
|
2
2
|
|
3
|
-
import warnings
|
4
3
|
from functools import wraps
|
5
4
|
import types
|
6
5
|
import builtins
|
@@ -13,19 +12,20 @@ try:
|
|
13
12
|
except ImportError:
|
14
13
|
_tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc)
|
15
14
|
|
15
|
+
_type = builtins.type
|
16
16
|
|
17
|
-
__version__ = "2.
|
17
|
+
__version__ = "2.2.0"
|
18
18
|
|
19
19
|
MISSING = object()
|
20
20
|
|
21
|
-
def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=None, arrange_names = None,
|
21
|
+
def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=None, arrange_names = None, sep = None):
|
22
22
|
"""
|
23
23
|
Create a custom named tuple class with swizzled attributes, allowing for rearranged field names
|
24
24
|
and customized attribute access.
|
25
25
|
|
26
26
|
This function generates a new subclass of `tuple` with named fields, similar to Python's
|
27
27
|
`collections.namedtuple`. However, it extends the functionality by allowing field names to be
|
28
|
-
rearranged, and attributes to be accessed with a customizable
|
28
|
+
rearranged, and attributes to be accessed with a customizable sep. The function also
|
29
29
|
provides additional safeguards for field naming and attribute access.
|
30
30
|
|
31
31
|
Args:
|
@@ -41,9 +41,9 @@ def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=
|
|
41
41
|
in which fields should be arranged in the resulting named tuple. This allows for fields
|
42
42
|
to be rearranged and, unlike standard `namedtuple`, can include duplicates. Defaults
|
43
43
|
to the order given in `field_names`.
|
44
|
-
|
45
|
-
access. If provided, this
|
46
|
-
names with the
|
44
|
+
sep (str, optional): A separator string that customizes the structure of attribute
|
45
|
+
access. If provided, this sep allows attributes to be accessed by combining field
|
46
|
+
names with the sep in between them. Defaults to no sep.
|
47
47
|
|
48
48
|
Returns:
|
49
49
|
type: A new subclass of `tuple` with named fields and customized attribute access.
|
@@ -55,8 +55,8 @@ def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=
|
|
55
55
|
duplicates, which is not possible in a standard `namedtuple`.
|
56
56
|
- The generated named tuple class includes methods like `_make`, `_replace`, `__repr__`,
|
57
57
|
`_asdict`, and `__getnewargs__`, partially customized to handle the rearranged field order.
|
58
|
-
- The `
|
59
|
-
combined attribute names based on the provided
|
58
|
+
- The `sep` argument enables a custom structure for attribute access, allowing for
|
59
|
+
combined attribute names based on the provided sep. If no sep is provided,
|
60
60
|
standard attribute access is used.
|
61
61
|
|
62
62
|
Example:
|
@@ -192,7 +192,7 @@ def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=
|
|
192
192
|
'Return self as a plain tuple. Used by copy and pickle.'
|
193
193
|
return _tuple(self)
|
194
194
|
|
195
|
-
@swizzle_attributes_retriever(
|
195
|
+
@swizzle_attributes_retriever(sep=sep, type = swizzledtuple)
|
196
196
|
def __getattribute__(self, attr_name):
|
197
197
|
return super(_tuple, self).__getattribute__(attr_name)
|
198
198
|
|
@@ -245,18 +245,12 @@ def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=
|
|
245
245
|
|
246
246
|
return result
|
247
247
|
|
248
|
-
#
|
249
|
-
def
|
250
|
-
|
251
|
-
return swizzledtuple(typename, field_names, rename=rename, defaults=defaults, module=module, arrange_names=arrange_names, seperator=seperator)
|
252
|
-
|
253
|
-
|
254
|
-
# Helper function to split a string based on a separator
|
255
|
-
def split_string(string, separator):
|
256
|
-
if separator == '':
|
248
|
+
# Helper function to split a string based on a sep
|
249
|
+
def split_string(string, sep):
|
250
|
+
if sep == '':
|
257
251
|
return list(string)
|
258
252
|
else:
|
259
|
-
return string.split(
|
253
|
+
return string.split(sep)
|
260
254
|
|
261
255
|
# Helper function to collect attribute retrieval functions from a class or meta-class
|
262
256
|
def collect_attribute_functions(cls):
|
@@ -271,7 +265,7 @@ def collect_attribute_functions(cls):
|
|
271
265
|
|
272
266
|
# Function to combine multiple attribute retrieval functions
|
273
267
|
|
274
|
-
def swizzle_attributes_retriever(attribute_funcs=None,
|
268
|
+
def swizzle_attributes_retriever(attribute_funcs=None, sep=None, type = swizzledtuple):
|
275
269
|
def _swizzle_attributes_retriever(attribute_funcs):
|
276
270
|
if not isinstance(attribute_funcs, list):
|
277
271
|
attribute_funcs = [attribute_funcs]
|
@@ -293,16 +287,18 @@ def swizzle_attributes_retriever(attribute_funcs=None, separator=None, type = tu
|
|
293
287
|
|
294
288
|
matched_attributes = []
|
295
289
|
arranged_names = []
|
296
|
-
# If a
|
297
|
-
if
|
298
|
-
attr_parts = split_string(attr_name,
|
290
|
+
# If a sep is provided, split the name accordingly
|
291
|
+
if sep is not None:
|
292
|
+
attr_parts = split_string(attr_name, sep)
|
299
293
|
arranged_names = attr_parts
|
300
294
|
for part in attr_parts:
|
301
295
|
attribute = retrieve_attribute(obj, part)
|
302
296
|
if attribute is not MISSING:
|
303
297
|
matched_attributes.append(attribute)
|
298
|
+
else:
|
299
|
+
raise AttributeError(f"No matching attribute found for part: {part}")
|
304
300
|
else:
|
305
|
-
# No
|
301
|
+
# No sep provided, attempt to match substrings
|
306
302
|
i = 0
|
307
303
|
while i < len(attr_name):
|
308
304
|
match_found = False
|
@@ -318,7 +314,7 @@ def swizzle_attributes_retriever(attribute_funcs=None, separator=None, type = tu
|
|
318
314
|
if not match_found:
|
319
315
|
raise AttributeError(f"No matching attribute found for substring: {attr_name[i:]}")
|
320
316
|
|
321
|
-
if type == swizzledtuple
|
317
|
+
if type == swizzledtuple:
|
322
318
|
field_names = set(arranged_names)
|
323
319
|
field_values = [retrieve_attribute(obj, name) for name in field_names]
|
324
320
|
name = "swizzledtuple"
|
@@ -342,38 +338,26 @@ def swizzle_attributes_retriever(attribute_funcs=None, separator=None, type = tu
|
|
342
338
|
return _swizzle_attributes_retriever
|
343
339
|
|
344
340
|
# Decorator function to enable swizzling for a class
|
345
|
-
def swizzle(cls=None, meta=False,
|
346
|
-
|
347
|
-
if 'use_meta' in kwargs:
|
348
|
-
warnings.warn("The 'use_meta' argument is deprecated and will be removed in a future version. Use 'meta' instead.", DeprecationWarning, stacklevel=2)
|
349
|
-
meta = kwargs.pop('use_meta')
|
350
|
-
if '_type' in kwargs:
|
351
|
-
warnings.warn("The '_type' argument is deprecated and will be removed in a future version. Use 'type' instead.", DeprecationWarning, stacklevel=2)
|
352
|
-
type = kwargs.pop('_type')
|
353
|
-
|
354
|
-
_type = builtins.type
|
341
|
+
def swizzle(cls=None, meta=False, sep=None, type = tuple):
|
355
342
|
|
356
343
|
def class_decorator(cls):
|
357
344
|
# Collect attribute retrieval functions from the class
|
358
345
|
attribute_funcs = collect_attribute_functions(cls)
|
359
346
|
|
360
347
|
# Apply the swizzling to the class's attribute retrieval
|
361
|
-
setattr(cls, attribute_funcs[-1].__name__, swizzle_attributes_retriever(attribute_funcs,
|
348
|
+
setattr(cls, attribute_funcs[-1].__name__, swizzle_attributes_retriever(attribute_funcs, sep, type))
|
362
349
|
|
363
350
|
# Handle meta-class swizzling if requested
|
364
351
|
if meta:
|
365
|
-
print(cls)
|
366
352
|
meta_cls = _type(cls)
|
367
353
|
if meta_cls == _type:
|
368
354
|
class SwizzledMetaType(meta_cls):
|
369
355
|
pass
|
370
356
|
meta_cls = SwizzledMetaType
|
371
357
|
cls = meta_cls(cls.__name__, cls.__bases__, dict(cls.__dict__))
|
372
|
-
meta_cls = SwizzledMetaType
|
373
|
-
cls = meta_cls(cls.__name__, cls.__bases__, dict(cls.__dict__))
|
374
358
|
|
375
359
|
meta_funcs = collect_attribute_functions(meta_cls)
|
376
|
-
setattr(meta_cls, meta_funcs[-1].__name__, swizzle_attributes_retriever(meta_funcs,
|
360
|
+
setattr(meta_cls, meta_funcs[-1].__name__, swizzle_attributes_retriever(meta_funcs, sep, type))
|
377
361
|
|
378
362
|
return cls
|
379
363
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: swizzle
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.2.0
|
4
4
|
Summary: Swizzle enables the retrieval of multiple attributes, similar to swizzling in computer graphics.
|
5
5
|
Home-page: https://github.com/janthmueller/swizzle
|
6
6
|
Author: Jan T. Müller
|
@@ -19,10 +19,10 @@ Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
20
20
|
|
21
21
|
# Swizzle
|
22
|
-
[](https://pypi.org/project/swizzle/)
|
23
|
+
[](https://pepy.tech/project/swizzle)
|
24
|
+
[](https://github.com/janthmueller/swizzle/blob/main/LICENSE)
|
25
|
+
[](https://github.com/janthmueller/swizzle/stargazers)
|
26
26
|
|
27
27
|
**Swizzle** for Python enhances attribute lookup methods to facilitate dynamic and flexible retrieval of multiple attributes based on specified arrangements of their names.
|
28
28
|
> **Update v2:**
|
@@ -104,7 +104,7 @@ Setting the `meta` argument to `True` in the swizzle decorator extends the `geta
|
|
104
104
|
|
105
105
|
|
106
106
|
### Sequential matching
|
107
|
-
Attributes are matched from left to right, starting with the longest substring match. This behavior can be controlled by the `
|
107
|
+
Attributes are matched from left to right, starting with the longest substring match. This behavior can be controlled by the `sep` argument in the swizzle decorator.
|
108
108
|
```python
|
109
109
|
import swizzle
|
110
110
|
|
@@ -0,0 +1,6 @@
|
|
1
|
+
swizzle/__init__.py,sha256=tdMYMDJVpTR3TGGyvQz5r6Qm48uzwdpfxt8EnmqTFbU,15304
|
2
|
+
swizzle-2.2.0.dist-info/LICENSE,sha256=WDAegKWtl3rZUiN-SQ2FEQQwEFxlM_jEKQyJRJawJXo,1070
|
3
|
+
swizzle-2.2.0.dist-info/METADATA,sha256=5GpqF5HP7Zlj3HGy-3z0r4Z79U10ODitqRJ5iwoQ4t4,3819
|
4
|
+
swizzle-2.2.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
5
|
+
swizzle-2.2.0.dist-info/top_level.txt,sha256=XFSQti81x2zM0zAMCY1YD0lqB1eSg5my9BB03uFgCic,8
|
6
|
+
swizzle-2.2.0.dist-info/RECORD,,
|
swizzle-2.1.0.dist-info/RECORD
DELETED
@@ -1,6 +0,0 @@
|
|
1
|
-
swizzle/__init__.py,sha256=124893c7gC4KJhrpFAGOuOJb5TVBGSUPyZPm0wilsKQ,16394
|
2
|
-
swizzle-2.1.0.dist-info/LICENSE,sha256=WDAegKWtl3rZUiN-SQ2FEQQwEFxlM_jEKQyJRJawJXo,1070
|
3
|
-
swizzle-2.1.0.dist-info/METADATA,sha256=x1iq2dpfhqBWHYdn0MeqqL3vqa9Jw-Fb6lt3PITDjfs,3825
|
4
|
-
swizzle-2.1.0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
5
|
-
swizzle-2.1.0.dist-info/top_level.txt,sha256=XFSQti81x2zM0zAMCY1YD0lqB1eSg5my9BB03uFgCic,8
|
6
|
-
swizzle-2.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|