5050from operator import mul , add
5151from typing import TypeVar , Generic , Generator , Any , overload
5252
53- __version__ = ' 0.12.0.dev0'
53+ __version__ = " 0.12.0.dev0"
5454
5555K = TypeVar ("K" , bound = Hashable )
5656V = TypeVar ("V" )
5757
58- def _process_keys (left : Cycler [K , V ]| Iterable [dict [K ,V ]]| None , right : Cycler [K , V ]| Iterable [dict [K ,V ]]| None ) -> set [K ]:
58+
59+ def _process_keys (
60+ left : Cycler [K , V ] | Iterable [dict [K , V ]] | None ,
61+ right : Cycler [K , V ] | Iterable [dict [K , V ]] | None ,
62+ ) -> set [K ]:
5963 """
6064 Helper function to compose cycler keys.
6165
@@ -97,15 +101,18 @@ def concat(left: Cycler[K, V], right: Cycler[K, V]) -> Cycler[K, V]:
97101 The concatenated cycler.
98102 """
99103 if left .keys != right .keys :
100- raise ValueError ("Keys do not match:\n "
101- "\t Intersection: {both!r}\n "
102- "\t Disjoint: {just_one!r}" .format (
103- both = left .keys & right .keys ,
104- just_one = left .keys ^ right .keys ))
104+ raise ValueError (
105+ "Keys do not match:\n "
106+ "\t Intersection: {both!r}\n "
107+ "\t Disjoint: {just_one!r}" .format (
108+ both = left .keys & right .keys , just_one = left .keys ^ right .keys
109+ )
110+ )
105111 _l = left .by_key ()
106112 _r = right .by_key ()
107113 return reduce (add , (_cycler (k , _l [k ] + _r [k ]) for k in left .keys ))
108114
115+
109116class Cycler (Generic [K , V ]):
110117 """
111118 Composable cycles.
@@ -137,14 +144,21 @@ class Cycler(Generic[K, V]):
137144 def __call__ (self ):
138145 return cycle (self )
139146
140- def __init__ (self , left : Cycler [K , V ] | Iterable [dict [K ,V ]] | None , right : Cycler [K , V ] | Iterable [dict [K ,V ]] | None = None , op : Any = None ):
147+ def __init__ (
148+ self ,
149+ left : Cycler [K , V ] | Iterable [dict [K , V ]] | None ,
150+ right : Cycler [K , V ] | Iterable [dict [K , V ]] | None = None ,
151+ op : Any = None ,
152+ ):
141153 """
142154 Semi-private init.
143155
144156 Do not use this directly, use `cycler` function instead.
145157 """
146158 if isinstance (left , Cycler ):
147- self ._left : Cycler [K , V ] | list [dict [K ,V ]] | None = Cycler (left ._left , left ._right , left ._op )
159+ self ._left : Cycler [K , V ] | list [dict [K , V ]] | None = Cycler (
160+ left ._left , left ._right , left ._op
161+ )
148162 elif left is not None :
149163 # Need to copy the dictionary or else that will be a residual
150164 # mutable that could lead to strange errors
@@ -153,7 +167,9 @@ def __init__(self, left: Cycler[K, V] | Iterable[dict[K,V]] | None, right: Cycle
153167 self ._left = None
154168
155169 if isinstance (right , Cycler ):
156- self ._right : Cycler [K , V ] | list [dict [K ,V ]] | None = Cycler (right ._left , right ._right , right ._op )
170+ self ._right : Cycler [K , V ] | list [dict [K , V ]] | None = Cycler (
171+ right ._left , right ._right , right ._op
172+ )
157173 elif right is not None :
158174 # Need to copy the dictionary or else that will be a residual
159175 # mutable that could lead to strange errors
@@ -185,22 +201,31 @@ def change_key(self, old: K, new: K) -> None:
185201 return
186202 if new in self ._keys :
187203 raise ValueError (
188- "Can't replace {old} with {new}, {new} is already a key"
189- .format (old = old , new = new )
204+ "Can't replace {old} with {new}, {new} is already a key" .format (
205+ old = old , new = new
206+ )
190207 )
191208 if old not in self ._keys :
192- raise KeyError ("Can't replace {old} with {new}, {old} is not a key"
193- .format (old = old , new = new ))
209+ raise KeyError (
210+ "Can't replace {old} with {new}, {old} is not a key" .format (
211+ old = old , new = new
212+ )
213+ )
194214
195215 self ._keys .remove (old )
196216 self ._keys .add (new )
197217
198- if self ._right is not None and isinstance (self ._right , Cycler ) and old in self ._right .keys :
218+ if (
219+ self ._right is not None
220+ and isinstance (self ._right , Cycler )
221+ and old in self ._right .keys
222+ ):
199223 self ._right .change_key (old , new )
200224
201225 # self._left should always be non-None
202226 # if self._keys is non-empty.
203- elif self ._left is None : pass
227+ elif self ._left is None :
228+ pass
204229 elif isinstance (self ._left , Cycler ):
205230 self ._left .change_key (old , new )
206231 else :
@@ -249,7 +274,9 @@ def __iter__(self) -> Generator[dict[K, V], None, None]:
249274 yield dict (left )
250275 else :
251276 if self ._op is None :
252- raise TypeError ("Operation cannot be None when both left and right are defined" )
277+ raise TypeError (
278+ "Operation cannot be None when both left and right are defined"
279+ )
253280 for a , b in self ._op (self ._left , self ._right ):
254281 out = {}
255282 out .update (a )
@@ -265,8 +292,9 @@ def __add__(self, other: Cycler[K, V]) -> Cycler[K, V]:
265292 other : Cycler
266293 """
267294 if len (self ) != len (other ):
268- raise ValueError ("Can only add equal length cycles, "
269- f"not { len (self )} and { len (other )} " )
295+ raise ValueError (
296+ f"Can only add equal length cycles, not { len (self )} and { len (other )} "
297+ )
270298 return Cycler (self , other , zip )
271299
272300 def __mul__ (self , other : Cycler [K , V ] | int ) -> Cycler [K , V ]:
@@ -282,7 +310,7 @@ def __mul__(self, other: Cycler[K, V] | int) -> Cycler[K, V]:
282310 return Cycler (self , other , product )
283311 elif isinstance (other , int ):
284312 trans = self .by_key ()
285- return reduce (add , (_cycler (k , v * other ) for k , v in trans .items ()))
313+ return reduce (add , (_cycler (k , v * other ) for k , v in trans .items ()))
286314 else :
287315 return NotImplemented
288316
@@ -319,7 +347,7 @@ def __iadd__(self, other: Cycler[K, V]) -> Cycler[K, V]:
319347 self ._right = Cycler (other ._left , other ._right , other ._op )
320348 return self
321349
322- def __imul__ (self , other : Cycler [K ,V ] | int ) -> Cycler [K , V ]:
350+ def __imul__ (self , other : Cycler [K , V ] | int ) -> Cycler [K , V ]:
323351 """
324352 In-place outer product of two cyclers (`itertools.product`).
325353
@@ -349,13 +377,13 @@ def __eq__(self, other: object) -> bool:
349377 __hash__ = None # type: ignore
350378
351379 def __repr__ (self ) -> str :
352- op_map = {zip : '+' , product : '*' }
380+ op_map = {zip : "+" , product : "*" }
353381 if self ._right is None :
354382 lab = self .keys .pop ()
355383 itr = list (v [lab ] for v in self )
356384 return f"cycler({ lab !r} , { itr !r} )"
357385 else :
358- op = op_map .get (self ._op , '?' )
386+ op = op_map .get (self ._op , "?" )
359387 msg = "({left!r} {op} {right!r})"
360388 return msg .format (left = self ._left , op = op , right = self ._right )
361389
@@ -423,12 +451,22 @@ def simplify(self) -> Cycler[K, V]:
423451
424452 concat = concat
425453
454+
426455@overload
427- def cycler (args : Cycler [K , V ]) -> Cycler [K , V ]: ...
456+ def cycler (args : Cycler [K , V ]) -> Cycler [K , V ]:
457+ ...
458+
459+
428460@overload
429- def cycler (** kwargs : Iterable [V ]) -> Cycler [str , V ]: ...
461+ def cycler (** kwargs : Iterable [V ]) -> Cycler [str , V ]:
462+ ...
463+
464+
430465@overload
431- def cycler (label : K , itr : Iterable [V ]) -> Cycler [K , V ]: ...
466+ def cycler (label : K , itr : Iterable [V ]) -> Cycler [K , V ]:
467+ ...
468+
469+
432470def cycler (* args , ** kwargs ):
433471 """
434472 Create a new `Cycler` object from a single positional argument,
@@ -468,19 +506,24 @@ def cycler(*args, **kwargs):
468506
469507 """
470508 if args and kwargs :
471- raise TypeError ("cyl() can only accept positional OR keyword "
472- "arguments -- not both." )
509+ raise TypeError (
510+ "cyl() can only accept positional OR keyword arguments -- not both."
511+ )
473512
474513 if len (args ) == 1 :
475514 if not isinstance (args [0 ], Cycler ):
476- raise TypeError ("If only one positional argument given, it must "
477- "be a Cycler instance." )
515+ raise TypeError (
516+ "If only one positional argument given, it must "
517+ "be a Cycler instance."
518+ )
478519 return Cycler (args [0 ])
479520 elif len (args ) == 2 :
480521 return _cycler (* args )
481522 elif len (args ) > 2 :
482- raise TypeError ("Only a single Cycler can be accepted as the lone "
483- "positional argument. Use keyword arguments instead." )
523+ raise TypeError (
524+ "Only a single Cycler can be accepted as the lone "
525+ "positional argument. Use keyword arguments instead."
526+ )
484527
485528 if kwargs :
486529 return reduce (add , (_cycler (k , v ) for k , v in kwargs .items ()))
0 commit comments