MultiProxPy 0.0.1__tar.gz → 0.2.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.
- multiproxpy-0.2.0/PKG-INFO +51 -0
- multiproxpy-0.2.0/README.md +35 -0
- {multiproxpy-0.0.1 → multiproxpy-0.2.0}/pyproject.toml +27 -26
- multiproxpy-0.2.0/src/MultiProxPy/ModifyMultiProxy.py +134 -0
- {multiproxpy-0.0.1 → multiproxpy-0.2.0}/src/MultiProxPy/MultiProxyClass.py +22 -5
- multiproxpy-0.2.0/src/MultiProxPy/__init__.py +3 -0
- multiproxpy-0.0.1/PKG-INFO +0 -19
- multiproxpy-0.0.1/README.md +0 -3
- multiproxpy-0.0.1/src/MultiProxPy/__init__.py +0 -3
- {multiproxpy-0.0.1 → multiproxpy-0.2.0}/LICENSE +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: MultiProxPy
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: An easy way to combine multiple objects into one
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Eric aka CheesecakeTV
|
|
8
|
+
Author-email: eric@swiftgui.de
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Project-URL: Documentation, https://github.com/CheesecakeTV/MultiProxPy
|
|
13
|
+
Project-URL: Repository, https://github.com/CheesecakeTV/MultiProxPy
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# MultiProxPy
|
|
17
|
+
A small python-package that allows you to "group" calls to objects.
|
|
18
|
+
|
|
19
|
+
The cool part is that the resulting "MultiProxy"-object can be used like the referenced objects:
|
|
20
|
+
```py
|
|
21
|
+
from MultiProxPy import group_objects
|
|
22
|
+
|
|
23
|
+
list1 = [3,1,2]
|
|
24
|
+
list2 = [5,2]
|
|
25
|
+
list3 = [7,8,9]
|
|
26
|
+
|
|
27
|
+
list_proxy = group_objects(list1, list2, list3)
|
|
28
|
+
|
|
29
|
+
list_proxy.sort() # Sorts all lists
|
|
30
|
+
list_proxy.append(15) # Appends 15 to all lists
|
|
31
|
+
list_proxy[0] = -1 # Sets the first elemet to 0 for all lists
|
|
32
|
+
|
|
33
|
+
print(list1, list2, list3)
|
|
34
|
+
```
|
|
35
|
+
The grouping is very abstract and should work with any type of object.
|
|
36
|
+
|
|
37
|
+
The best part is that your IDE will treat the proxy-object like one of the contained objects.
|
|
38
|
+
It will suggest methods/attributes bound to that class:\
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
Other examples can be found in the github-repository: https://github.com/CheesecakeTV/MultiProxPy
|
|
42
|
+
|
|
43
|
+
## Limitations
|
|
44
|
+
There are a few downsides you should be aware of.
|
|
45
|
+
|
|
46
|
+
1. Any return-value on proxy-calls will be lost
|
|
47
|
+
2. Simmilarely, math operations like additions don't work for the proxy. However, inline-operations do, e.g.: `list_proxy += [5]`
|
|
48
|
+
3. The proxy can't fool `isinstance`, e.g.: `isinstance(list_proxy, list)` will return `False`
|
|
49
|
+
4. Objects inside the proxy should have the same type, or a derived one. This is only a suggestion. If you are careful enough, you can mix different types
|
|
50
|
+
|
|
51
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# MultiProxPy
|
|
2
|
+
A small python-package that allows you to "group" calls to objects.
|
|
3
|
+
|
|
4
|
+
The cool part is that the resulting "MultiProxy"-object can be used like the referenced objects:
|
|
5
|
+
```py
|
|
6
|
+
from MultiProxPy import group_objects
|
|
7
|
+
|
|
8
|
+
list1 = [3,1,2]
|
|
9
|
+
list2 = [5,2]
|
|
10
|
+
list3 = [7,8,9]
|
|
11
|
+
|
|
12
|
+
list_proxy = group_objects(list1, list2, list3)
|
|
13
|
+
|
|
14
|
+
list_proxy.sort() # Sorts all lists
|
|
15
|
+
list_proxy.append(15) # Appends 15 to all lists
|
|
16
|
+
list_proxy[0] = -1 # Sets the first elemet to 0 for all lists
|
|
17
|
+
|
|
18
|
+
print(list1, list2, list3)
|
|
19
|
+
```
|
|
20
|
+
The grouping is very abstract and should work with any type of object.
|
|
21
|
+
|
|
22
|
+
The best part is that your IDE will treat the proxy-object like one of the contained objects.
|
|
23
|
+
It will suggest methods/attributes bound to that class:\
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
Other examples can be found in the github-repository: https://github.com/CheesecakeTV/MultiProxPy
|
|
27
|
+
|
|
28
|
+
## Limitations
|
|
29
|
+
There are a few downsides you should be aware of.
|
|
30
|
+
|
|
31
|
+
1. Any return-value on proxy-calls will be lost
|
|
32
|
+
2. Simmilarely, math operations like additions don't work for the proxy. However, inline-operations do, e.g.: `list_proxy += [5]`
|
|
33
|
+
3. The proxy can't fool `isinstance`, e.g.: `isinstance(list_proxy, list)` will return `False`
|
|
34
|
+
4. Objects inside the proxy should have the same type, or a derived one. This is only a suggestion. If you are careful enough, you can mix different types
|
|
35
|
+
|
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "MultiProxPy"
|
|
3
|
-
version = "0.0
|
|
4
|
-
packages = [
|
|
5
|
-
{ include = "MultiProxPy", from = "src" }
|
|
6
|
-
]
|
|
7
|
-
authors = [
|
|
8
|
-
{ name="Eric aka CheesecakeTV", email="eric@swiftgui.de" },
|
|
9
|
-
]
|
|
10
|
-
description = "An easy way to combine multiple objects into one"
|
|
11
|
-
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.10"
|
|
13
|
-
classifiers = [
|
|
14
|
-
"Programming Language :: Python :: 3",
|
|
15
|
-
"Operating System :: OS Independent",
|
|
16
|
-
]
|
|
17
|
-
license = "Apache-2.0"
|
|
18
|
-
license-files = ["LICEN[CS]E*"]
|
|
19
|
-
dependencies = []
|
|
20
|
-
[project.urls]
|
|
21
|
-
Repository = "https://github.com/CheesecakeTV/
|
|
22
|
-
Documentation = "https://github.com/CheesecakeTV/
|
|
23
|
-
|
|
24
|
-
[build-system]
|
|
25
|
-
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
26
|
-
build-backend = "poetry.core.masonry.api"
|
|
1
|
+
[project]
|
|
2
|
+
name = "MultiProxPy"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
packages = [
|
|
5
|
+
{ include = "MultiProxPy", from = "src" }
|
|
6
|
+
]
|
|
7
|
+
authors = [
|
|
8
|
+
{ name="Eric aka CheesecakeTV", email="eric@swiftgui.de" },
|
|
9
|
+
]
|
|
10
|
+
description = "An easy way to combine multiple objects into one"
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
]
|
|
17
|
+
license = "Apache-2.0"
|
|
18
|
+
license-files = ["LICEN[CS]E*"]
|
|
19
|
+
dependencies = []
|
|
20
|
+
[project.urls]
|
|
21
|
+
Repository = "https://github.com/CheesecakeTV/MultiProxPy"
|
|
22
|
+
Documentation = "https://github.com/CheesecakeTV/MultiProxPy"
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
26
|
+
build-backend = "poetry.core.masonry.api"
|
|
27
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from typing import Any, Callable, Iterable
|
|
2
|
+
from MultiProxPy import MultiProxy
|
|
3
|
+
from functools import wraps
|
|
4
|
+
|
|
5
|
+
def _typecheck_multiprox(fct: Callable):
|
|
6
|
+
"""
|
|
7
|
+
Only allows an instance of Multiproxy as the first parameter
|
|
8
|
+
:param fct:
|
|
9
|
+
:return:
|
|
10
|
+
"""
|
|
11
|
+
@wraps(fct)
|
|
12
|
+
def inner(*args, **kwargs):
|
|
13
|
+
if not isinstance(args[0], MultiProxy):
|
|
14
|
+
raise TypeError("The passed object was not a MultiProxy.")
|
|
15
|
+
|
|
16
|
+
return fct(*args, **kwargs)
|
|
17
|
+
|
|
18
|
+
return inner
|
|
19
|
+
|
|
20
|
+
@_typecheck_multiprox
|
|
21
|
+
def get_object_list(multi_proxy: MultiProxy | Any) -> list[object]:
|
|
22
|
+
"""
|
|
23
|
+
Returns the inner list of the given multi-proxy.
|
|
24
|
+
You may use it to edit the contents of a MultiProxy.
|
|
25
|
+
|
|
26
|
+
Use at your own risk, there are no type-checks beyond this point!
|
|
27
|
+
|
|
28
|
+
:param multi_proxy:
|
|
29
|
+
:return:
|
|
30
|
+
"""
|
|
31
|
+
return object.__getattribute__(multi_proxy, "_objects")
|
|
32
|
+
|
|
33
|
+
@_typecheck_multiprox
|
|
34
|
+
def get_inner_type(multi_proxy: MultiProxy | Any) -> type:
|
|
35
|
+
"""
|
|
36
|
+
Return the assumed type of a multi-proxy.
|
|
37
|
+
:param multi_proxy:
|
|
38
|
+
:return:
|
|
39
|
+
"""
|
|
40
|
+
return object.__getattribute__(multi_proxy, "_type")
|
|
41
|
+
|
|
42
|
+
def _assert_type_match(multi_proxy: MultiProxy | Any, assert_match: bool = True, *objects: object) -> bool:
|
|
43
|
+
"""
|
|
44
|
+
Check if all objects
|
|
45
|
+
:param multi_proxy:
|
|
46
|
+
:param objects:
|
|
47
|
+
:return:
|
|
48
|
+
"""
|
|
49
|
+
main_type: type = get_inner_type(multi_proxy)
|
|
50
|
+
all_mismatching = tuple(filter(lambda a:not isinstance(a, main_type), objects))
|
|
51
|
+
is_matching = not all_mismatching
|
|
52
|
+
|
|
53
|
+
if not (is_matching or assert_match):
|
|
54
|
+
raise TypeError("The passed objects do not match with the multi-proxys inner type.\n"
|
|
55
|
+
f"Expected {main_type}, got some mismatching: {all_mismatching}\n"
|
|
56
|
+
f"You may turn off this check by passing assert_type=False to the function you called.")
|
|
57
|
+
|
|
58
|
+
return is_matching
|
|
59
|
+
|
|
60
|
+
@_typecheck_multiprox
|
|
61
|
+
def append_objects(multi_proxy: MultiProxy | Any, *objects: object, assert_type: bool = True):
|
|
62
|
+
"""
|
|
63
|
+
Add objects to a multi-proxy
|
|
64
|
+
|
|
65
|
+
:param multi_proxy:
|
|
66
|
+
:param objects:
|
|
67
|
+
:param assert_type:
|
|
68
|
+
:return:
|
|
69
|
+
"""
|
|
70
|
+
_assert_type_match(multi_proxy, assert_match=assert_type)
|
|
71
|
+
|
|
72
|
+
inner_list = get_object_list(multi_proxy)
|
|
73
|
+
for obj in objects:
|
|
74
|
+
inner_list.append(obj)
|
|
75
|
+
|
|
76
|
+
@_typecheck_multiprox
|
|
77
|
+
def remove_index(multi_proxy: MultiProxy | Any, index: int) -> object:
|
|
78
|
+
"""
|
|
79
|
+
Remove the linked object at that index from the passed multi-proxy.
|
|
80
|
+
|
|
81
|
+
:param multi_proxy:
|
|
82
|
+
:param index:
|
|
83
|
+
:return:
|
|
84
|
+
"""
|
|
85
|
+
inner_list = get_object_list(multi_proxy)
|
|
86
|
+
return inner_list.pop(index)
|
|
87
|
+
|
|
88
|
+
@_typecheck_multiprox
|
|
89
|
+
def remove_object_by_value(multi_proxy: MultiProxy | Any, value_to_remove: object) -> object:
|
|
90
|
+
"""
|
|
91
|
+
Remove the passed object from the passed multi-proxy and return its object.
|
|
92
|
+
The object is identified by its value.
|
|
93
|
+
|
|
94
|
+
:param multi_proxy:
|
|
95
|
+
:param value_to_remove: Value of the object to unlink
|
|
96
|
+
:return:
|
|
97
|
+
"""
|
|
98
|
+
inner_list = get_object_list(multi_proxy)
|
|
99
|
+
index = inner_list.index(value_to_remove)
|
|
100
|
+
return inner_list.pop(index)
|
|
101
|
+
|
|
102
|
+
@_typecheck_multiprox
|
|
103
|
+
def remove_object(multi_proxy: MultiProxy | Any, object_to_remove: object, ignore_error: bool = False) -> object:
|
|
104
|
+
"""
|
|
105
|
+
Remove the passed object from the passed multi-proxy and return the object.
|
|
106
|
+
The object is defined by the memory-address, so the passed object must be actually the same one.
|
|
107
|
+
|
|
108
|
+
:param multi_proxy:
|
|
109
|
+
:param object_to_remove: Object to unlink
|
|
110
|
+
:param ignore_error: If the object is not found, do nothing
|
|
111
|
+
:return:
|
|
112
|
+
"""
|
|
113
|
+
inner_list = get_object_list(multi_proxy)
|
|
114
|
+
|
|
115
|
+
ids = tuple(map(id, inner_list))
|
|
116
|
+
try:
|
|
117
|
+
index = ids.index(id(object_to_remove))
|
|
118
|
+
except ValueError:
|
|
119
|
+
if ignore_error:
|
|
120
|
+
return object_to_remove
|
|
121
|
+
raise ValueError("The object to remove is not linked to this multi-proxy.\n"
|
|
122
|
+
"You may pass ignore_error=True to do nothing instead of raising an error.")
|
|
123
|
+
|
|
124
|
+
return inner_list.pop(index)
|
|
125
|
+
|
|
126
|
+
@_typecheck_multiprox
|
|
127
|
+
def remove_all(multi_proxy: MultiProxy | Any):
|
|
128
|
+
"""
|
|
129
|
+
Unlink all elements from a multi-proxy
|
|
130
|
+
:param multi_proxy:
|
|
131
|
+
:return:
|
|
132
|
+
"""
|
|
133
|
+
inner_list = get_object_list(multi_proxy)
|
|
134
|
+
inner_list.clear()
|
|
@@ -2,19 +2,25 @@ from typing import TypeVar
|
|
|
2
2
|
|
|
3
3
|
class MultiProxy:
|
|
4
4
|
|
|
5
|
-
_objects:
|
|
5
|
+
_objects: list[object] # Objects to call the methods from
|
|
6
|
+
_type: type # Type of object in this element
|
|
6
7
|
|
|
7
8
|
def __init__(
|
|
8
9
|
self,
|
|
9
10
|
*objects: object,
|
|
11
|
+
assume_type: type | None = None,
|
|
10
12
|
):
|
|
11
13
|
"""
|
|
12
14
|
Do not call directly!
|
|
13
15
|
Use group_objects instead!
|
|
14
16
|
"""
|
|
15
|
-
assert objects, "At least one object is required to create a
|
|
17
|
+
assert objects, "At least one object is required to create a MultiProxy!"
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
if assume_type is None:
|
|
20
|
+
assume_type = type(objects[0])
|
|
21
|
+
|
|
22
|
+
super().__setattr__("_type", assume_type)
|
|
23
|
+
super().__setattr__("_objects", list(objects))
|
|
18
24
|
|
|
19
25
|
def __getattribute__(self, item):
|
|
20
26
|
objects = super().__getattribute__("_objects")
|
|
@@ -34,11 +40,11 @@ class MultiProxy:
|
|
|
34
40
|
|
|
35
41
|
def __str__(self) -> str:
|
|
36
42
|
objects = super().__getattribute__("_objects")
|
|
37
|
-
return f"<
|
|
43
|
+
return f"<MultiProxy {tuple(map(str, objects))}>"
|
|
38
44
|
|
|
39
45
|
def __repr__(self):
|
|
40
46
|
objects = super().__getattribute__("_objects")
|
|
41
|
-
return f"<
|
|
47
|
+
return f"<MultiProxy {id(self)} {tuple(map(repr, objects))}>"
|
|
42
48
|
|
|
43
49
|
def __await__(self):
|
|
44
50
|
objects = super().__getattribute__("_objects")
|
|
@@ -102,6 +108,15 @@ def group_objects(
|
|
|
102
108
|
primary: inner_type, *others: inner_type,
|
|
103
109
|
check_type_mismatch: bool = True,
|
|
104
110
|
) -> inner_type:
|
|
111
|
+
"""
|
|
112
|
+
Create a MultiProxy-object and fool the IDE about its type.
|
|
113
|
+
This is the proper way to create such an object.
|
|
114
|
+
|
|
115
|
+
:param primary: The "type" of the returned object
|
|
116
|
+
:param others: All the other elements inside that proxy
|
|
117
|
+
:param check_type_mismatch: False to go the dangerous route of mixing together types
|
|
118
|
+
:return:
|
|
119
|
+
"""
|
|
105
120
|
|
|
106
121
|
if check_type_mismatch:
|
|
107
122
|
main_type = type(primary)
|
|
@@ -119,3 +134,5 @@ def group_objects(
|
|
|
119
134
|
|
|
120
135
|
return my_caller
|
|
121
136
|
|
|
137
|
+
|
|
138
|
+
|
multiproxpy-0.0.1/PKG-INFO
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: MultiProxPy
|
|
3
|
-
Version: 0.0.1
|
|
4
|
-
Summary: An easy way to combine multiple objects into one
|
|
5
|
-
License-Expression: Apache-2.0
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Author: Eric aka CheesecakeTV
|
|
8
|
-
Author-email: eric@swiftgui.de
|
|
9
|
-
Requires-Python: >=3.10
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Project-URL: Documentation, https://github.com/CheesecakeTV/MultiProxy
|
|
13
|
-
Project-URL: Repository, https://github.com/CheesecakeTV/MultiProxy
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
|
-
# MultiProxy
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
multiproxpy-0.0.1/README.md
DELETED
|
File without changes
|