This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Implement an informative `BoundArguments.__repr__`
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: yselivanov Nosy List: cool-RR, larry, ncoghlan, python-dev, serhiy.storchaka, terry.reedy, yselivanov
Priority: normal Keywords: patch

Created on 2014-10-03 13:19 by cool-RR, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
BoundArguments_repr_alt.patch serhiy.storchaka, 2015-05-15 06:56 review
Messages (14)
msg228332 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2014-10-03 16:26
Can you propose a format for it?

I'm not sure that including all arguments and their reprs is a good idea, as it will make BA's repr too long.
msg228333 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-03 16:28
Something like <BoundArguments: foo=bar, boo=baz>

I have no problem with truncation when it gets too long.
msg228334 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2014-10-03 16:29
How about we just list bound arguments names, without values?
msg228335 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-03 16:31
Em, that kind of defeats the purpose of describing the object, doesn't it?
msg228337 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2014-10-03 16:44
Yes and no ;)

You can have partially bound args, you can bind just one argument and use defaults for the rest, etc. I agree that it's not an ideal solution, but it is a sane compromise.
msg228338 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-03 16:45
I think the point of `__init__` is to know what the object is, and if you're hiding the values then someone has to access the attributes to find out the values and that sucks.
msg228376 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-10-03 20:56
Context: inspect.signature returns an inspect.Signature instance. Its .bind and .bind_partial methods return ab inspect.BoundArguments instance with a standard <...@ 0x...> representation.

>>> import inspect
>>> def foo(a, b=10): pass

>>> ba = inspect.signature(foo).bind(5)
>>> ba
<inspect.BoundArguments object at 0x0000000002C94080>

BAs already have 3 data access methods
>>> ba.arguments  # I believe this describes the object pretty fully
OrderedDict([('a', 5)])
>>> ba.args
(5,)
>>> ba.kwargs
{}

A possible proposal for this case would be <BoundArguments: a=5>.  However, this contains the same info as ba.arguments but in a less accessible form.

Listing all parameters (and their default values if any) would be wrong as the additional info is not part of the object.  The doc says to use Signature.parameters for full info, and it shows how to do that.  So I am negative on the proposal.
msg228377 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-03 20:59
Another thing I proposed in python-ideas is to have `__getitem__` delegate to `.arguments`, so this proposal is similar in spirit, because I want to have `__repr__` show information from `.arguments`.

To be honest I don't see the point in having to access `.arguments` manually for anything. `BoundArguments` is all about arguments. I don't see a reason to waste anyone's time with accessing an attribute on it to get to the arguments. There isn't much more to get on the thing. So this applies both to __repr__ and __getitem__.
msg228378 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2014-10-03 21:03
> Another thing I proposed in python-ideas is to have `__getitem__` delegate to `.arguments`, so this proposal is similar in spirit, because I want to have `__repr__` show information from `.arguments`.

Big -1 on __getitem__

> To be honest I don't see the point in having to access `.arguments` manually for anything. `BoundArguments` is all about arguments.

I agree. I'll take a look.
msg228381 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-10-03 21:16
.arguments returns a mutable (ordered) dict that can be modified.  See the example in the doc
https://docs.python.org/3.4/library/inspect.html#inspect.BoundArguments
msg243228 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-05-14 22:47
New changeset a444464a2e87 by Yury Selivanov in branch 'default':
Issue 22547: Implement informative __repr__ for inspect.BoundArguments
https://hg.python.org/cpython/rev/a444464a2e87
msg243249 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-05-15 06:43
May be omit names for positionalarguments?

>>> def foo(a, *args, b=10, **kwargs): pass
... 
>>> inspect.signature(foo).bind(1, 2, 3, b=4, c=5)
<BoundArguments at 0xb6eee9ec (a=1, args=(2, 3), b=4, kwargs={'c': 5})>

I think it would look better as:

<BoundArguments (1, 2, 3, b=4, c=5)>
msg243250 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-05-15 06:56
Here is an implementation.
msg243278 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2015-05-15 16:42
Actually, I like the current repr (minus the object ID, I'll update the code).

The thing about BoundArguments is that '.arguments' is the main property. You use it to add more stuff to *args & **kwargs, or to add/remove positional/keyword arguments.  Seeing a flattened call signature in the repr won't help you with debugging.

Perhaps, we can implement __str__ using your approach.
History
Date User Action Args
2022-04-11 14:58:08adminsetgithub: 66737
2015-05-15 16:42:36yselivanovsetmessages: + msg243278
2015-05-15 06:56:20serhiy.storchakasetfiles: + BoundArguments_repr_alt.patch
keywords: + patch
messages: + msg243250
2015-05-15 06:43:04serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg243249
2015-05-14 22:47:54yselivanovsetstatus: open -> closed
type: enhancement
resolution: fixed
stage: resolved
2015-05-14 22:47:35python-devsetnosy: + python-dev
messages: + msg243228
2014-10-03 21:16:17terry.reedysetmessages: + msg228381
2014-10-03 21:03:37yselivanovsetassignee: yselivanov

messages: + msg228378
nosy: + ncoghlan, larry
2014-10-03 20:59:16cool-RRsetmessages: + msg228377
2014-10-03 20:56:15terry.reedysetnosy: + terry.reedy
messages: + msg228376
2014-10-03 16:45:52cool-RRsetmessages: + msg228338
2014-10-03 16:44:41yselivanovsetmessages: + msg228337
2014-10-03 16:31:23cool-RRsetmessages: + msg228335
2014-10-03 16:29:45yselivanovsetmessages: + msg228334
2014-10-03 16:28:37cool-RRsetmessages: + msg228333
2014-10-03 16:26:34yselivanovsetnosy: + yselivanov
messages: + msg228332
2014-10-03 13:19:59cool-RRcreate