swizzle 2.1.1__py3-none-any.whl → 2.2.1__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 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.1.1"
17
+ __version__ = "2.2.1"
18
18
 
19
19
  MISSING = object()
20
20
 
21
- def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=None, arrange_names = None, seperator = 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 separator. The function also
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
- separator (str, optional): A separator string that customizes the structure of attribute
45
- access. If provided, this separator allows attributes to be accessed by combining field
46
- names with the separator in between them. Defaults to no separator.
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 `separator` argument enables a custom structure for attribute access, allowing for
59
- combined attribute names based on the provided separator. If no separator is 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(separator=seperator, type = swizzledtuple)
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
- # deprecated name
249
- def swizzlednamedtuple(typename, field_names, *, rename=False, defaults=None, module=None, arrange_names = None, seperator = None):
250
- warnings.warn("swizzlednamedtuple is deprecated, use swizzledtuple instead", DeprecationWarning, stacklevel=2)
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(separator)
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, separator=None, type = tuple):
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 separator is provided, split the name accordingly
297
- if separator is not None:
298
- attr_parts = split_string(attr_name, separator)
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 separator provided, attempt to match substrings
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 or type == swizzlednamedtuple:
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,23 +338,14 @@ 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, separator=None, type = tuple, **kwargs):
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, separator, type))
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:
@@ -368,11 +355,9 @@ def swizzle(cls=None, meta=False, separator=None, type = tuple, **kwargs):
368
355
  pass
369
356
  meta_cls = SwizzledMetaType
370
357
  cls = meta_cls(cls.__name__, cls.__bases__, dict(cls.__dict__))
371
- meta_cls = SwizzledMetaType
372
- cls = meta_cls(cls.__name__, cls.__bases__, dict(cls.__dict__))
373
358
 
374
359
  meta_funcs = collect_attribute_functions(meta_cls)
375
- setattr(meta_cls, meta_funcs[-1].__name__, swizzle_attributes_retriever(meta_funcs, separator, type))
360
+ setattr(meta_cls, meta_funcs[-1].__name__, swizzle_attributes_retriever(meta_funcs, sep, type))
376
361
 
377
362
  return cls
378
363
 
