◐ Shell
reader mode source ↗
Skip to content

PEP 737: gh-111696: Add type.__fully_qualified_name__ attribute#112133

Closed
vstinner wants to merge 8 commits into
python:mainfrom
vstinner:type_fullyqualname
Closed

PEP 737: gh-111696: Add type.__fully_qualified_name__ attribute#112133
vstinner wants to merge 8 commits into
python:mainfrom
vstinner:type_fullyqualname

Conversation

@vstinner

@vstinner vstinner commented Nov 15, 2023

Copy link
Copy Markdown
Member

Add PyType_GetFullyQualName() function with documentation and tests.


📚 Documentation preview 📚: https://cpython-previews--112133.org.readthedocs.build/

@vstinner

Copy link
Copy Markdown
Member Author

Existing logic to format a type name as type.__fullyqualname__ does.

I found a lot of code like:

  • name = "%s.%s" % (obj.__module__, obj.__qualname__)
  • __repr__() method: cls = self.__class__; return f"<{cls.__module__}.{cls.__qualname__} at ...}"

traceback: only code that I found which treats the __main__ module differently:

        stype = self.exc_type.__qualname__
        smod = self.exc_type.__module__
        if smod not in ("__main__", "builtins"):
            if not isinstance(smod, str):
                smod = "<unknown>"
            stype = smod + '.' + stype

_collections_abc: _type_repr() function

def _type_repr(obj):
    ...
    if isinstance(obj, type):
        if obj.__module__ == 'builtins':
            return obj.__qualname__
        return f'{obj.__module__}.{obj.__qualname__}'
    ...

inspect: omit base_module if specified

def formatannotation(annotation, base_module=None):
    ...
    if isinstance(annotation, type):
        if annotation.__module__ in ('builtins', base_module):
            return annotation.__qualname__
        return annotation.__module__+'.'+annotation.__qualname__
    ...

unittest:

def strclass(cls):
    return "%s.%s" % (cls.__module__, cls.__qualname__)

@vstinner

Copy link
Copy Markdown
Member Author

I added a second commit using the new type.__fullyqualname__ attribute in the stdlib to show how it can be used. Even if the attribute is not used to add new "%T" and "%#T" formats to PyUnicode_FromFormat(), this change is useful.

Add PyType_GetFullyQualifiedName() function with documentation and
tests.
@gvanrossum

Copy link
Copy Markdown
Member

Naming is hard. Taking care of myself is harder. I have a lot going on at the moment and I really would prefer not to be responsible for this particular naming decision. Hopefully one or more of the other reviewers can help instead.

@encukou

encukou commented Nov 16, 2023

Copy link
Copy Markdown
Member

IMO, this should use something more customizable than an attribute. A format() directive for example.

@malemburg malemburg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hide comment

Functional changes should not go into this PR.

@vstinner

Copy link
Copy Markdown
Member Author

@gvanrossum:

Naming is hard. Taking care of myself is harder.

He he, I totally get it and it's perfectly fine. Take care.

@vstinner

Copy link
Copy Markdown
Member Author

@encukou:

IMO, this should use something more customizable than an attribute. A format() directive for example.

This change is not exclusive with extending type.__format__() to get new formats. Moreover, if we add a format to get the fully qualified name of a type, I would prefer to have a more "regular" way to get it instead of having to go through formatting.

unittest example from this PR:

def strclass(cls): return "%s.%s" % (cls.__module__, cls.__qualname__)

is replaced with:

def strclass(cls): return cls.__fully_qualified_name__

I like the ability to get an attribute rather than having to build a f-string for that.


Adding new formats to format a type name in Python has been discussed in length. Most recent to oldest discussions:

Problems:

  • I'm not convinced that there is a strong need for formats other than type.__name__ and type.__fully_qualified_name__. I prefer to get an attribute easy to read and understand without having to check the documentation, rather than using a single letter format such as {type|T}
  • So far, I didn't see a clear consensus on an API for such formatting.

So my plan is now to add type.__fully_qualified_name__ attribute, add %T (type.__name__) and %#T (type.__fully_qualified_name__) to PyUnicode_FromFormat() in C, use these new APIs, and then see if more APIs should be added.

@encukou

encukou commented Nov 16, 2023

Copy link
Copy Markdown
Member

Adding new formats to format a type name in Python has been discussed in length.

Yes. Did any of those discussions reach consensus on adding __fully_qualified_name__ with this implementation?

@vstinner vstinner changed the title gh-111696: Add type.__fullyqualname__ attribute Nov 16, 2023
15 hidden items Load more…
@vstinner vstinner requested review from a team and vsajip as code owners November 17, 2023 21:35
@vstinner

Copy link
Copy Markdown
Member Author

@JelleZijlstra: Please review the updated PR. I tried to address all comments of your latest review.

@rhettinger rhettinger removed their request for review November 23, 2023 19:44
@vstinner

Copy link
Copy Markdown
Member Author

@AlexWaygood

Copy link
Copy Markdown
Member

I wrote PEP 737 – Unify type name formatting for these changes: see the PEP discussion.

Thanks for taking the time to write a PEP. I think it's important that changes to builtin classes like this go through the PEP process :-)

@vstinner vstinner changed the title gh-111696: Add type.__fully_qualified_name__ attribute Dec 1, 2023
@AlexWaygood AlexWaygood removed their request for review December 13, 2023 12:52
@vstinner

Copy link
Copy Markdown
Member Author

PEP 737 changed the API since this PR was created. I close this PR for now and will create a new one (or maybe reopen this PR) since PEP 737 will be approved.

@vstinner vstinner closed this Dec 20, 2023
@vstinner vstinner deleted the type_fullyqualname branch December 20, 2023 10:56
@vstinner

Copy link
Copy Markdown
Member Author

The Steering Council rejected the type.__fully_qualified_name__ attribute: see https://peps.python.org/pep-0737/#id1 for details. Thomas wrote: "I think the SC could be persuaded given some concrete use-cases."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants