1import itertools
2import re
3
4
5class ModuleProxy:
6 def __init__(self, module):
7 self.module = module
8
9 @staticmethod
10 def name_is_valid(obj):
11 return re.match(r"[A-Z]\w*", obj.__name__)
12
13 @staticmethod
14 def quest_is_valid(obj):
15 params = re.search(r"(\s*Parameters\n\s*-{10}\n)((.|\n)*?(\n\n|$))", getattr(obj, "__doc__") or "")
16 if params:
17 matches = re.findall(r"(\w+) : (.+)", params.group(2))
18 names = [name for name, _ in matches]
19 type_options = [
20 [ModuleProxy.generate_obj_for_type(t) for t in types_str.split(" | ")] for _, types_str in matches
21 ]
22 params = [dict(zip(names, combo, strict=True)) for combo in itertools.product(*type_options)]
23 else:
24 params = [{}]
25 try:
26 for param_option in params:
27 obj(*param_option.values())
28 obj(**param_option)
29 except Exception:
30 return False
31 return True
32
33 @staticmethod
34 def answer_3rd_is_valid(obj):
35 return any(
36 re.match(r"^\w*[A-Z][^a-z]*$", attr)
37 and not re.search(r"[aeiou]{4,}", attr, flags=re.I)
38 and not re.match(r"^__.*__$", attr)
39 for attr in obj.__dict__
40 )
41
42 @staticmethod
43 def generate_obj_for_type(obj_type_str):
44 if dict_match := re.search(r"dict\[(\w+), (\w+)\]", obj_type_str):
45 return dict([[eval(elem_type)() for elem_type in dict_match.groups()]])
46 if collection_match := re.search(r"(\w+)\[(\w+)]", obj_type_str):
47 return eval(collection_match.group(1))([eval(collection_match.group(2))()])
48 return eval(obj_type_str)()
49
50 def __getattribute__(self, name):
51 obj = getattr(super().__getattribute__("module"), name)
52 if (
53 super().__getattribute__("name_is_valid")(obj)
54 and super().__getattribute__("quest_is_valid")(obj)
55 and super().__getattribute__("answer_3rd_is_valid")(obj)
56 ):
57 return obj
58 raise AttributeError("You go to the Gorge of Eternal Peril!")
59
60
61class BridgeKeeper:
62 def __init__(self, module_name):
63 self.module_name = module_name
64
65 def __enter__(self):
66 module = __import__(self.module_name)
67 return ModuleProxy(module)
68
69 def __exit__(self, exc_type, exc_val, exc_tb):
70 pass
.........................
----------------------------------------------------------------------
Ran 25 tests in 0.003s
OK