Домашни > The Old Man from Scene #24 > Решения > Решението на Пламена Колева

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

3 точки общо

19 успешни теста
6 неуспешни теста
Код
Скрий всички коментари

 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)

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