I'm not a fan of this idea for two (related) reasons:

1) This seems like something that's a relatively niche case to *want* to do rather than doing unintentionally.
2) This vastly increases the chance of silent bugs in code.

With regards to #1, the main examples I've seen posited in this thread are unpacking of unstructured object formats (e.g. JSON) and applying subsets of key-values from a configuration file [which is basically another unstructured object format). This seems like the level of functionality that I'd expect a helper function to be the right choice for - it can be part of the overall library handling the objects, or coded as a one-off for smaller projects.

Regarding #2, passing unknown bags of values to functions is an easy way to run into both logic and security errors - see for example the problems that the Ruby on Rails ORM ran into with its batch-setter functionality when developers didn't properly limit what values in objects could be updated and forgot to sanitize inputs. Similarly, for keyword args with default values, adding this functionality would make it easy for a typo to result in a parameter that a user expects to be getting passed in not actually getting passed, because the function got {foobra=1} instead of {foobar=1} and silently discarded foobra=1 in favor of the default value for foobar.

There may be cases where passing an unknown bag is what you want to do, but it's probably worth requiring that to be more explicit and intentional rather than an easily-missed extra asterisk.

On Fri, Apr 12, 2019 at 4:09 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Bruce Leban wrote:
> I think this is a real problem given the frequent convention that you
> can freely add fields to json objects with the additional fields to be
> ignored.

Unpacking json objects isn't something one does every day, so I
don't think it would be worth adding syntax just for this.

Rather than new syntax, how about a helper function such as:

def call_with_kwds_from(func, kwds):
     code = func.__code__
     names = code.co_varnames[:code.co_argcount]
     func(**{name : kwds[name] for name in names})

Usage example:

def f(a, b):
     print("a =", a, "b =", b)

d = {"a": "a_value", "b": "b_value", "c": "something extra"}

call_with_kwds_from(f, d)

--
Greg
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/