What if * and ** forwarded all unnamed arguments to a function? Example: import traceback def print_http_response(request, color=True): ... def print_invalid_api_response(error, *, show_traceback=False, **): print_http_response(*, **) if show_traceback: traceback.print_last() else: print(error)
This would essentially allow * and ** to be used to call a function without having to give a name: *args or **kwargs. However in this scenario, the client function is more likely to be “inheriting from” the behavior of the inner function, in a way where all or most of the arguments of the inner function are valid on the client function. Example: requests.get creates a Request object and immediately sends the response while blocking for it. > On Sep 6, 2018, at 3:27 PM, python-ideas-requ...@python.org wrote: > > Send Python-ideas mailing list submissions to > python-ideas@python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/python-ideas > or, via email, send a message with subject or body 'help' to > python-ideas-requ...@python.org > > You can reach the person managing the list at > python-ideas-ow...@python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Python-ideas digest..." > > > Today's Topics: > > 1. Re: On evaluating features [was: Unpacking iterables for > augmented assignment] (Franklin? Lee) > 2. Re: On evaluating features [was: Unpacking iterables for > augmented assignment] (Chris Angelico) > 3. Re: Keyword only argument on function call (Jonathan Fine) > 4. Re: On evaluating features [was: Unpacking iterables for > augmented assignment] (Franklin? Lee) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Thu, 6 Sep 2018 14:38:26 -0400 > From: "Franklin? Lee" <leewangzhong+pyt...@gmail.com> > To: Chris Angelico <ros...@gmail.com> > Cc: Python-Ideas <python-ideas@python.org> > Subject: Re: [Python-ideas] On evaluating features [was: Unpacking > iterables for augmented assignment] > Message-ID: > <cab_e7iyjcflccmnbviudkzy6mxdv0hs7-_4kuqepze8mvtz...@mail.gmail.com> > Content-Type: text/plain; charset="UTF-8" > >> On Thu, Sep 6, 2018 at 2:23 PM Chris Angelico <ros...@gmail.com> wrote: >> >> On Fri, Sep 7, 2018 at 4:11 AM, Franklin? Lee >> <leewangzhong+pyt...@gmail.com> wrote: >>>> On Tue, Aug 28, 2018 at 6:37 PM Greg Ewing <greg.ew...@canterbury.ac.nz> >>>> wrote: >>>> >>>> Guido van Rossum wrote: >>>>> we might propose (as the OP did) that this: >>>>> >>>>> a, b, c += x, y, z >>>>> >>>>> could be made equivalent to this: >>>>> >>>>> a += x >>>>> b += y >>>>> c += z >>>> >>>> But not without violating the principle that >>>> >>>> lhs += rhs >>>> >>>> is equivalent to >>>> >>>> lhs = lhs.__iadd__(lhs) >>> >>> (Corrected: lhs = lhs.__iadd__(rhs)) >>> >>> Since lhs here is neither a list nor a tuple, how is it violated? Or >>> rather, how is it any more of a special case than in this syntax: >>> >>> # Neither name-binding or setitem/setattr. >>> [a,b,c] = items >>> >>> If lhs is a Numpy array, then: >>> a_b_c += x, y, z >>> is equivalent to: >>> a_b_c = a_b_c.__iadd__((x,y,z)) >>> >>> We can translate the original example: >>> a, b, c += x, y, z >>> to: >>> a, b, c = target_list(a,b,c).__iadd__((x,y,z)) >>> where `target_list` is a virtual (not as in "virtual function") type >>> for target list constructs. >> >> What is the virtual type here, and what does its __iadd__ method do? I >> don't understand you here. Can you go into detail? Suppose I'm the >> author of the class that all six of these objects are instances of; >> can I customize the effect of __iadd__ here in some way, and if so, >> how? > > I shouldn't have used jargon I had to look up myself. > > The following are equivalent and compile down to the same code: > a, b, c = lst > [a, b, c] = lst > > The left hand side is not an actual list (even though it looks like > one). The brackets are optional. The docs call the left hand side a > target list: > https://docs.python.org/3/reference/simple_stmts.html#assignment-statements > > "Target list" is not a real type. You can't construct such an object, > or hold one in memory. You can't make a class that emulates it > (without interpreter-specific hacks), because it is a collection of > its names, not a collection of values. > > target_list.__iadd__ also does not exist, because target_list does not > exist. However, target_list can be thought of as a virtual type, a > type that the compiler compiles away. We can then consider > target_list.__iadd__ as a virtual operator, which the compiler will > understand but hide from the runtime. > > I was making the point that, because the __iadd__ in the example does > not refer to list.__iadd__, but rather a virtual target_list.__iadd__, > there is not yet a violation of the rule. > > > ------------------------------ > > Message: 2 > Date: Fri, 7 Sep 2018 04:46:36 +1000 > From: Chris Angelico <ros...@gmail.com> > To: Python-Ideas <python-ideas@python.org> > Subject: Re: [Python-ideas] On evaluating features [was: Unpacking > iterables for augmented assignment] > Message-ID: > <CAPTjJmrauU+GD+Utcm=zugfqwx5qxohwlg5pl94s5oh_o8j...@mail.gmail.com> > Content-Type: text/plain; charset="UTF-8" > > On Fri, Sep 7, 2018 at 4:38 AM, Franklin? Lee > <leewangzhong+pyt...@gmail.com> wrote: >> The following are equivalent and compile down to the same code: >> a, b, c = lst >> [a, b, c] = lst >> >> The left hand side is not an actual list (even though it looks like >> one). The brackets are optional. The docs call the left hand side a >> target list: >> https://docs.python.org/3/reference/simple_stmts.html#assignment-statements >> >> "Target list" is not a real type. You can't construct such an object, >> or hold one in memory. You can't make a class that emulates it >> (without interpreter-specific hacks), because it is a collection of >> its names, not a collection of values. > > A target list is a syntactic element, like a name, or an operator, or > a "yield" statement. You can't construct one, because it isn't an > object type. It's not a "virtual type". It's a completely different > sort of thing. > >> target_list.__iadd__ also does not exist, because target_list does not >> exist. However, target_list can be thought of as a virtual type, a >> type that the compiler compiles away. We can then consider >> target_list.__iadd__ as a virtual operator, which the compiler will >> understand but hide from the runtime. >> >> I was making the point that, because the __iadd__ in the example does >> not refer to list.__iadd__, but rather a virtual target_list.__iadd__, >> there is not yet a violation of the rule. > > What you're suggesting is on par with trying to say that: > > for += 5 > > should be implemented as: > > current_loop.__iadd__(5) > > where "current_loop" doesn't really exist, but it's a virtual type > that represents a 'for' loop. That doesn't make sense, because there > is no object in Python to represent the loop. There is no class/type > that represents all loops, on which a method like this could be added. > The word 'for' is part of the grammar, not the object model. And > "target list" is the same. There's no way to attach an __iadd__ method > to something that doesn't exist. > > So for your proposal to work, you would need to break that rule, and > give a *different* meaning to this. > > ChrisA > > > ------------------------------ > > Message: 3 > Date: Thu, 6 Sep 2018 20:10:49 +0100 > From: Jonathan Fine <jfine2...@gmail.com> > To: Anders Hovm?ller <bo...@killingar.net> > Cc: python-ideas <python-ideas@python.org> > Subject: Re: [Python-ideas] Keyword only argument on function call > Message-ID: > <CALD=yf8ddn4mqnblw+ouoac7yqedc_esk8o5pykuwetmunm...@mail.gmail.com> > Content-Type: text/plain; charset="UTF-8" > > Summary: I addressed the DEFINING problem. My mistake. Some rough > ideas for the CALLING problem. > > Anders has kindly pointed out to me, off-list, that I solved the wrong > problem. His problem is CALLING the function fn, not DEFINING fn. > Thank you very much for this, Anders. > > For calling, we can use > https://docs.python.org/3/library/functions.html#locals > >>>> lcls = locals() > >>>> a = 'apple' >>>> b = 'banana' >>>> c = 'cherry' > >>>> dict((k, lcls[k]) for k in ('a', 'b', 'c')) > {'b': 'banana', 'c': 'cherry', 'a': 'apple'} > > So in his example > > foo(a=a, b=b, c=c, d=3, e=e) > > one could instead write > > foo(d=3, **helper(locals(), ('a', 'b', 'c', 'e'))) > > or perhaps better > > helper(locals(), 'a', 'b', 'c', 'e')(foo, d=3) > > where the helper() picks out items from the locals(). And in the > second form, does the right thing with them. > > Finally, one might be able to use > >>>> def fn(*, a, b, c, d, e): f, g, h = 3, 4, 5 >>>> fn.__code__.co_kwonlyargcount > 5 >>>> fn.__code__.co_varnames > ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') >>>> fn.__code__.co_argcount > 0 > > to identify the names of all keyword arguments of the function foo(), > and they provide the values in locals() as the defaults. Of course, > this is somewhat magical, and requires strict conformance to > conventions. So might not be a good idea. > > The syntax could then be > > localmagic(foo, locals())(d=3) > > which, for magicians, might be easier. But rightly in my opinion, > Python is reluctant to use magic. > > On the other hand, for a strictly controlled Domain Specific Language, > it might, just might, be useful. And this list is for "speculative > language ideas" (see > https://mail.python.org/mailman/listinfo/python-ideas). > > -- > Jonathan > > > ------------------------------ > > Message: 4 > Date: Thu, 6 Sep 2018 15:26:47 -0400 > From: "Franklin? Lee" <leewangzhong+pyt...@gmail.com> > To: Chris Angelico <ros...@gmail.com> > Cc: Python-Ideas <python-ideas@python.org> > Subject: Re: [Python-ideas] On evaluating features [was: Unpacking > iterables for augmented assignment] > Message-ID: > <cab_e7iyim2byzkxtonumtvrmtzr0s0k8-zybykubkyvv7ae...@mail.gmail.com> > Content-Type: text/plain; charset="UTF-8" > > n Thu, Sep 6, 2018 at 2:47 PM Chris Angelico <ros...@gmail.com> wrote: >> >> On Fri, Sep 7, 2018 at 4:38 AM, Franklin? Lee >> <leewangzhong+pyt...@gmail.com> wrote: >>> The following are equivalent and compile down to the same code: >>> a, b, c = lst >>> [a, b, c] = lst >>> >>> The left hand side is not an actual list (even though it looks like >>> one). The brackets are optional. The docs call the left hand side a >>> target list: >>> https://docs.python.org/3/reference/simple_stmts.html#assignment-statements >>> >>> "Target list" is not a real type. You can't construct such an object, >>> or hold one in memory. You can't make a class that emulates it >>> (without interpreter-specific hacks), because it is a collection of >>> its names, not a collection of values. >> >> A target list is a syntactic element, like a name, or an operator, or >> a "yield" statement. You can't construct one, because it isn't an >> object type. It's not a "virtual type". It's a completely different >> sort of thing. > > I didn't think I gave the impression that I was complaining about not > being able to construct it. I gave an explanation for how it isn't a > real type, because you asked how you could modify the behavior, and > because I wanted to give an explanation for more than just you. > > There are constructs that correspond to types (such as slices and > functions). There are those that don't. We call `3:2` (in the right > context) a slice, even though it's technically a construct which is > compiled down to a `slice` object. I see no problem there. > > I called it a "virtual type" and explained why I called it that. You > reject the use of that term, but you don't even acknowledge that I > gave reasons for it. > >>> target_list.__iadd__ also does not exist, because target_list does not >>> exist. However, target_list can be thought of as a virtual type, a >>> type that the compiler compiles away. We can then consider >>> target_list.__iadd__ as a virtual operator, which the compiler will >>> understand but hide from the runtime. >>> >>> I was making the point that, because the __iadd__ in the example does >>> not refer to list.__iadd__, but rather a virtual target_list.__iadd__, >>> there is not yet a violation of the rule. >> >> What you're suggesting is on par with trying to say that: >> >> for += 5 >> >> should be implemented as: >> >> current_loop.__iadd__(5) >> >> where "current_loop" doesn't really exist, but it's a virtual type >> that represents a 'for' loop. > > I explained how target_list could be thought of as a special imaginary > type which only exists in the compiler's "mind", and then extended > that to an imaginary method on that type. Of course your example shows > absurdity: you didn't try to say how a for-loop is like an object in > the first place. > >> That doesn't make sense, because there >> is no object in Python to represent the loop. There is no class/type >> that represents all loops, on which a method like this could be added. >> The word 'for' is part of the grammar, not the object model. And >> "target list" is the same. There's no way to attach an __iadd__ method >> to something that doesn't exist. > > But I'm not using the word `for`. I am using constructs like `[a,b,c]` > (where it is not a list). At least use `(for x in y: z) += 5` as your > example. You're effectively accusing me of trying to make `[` (a > single token, not a full construct) an object. > > Your argument here is that there is no Python object to represent a > loop, but that really means there's no _runtime_ object to represent a > loop. I already said that target lists don't exist in memory (i.e. > runtime). > > "Target list" does exist, just not as a runtime type. It exists as an > abstraction not available to the runtime, and we can extend that > abstraction in ways not available to the runtime. That means that you > can't attach it during the runtime. It does not mean you can't reason > with it during compile-time. > >> So for your proposal to work, you would need to break that rule, and >> give a *different* meaning to this. > > It is not my proposal. I was questioning how there was a rule > violation about x+=y translating to `x = x.__iadd__(y)`. You're > talking about a different, made-up rule about how syntactical > constructs can't correspond to compile-time imaginary objects or > runtime objects. But there are syntactical constructs that DO > correspond to runtime types (slice, list, class), there are those > which don't but can (let's not get into that), there are those which > can stay compile-time (f-strings, target lists), and there are those > which probably can't be thought of as types at all (import). > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > > > ------------------------------ > > End of Python-ideas Digest, Vol 142, Issue 22 > ********************************************* _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/