8000 Change docstring of `format()` built-in · Issue #96526 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

Change docstring of format() built-in #96526

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

Closed
mikez opened this issue Sep 3, 2022 · 17 comments
Closed

Change docstring of format() built-in #96526

mikez opened this issue Sep 3, 2022 · 17 comments
Assignees
Labels
type-feature A feature request or enhancement

Comments

@mikez
Copy link
Contributor
mikez commented Sep 3, 2022

Feature or enhancement

The format.__doc__ currently states

Return value.__format__(format_spec)

format_spec defaults to the empty string.
See the Format Specification Mini-Language section of help('FORMATTING') for
details.

I propose to change this to

Return type(value).__format__(value, format_spec)

Many built-in types implement format_spec according to the
Format Specification Mini-language. See help('FORMATTING').

If type(value) does not supply a method named __format__
and format_spec is empty, then str(value) is returned.
See also help('SPECIALMETHODS').

While I'm at it, I propose to also clarify the docstrings of object.__format__ and int.__format__. (See comment here for current behavior.)

Pitch

I saw this documentation today and it confused me as I tried to understand how to format bytes. The help prompted me to look at help('FORMATTING') which seemed misleading. Only after looking at the C-code of format() did I understand what was going on.

The main clarifications I added here was:

  1. no, not all types support this
  2. the behavior of object.__format__ and pointer to __format__ documentation.
  3. type(value).__format__(...) is returned, not value.__format__(...)

Moreover, I propose to remove "format_spec defaults to the empty string", since this is shown already in "help()" through the function signature.

Previous discussion

Note: Updated on 2022-09-03 to include @TeamSpen210's remark.
Note: Updated on 2022-09-05 to include @ericvsmith's remark.
Note: Updated on 2022-09-06 to include @TeamSpen210's remark.
Note: Updated on 2022-09-07 to include new findings upon reading the C code.

@mikez mikez added the type-feature A feature request or enhancement label Sep 3, 2022
@TeamSpen210
Copy link

The mini-language actually doesn't only apply to strings. Most of those options are actually specific to numeric types. The fallback you mentioned is quite correct though.

@mikez
Copy link
Contributor Author
mikez commented Sep 3, 2022

@TeamSpen210 Thank you. I updated the proposal wording to include numeric types. Also, for further verification, I tested x.__format__ for all built-ins. Only str, complex, float, bool, and int seemed to accept a non-empty format_spec at this time.

@ericvsmith
Copy link
Member

Only str, complex, float, bool, and int seemed to accept a non-empty format_spec at this time.

There's also at least datetime.datetime, .date, and .time; and decimal.Decimal.

The actual behavior is that (after a few optimizations) it really just calls value.__format__(format_spec). I'm not sure it's a good idea to always point to the mini-language. The datetime types don't use it, for example. Maybe some hand waving like "For many builtin types see help('FORMATTING')", or something like that. It's also true that if a type doesn't define __format__ and thus relies on object.__format__, it's an error to specify a non-empty string.

@mikez
Copy link
Contributor Author
mikez commented Sep 4, 2022

@ericvsmith Thank you for the pointer. I had only checked built-in types (via import builtins). I now also searched the built-in modules. Besides datetime and decimal, there is also enum and ipaddress.

I'll ponder a bit on how to reformulate this to make it explicit yet simple and readable.

While I'm at it, I checked the various help(x.__format__). Some are helpful, some I found less so.

These are confusing to me:

>>> import inspect; doc = inspect.getdoc
>>> doc(object.__format__)
'Default object formatter'
>>> doc(int.__format__)
'Default object formatter'
>>> doc(bool.__format__)
'Default object formatter.'
>>> doc(bytes.__format__)  # as an example of a type without a defined __format__
'Default object formatter.'
>>> doc(decimal.Decimal.__format__)
'Default object formatter.'

These I find more helpful, and some may benefit from a pointer to the mini-language:

>>> doc(str.__format__)
'Return a formatted version of the string as described by format_spec.'
>>> doc(float.__format__)
'Formats the float according to format_spec.'
>>> doc(complex.__format__)
'Convert to a string according to format_spec.'
>>> doc(datetime.date.__format__)
'Formats self with strftime.'
>>> doc(enum.Enum.__format__)
'Returns format using actual value type unless __str__ has been overridden.'
>>> print(doc(ipaddress.IPv4Address.__format__))
Returns an IP address as a formatted string.

Supported presentation types are:
's': returns the IP address as a string (default)
'b': converts to binary and returns a zero-padded string
'X' or 'x': converts to upper- or lower-case hex and returns a zero-padded string
'n': the same as 'b' for IPv4 and 'x' for IPv6

For binary and hex presentation types, the alternate form specifier
'#' and the grouping option '_' are supported.

@mikez
Copy link
Contributor Author
mikez commented Sep 5, 2022

@ericvsmith @TeamSpen210 Your comments helped me think more clearly. I updated the wording and pitch with what I think captures the essence. What do you think?

@TeamSpen210
Copy link

I'd suggest tweaking the second sentence a bit, to indicate that the spec has to be empty if no __format__ method is defined.

@ericvsmith
Copy link
Member

What’s the PR number?

@mikez
Copy link
Contributor Author
mikez commented Sep 6, 2022

@TeamSpen210 Updated. Thank you.

@ericvsmith No PR yet. My intention with posting here was to understand if this kind of a change would be welcomed. I've never done a Python PR before, but happy to try. :) I 8000 s the process described here the current one?

@ericvsmith
Copy link
Member

@mikez Yes, I think that's correct.

@mikez
Copy link
Contributor Author
mikez commented Sep 7, 2022

@ericvsmith see PR above.

I made two additional changes

  • type(value).__format__(value, format_spec) (if I read the C code correctly)
  • clarified the docstrings of object.__format__ and (for me) misleading int.__format__

decimal.Decimal might need to change too, since it misleadingly shows the docstring of object.__format__. However, I don't quite understand yet how their docstrings work—it seems to involve decimal.rst somehow? I could need some help here.

@mikez
Copy link
Contributor Author
mikez commented Sep 16, 2022

@ericvsmith @TeamSpen210 To clarify, when I did the pull request, it seems it got auto-assigned to @markshannon as a reviewer. Should I instead have assigned it to one of you? Or, is this reviewer-assignment correct, and I have to expect to wait at least a month or some more for it to get reviewed? (Asking, since I'm new here.)

@ericvsmith
Copy link
Member

I’m not sure why it was assigned to Mark. This is on my list of things to look at the week of October 3, when I’m at a sprint and plan to knock out a bunch of PRs.

@mikez
Copy link
Contributor Author
mikez commented Sep 16, 2022

@ericvsmith Thank you for the clarification. (Also odd, I couldn't find any way on Github to reassign it or add you to it, at least not with my current user permissions.)

@ericvsmith
Copy link
Member

I see it as unassigned. I'll assign it to myself.

@ericvsmith ericvsmith self-assigned this Sep 16, 2022
@mikez
Copy link
Contributor Author
mikez commented Sep 16, 2022

@ericvsmith 👍 To clarify, when 8000 I said "assigned" I meant the PR: #96648

@ericvsmith
Copy link
Member

I see Mark as a reviewer, not assignee. I've assigned the PR to myself.

@mikez
Copy link
Contributor Author
mikez commented Sep 17, 2022

@ericvsmith I previously thought of reviewer and assignee as synonymous, but according to this article it seems they're not. I guess for Python "assignee" is relevant here, and reviewer acts more like a CC in email.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants
0