Домашни > The Old Man from Scene #24 > Решения > Решението на Алекс Карабашев

Резултати
3 точки от тестове
0 точки от учител

3 точки общо

20 успешни теста
5 неуспешни теста
Код

 1import inspect
 2import re
 3
 4
 5class FilteredModule:
 6    def __init__(self, module):
 7        self._module = module
 8
 9    def __getattr__(self, name):
10        obj = getattr(self._module, name)
11
12        if BridgeKeeper.ask_questions(obj):
13            return obj
14
15        raise AttributeError(name)
16
17
18class BridgeKeeper:
19    def __init__(self, module_name):
20        self.module_name = module_name
21        self.module = None
22
23    def __enter__(self):
24        self.module = __import__(self.module_name)
25        return FilteredModule(self.module)
26
27    def __exit__(self, exc_type, exc_value, traceback):
28        pass
29
30    @classmethod
31    def ask_questions(cls, obj):
32        return cls._what_is_your_name(obj) and cls._what_is_your_quest(obj) and cls._what_is(obj)
33
34    @classmethod
35    def _what_is_your_name(cls, obj):
36        name = getattr(obj, "__name__", None)
37        if not isinstance(name, str) or not name:
38            return False
39        return name[0].isupper()
40
41    @classmethod
42    def _what_is_your_quest(cls, obj):
43        if not callable(obj):
44            return False
45
46        docstring = inspect.getdoc(obj) or ""
47        match = re.search(
48            r"^Parameters[ \t]*\n-{10}[ \t]*\n(.*?)(?=\n[ \t]*\n|\Z)",
49            docstring,
50            re.DOTALL | re.MULTILINE,
51        )
52        parameters = match.group(1).strip().splitlines() if match else []
53        parsed_parameters = []
54
55        for parameter in parameters:
56            parameter = parameter.strip()
57            if not parameter:
58                continue
59
60            name, _ = parameter.split(":", 1)
61            parsed_parameters.append(name.strip())
62
63        try:
64            signature = inspect.signature(obj)
65        except (TypeError, ValueError):
66            return False
67
68        return list(signature.parameters.keys()) == parsed_parameters
69
70    @classmethod
71    def _what_is(cls, obj):
72        for name in dir(obj):
73            if name.startswith("__") and name.endswith("__"):
74                continue
75
76            if re.search(r"[aeiou]{4,}", name.lower()):
77                continue
78
79            for char in reversed(name):
80                if "a" <= char.lower() <= "z":
81                    if char.isupper():
82                        return True
83                    break
84
85        return False

..............F..F...F.FF
======================================================================
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=5)

Дискусия
История
Това решение има само една версия.