|
3 | 3 | import hashlib |
4 | 4 | import itertools |
5 | 5 | import time |
6 | | -import types |
7 | 6 | import typing |
8 | 7 | from datetime import timedelta, tzinfo |
9 | 8 |
|
|
17 | 16 |
|
18 | 17 |
|
19 | 18 | if typing.TYPE_CHECKING: |
20 | | - from typing import Union, Callable, Any, Dict, List |
21 | | - from selenium.webdriver.remote.webdriver import WebDriver |
22 | | - from selenium.webdriver.remote.webelement import WebElement |
23 | | - from selenium.webdriver.remote.switch_to import SwitchTo |
24 | | - |
25 | | - from applitools.selenium.webdriver import EyesWebDriver, _EyesSwitchTo |
26 | | - from applitools.selenium.webelement import EyesWebElement |
| 19 | + from typing import Callable, Any, List, Text |
27 | 20 |
|
28 | 21 | T = typing.TypeVar("T") |
29 | 22 |
|
@@ -59,82 +52,6 @@ def default(attr_name): |
59 | 52 | return default |
60 | 53 |
|
61 | 54 |
|
62 | | -def create_proxy_property(property_name, target_name, is_settable=False): |
63 | | - # type: (str, str, bool) -> property |
64 | | - """ |
65 | | - Returns a property object which forwards "name" to target. |
66 | | -
|
67 | | - :param property_name: The name of the property. |
68 | | - :param target_name: The target to forward to. |
69 | | - """ |
70 | | - |
71 | | - # noinspection PyUnusedLocal |
72 | | - def _proxy_get(self): |
73 | | - # type: (Any) -> Dict[str, float] |
74 | | - return getattr(getattr(self, target_name), property_name) |
75 | | - |
76 | | - # noinspection PyUnusedLocal |
77 | | - def _proxy_set(self, val): |
78 | | - return setattr(getattr(self, target_name), property_name, val) |
79 | | - |
80 | | - if not is_settable: |
81 | | - return property(_proxy_get) |
82 | | - else: |
83 | | - return property(_proxy_get, _proxy_set) |
84 | | - |
85 | | - |
86 | | -def create_forwarded_method( |
87 | | - from_, # type: Union[EyesWebDriver, EyesWebElement, _EyesSwitchTo] |
88 | | - to, # type: Union[WebDriver, WebElement, SwitchTo] |
89 | | - func_name, # type: str |
90 | | -): |
91 | | - # type: (...) -> Callable |
92 | | - """ |
93 | | - Returns a method(!) to be set on 'from_', which activates 'func_name' on 'to'. |
94 | | -
|
95 | | - :param from_: Source. |
96 | | - :param to: Destination. |
97 | | - :param func_name: The name of function to activate. |
98 | | - :return: Relevant method. |
99 | | - """ |
100 | | - |
101 | | - # noinspection PyUnusedLocal |
102 | | - def forwarded_method(self_, *args, **kwargs): |
103 | | - # type: (EyesWebDriver, *Any, **Any) -> Callable |
104 | | - return getattr(to, func_name)(*args, **kwargs) |
105 | | - |
106 | | - return types.MethodType(forwarded_method, from_) |
107 | | - |
108 | | - |
109 | | -def create_proxy_interface( |
110 | | - from_, # type: Union[EyesWebDriver, EyesWebElement, _EyesSwitchTo] |
111 | | - to, # type: Union[WebDriver, WebElement, SwitchTo] |
112 | | - ignore_list=None, # type: List[str] |
113 | | - override_existing=False, # type: bool |
114 | | -): |
115 | | - # type: (...) -> None |
116 | | - """ |
117 | | - Copies the public interface of the destination object, excluding names in the |
118 | | - ignore_list, and creates an identical interface in 'eyes_core', |
119 | | - which forwards calls to dst. |
120 | | -
|
121 | | - :param from_: Source. |
122 | | - :param to: Destination. |
123 | | - :param ignore_list: List of names to ignore while copying. |
124 | | - :param override_existing: If False, attributes already existing in 'eyes_core' |
125 | | - will not be overridden. |
126 | | - """ |
127 | | - if not ignore_list: |
128 | | - ignore_list = [] |
129 | | - for attr_name in dir(to): |
130 | | - if not attr_name.startswith("_") and attr_name not in ignore_list: |
131 | | - if callable(getattr(to, attr_name)): |
132 | | - if override_existing or not hasattr(from_, attr_name): |
133 | | - setattr( |
134 | | - from_, attr_name, create_forwarded_method(from_, to, attr_name) |
135 | | - ) |
136 | | - |
137 | | - |
138 | 55 | def cached_property(f): |
139 | 56 | # type: (Callable) -> Any |
140 | 57 | """ |
@@ -229,3 +146,35 @@ def set_query_parameter(url, param_name, param_value): |
229 | 146 | new_query_string = urlencode(query_params, doseq=True) |
230 | 147 |
|
231 | 148 | return urlunsplit((scheme, netloc, path, new_query_string, fragment)) |
| 149 | + |
| 150 | + |
| 151 | +def proxy_to(proxy_obj_name, fields): |
| 152 | + # type: (Text, List[Text]) -> Callable |
| 153 | + """ |
| 154 | + Adds to decorated class __getter__ and __setter__ methods that allow to access |
| 155 | + attributes from proxy_object in the parent class |
| 156 | +
|
| 157 | + :param proxy_obj_name: The name of the proxy object that has decorated class. |
| 158 | + :param fields: |
| 159 | + Fields which should be accessible in parent object from the proxy object. |
| 160 | + """ |
| 161 | + |
| 162 | + def __getattr__(self, name): |
| 163 | + if name in fields: |
| 164 | + proxy_obj = getattr(self, proxy_obj_name) |
| 165 | + return getattr(proxy_obj, name) |
| 166 | + raise AttributeError("{} has not attr {}".format(self.__class__.__name__, name)) |
| 167 | + |
| 168 | + def __setattr__(self, key, value): |
| 169 | + if key in fields: |
| 170 | + proxy_obj = getattr(self, proxy_obj_name) |
| 171 | + setattr(proxy_obj, key, value) |
| 172 | + else: |
| 173 | + super(self.__class__, self).__setattr__(key, value) |
| 174 | + |
| 175 | + def dec(cls): |
| 176 | + cls.__getattr__ = __getattr__ |
| 177 | + cls.__setattr__ = __setattr__ |
| 178 | + return cls |
| 179 | + |
| 180 | + return dec |
0 commit comments