Skip to content

Commit 9b96bea

Browse files
Евгений БлиновЕвгений Блинов
authored andcommitted
Refactor Collector to use meta inheritance and add tests
1 parent 851bfed commit 9b96bea

2 files changed

Lines changed: 83 additions & 6 deletions

File tree

cstvis/collector.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
from dataclasses import dataclass, field
21
from functools import partial
32
from typing import Any, Callable, Dict, List, Optional, Union
43

54
from libcst import CSTNode
5+
from printo import repred
66

77
from cstvis.dto import Context
88
from cstvis.wrapper import CallableWrapper
99

1010

11-
@dataclass
11+
@repred(getters={'meta': lambda x: x._meta}, filters={'meta': lambda x: x})
1212
class Collector:
13-
_filters: List[CallableWrapper[bool]] = field(default_factory=list)
14-
_converters: List[CallableWrapper[CSTNode]] = field(default_factory=list)
13+
def __init__(self, meta: Optional[Dict[str, Any]] = None) -> None:
14+
self._meta: Dict[str, Any] = meta if meta else {}
15+
self._filters: List[CallableWrapper[bool]] = []
16+
self._converters: List[CallableWrapper[CSTNode]] = []
1517

1618
def __add__(self, other: 'Collector') -> 'Collector':
1719
if not isinstance(other, type(self)):
@@ -30,12 +32,21 @@ def filter(self, function: Optional[Union[Callable[[CSTNode], bool], Callable[[C
3032
if function is None:
3133
return partial(self.filter, meta=meta) # type: ignore[return-value]
3234

33-
self._filters.append(CallableWrapper(function, meta=meta))
35+
self._add_to_collection(function, meta, self._filters)
3436
return function
3537

3638
def converter(self, function: Optional[Union[Callable[[CSTNode], CSTNode], Callable[[CSTNode, Context], CSTNode]]] = None, meta: Optional[Dict[str, Any]] = None) -> Union[Union[Callable[[CSTNode], CSTNode], Callable[[CSTNode, Context], CSTNode]], Callable[[Union[Callable[[CSTNode], CSTNode], Callable[[CSTNode, Context], CSTNode]]], Union[Callable[[CSTNode], CSTNode], Callable[[CSTNode, Context], CSTNode]]]]:
3739
if function is None:
3840
return partial(self.converter, meta=meta) # type: ignore[return-value]
3941

40-
self._converters.append(CallableWrapper(function, meta=meta))
42+
self._add_to_collection(function, meta, self._converters)
4143
return function
44+
45+
def _add_to_collection(self, function, meta, collection) -> None:
46+
if meta is not None:
47+
meta = meta.copy()
48+
meta.update(self._meta)
49+
elif self._meta:
50+
meta = self._meta.copy()
51+
52+
collection.append(CallableWrapper(function, meta=meta))

tests/test_collector.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,69 @@ def test_add_wrong_things_to_collector():
8484

8585
with pytest.raises(TypeError, match=match('Collector objects can only be added to other collector objects.')):
8686
Collector() + 'kek'
87+
88+
89+
def test_repr():
90+
assert repr(Collector()) == 'Collector()'
91+
assert repr(Collector(meta={'lol': 'kek'})) == "Collector(meta={'lol': 'kek'})"
92+
93+
94+
def test_meta_for_collector_but_not_for_converter_or_filter():
95+
meta = {'lol': 'kek'}
96+
collector = Collector(meta=meta)
97+
98+
@collector.converter
99+
def some_converter(node, context): # noqa: ARG001
100+
return node
101+
102+
@collector.filter
103+
def some_filter(node, context): # noqa: ARG001
104+
return False
105+
106+
collector._converters[0].meta == meta
107+
collector._converters[0].meta is not meta
108+
109+
collector._filters[0].meta == meta
110+
collector._filters[0].meta is not meta
111+
112+
113+
def test_meta_for_converter_or_filter_but_not_for_collector():
114+
meta = {'lol': 'kek'}
115+
collector = Collector()
116+
117+
@collector.converter(meta=meta)
118+
def some_converter(node, context): # noqa: ARG001
119+
return node
120+
121+
@collector.filter(meta=meta)
122+
def some_filter(node, context): # noqa: ARG001
123+
return False
124+
125+
collector._converters[0].meta == meta
126+
collector._converters[0].meta is not meta
127+
128+
collector._filters[0].meta == meta
129+
collector._filters[0].meta is not meta
130+
131+
132+
def test_meta_for_for_converter_or_filter_and_for_collector():
133+
meta_1 = {'lol_1': 'kek_1', 'lol_2': 'kek_2'}
134+
meta_2 = {'lol_2': 'kek_2-2', 'lol_3': 'kek_3'}
135+
136+
collector = Collector(meta=meta_1)
137+
138+
@collector.converter(meta=meta_2)
139+
def some_converter(node, context): # noqa: ARG001
140+
return node
141+
142+
@collector.filter(meta=meta_2)
143+
def some_filter(node, context): # noqa: ARG001
144+
return False
145+
146+
collector._converters[0].meta == {'lol_1': 'kek_1', 'lol_2': 'kek_2-2', 'lol_3': 'kek_3'}
147+
collector._converters[0].meta is not meta_1
148+
collector._converters[0].meta is not meta_2
149+
150+
collector._filters[0].meta == {'lol_1': 'kek_1', 'lol_2': 'kek_2-2', 'lol_3': 'kek_3'}
151+
collector._filters[0].meta is not meta_1
152+
collector._filters[0].meta is not meta_2

0 commit comments

Comments
 (0)