1import re
2import itertools
3
4class BridgeKeeper:
5 def __init__(self, module_name):
6 self._module = __import__(module_name)
7
8 def __enter__(self):
9 return self
10
11 def __exit__(self, exc_type, exc_val, exc_tb):
12 pass
13
14 def __getattr__(self, name):
15 obj = getattr(self._module, name)
16
17 obj_name = getattr(obj, '__name__')
18 if not (obj_name and len(obj_name) != 0 and obj_name[0].isupper()):
19 raise AttributeError(f"Invalid name")
20
21 if not callable(obj) or not self._test_quest_completion(obj):
22 raise AttributeError(f"Cannot be called")
23
24 if not self._has_attribute(obj):
25 raise AttributeError(f"No attribute works")
26
27 return obj
28
29 @staticmethod
30 def _test_quest_completion(obj):
31
32 doc = obj.__doc__ or ""
33 lines = doc.split("\n")
34 start = len(lines)
35 parameters = []
36 for i in range(0,len(lines)):
37 if lines[i] == 'Parameters':
38 start = i+2
39 break
40 for j in range(start,len(lines)):
41 if not lines[j].strip():
42 break
43
44 parameters.append(BridgeKeeper._parse_line(lines[j]))
45
46 if start == len(lines):
47 try:
48 obj()
49 return True
50 except Exception:
51 return False
52
53
54 all_possibilities = itertools.product(*parameters)
55
56 try:
57 for combination in all_possibilities:
58 obj(*combination)
59 except Exception:
60 return False
61 return True
62
63 @staticmethod
64 def _parse_line(line):
65 part = line
66 if ':' in line:
67 part = line.split(':')[1]
68
69 if '|' in part:
70 res = []
71 for option in part.split('|'):
72 option = option.strip()
73 res.extend(BridgeKeeper._parse_line(option))
74 return res
75
76 dict_pattern = r'.*dict.*'
77 set_pattern = r'.*set.*'
78 list_pattern = r'.*list.*'
79 tuple_pattern = r'.*tuple.*'
80
81 if re.match(dict_pattern, part):
82 first_param = part.split('[')[1].split(']')[0].split(',')[0]
83 second_param = part.split('[')[1].split(']')[0].split(',')[1]
84 return [{BridgeKeeper.__parse_primitive(first_param) : BridgeKeeper._parse_primitive(second_param)}]
85
86 if re.match(set_pattern, part):
87 first_param = part.split('[')[1].split(']')[0]
88 return [{BridgeKeeper._parse_primitive(first_param)}]
89
90 if re.match(list_pattern, part):
91 first_param = part.split('[')[1].split(']')[0]
92 return [[BridgeKeeper._parse_primitive(first_param)]]
93
94 if re.match(tuple_pattern, part):
95 first_param = part.split('[')[1].split(']')[0]
96 return [(BridgeKeeper._parse_primitive(first_param), )]
97
98 return [BridgeKeeper._parse_primitive(part)]
99
100 @staticmethod
101 def _parse_primitive(line):
102 if re.match(r'.*int.*', line):
103 return 1
104 if re.match(r'.*float.*', line):
105 return 1.0
106 if re.match(r'.*str.*', line):
107 return "This string is certainly very interesting"
108 if re.match(r'.*bool.*', line):
109 return True
110 if re.match(r'.*complex.*', line):
111 return 1+2j
112
113 return None
114
115 @staticmethod
116 def _has_attribute(obj):
117 for attr in dir(obj):
118 dunder_regex = r'__.*__'
119 if re.match(dunder_regex, attr):
120 continue
121 vowel_regex = r'.*[aeiouAEIOU]{4,}.*'
122 if re.match(vowel_regex, attr):
123 continue
124 last_latin_regex = r'[a-zA-Z]'
125 all_results = re.findall(last_latin_regex, attr)
126 if not all_results:
127 continue
128 if all_results[-1].isupper():
129 return True
130 return False
..E.........F............
======================================================================
ERROR: test_allows_dict_typed_parameter (test.TestBridgeKeeper.test_allows_dict_typed_parameter)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 68, in test_allows_dict_typed_parameter
self.assertEqual(filtered.score_map({"alice": 3, "bob": 7}), 10)
^^^^^^^^^^^^^^^^^^
File "/tmp/solution.py", line 21, in __getattr__
if not callable(obj) or not self._test_quest_completion(obj):
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
File "/tmp/solution.py", line 44, in _test_quest_completion
parameters.append(BridgeKeeper._parse_line(lines[j]))
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/tmp/solution.py", line 84, in _parse_line
return [{BridgeKeeper.__parse_primitive(first_param) : BridgeKeeper._parse_primitive(second_param)}]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'BridgeKeeper' has no attribute '_BridgeKeeper__parse_primitive'
======================================================================
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
----------------------------------------------------------------------
Ran 25 tests in 0.003s
FAILED (failures=1, errors=1)
01.05.2026 15:33
01.05.2026 15:33
01.05.2026 15:33
01.05.2026 15:35
01.05.2026 15:37
01.05.2026 15:38