swizzle 2.0.0__py3-none-any.whl → 2.1.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,7 +1,9 @@
1
1
  # Copyright (c) 2024 Jan T. Müller <mail@jantmueller.com>
2
2
 
3
+ import warnings
3
4
  from functools import wraps
4
5
  import types
6
+ import builtins
5
7
  import sys as _sys
6
8
 
7
9
  from keyword import iskeyword as _iskeyword
@@ -12,12 +14,60 @@ except ImportError:
12
14
  _tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc)
13
15
 
14
16
 
15
- __version__ = "2.0.0"
17
+ __version__ = "2.1.1"
16
18
 
17
19
  MISSING = object()
18
20
 
19
- def swizzlednamedtuple(typename, field_names, *, rename=False, defaults=None, module=None, arrange_names = None, seperator = None):
20
- # Validate the field names. Skip duplicate and underscore checks.
21
+ def swizzledtuple(typename, field_names, *, rename=False, defaults=None, module=None, arrange_names = None, seperator = None):
22
+ """
23
+ Create a custom named tuple class with swizzled attributes, allowing for rearranged field names
24
+ and customized attribute access.
25
+
26
+ This function generates a new subclass of `tuple` with named fields, similar to Python's
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
29
+ provides additional safeguards for field naming and attribute access.
30
+
31
+ Args:
32
+ typename (str): The name of the new named tuple type.
33
+ field_names (sequence of str or str): A sequence of field names for the tuple. If given as
34
+ a single string, it will be split into separate field names.
35
+ rename (bool, optional): If True, invalid field names are automatically replaced with
36
+ positional names. Defaults to False.
37
+ defaults (sequence, optional): Default values for the fields. Defaults to None.
38
+ module (str, optional): The module name in which the named tuple is defined. Defaults to
39
+ the caller's module.
40
+ arrange_names (sequence of str, optional): A sequence of field names indicating the order
41
+ in which fields should be arranged in the resulting named tuple. This allows for fields
42
+ to be rearranged and, unlike standard `namedtuple`, can include duplicates. Defaults
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.
47
+
48
+ Returns:
49
+ type: A new subclass of `tuple` with named fields and customized attribute access.
50
+
51
+ Notes:
52
+ - The function is based on `collections.namedtuple` but with additional features such as
53
+ field rearrangement and swizzled attribute access.
54
+ - The `arrange_names` argument allows rearranging the field names, and it can include
55
+ duplicates, which is not possible in a standard `namedtuple`.
56
+ - The generated named tuple class includes methods like `_make`, `_replace`, `__repr__`,
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,
60
+ standard attribute access is used.
61
+
62
+ Example:
63
+ >>> Vector = swizzledtuple('Vector', 'x y z', arrange_names='y z x x')
64
+ >>> # Test the swizzle
65
+ >>> v = Vector(1, 2, 3)
66
+ >>> print(v) # Output: Vector(y=2, z=3, x=1, x=1)
67
+ >>> print(v.yzx) # Output: Vector(y=2, z=3, x=1)
68
+ >>> print(v.yzx.xxzyzz) # Output: Vector(x=1, x=1, z=3, y=2, z=3, z=3)
69
+ """
70
+
21
71
  if isinstance(field_names, str):
22
72
  field_names = field_names.replace(',', ' ').split()
23
73
  field_names = list(map(str, field_names))
@@ -142,7 +192,7 @@ def swizzlednamedtuple(typename, field_names, *, rename=False, defaults=None, mo
142
192
  'Return self as a plain tuple. Used by copy and pickle.'
143
193
  return _tuple(self)
144
194
 
145
- @swizzle_attributes_retriever(separator=seperator, type = swizzlednamedtuple)
195
+ @swizzle_attributes_retriever(separator=seperator, type = swizzledtuple)
146
196
  def __getattribute__(self, attr_name):
147
197
  return super(_tuple, self).__getattribute__(attr_name)
148
198
 
@@ -195,6 +245,11 @@ def swizzlednamedtuple(typename, field_names, *, rename=False, defaults=None, mo
195
245
 
196
246
  return result
197
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
+
198
253
 
199
254
  # Helper function to split a string based on a separator
200
255
  def split_string(string, separator):
@@ -263,10 +318,10 @@ def swizzle_attributes_retriever(attribute_funcs=None, separator=None, type = tu
263
318
  if not match_found:
264
319
  raise AttributeError(f"No matching attribute found for substring: {attr_name[i:]}")
265
320
 
266
- if type == swizzlednamedtuple:
321
+ if type == swizzledtuple or type == swizzlednamedtuple:
267
322
  field_names = set(arranged_names)
268
323
  field_values = [retrieve_attribute(obj, name) for name in field_names]
269
- name = "swizzlednamedtuple"
324
+ name = "swizzledtuple"
270
325
  if hasattr(obj, "__name__"):
271
326
  name = obj.__name__
272
327
  elif hasattr(obj, "__class__"):
@@ -287,19 +342,28 @@ def swizzle_attributes_retriever(attribute_funcs=None, separator=None, type = tu
287
342
  return _swizzle_attributes_retriever
288
343
 
289
344
  # Decorator function to enable swizzling for a class
290
- def swizzle(cls=None, use_meta=False, separator=None, _type = tuple):
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
355
+
291
356
  def class_decorator(cls):
292
357
  # Collect attribute retrieval functions from the class
293
358
  attribute_funcs = collect_attribute_functions(cls)
294
359
 
295
360
  # Apply the swizzling to the class's attribute retrieval
296
- setattr(cls, attribute_funcs[-1].__name__, swizzle_attributes_retriever(attribute_funcs, separator, _type))
361
+ setattr(cls, attribute_funcs[-1].__name__, swizzle_attributes_retriever(attribute_funcs, separator, type))
297
362
 
298
363
  # Handle meta-class swizzling if requested
299
- if use_meta:
300
- print(cls)
301
- meta_cls = type(cls)
302
- if meta_cls == type:
364
+ if meta:
365
+ meta_cls = _type(cls)
366
+ if meta_cls == _type:
303
367
  class SwizzledMetaType(meta_cls):
304
368
  pass
305
369
  meta_cls = SwizzledMetaType
@@ -308,7 +372,7 @@ def swizzle(cls=None, use_meta=False, separator=None, _type = tuple):
308
372
  cls = meta_cls(cls.__name__, cls.__bases__, dict(cls.__dict__))
309
373
 
310
374
  meta_funcs = collect_attribute_functions(meta_cls)
311
- setattr(meta_cls, meta_funcs[-1].__name__, swizzle_attributes_retriever(meta_funcs, separator, _type))
375
+ setattr(meta_cls, meta_funcs[-1].__name__, swizzle_attributes_retriever(meta_funcs, separator, type))
312
376
 
313
377
  return cls
314
378
 
@@ -323,7 +387,7 @@ class Swizzle(types.ModuleType):
323
387
  types.ModuleType.__init__(self, __name__)
324
388
  self.__dict__.update(_sys.modules[__name__].__dict__)
325
389
 
326
- def __call__(self, cls=None, meta=False, sep = None, type = swizzlednamedtuple):
390
+ def __call__(self, cls=None, meta=False, sep = None, type = swizzledtuple):
327
391
  return swizzle(cls, meta, sep, type)
328
392
 
329
393
  _sys.modules[__name__] = Swizzle()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: swizzle
3
- Version: 2.0.0
3
+ Version: 2.1.1
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,17 +19,18 @@ Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
 
21
21
  # Swizzle
22
- [![PyPI version](https://badge.fury.io/py/swizzle.svg)](https://badge.fury.io/py/swizzle)
23
- [![Downloads](https://pepy.tech/badge/swizzle)](https://pepy.tech/project/swizzle)
24
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/janthmueller/swizzle/blob/main/LICENSE)
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
25
  [![GitHub Stars](https://img.shields.io/github/stars/janthmueller/swizzle.svg)](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:**
29
- > Introducing `swizzlednamedtuple` , 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.
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
30
  > ```python
31
- > from swizzle import swizzlednamedtuple
32
- > Vector = swizzlednamedtuple('Vector', 'x y z', arrange_names = "y z x x")
31
+ > from swizzle import swizzledtuple
32
+ >
33
+ > Vector = swizzledtuple('Vector', 'x y z', arrange_names = "y z x x")
33
34
  >
34
35
  > # Test the swizzle
35
36
  > v = Vector(1, 2, 3)
@@ -0,0 +1,6 @@
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.2.0)
2
+ Generator: setuptools (73.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +0,0 @@
1
- swizzle/__init__.py,sha256=fg47lzErJW1TS48sxnWsKA0myGIzp7SCxqleo2wHoyI,12504
2
- swizzle-2.0.0.dist-info/LICENSE,sha256=WDAegKWtl3rZUiN-SQ2FEQQwEFxlM_jEKQyJRJawJXo,1070
3
- swizzle-2.0.0.dist-info/METADATA,sha256=3zFLwkydXuLnXpdVr59kS6-ozGwX8Qdsk87BhK4kWN0,3803
4
- swizzle-2.0.0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
5
- swizzle-2.0.0.dist-info/top_level.txt,sha256=XFSQti81x2zM0zAMCY1YD0lqB1eSg5my9BB03uFgCic,8
6
- swizzle-2.0.0.dist-info/RECORD,,