1import importlib
2import re
3
4
5class BridgeKeeper:
6 def __init__(self, module_name):
7 self.module_name = module_name
8
9 def __enter__(self):
10 module = importlib.import_module(self.module_name)
11 return BridgeProxy(module)
12
13 def __exit__(self, *args):
14 pass
15
16
17class BridgeProxy:
18 def __init__(self, module):
19 self._module = module
20
21 def __getattr__(self, name):
22 obj = getattr(self._module, name)
23 name_val = getattr(obj, '__name__', '')
24 if not (name_val and name_val[0].isupper()):
25 raise AttributeError
26 if not callable(obj):
27 raise AttributeError
28 try:
29 params_options = self._get_params(obj.__doc__ or "")
30 args = [self._mock_val(options[0]) for options in params_options]
31 obj(*args)
32 except Exception:
33 raise AttributeError
34 if not any(self._is_valid_attr(a) for a in dir(obj)):
35 raise AttributeError
36 return obj
37
38 def _get_params(self, doc):
39 match = re.search(r"Parameters\s*-+", doc)
40 if not match: return []
41 block = re.split(r'\n\s*\n', doc[match.end():])[0].strip()
42 params = []
43 for line in block.split('\n'):
44 if ':' in line:
45 types = [t.strip() for t in line.split(':')[1].split('|')]
46 params.append(types)
47 return params
48
49 def _mock_val(self, t):
50 t = t.lower()
51 if 'dict' in t: return {}
52 if 'list' in t: return []
53 if 'tuple' in t: return ()
54 if 'set' in t: return set()
55 if 'int' in t: return 0
56 if 'float' in t: return 0.0
57 if 'bool' in t: return True
58 return ""
59
60 def _is_valid_attr(self, a):
61 if a.startswith('__') and a.endswith('__'): return False
62 if re.search(r'[aeiou]{4,}', a, re.I): return False
63 letters = re.findall(r'[a-zA-Z]', a)
64 return letters[-1].isupper() if letters else False
............F.F..F...F.FF
======================================================================
FAIL: test_rejects_callable_when_parameter_names_do_not_match (test.TestBridgeKeeper.test_rejects_callable_when_parameter_names_do_not_match)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 59, in test_rejects_callable_when_parameter_names_do_not_match
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised
======================================================================
FAIL: test_rejects_dict_when_callable_does_not_work_with_documented_key_and_value_types (test.TestBridgeKeeper.test_rejects_dict_when_callable_does_not_work_with_documented_key_and_value_types)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 90, in test_rejects_dict_when_callable_does_not_work_with_documented_key_and_value_types
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised
======================================================================
FAIL: test_rejects_list_when_callable_does_not_work_with_documented_element_type (test.TestBridgeKeeper.test_rejects_list_when_callable_does_not_work_with_documented_element_type)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 102, in test_rejects_list_when_callable_does_not_work_with_documented_element_type
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised
======================================================================
FAIL: test_rejects_set_when_callable_does_not_work_with_documented_element_type (test.TestBridgeKeeper.test_rejects_set_when_callable_does_not_work_with_documented_element_type)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 112, in test_rejects_set_when_callable_does_not_work_with_documented_element_type
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised
======================================================================
FAIL: test_rejects_tuple_when_callable_does_not_work_with_documented_element_type (test.TestBridgeKeeper.test_rejects_tuple_when_callable_does_not_work_with_documented_element_type)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 107, in test_rejects_tuple_when_callable_does_not_work_with_documented_element_type
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised
======================================================================
FAIL: test_rejects_union_when_callable_does_not_support_all_union_branches (test.TestBridgeKeeper.test_rejects_union_when_callable_does_not_support_all_union_branches)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 72, in test_rejects_union_when_callable_does_not_support_all_union_branches
with self.assertRaises(AttributeError):
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
AssertionError: AttributeError not raised
----------------------------------------------------------------------
Ran 25 tests in 0.003s
FAILED (failures=6)
03.05.2026 23:14
03.05.2026 23:14
03.05.2026 23:13