1import re
2import importlib
3BASE_SAMPLES = {
4 'int': 1,
5 'float': 1.0,
6 'str': "test",
7 'bool': True,
8 'complex': 1j
9}
10def get_test_value(type_str):
11 type_str = type_str.strip()
12
13 if '|' in type_str:
14 first_type = type_str.split('|')[0].strip()
15 return get_test_value(first_type)
16
17 dict_match = re.match(r"dict\[(\w+),\s*(\w+)\]", type_str)
18 if dict_match:
19 t1, t2 = dict_match.groups()
20 return {get_test_value(t1): get_test_value(t2)}
21
22 coll_match = re.match(r"(\w+)\[(\w+)\]", type_str)
23 if coll_match:
24 coll_type, base_type = coll_match.groups()
25 sample_val = get_test_value(base_type)
26 if coll_type == 'list': return [sample_val]
27 if coll_type == 'tuple': return (sample_val,)
28 if coll_type == 'set': return {sample_val}
29
30 return BASE_SAMPLES.get(type_str, None)
31
32
33class Module:
34 def __init__(self, module):
35 self._module = module
36
37 def _check_name(self, obj):
38 return (callable(obj) and hasattr(obj, "__name__") and obj.__name__ and obj.__name__[0].isupper())
39
40 def _check_quest(self, obj):
41 doc = obj.__doc__ or ""
42 block_match = re.search(r"Parameters\n-+\n(.*?)(?:\n\n|$)", doc, re.S)
43 parameters_block = block_match.group(1) if block_match else ""
44 pattern = r"^(\w+) : (.+)$"
45 matches = re.findall(pattern, parameters_block, re.M)
46
47 args_to_pass = [get_test_value(m[1]) for m in matches]
48 try:
49 obj(*args_to_pass)
50 return True
51 except Exception:
52 return False
53
54 def _check_what_is(self, obj):
55 found_attr = False
56 for attr in dir(obj):
57 if attr.startswith('__') and attr.endswith('__'):
58 continue
59 if re.search(r'[aeiouAEIOU]{4,}', attr):
60 continue
61 letters = re.findall(r'[a-zA-Z]', attr)
62 if letters and letters[-1].isupper():
63 found_attr = True
64 break
65 return found_attr
66
67 def __getattr__(self, name):
68 obj = getattr(self._module, name);
69 if not self._check_name(obj):
70 raise AttributeError
71 if not self._check_quest(obj):
72 raise AttributeError
73 if not self._check_what_is(obj):
74 raise AttributeError
75 return obj
76
77
78class BridgeKeeper:
79 def __init__(self, module_name):
80 self.module_name = module_name
81 def __enter__(self):
82 open_mod = importlib.import_module(self.module_name);
83 return Module(open_mod)
84 def __exit__(self, exc_type, exc_val, exc_tb):
85 pass
............F...........F
======================================================================
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_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.002s
FAILED (failures=2)
03.05.2026 23:11
03.05.2026 23:13
03.05.2026 23:13