swizzle 0.1.0__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.
swizzle-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.1
2
+ Name: swizzle
3
+ Version: 0.1.0
4
+ Summary: Transforms a string representation of a Python literal into the corresponding Python object.
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
+
20
+ # Swizzle Decorator
21
+
22
+ The **Swizzle Decorator** for Python enhances attribute lookup methods (`__getattr__` or `__getattribute__`) to facilitate dynamic and flexible retrieval of multiple attributes based on specified arrangements of their names. This concept is reminiscent of swizzling in computer graphics, where it allows efficient access to components of vectors or coordinates in various orders:
23
+
24
+ ```python
25
+ import swizzle
26
+
27
+ @swizzle
28
+ class Vector:
29
+ def __init__(self, x, y, z):
30
+ self.x = x
31
+ self.y = y
32
+ self.z = z
33
+
34
+ print(Vector(1, 2, 3).yzx) # Output: (2, 3, 1)
35
+ ```
36
+
37
+ ## Installation
38
+ ```bash
39
+ pip install git+https://github.com/janthmueller/swizzle.git
40
+ ```
41
+
42
+ ## Further Examples
43
+
44
+ ### Using `swizzle` with `dataclass`
45
+
46
+ ```python
47
+ import swizzle
48
+ from dataclasses import dataclass
49
+
50
+ @swizzle
51
+ @dataclass
52
+ class XYZ:
53
+ x: int
54
+ y: int
55
+ z: int
56
+
57
+ # Test the swizzle
58
+ xyz = XYZ(1, 2, 3)
59
+ print(xyz.yzx) # Output: (2, 3, 1)
60
+ ```
61
+
62
+ ### Using `swizzle` with `IntEnum`
63
+
64
+ ```python
65
+ import swizzle
66
+ from enum import IntEnum
67
+
68
+ @swizzle(meta=True)
69
+ class XYZ(IntEnum):
70
+ X = 1
71
+ Y = 2
72
+ Z = 3
73
+
74
+ # Test the swizzle
75
+ print(XYZ.yxz) # Output: (2, 3, 1)
76
+ ```
77
+ 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.
78
+
79
+ ### Using `swizzle` with `NamedTuple`
80
+
81
+ ```python
82
+ import swizzle
83
+ from typing import NamedTuple
84
+
85
+ @swizzle
86
+ class XYZ(NamedTuple):
87
+ x: int
88
+ y: int
89
+ z: int
90
+
91
+ # Test the swizzle
92
+ xyz = XYZ(1, 2, 3)
93
+ print(xyz.yzx) # Output: (2, 3, 1)
94
+ ```
95
+
96
+
97
+ ### Sequential matching
98
+ Attributes are matched from left to right, starting with the longest substring match.
99
+ ```python
100
+ import swizzle
101
+
102
+ @swizzle(meta=True)
103
+ class Test:
104
+ x = 1
105
+ y = 2
106
+ z = 3
107
+ xy = 4
108
+ yz = 5
109
+ xz = 6
110
+ xyz = 7
111
+
112
+ # Test the swizzle
113
+ print(Test.xz) # Output: (6,)
114
+ print(Test.yz) # Output: (5,)
115
+ print(Test.xyyz) # Output: (4, 5)
116
+ print(Test.xyzx) # Output: (7, 1)
117
+ ```
118
+
@@ -0,0 +1,99 @@
1
+ # Swizzle Decorator
2
+
3
+ The **Swizzle Decorator** for Python enhances attribute lookup methods (`__getattr__` or `__getattribute__`) to facilitate dynamic and flexible retrieval of multiple attributes based on specified arrangements of their names. This concept is reminiscent of swizzling in computer graphics, where it allows efficient access to components of vectors or coordinates in various orders:
4
+
5
+ ```python
6
+ import swizzle
7
+
8
+ @swizzle
9
+ class Vector:
10
+ def __init__(self, x, y, z):
11
+ self.x = x
12
+ self.y = y
13
+ self.z = z
14
+
15
+ print(Vector(1, 2, 3).yzx) # Output: (2, 3, 1)
16
+ ```
17
+
18
+ ## Installation
19
+ ```bash
20
+ pip install git+https://github.com/janthmueller/swizzle.git
21
+ ```
22
+
23
+ ## Further Examples
24
+
25
+ ### Using `swizzle` with `dataclass`
26
+
27
+ ```python
28
+ import swizzle
29
+ from dataclasses import dataclass
30
+
31
+ @swizzle
32
+ @dataclass
33
+ class XYZ:
34
+ x: int
35
+ y: int
36
+ z: int
37
+
38
+ # Test the swizzle
39
+ xyz = XYZ(1, 2, 3)
40
+ print(xyz.yzx) # Output: (2, 3, 1)
41
+ ```
42
+
43
+ ### Using `swizzle` with `IntEnum`
44
+
45
+ ```python
46
+ import swizzle
47
+ from enum import IntEnum
48
+
49
+ @swizzle(meta=True)
50
+ class XYZ(IntEnum):
51
+ X = 1
52
+ Y = 2
53
+ Z = 3
54
+
55
+ # Test the swizzle
56
+ print(XYZ.yxz) # Output: (2, 3, 1)
57
+ ```
58
+ 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.
59
+
60
+ ### Using `swizzle` with `NamedTuple`
61
+
62
+ ```python
63
+ import swizzle
64
+ from typing import NamedTuple
65
+
66
+ @swizzle
67
+ class XYZ(NamedTuple):
68
+ x: int
69
+ y: int
70
+ z: int
71
+
72
+ # Test the swizzle
73
+ xyz = XYZ(1, 2, 3)
74
+ print(xyz.yzx) # Output: (2, 3, 1)
75
+ ```
76
+
77
+
78
+ ### Sequential matching
79
+ Attributes are matched from left to right, starting with the longest substring match.
80
+ ```python
81
+ import swizzle
82
+
83
+ @swizzle(meta=True)
84
+ class Test:
85
+ x = 1
86
+ y = 2
87
+ z = 3
88
+ xy = 4
89
+ yz = 5
90
+ xz = 6
91
+ xyz = 7
92
+
93
+ # Test the swizzle
94
+ print(Test.xz) # Output: (6,)
95
+ print(Test.yz) # Output: (5,)
96
+ print(Test.xyyz) # Output: (4, 5)
97
+ print(Test.xyzx) # Output: (7, 1)
98
+ ```
99
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
swizzle-0.1.0/setup.py ADDED
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2023 Jan T. Müller <mail@jantmueller.com>
2
+
3
+ import sys
4
+ import os
5
+ from setuptools import setup, find_packages
6
+ import swizzle
7
+
8
+ if sys.version_info < (3, 6):
9
+ sys.exit("ERROR: swizzle requires Python 3.6+")
10
+
11
+ with open("README.md", "r", encoding="utf-8") as fh:
12
+ long_description = fh.read()
13
+
14
+ setup(
15
+ name="swizzle",
16
+ version=swizzle.__version__,
17
+ packages=find_packages(exclude=["tests"]),
18
+ author="Jan T. Müller",
19
+ author_email="mail@jantmueller.com",
20
+ description="Transforms a string representation of a Python literal into the corresponding Python object.",
21
+ long_description=long_description,
22
+ long_description_content_type="text/markdown",
23
+ url="https://github.com/janthmueller/swizzle",
24
+ project_urls={
25
+ "Documentation": "https://github.com/janthmueller/swizzle/blob/main/README.md",
26
+ "Source": "https://github.com/janthmueller/swizzle",
27
+ "Tracker": "https://github.com/janthmueller/swizzle/issues",
28
+ },
29
+ license="MIT",
30
+ classifiers=[
31
+ "Intended Audience :: Developers",
32
+ "Topic :: Software Development :: Libraries :: Python Modules",
33
+ "License :: OSI Approved :: MIT License",
34
+ "Operating System :: OS Independent",
35
+ "Programming Language :: Python :: 3 :: Only",
36
+ ],
37
+ python_requires=">=3.6",
38
+ )
@@ -0,0 +1,70 @@
1
+ from functools import wraps
2
+ import sys
3
+ import types
4
+ import inspect
5
+
6
+ __version__ = "0.1.0"
7
+
8
+ def _swizzle(func):
9
+ def _getattr(obj, name, default=object()):
10
+ try:
11
+ return func(obj, name)
12
+ except AttributeError:
13
+ return default
14
+
15
+ @wraps(func)
16
+ def _swizzle_attributes(obj, name):
17
+ """Find attributes of an object that match substrings of a given name."""
18
+ found_attributes = []
19
+ sentinel = object()
20
+ i = 0
21
+ while i < len(name):
22
+ match_found = False
23
+ for j in range(len(name), i, -1):
24
+ substr = name[i:j]
25
+ attr = _getattr(obj, substr, sentinel)
26
+ if attr is not sentinel:
27
+ found_attributes.append(attr)
28
+ i = j # Move index to end of the matched substring
29
+ match_found = True
30
+ break
31
+ if not match_found:
32
+ raise AttributeError(f"No matching attribute found for substring: {name[i:]}")
33
+ return tuple(found_attributes)
34
+ return _swizzle_attributes
35
+
36
+ def swizzle(cls=None, meta = False):
37
+ def decorator(cls):
38
+ # Decorate the class's __getattr__ or __getattribute__
39
+ cls_fn = cls.__getattr__ if hasattr(cls, '__getattr__') else cls.__getattribute__
40
+ setattr(cls, cls_fn.__name__, _swizzle(cls_fn))
41
+
42
+ # Handle the meta class
43
+ if meta:
44
+ meta_cls = type(cls)
45
+ if meta_cls == type:
46
+ class SwizzleType(meta_cls): pass
47
+ meta_cls = SwizzleType
48
+ cls = meta_cls(cls.__name__, cls.__bases__, dict(cls.__dict__))
49
+ meta_fn = meta_cls.__getattr__ if hasattr(meta_cls, '__getattr__') else meta_cls.__getattribute__
50
+ setattr(meta_cls, meta_fn.__name__, _swizzle(meta_fn))
51
+ return cls
52
+
53
+ if cls is None:
54
+ return decorator
55
+ else:
56
+ return decorator(cls)
57
+
58
+
59
+
60
+ # make swizzle a callable module
61
+ class Swizzle(types.ModuleType):
62
+ def __init__(self):
63
+ types.ModuleType.__init__(self, __name__)
64
+ self.__dict__.update(sys.modules[__name__].__dict__)
65
+
66
+ def __call__(self, cls=None, meta=False):
67
+ return swizzle(cls, meta)
68
+
69
+ sys.modules[__name__] = Swizzle()
70
+
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.1
2
+ Name: swizzle
3
+ Version: 0.1.0
4
+ Summary: Transforms a string representation of a Python literal into the corresponding Python object.
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
+
20
+ # Swizzle Decorator
21
+
22
+ The **Swizzle Decorator** for Python enhances attribute lookup methods (`__getattr__` or `__getattribute__`) to facilitate dynamic and flexible retrieval of multiple attributes based on specified arrangements of their names. This concept is reminiscent of swizzling in computer graphics, where it allows efficient access to components of vectors or coordinates in various orders:
23
+
24
+ ```python
25
+ import swizzle
26
+
27
+ @swizzle
28
+ class Vector:
29
+ def __init__(self, x, y, z):
30
+ self.x = x
31
+ self.y = y
32
+ self.z = z
33
+
34
+ print(Vector(1, 2, 3).yzx) # Output: (2, 3, 1)
35
+ ```
36
+
37
+ ## Installation
38
+ ```bash
39
+ pip install git+https://github.com/janthmueller/swizzle.git
40
+ ```
41
+
42
+ ## Further Examples
43
+
44
+ ### Using `swizzle` with `dataclass`
45
+
46
+ ```python
47
+ import swizzle
48
+ from dataclasses import dataclass
49
+
50
+ @swizzle
51
+ @dataclass
52
+ class XYZ:
53
+ x: int
54
+ y: int
55
+ z: int
56
+
57
+ # Test the swizzle
58
+ xyz = XYZ(1, 2, 3)
59
+ print(xyz.yzx) # Output: (2, 3, 1)
60
+ ```
61
+
62
+ ### Using `swizzle` with `IntEnum`
63
+
64
+ ```python
65
+ import swizzle
66
+ from enum import IntEnum
67
+
68
+ @swizzle(meta=True)
69
+ class XYZ(IntEnum):
70
+ X = 1
71
+ Y = 2
72
+ Z = 3
73
+
74
+ # Test the swizzle
75
+ print(XYZ.yxz) # Output: (2, 3, 1)
76
+ ```
77
+ 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.
78
+
79
+ ### Using `swizzle` with `NamedTuple`
80
+
81
+ ```python
82
+ import swizzle
83
+ from typing import NamedTuple
84
+
85
+ @swizzle
86
+ class XYZ(NamedTuple):
87
+ x: int
88
+ y: int
89
+ z: int
90
+
91
+ # Test the swizzle
92
+ xyz = XYZ(1, 2, 3)
93
+ print(xyz.yzx) # Output: (2, 3, 1)
94
+ ```
95
+
96
+
97
+ ### Sequential matching
98
+ Attributes are matched from left to right, starting with the longest substring match.
99
+ ```python
100
+ import swizzle
101
+
102
+ @swizzle(meta=True)
103
+ class Test:
104
+ x = 1
105
+ y = 2
106
+ z = 3
107
+ xy = 4
108
+ yz = 5
109
+ xz = 6
110
+ xyz = 7
111
+
112
+ # Test the swizzle
113
+ print(Test.xz) # Output: (6,)
114
+ print(Test.yz) # Output: (5,)
115
+ print(Test.xyyz) # Output: (4, 5)
116
+ print(Test.xyzx) # Output: (7, 1)
117
+ ```
118
+
@@ -0,0 +1,7 @@
1
+ README.md
2
+ setup.py
3
+ swizzle/__init__.py
4
+ swizzle.egg-info/PKG-INFO
5
+ swizzle.egg-info/SOURCES.txt
6
+ swizzle.egg-info/dependency_links.txt
7
+ swizzle.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ swizzle