5858 + : :func:`.varargs`
5959 @ : :term:`accessor` (mostly for :term:`jsonp`)
6060 $ : :func:`token`
61+ ^ : :func:`implicit`
6162
6263.. diacritics-end
6364"""
8081#: Arguments-presence patterns for :class:`_Modifier` constructor.
8182#: Combinations missing raise errors.
8283_modifier_cstor_matrix = {
83- # TODO: Add `implicit` in the table, to augment REPR & forbid implicit sfxed.
84- # (7, kw, opt, accessors, token, sfxed): (STR, REPR, FUNC) OR None
85- 700000 : None ,
86- 710000 : ( "%(dep)s" , "'%(dep)s'(%(acs)s>%(kw)s)" , "keyword" ),
87- 711000 : ( "%(dep)s" , "'%(dep)s'(%(acs)s?%(kw)s)" , "optional" ),
88- 702000 : ( "%(dep)s" , "'%(dep)s'(*)" , "vararg" ),
89- 703000 : ( "%(dep)s" , "'%(dep)s'(+)" , "varargs" ),
84+ # (7, kw, opt, implicit, accessors, sfxed, token/sfx_list): (STR, REPR, FUNC) OR None
85+ 7000000 : None ,
86+ 7100000 : ( "%(dep)s" , "'%(dep)s'(%(acs)s>%(kw)s)" , "keyword" ),
87+ 7110000 : ( "%(dep)s" , "'%(dep)s'(%(acs)s?%(kw)s)" , "optional" ),
88+ 7020000 : ( "%(dep)s" , "'%(dep)s'(*)" , "vararg" ),
89+ 7030000 : ( "%(dep)s" , "'%(dep)s'(+)" , "varargs" ),
9090# Accessor
91- 700100 : ( "%(dep)s" , "'%(dep)s'(@)" , "accessor" ),
92- 710100 : ( "%(dep)s" , "'%(dep)s'(@>%(kw)s)" , "keyword" ),
93- 711100 : ( "%(dep)s" , "'%(dep)s'(@?%(kw)s)" , "optional" ),
94- 702100 : ( "%(dep)s" , "'%(dep)s'(@*)" , "vararg" ),
95- 703100 : ( "%(dep)s" , "'%(dep)s'(@+)" , "varargs" ),
96-
97- 700010 : ( "$%(dep)s$" , "'%(dep)s'($)" , "token" ),
98- 701010 : ( "$%(dep)s$" , "'%(dep)s'($?)" , "token" ),
91+ 7000100 : ( "%(dep)s" , "'%(dep)s'(@)" , "accessor" ),
92+ 7100100 : ( "%(dep)s" , "'%(dep)s'(@>%(kw)s)" , "keyword" ),
93+ 7110100 : ( "%(dep)s" , "'%(dep)s'(@?%(kw)s)" , "optional" ),
94+ 7020100 : ( "%(dep)s" , "'%(dep)s'(@*)" , "vararg" ),
95+ 7030100 : ( "%(dep)s" , "'%(dep)s'(@+)" , "varargs" ),
96+ # Implicit
97+ 7001000 : ( "%(dep)s" , "'%(dep)s'(^)" , "implicit" ),
98+ 7011000 : ( "%(dep)s" , "'%(dep)s'(^?)" , "implicit" ),
99+
100+ 7000010 : ( "$%(dep)s$" , "'%(dep)s'($)" , "token" ),
101+ 7010010 : ( "$%(dep)s$" , "'%(dep)s'($?)" , "token" ),
99102#SFXED
100- 700011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s', %(sfx)s)" , "sfxed" ),
101- 710011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(>%(kw)s), %(sfx)s)" , "sfxed" ),
102- 711011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(?%(kw)s), %(sfx)s)" , "sfxed" ),
103- 702011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(*), %(sfx)s)" , "sfxed_vararg" ),
104- 703011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(+), %(sfx)s)" , "sfxed_varargs" ),
103+ 7000011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s', %(sfx)s)" , "sfxed" ),
104+ 7100011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(>%(kw)s), %(sfx)s)" , "sfxed" ),
105+ 7110011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(?%(kw)s), %(sfx)s)" , "sfxed" ),
106+ 7020011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(*), %(sfx)s)" , "sfxed_vararg" ),
107+ 7030011 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed(%(acs)s'%(dep)s'(+), %(sfx)s)" , "sfxed_varargs" ),
105108# Accessor
106- 700111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@), %(sfx)s)" , "sfxed" ),
107- 710111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@>%(kw)s), %(sfx)s)" , "sfxed" ),
108- 711111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@?%(kw)s), %(sfx)s)" , "sfxed" ),
109- 702111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@*), %(sfx)s)" , "sfxed_vararg" ),
110- 703111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@+), %(sfx)s)" , "sfxed_varargs" ),
109+ 7000111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@), %(sfx)s)" , "sfxed" ),
110+ 7100111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@>%(kw)s), %(sfx)s)" , "sfxed" ),
111+ 7110111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@?%(kw)s), %(sfx)s)" , "sfxed" ),
112+ 7020111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@*), %(sfx)s)" , "sfxed_vararg" ),
113+ 7030111 : ("sfxed('%(dep)s', %(sfx)s)" , "sfxed('%(dep)s'(@+), %(sfx)s)" , "sfxed_varargs" ),
111114}
112115# fmt: on
113116
@@ -127,7 +130,7 @@ def _match_modifier_args(name, *args):
127130
128131
129132class _Optionals (enum .Enum ):
130- keyword = 1
133+ keyword = 1 # or don't bother for tokens & implicits
131134 vararg = 2
132135 varargs = 3
133136
@@ -242,6 +245,7 @@ class _Modifier(str):
242245 #: :func:`is_optional()` returns it.
243246 #: All regulars are `keyword`.
244247 _optional : _Optionals = None
248+ _implicit : bool = None
245249 #: An :term:`accessor` with getter/setter functions to read/write solution values.
246250 #: Any sequence of 2-callables will do.
247251 _accessor : Accessor = None
@@ -262,6 +266,7 @@ def __new__(
262266 _func ,
263267 keyword ,
264268 optional : _Optionals ,
269+ implicit ,
265270 accessor ,
266271 sideffected ,
267272 sfx_list ,
@@ -283,13 +288,6 @@ def __new__(
283288 f"`sideffected` cannot be `sfx`, got { sideffected !r} "
284289 f"\n locals={ locals ()} "
285290 )
286-
287- # TODO: Add `implicit` in the table, to augment REPR & forbid implicit sfxed.
288- if sideffected and kw .get ("_implicit" ):
289- raise ValueError (
290- f"`sideffected` cannot be `implicit`, got { sideffected !r} "
291- f"\n locals={ locals ()} "
292- )
293291 double_sideffects = [
294292 f"{ type (i ).__name__ } ({ i !r} )" for i in sfx_list if is_sfx (i )
295293 ]
@@ -306,6 +304,8 @@ def __new__(
306304 obj ._keyword = keyword
307305 if optional :
308306 obj ._optional = optional
307+ if implicit :
308+ obj ._implicit = implicit
309309 if accessor :
310310 obj ._accessor = accessor
311311 if sideffected :
@@ -331,6 +331,8 @@ def cmd(self):
331331 items .append (f"keyword={ keyword } " if self ._sfx_list else keyword )
332332 if self ._optional == _Optionals .keyword and self ._func != "optional" :
333333 items .append ("optional=1" if self ._sfx_list else "1" )
334+ if self ._implicit :
335+ items .append ("implicit=1" )
334336 if self ._accessor :
335337 items .append (f"accessor={ self ._accessor !r} " )
336338 return f"{ self ._func } ({ ', ' .join (items )} )"
@@ -342,6 +344,7 @@ def __getnewargs__(self):
342344 self ._func ,
343345 self ._keyword ,
344346 self ._optional ,
347+ self ._implicit ,
345348 self ._accessor ,
346349 self ._sideffected ,
347350 self ._sfx_list ,
@@ -353,6 +356,7 @@ def _modifier(
353356 * ,
354357 keyword = None ,
355358 optional : _Optionals = None ,
359+ implicit = None ,
356360 accessor = None ,
357361 sideffected = None ,
358362 sfx_list = (),
@@ -384,11 +388,11 @@ def _modifier(
384388 jsonp = jsonp_path (name )
385389 if jsonp is not None :
386390 kw ["_jsonp" ] = jsonp
387- if not accessor and jsonp :
391+ if not accessor and jsonp and not implicit :
388392 # Honor user's accessor.
389393 accessor = JsonpAcc ()
390394
391- args = (name , keyword , optional , accessor , sideffected , sfx_list )
395+ args = (name , keyword , optional , implicit , accessor , sideffected , sfx_list )
392396 formats = _match_modifier_args (* args )
393397
394398 ## Private-ize all keywords and throw away nulls.
@@ -398,7 +402,14 @@ def _modifier(
398402 if not formats :
399403 if kw :
400404 # Just jsonp given.
401- assert not accessor and (optional , accessor , sideffected , sfx_list ) == (
405+ assert not accessor and (
406+ optional ,
407+ implicit ,
408+ accessor ,
409+ sideffected ,
410+ sfx_list ,
411+ ) == (
412+ None ,
402413 None ,
403414 None ,
404415 None ,
@@ -427,6 +438,7 @@ def modifier_withset(
427438 name = ...,
428439 keyword = ...,
429440 optional : _Optionals = ...,
441+ implicit = ...,
430442 accessor = ...,
431443 sideffected = ...,
432444 sfx_list = ...,
@@ -452,7 +464,7 @@ def modifier_withset(
452464 kw = {
453465 k : v
454466 for k , v in kw .items ()
455- if k not in set ([ "dep" , "name" , "kw" , "repr" , "func" ])
467+ if k not in { "dep" , "name" , "kw" , "repr" , "func" }
456468 }
457469 if name is ...:
458470 name = dep ._sideffected or str (dep )
@@ -741,7 +753,7 @@ class that supports *accessors**, and this requires the operation to be wrapped
741753 )
742754
743755
744- def implicit (name , * , jsonp = None ) -> _Modifier :
756+ def implicit (name , * , optional : bool = None , jsonp = None ) -> _Modifier :
745757 """
746758 :term:`implicit` dependencies are not fed into/out of the function,
747759 usually they are accessed as :term:`jsonp` from some other dependency
@@ -752,7 +764,12 @@ def implicit(name, *, jsonp=None) -> _Modifier:
752764 An *implicit* dependency is expected to always exist in the solution,
753765 contrary to :func:`token`\\ s and the :term:`sfx_list` of :func:`sfxed`\\ s.
754766 """
755- return _modifier (name , implicit = True , jsonp = jsonp )
767+ return _modifier (
768+ name ,
769+ implicit = True ,
770+ optional = _Optionals .keyword if optional else None ,
771+ jsonp = jsonp ,
772+ )
756773
757774
758775def vcat (name , * , keyword : str = None , jsonp = None ) -> _Modifier :
@@ -857,7 +874,7 @@ def keyword(
857874
858875
859876def optional (
860- name : str , keyword : str = None , accessor : Accessor = None , jsonp = None , implicit = None
877+ name : str , keyword : str = None , accessor : Accessor = None , jsonp = None
861878) -> _Modifier :
862879 """
863880 Annotate :term:`optionals` `needs` corresponding to *defaulted* op-function arguments, ...
@@ -878,9 +895,6 @@ def optional(
878895 :param jsonp:
879896 None (derrived from `name`), ``False``, str, collection of str/callable (last one)
880897 See generic :func:`.modify` modifier.
881- :param implicit:
882- :term:`implicit` dependencies are not fed into/out of the function.
883- You may use directly :func:`implicit`.
884898
885899 **Example:**
886900
@@ -928,7 +942,6 @@ def optional(
928942 optional = _Optionals .keyword ,
929943 accessor = accessor ,
930944 jsonp = jsonp ,
931- implicit = implicit ,
932945 )
933946
934947
0 commit comments