@@ -0,0 +1,184 @@
1
+ Metadata-Version: 2.1
2
+ Name: swizzle
3
+ Version: 2.2.1
4
+ Summary: Swizzle enables the retrieval of multiple attributes, similar to swizzling in computer graphics.
5
+ Home-page: https://github.com/janthmueller/swizzle
6
+ Author: Jan T. Müller
7
+ Author-email: mail@jantmueller.com
8
+ License: MIT
9
+ Project-URL: Documentation, https://github.com/janthmueller/swizzle/blob/main/README.md
10
+ Project-URL: Source, https://github.com/janthmueller/swizzle
11
+ Project-URL: Tracker, https://github.com/janthmueller/swizzle/issues
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Requires-Python: >=3.6
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+
21
+ # Swizzle
22
+
23
+ [![PyPI Latest Release](https://img.shields.io/pypi/v/swizzle.svg)](https://pypi.org/project/swizzle/)
24
+ [![Pepy Total Downloads](https://img.shields.io/pepy/dt/swizzle)](https://pepy.tech/project/swizzle)
25
+ [![GitHub License](https://img.shields.io/github/license/janthmueller/swizzle)](https://github.com/janthmueller/swizzle/blob/main/LICENSE)
26
+
27
+ ## Introduction
28
+
29
+ **Swizzle** is a Python package that enhances attribute access, allowing for flexible retrieval of multiple attributes based on specified arrangements of their names.
30
+
31
+ Managing object attributes efficiently can sometimes become cumbersome, especially when you need to access multiple attributes in various combinations. Swizzle simplifies this process by extending Python's attribute access mechanisms, enabling you to access attributes in any order or combination without explicitly referencing the instance every time or defining new methods for each combination.
32
+
33
+ ## Features
34
+
35
+ - **Dynamic Attribute Access**: Retrieve multiple attributes in any specified arrangement.
36
+ - **Reduced Boilerplate**: Eliminate redundant code by avoiding multiple getter methods.
37
+ - **Integration with Existing Classes**: Works seamlessly with regular classes, `dataclass`, and even `Enum` types.
38
+ - **Customizable Matching**: Control attribute matching behavior with parameters like `sep`.
39
+
40
+ ## Installation
41
+
42
+ ### From PyPI
43
+
44
+ Install Swizzle via pip:
45
+
46
+ ```bash
47
+ pip install swizzle
48
+ ```
49
+
50
+ ### From GitHub
51
+
52
+ Install the latest version directly from GitHub:
53
+
54
+ ```bash
55
+ pip install git+https://github.com/janthmueller/swizzle.git
56
+ ```
57
+
58
+ ## Getting Started
59
+
60
+ ### Basic Usage with the `@swizzle` Decorator
61
+
62
+ Apply the `@swizzle` decorator to your class:
63
+
64
+ ```python
65
+ import swizzle
66
+
67
+ @swizzle
68
+ class Vector:
69
+ def __init__(self, x, y, z):
70
+ self.x = x
71
+ self.y = y
72
+ self.z = z
73
+
74
+ v = Vector(1, 2, 3)
75
+
76
+ # Access attributes in different orders
77
+ print(v.yzx) # Output: Vector(y=2, z=3, x=1)
78
+ ```
79
+
80
+ ### Using Swizzle with `dataclass`
81
+
82
+ Swizzle integrates smoothly with Python's `dataclass`:
83
+
84
+ ```python
85
+ import swizzle
86
+ from dataclasses import dataclass
87
+
88
+ @swizzle
89
+ @dataclass
90
+ class Point:
91
+ x: int
92
+ y: int
93
+ z: int
94
+
95
+ p = Point(1, 2, 3)
96
+
97
+ print(p.zxy) # Output: Point(z=3, x=1, y=2)
98
+ ```
99
+
100
+ ### Swizzling Enums with `meta=True`
101
+
102
+ Enable attribute swizzling directly on the class by setting `meta=True`:
103
+
104
+ ```python
105
+ import swizzle
106
+ from enum import IntEnum
107
+
108
+ @swizzle(meta=True)
109
+ class Axis(IntEnum):
110
+ X = 1
111
+ Y = 2
112
+ Z = 3
113
+
114
+ print(Axis.YXZ) # Output: Axis(Y=<Axis.Y: 2>, X=<Axis.X: 1>, Z=<Axis.Z: 3>)
115
+ ```
116
+
117
+ ## Advanced Usage
118
+
119
+ ### Swizzled Named Tuples with `swizzledtuple`
120
+
121
+ Create swizzled named tuples inspired by `namedtuple`:
122
+
123
+ ```python
124
+ from swizzle import swizzledtuple
125
+
126
+ Vector = swizzledtuple('Vector', 'x y z')
127
+
128
+ v = Vector(1, 2, 3)
129
+
130
+ print(v.yzx) # Output: Vector(y=2, z=3, x=1)
131
+ print(v.yzx.xxzyzz) # Output: Vector(x=1, x=1, z=3, y=2, z=3, z=3)
132
+ ```
133
+
134
+ ### Custom Separators
135
+
136
+ 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:
137
+
138
+ ```python
139
+ import swizzle
140
+
141
+ @swizzle(meta=True, sep='_')
142
+ class BoundingBox:
143
+ x = 10
144
+ y = 20
145
+ w = 100
146
+ h = 200
147
+
148
+ print(BoundingBox.x_y_w_h) # Output: BoundingBox(x=10, y=20, w=100, h=200)
149
+ ```
150
+
151
+ ## Understanding Swizzling
152
+
153
+ Swizzling allows:
154
+
155
+ - **Rearrangement**: Access attributes in any order (e.g., `v.yzx`).
156
+ - **Duplication**: Access the same attribute multiple times (e.g., `v.xxy`).
157
+ - **Dynamic Composition**: Create new instances with desired attribute arrangements.
158
+
159
+ ## Benefits
160
+
161
+ - **Efficient Attribute Management**: Simplify complex attribute combinations.
162
+ - **Dynamic Access Patterns**: No need for predefined attribute combinations.
163
+ - **Cleaner Codebase**: Reduce redundancy and improve maintainability.
164
+ - **Enhanced Readability**: Code becomes more expressive and intuitive.
165
+
166
+ ## Conclusion
167
+
168
+ Swizzle is a powerful tool that streamlines attribute management in Python. It offers a flexible and efficient way to access and manipulate object attributes, making your code cleaner and more maintainable.
169
+
170
+ ## License
171
+
172
+ This project is licensed under the terms of the MIT license. See the [LICENSE](https://github.com/janthmueller/swizzle/blob/main/LICENSE) file for details.
173
+
174
+ ## Contributions
175
+
176
+ Contributions are welcome! Feel free to submit a Pull Request or open an Issue on GitHub.
177
+
178
+ ## Acknowledgments
179
+
180
+ Inspired by swizzling in graphics programming, Swizzle brings similar flexibility to Python attribute management.
181
+
182
+ ---
183
+
184
+ Give Swizzle a try and see how it can simplify your Python projects!
@@ -0,0 +1,6 @@
1
+ swizzle/__init__.py,sha256=_clk7y4NCO9KY-I-iSNsLc6iT8ylLcNPD4aiqoun1NE,15304
2
+ swizzle-2.2.1.dist-info/LICENSE,sha256=WDAegKWtl3rZUiN-SQ2FEQQwEFxlM_jEKQyJRJawJXo,1070
3
+ swizzle-2.2.1.dist-info/METADATA,sha256=vsupVSVUEg4uC3ZodBYPaLyUhvVPSXr2AgG9om0WMlY,5450
4
+ swizzle-2.2.1.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
5
+ swizzle-2.2.1.dist-info/top_level.txt,sha256=XFSQti81x2zM0zAMCY1YD0lqB1eSg5my9BB03uFgCic,8
6
+ swizzle-2.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (73.0.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,128 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: swizzle
3
- Version: 2.1.1
4
- Summary: Swizzle enables the retrieval of multiple attributes, similar to swizzling in computer graphics.
5
- Home-page: https://github.com/janthmueller/swizzle
6
- Author: Jan T. Müller
7
- Author-email: mail@jantmueller.com
8
- License: MIT
9
- Project-URL: Documentation, https://github.com/janthmueller/swizzle/blob/main/README.md
10
- Project-URL: Source, https://github.com/janthmueller/swizzle
11
- Project-URL: Tracker, https://github.com/janthmueller/swizzle/issues
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Operating System :: OS Independent
16
- Classifier: Programming Language :: Python :: 3 :: Only
17
- Requires-Python: >=3.6
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
-
21
- # Swizzle
22
- [![PyPI Latest Release](https://img.shields.io/pypi/v/swizzle.svg)](https://pypi.org/project/swizzle/)
23
- [![Pepy Total Downlods](https://img.shields.io/pepy/dt/swizzle)](https://pepy.tech/project/swizzle)
24
- [![GitHub License](https://img.shields.io/github/license/janthmueller/swizzle)](https://github.com/janthmueller/swizzle/blob/main/LICENSE)
25
- [![GitHub Stars](https://img.shields.io/github/stars/janthmueller/swizzle.svg)](https://github.com/janthmueller/swizzle/stargazers)
26
-
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
- > **Update v2:**
29
- > Introducing `swizzledtuple` , a new function that allows you to create swizzled named tuples. This feature is inspired by the `namedtuple` function from the [collections module](https://docs.python.org/3/library/collections.html#collections.namedtuple) and provides a concise way to define swizzled tuples.
30
- > ```python
31
- > from swizzle import swizzledtuple
32
- >
33
- > Vector = swizzledtuple('Vector', 'x y z', arrange_names = "y z x x")
34
- >
35
- > # Test the swizzle
36
- > v = Vector(1, 2, 3)
37
- > print(v) # Output: Vector(y=2, z=3, x=1, x=1)
38
- > print(v.yzx) # Output: Vector(y = 2, z = 3, x = 1)
39
- > print(v.yzx.xxzyzz) # Output: Vector(x=1, x=1, z=3, y=2, z=3, z=3)
40
- >```
41
-
42
- ### Swizzle Decorator:
43
-
44
- ```python
45
- import swizzle
46
-
47
- @swizzle
48
- class Vector:
49
- def __init__(self, x, y, z):
50
- self.x = x
51
- self.y = y
52
- self.z = z
53
-
54
- # Test the swizzle
55
- print(Vector(1, 2, 3).yzx) # Output: Vector(y = 2, z = 3, x = 1)
56
- ```
57
-
58
-
59
- ## Installation
60
- ### From PyPI
61
- ```bash
62
- pip install swizzle
63
- ```
64
- ### From GitHub
65
- ```bash
66
- pip install git+https://github.com/janthmueller/swizzle.git
67
- ```
68
-
69
- ## Further Examples
70
-
71
- ### Using `swizzle` with `dataclass`
72
-
73
- ```python
74
- import swizzle
75
- from dataclasses import dataclass
76
-
77
- @swizzle
78
- @dataclass
79
- class Vector:
80
- x: int
81
- y: int
82
- z: int
83
-
84
- # Test the swizzle
85
- print(Vector(1, 2, 3).yzx) # Output: Vector(y = 2, z = 3, x = 1)
86
- ```
87
-
88
- ### Using `swizzle` with `IntEnum`
89
-
90
- ```python
91
- import swizzle
92
- from enum import IntEnum
93
-
94
- @swizzle(meta=True)
95
- class Vector(IntEnum):
96
- X = 1
97
- Y = 2
98
- Z = 3
99
-
100
- # Test the swizzle
101
- print(Vector.YXZ) # Output: Vector(Y=<Vector.Y: 2>, X=<Vector.X: 1>, Z=<Vector.Z: 3>)
102
- ```
103
- Setting the `meta` argument to `True` in the swizzle decorator extends the `getattr` behavior of the metaclass, enabling attribute swizzling directly on the class itself.
104
-
105
-
106
- ### Sequential matching
107
- Attributes are matched from left to right, starting with the longest substring match. This behavior can be controlled by the `seperator` argument in the swizzle decorator.
108
- ```python
109
- import swizzle
110
-
111
- @swizzle(meta=True)
112
- class Vector:
113
- x = 1
114
- y = 2
115
- z = 3
116
- xy = 4
117
- yz = 5
118
- xz = 6
119
- xyz = 7
120
-
121
- # Test the swizzle
122
- print(Vector.xz) # Output: 6
123
- print(Vector.yz) # Output: 5
124
- print(Vector.xyyz) # Output: Vector(xy=4, yz=5)
125
- print(Vector.xyzx) # Output: Vector(xyz=7, x=1)
126
- ```
127
-
128
-
@@ -1,6 +0,0 @@
1
- swizzle/__init__.py,sha256=_YUDBGbs3unvltIfO8A0DIsWC05vxQaklY43vsFKyK4,16370
2
- swizzle-2.1.1.dist-info/LICENSE,sha256=WDAegKWtl3rZUiN-SQ2FEQQwEFxlM_jEKQyJRJawJXo,1070
3
- swizzle-2.1.1.dist-info/METADATA,sha256=xwo2y2C9uuy_-fW5YRDQd3PtMnn7hkD9zXVlAIBqNiU,3826
4
- swizzle-2.1.1.dist-info/WHEEL,sha256=nCVcAvsfA9TDtwGwhYaRrlPhTLV9m-Ga6mdyDtuwK18,91
5
- swizzle-2.1.1.dist-info/top_level.txt,sha256=XFSQti81x2zM0zAMCY1YD0lqB1eSg5my9BB03uFgCic,8
6
- swizzle-2.1.1.dist-info/RECORD,,