GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — PEP 737: gh-111696: Add type.__fully_qualified_name__ attribute by vstinner · Pull Request #112133 · python/cpython Conversation
|
|
Existing logic to format a type name as I found a lot of code like:
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
def _type_repr(obj): ... if isinstance(obj, type): if obj.__module__ == 'builtins': return obj.__qualname__ return f'{obj.__module__}.{obj.__qualname__}' ...
def strclass(cls): return "%s.%s" % (cls.__module__, cls.__qualname__) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I added a second commit using the new |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| .. versionadded:: 3.11 | ||
|
|
||
| .. c:function:: PyObject* PyType_GetFullyQualName(PyTypeObject *type) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Why can't it just be GetFullyQualifiedName?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
We already have a PyType_GetQualName() function which returns type.__qualname__: https://docs.python.org/dev/c-api/type.html#c.PyType_GetQualName
I followed the PyType_GetQualName() name: PyType_GetFullyQualName() returns type.__fullyqualname__.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I know that, but it still tickles my grammar bone. :-(
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ok, I renamed the function to PyType_GetFullyQualifiedName().
I prefer to keep __fullyqualname__ for the attribute name. We already have __qualname__. And since it's commonly used, I prefer to make it short.
An alternative is to use FQN acronym :-D
type.__fqn__PyType_GetFQN()But I prefer "longer" names, so I don't need to check the doc to know what they mean ;-)
On the Internet, Domain Name Service (DNS) use FQDN: Fully Qualified Domain Name :-)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I share Guido's unease with "fullyqualname": it sounds wrong to have the abbreviated "qual" between two unabbreviated words.
For comparison:
__class_getitem__, __release_buffer__, __type_params__, __init_subclass__, __text_signature____getnewargs__, __kwdefaults__, __isabstractmethod__I would prefer __fully_qualified_name__. It's on the long side, but it matches the current name for the concept (mentioned in https://docs.python.org/3.12/glossary.html#term-qualified-name). __fqn__ seems too cryptic.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I concur with Jelle.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ok, I renamed the attribute to __fully_qualified_name__. Does it look better to you?
It's on the long side, but it matches the current name for the concept (mentioned in https://docs.python.org/3.12/glossary.html#term-qualified-name). fqn seems too cryptic.
I agree with you.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Add PyType_GetFullyQualifiedName() function with documentation and tests.
19c3bf6 to
82dd956
Compare
|
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. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
IMO, this should use something more customizable than an attribute. A |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| { | ||
| PyObject *tp_name = PyType_GetName(&PyLong_Type); | ||
| assert(strcmp(PyUnicode_AsUTF8(tp_name), "int") == 0); | ||
| assert(PyUnicode_EqualToUTF8(tp_name, "int")); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Even though it's still useful, this has nothing to do with the PR title and should go into a separate PR.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It's related, I changed the 3 tests which check the 3 C functions to get a "type name". I prefer to make the code consistent to make it easier to maintain.
This change also fix a bug: caller must check if PyUnicode_AsUTF8() is NULL. PyUnicode_EqualToUTF8() doesn't have this problem.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if obj.__module__ == 'builtins': | ||
| return obj.__qualname__ | ||
| return f'{obj.__module__}.{obj.__qualname__}' | ||
| return obj.__fullyqualname__ |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
You are changing the contract for the method here. This may result in breaking code relying on previous behavior.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I think that you misunderstood the API of this attribute. Please check its documentation in Doc/library/stdtypes.rst, or just try my PR.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Functional changes should not go into this PR.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| rtn = PyUnicode_FromFormat("<class '%s'>", type->tp_name); | ||
|
|
||
| Py_XDECREF(mod); | ||
| PyObject *result = PyUnicode_FromFormat("<class '%U'>", name); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above: you are readding "builtins." to builtin types.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
The fully qualified name omits the module if the module is "builtins". There is no behavior change. This code has multiple tests. I'm not sure that I get your comment correctly.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
As you can see from the code, the "builtins." part was deliberately omitted for builtin types.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure of what you are talking about. You are commenting type_repr() function. I didn't change the function output, it's the same:
>>> import builtins
>>> print(repr(builtins.str)) # <=== HERE "builtins." is omitted
<class 'str'>
>>> builtins.str.__module__
'builtins'
>>> builtins.str.__qualname__
'str'
repr() omits the module if it's "builtins". But it's added otherwise:
>>> import collections
>>> print(repr(collections.OrderedDict))
<class 'collections.OrderedDict'>
>>> collections.OrderedDict.__module__
'collections'
>>> collections.OrderedDict.__qualname__
'OrderedDict'
It's the same behavior than before.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
He he, I totally get it and it's perfectly fine. Take care. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
This change is not exclusive with extending unittest example from this PR:
is replaced with:
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:
So my plan is now to add |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Yes. Did any of those discussions reach consensus on adding |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
| PyObject * | ||
| PyType_GetFullyQualifiedName(PyTypeObject *type) | ||
| { | ||
| return type_get_fullyqualname(type, NULL); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| return type_get_fullyqualname(type, NULL); | |
| return type_fullyqualname(type, 0); |
No need to call the intermediate function
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I reorganized the calls. The special function with int is_repr parameter now gets a _impl suffix. The getter losts get_ in its name to look alike type_name() and type_qualname() getters. It now calls PyType_GetFullyQualifiedName(). Does it look better to you?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@JelleZijlstra: Please review the updated PR. I tried to address all comments of your latest review. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I wrote PEP 737 – Unify type name formatting for these changes: see the PEP discussion. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
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 :-) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
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. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
The Steering Council rejected the |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.