Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inspect.Signature and default arguments #67187

Closed
doerwalter opened this issue Dec 4, 2014 · 10 comments
Closed

inspect.Signature and default arguments #67187

doerwalter opened this issue Dec 4, 2014 · 10 comments
Labels
docs Documentation in the Doc dir type-feature A feature request or enhancement

Comments

@doerwalter
Copy link
Contributor

BPO 22998
Nosy @doerwalter, @terryjreedy, @bitdancer, @1st1
Files
  • signature-bind.diff
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2014-12-06.00:05:53.310>
    created_at = <Date 2014-12-04.20:14:01.621>
    labels = ['type-feature', 'docs']
    title = 'inspect.Signature and default arguments'
    updated_at = <Date 2014-12-09.13:33:49.428>
    user = 'https://github.com/doerwalter'

    bugs.python.org fields:

    activity = <Date 2014-12-09.13:33:49.428>
    actor = 'doerwalter'
    assignee = 'docs@python'
    closed = True
    closed_date = <Date 2014-12-06.00:05:53.310>
    closer = 'yselivanov'
    components = ['Documentation']
    creation = <Date 2014-12-04.20:14:01.621>
    creator = 'doerwalter'
    dependencies = []
    files = ['37362']
    hgrepos = []
    issue_num = 22998
    keywords = ['patch']
    message_count = 10.0
    messages = ['232150', '232151', '232152', '232153', '232154', '232175', '232227', '232228', '232234', '232375']
    nosy_count = 6.0
    nosy_names = ['doerwalter', 'terry.reedy', 'r.david.murray', 'docs@python', 'python-dev', 'yselivanov']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue22998'
    versions = ['Python 3.4', 'Python 3.5']

    @doerwalter
    Copy link
    Contributor Author

    inspect.Signature.bind() doesn't add values for parameters that are unspecified but have a default value. The documentation at https://docs.python.org/3/library/inspect.html#inspect.BoundArguments.arguments includes an example how to add default values, but that example doesn't work for the * and ** parameters.

    This patch adds a new method Signature.bind_with_defaults() that works like Signature.bind(), but includes parameters with a default value (and can handle values for the * and ** parameters).

    @doerwalter doerwalter added stdlib Python modules in the Lib dir type-feature A feature request or enhancement labels Dec 4, 2014
    @bitdancer
    Copy link
    Member

    Can you give an example of what you say doesn't work?

    IIRC the reason this method isn't part of the API is because normally it isn't needed (the defaults are filled in when you do the actual call). What is your use case for needing the defaults to be pre-bound?

    @doerwalter
    Copy link
    Contributor Author

    The following doesn't work::

       import inspect
    
       def foo(*args, **kwargs):
          return (args, kwargs)

    # Code from https://docs.python.org/3/library/inspect.html#inspect.BoundArguments.arguments to fill in the defaults

       sig = inspect.signature(foo)
       ba = sig.bind()
    
       for param in sig.parameters.values():
          if param.name not in ba.arguments:
             ba.arguments[param.name] = param.default
    
       print(foo(*ba.args, **ba.kwargs))

    instead it gives the following traceback::

       Traceback (most recent call last):
         File "sig_test.py", line 16, in <module>
           print(foo(*ba.args, **ba.kwargs))
         File "/Users/walter/.local/lib/python3.4/inspect.py", line 2246,    in args
           args.extend(arg)
       TypeError: 'type' object is not iterable

    In my use case there isn't a call to a function implemented in Python. Instead I'm implementing a templating languages that supports defining a signature for a template. Calling the template binds the arguments and inside the template the variables simply are a dictionary.

    I.e. define the template like this:

       t = Template("<?print a+b?>", signature="a, b=23")

    Then you can call it like this:

       t(17)

    and inside the template the variables will be {"a": 17, "b": 23}.

    The signature argument in the Template constructor will be parsed into an inspect.Signature object and I'd like to use Signature.bind() to get the final variables dictionary.

    @bitdancer
    Copy link
    Member

    This is indeed a bit tricky. Your use case is pretty specialized (it doesn't involve any actual python functions), so I don't think by itself it argues for the inclusion of a _with_defaults method. The example fill-in in the docs fails because args and kwargs don't check for _empty as a possible value for the VAR_POSITIONAL (resp VAR_KEYWORD).

    So I think either we add that check to args and kwargs, or we add a _with_defaults method because filling in the defaults would no longer be a simple loop (and thus easy to get wrong).

    Let's see what Yury thinks.

    @1st1
    Copy link
    Member

    1st1 commented Dec 4, 2014

    I think we should just fix the documentation, and update the code in example with a proper check:

      for param in sig.parameters.values():
        if (param.name not in ba.arguments 
                 and param.default is not param.empty):
           ba.arguments[param.name] = param.default

    I'm -1 on adding '_with_defaults' method, because usually you don't need this (at least in my experience).

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Dec 5, 2014

    New changeset 71c38c233e5c by Yury Selivanov in branch '3.4':
    docs.inspect: Fix BoundArguments example. Issue bpo-22998.
    https://hg.python.org/cpython/rev/71c38c233e5c

    New changeset 697adefaba6b by Yury Selivanov in branch 'default':
    docs.inspect: Fix BoundArguments example. Issue bpo-22998.
    https://hg.python.org/cpython/rev/697adefaba6b

    @terryjreedy
    Copy link
    Member

    Should this be closed now?

    @1st1
    Copy link
    Member

    1st1 commented Dec 6, 2014

    Should this be closed now?

    Yes, let's close it.

    David and Walter, you're welcome to re-open the issue if you want to discuss it in more detail.

    @1st1 1st1 closed this as completed Dec 6, 2014
    @bitdancer
    Copy link
    Member

    I'm good with your solution, but I'm going to adjust the resolution by changing the component :)

    @bitdancer bitdancer added docs Documentation in the Doc dir and removed stdlib Python modules in the Lib dir labels Dec 6, 2014
    @doerwalter
    Copy link
    Contributor Author

    The updated code in the documentation still doesn't set the * and ** parameters. I would have preferred the following code:

      for param in sig.parameters.values():
        if param.name not in ba.arguments:
          if param.kind is inspect.Parameter.VAR_POSITIONAL:
            default = ()
          elif param.kind is inspect.Parameter.VAR_KEYWORD:
            default = {}
          else:
            default = param.default
          ba.arguments[param.name] = default

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    docs Documentation in the Doc dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants