Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
vstinner wants to merge8 commits intopython:mainfromvstinner:type_fullyqualname
Closed
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletionsDoc/c-api/type.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -185,6 +185,14 @@ Type Objects

.. versionadded:: 3.11

.. c:function:: PyObject* PyType_GetFullyQualifiedName(PyTypeObject *type)

Return the type's :term:`fully qualified name`. Equivalent to getting the
type's :attr:`__fully_qualified_name__ <class.__fully_qualified_name__>`
attribute.

.. versionadded:: 3.13

.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot)

Return the function pointer stored in the given slot. If the
Expand Down
19 changes: 19 additions & 0 deletionsDoc/glossary.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -435,6 +435,25 @@ Glossary
division. Note that ``(-11) // 4`` is ``-3`` because that is ``-2.75``
rounded *downward*. See :pep:`238`.

fully qualified name
The fully qualified name is the entire dotted path to a class or a
module.

The :attr:`class.__fully_qualified_name__` attribute includes the module
name, except for built-in classes. Example::

>>> import collections
>>> collections.OrderedDict.__fully_qualified_name__
'collections.OrderedDict'

When used to refer to modules, the *fully qualified name* means the
entire dotted path to the module, including any parent packages,
e.g. ``email.mime.text``::

>>> import email.mime.text
>>> email.mime.text.__name__
'email.mime.text'

function
A series of statements which returns some value to a caller. It can also
be passed zero or more :term:`arguments <argument>` which may be used in
Expand Down
6 changes: 3 additions & 3 deletionsDoc/library/doctest.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -587,13 +587,13 @@ doctest decides whether actual output matches an example's expected output:
.. data:: IGNORE_EXCEPTION_DETAIL

When specified, doctests expecting exceptions pass so long as an exception
of the expected type is raised, even if the details
(message andfully qualified exception name) don't match.
of the expected type is raised, even if the details (message and
:term:`fully qualified exception name <fully qualified name>`) don't match.

For example, an example expecting ``ValueError: 42`` will pass if the actual
exception raised is ``ValueError: 3*14``, but will fail if, say, a
:exc:`TypeError` is raised instead.
It will also ignore any fully qualified name included before the
It will also ignore any:term:`fully qualified name` included before the
exception class, which can vary between implementations and versions
of Python and the code/libraries in use.
Hence, all three of these variations will work with the flag specified:
Expand Down
4 changes: 2 additions & 2 deletionsDoc/library/email.contentmanager.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -56,8 +56,8 @@
found:

* the type itself (``typ``)
* the type's fully qualified name (``typ.__module__ + '.' +
typ.__qualname__``).
* the type's:term:`fully qualified name`
(:attr:`typ.__fully_qualified_name__ <class.__fully_qualified_name__>`).
* the type's qualname (``typ.__qualname__``)
* the type's name (``typ.__name__``).

Expand Down
12 changes: 6 additions & 6 deletionsDoc/library/importlib.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -356,7 +356,7 @@ ABC hierarchy::
reloaded):

- :attr:`__name__`
The module's fully qualified name.
The module's:term:`fully qualified name`.
It is ``'__main__'`` for an executed module.

- :attr:`__file__`
Expand All@@ -377,8 +377,8 @@ ABC hierarchy::
as an indicator that the module is a package.

- :attr:`__package__`
The fully qualified name of the package the module is in (or the
empty string for a top-level module).
The:term:`fully qualified name` of the package the module is in
(or theempty string for a top-level module).
If the module is a package then this is the same as :attr:`__name__`.

- :attr:`__loader__`
Expand DownExpand Up@@ -1181,7 +1181,7 @@ find and load modules.

(:attr:`__name__`)

The module's fully qualified name.
The module's:term:`fully qualified name`.
The :term:`finder` should always set this attribute to a non-empty string.

.. attribute:: loader
Expand DownExpand Up@@ -1230,8 +1230,8 @@ find and load modules.

(:attr:`__package__`)

(Read-only) The fully qualified name of the package the module is in (or the
empty string for a top-level module).
(Read-only) The:term:`fully qualified name` of the package the module is in
(or theempty string for a top-level module).
If the module is a package then this is the same as :attr:`name`.

.. attribute:: has_location
Expand Down
2 changes: 1 addition & 1 deletionDoc/library/inspect.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,7 +182,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
| | co_name | name with which this code |
| | | object was defined |
+-----------+-------------------+---------------------------+
| | co_qualname |fullyqualified name with |
| | co_qualname | qualified name with |
| | | which this code object |
| | | was defined |
+-----------+-------------------+---------------------------+
Expand Down
2 changes: 1 addition & 1 deletionDoc/library/logging.config.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -286,7 +286,7 @@ otherwise, the context is used to determine what to instantiate.

The configuring dict is searched for the following keys:

* ``class`` (mandatory). This is the fully qualified name of the
* ``class`` (mandatory). This is the:term:`fully qualified name` of the
handler class.

* ``level`` (optional). The level of the handler.
Expand Down
2 changes: 1 addition & 1 deletionDoc/library/pickle.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -525,7 +525,7 @@ the function's code, nor any of its function attributes are pickled. Thus the
defining module must be importable in the unpickling environment, and the module
must contain the named object, otherwise an exception will be raised. [#]_

Similarly, classes are pickled by fully qualified name, so the same restrictions in
Similarly, classes are pickled by:term:`fully qualified name`, so the same restrictions in
the unpickling environment apply. Note that none of the class's code or data is
pickled, so in the following example the class attribute ``attr`` is not
restored in the unpickling environment::
Expand Down
9 changes: 9 additions & 0 deletionsDoc/library/stdtypes.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5496,6 +5496,15 @@ types, where they are relevant. Some of these are not reported by the
.. versionadded:: 3.3


.. attribute:: class.__fully_qualified_name__

The :term:`fully qualified name` of the class instance:
``f"{class.__module__}.{class.__qualname__}"``, or ``class.__qualname__`` if
``class.__module__`` is not a string or is equal to ``"builtins"``.

.. versionadded:: 3.13


.. attribute:: definition.__type_params__

The :ref:`type parameters <type-params>` of generic classes, functions,
Expand Down
4 changes: 2 additions & 2 deletionsDoc/library/unittest.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -234,8 +234,8 @@ Command-line options
test name using :meth:`fnmatch.fnmatchcase`; otherwise simple case-sensitive
substring matching is used.

Patterns are matched against the fully qualified test method name as
imported by the test loader.
Patterns are matched against the:term:`fully qualified test method name
<fully qualified name>` asimported by the test loader.

For example, ``-k foo`` matches ``foo_tests.SomeTest.test_something``,
``bar_tests.SomeTest.test_foo``, but not ``bar_tests.FooTest.test_something``.
Expand Down
3 changes: 2 additions & 1 deletionDoc/library/warnings.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -163,7 +163,8 @@ the disposition of the match. Each entry is a tuple of the form (*action*,
category must be a subclass in order to match.

* *module* is a string containing a regular expression that the start of the
fully qualified module name must match, case-sensitively. In :option:`-W` and
:term:`fully qualified module name <fully qualified name>` must match,
case-sensitively. In :option:`-W` and
:envvar:`PYTHONWARNINGS`, *module* is a literal string that the
fully qualified module name must be equal to (case-sensitively), ignoring any
whitespace at the start or end of *module*.
Expand Down
2 changes: 1 addition & 1 deletionDoc/reference/datamodel.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1076,7 +1076,7 @@ indirectly) to mutable objects.
single: co_qualname (code object attribute)

Special read-only attributes: :attr:`co_name` gives the function name;
:attr:`co_qualname` gives thefullyqualified function name;
:attr:`co_qualname` gives the qualified function name;
:attr:`co_argcount` is the total number of positional arguments
(including positional-only arguments and arguments with default values);
:attr:`co_posonlyargcount` is the number of positional-only arguments
Expand Down
10 changes: 5 additions & 5 deletionsDoc/reference/import.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -157,8 +157,8 @@ See also :pep:`420` for the namespace package specification.
Searching
=========

To begin the search, Python needs the :term:`fully qualified<qualifiedname>`
nameof the module (or package, but for the purposes of this discussion, the
To begin the search, Python needs the :term:`fully qualified name`
of the module (or package, but for the purposes of this discussion, the
difference is immaterial) being imported. This name may come from various
arguments to the :keyword:`import` statement, or from the parameters to the
:func:`importlib.import_module` or :func:`__import__` functions.
Expand DownExpand Up@@ -547,7 +547,7 @@ listed below.

.. attribute:: __name__

The ``__name__`` attribute must be set to the fully qualified name of
The ``__name__`` attribute must be set to the:term:`fully qualified name` of
the module. This name is used to uniquely identify the module in
the import system.

Expand DownExpand Up@@ -885,7 +885,7 @@ contribute portions to namespace packages, path entry finders must implement
the :meth:`~importlib.abc.PathEntryFinder.find_spec` method.

:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two arguments: the
fully qualified name of the module being imported, and the (optional) target
:term:`fully qualified name` of the module being imported, and the (optional) target
module. ``find_spec()`` returns a fully populated spec for the module.
This spec will always have "loader" set (with one exception).

Expand All@@ -905,7 +905,7 @@ a list containing the portion.
implemented on the path entry finder, the legacy methods are ignored.

:meth:`!find_loader` takes one argument, the
fully qualified name of the module being imported. ``find_loader()``
:term:`fully qualified name` of the module being imported. ``find_loader()``
returns a 2-tuple where the first item is the loader and the second item
is a namespace :term:`portion`.

Expand Down
4 changes: 2 additions & 2 deletionsDoc/using/cmdline.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -464,8 +464,8 @@ Miscellaneous options
whether the actual warning category of the message is a subclass of the
specified warning category.

The *module* field matches the(fully qualified) module name; this match is
case-sensitive.
The *module* field matches the:term:`fully qualified module name <fully
qualified name>`; this match iscase-sensitive.

The *lineno* field matches the line number, where zero matches all line
numbers and is thus equivalent to an omitted line number.
Expand Down
10 changes: 10 additions & 0 deletionsDoc/whatsnew/3.13.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -125,6 +125,11 @@ Other Language Changes
equivalent of the :option:`-X frozen_modules <-X>` command-line option.
(Contributed by Yilei Yang in :gh:`111374`.)

* Add the :attr:`__fully_qualified_name__ <class.__fully_qualified_name__>`
read-only attribute to types: the :term:`fully qualified name` of the type.
(Contributed by Victor Stinner in :gh:`111696`.)


New Modules
===========

Expand DownExpand Up@@ -1181,6 +1186,11 @@ New Features
:exc:`KeyError` if the key missing.
(Contributed by Stefan Behnel and Victor Stinner in :gh:`111262`.)

* Add :c:func:`PyType_GetFullyQualifiedName` function: get the type's
:term:`fully qualified name`. It is equivalent to getting the type's
:attr:`__fully_qualified_name__ <class.__fully_qualified_name__>` attribute.
(Contributed by Victor Stinner in :gh:`111696`.)


Porting to Python 3.13
----------------------
Expand Down
1 change: 1 addition & 0 deletionsInclude/cpython/object.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -271,6 +271,7 @@ PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *);
PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
PyAPI_FUNC(PyObject *) PyType_GetFullyQualifiedName(PyTypeObject *);

PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
PyAPI_FUNC(void) _Py_BreakPoint(void);
Expand Down
4 changes: 1 addition & 3 deletionsLib/_collections_abc.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -528,9 +528,7 @@ def _type_repr(obj):
(Keep this roughly in sync with the typing version.)
"""
if isinstance(obj, type):
if obj.__module__ == 'builtins':
return obj.__qualname__
return f'{obj.__module__}.{obj.__qualname__}'
return obj.__fully_qualified_name__
if obj is Ellipsis:
return '...'
if isinstance(obj, FunctionType):
Expand Down
2 changes: 1 addition & 1 deletionLib/_py_abc.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@ def register(cls, subclass):

def _dump_registry(cls, file=None):
"""Debug helper to print the ABC registry."""
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
print(f"Class: {cls.__fully_qualified_name__}", file=file)
print(f"Inv. counter: {get_cache_token()}", file=file)
for name in cls.__dict__:
if name.startswith("_abc_"):
Expand Down
2 changes: 1 addition & 1 deletionLib/abc.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -124,7 +124,7 @@ def __subclasscheck__(cls, subclass):

def _dump_registry(cls, file=None):
"""Debug helper to print the ABC registry."""
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
print(f"Class: {cls.__fully_qualified_name__}", file=file)
print(f"Inv. counter: {get_cache_token()}", file=file)
(_abc_registry, _abc_cache, _abc_negative_cache,
_abc_negative_cache_version) = _get_dump(cls)
Expand Down
4 changes: 2 additions & 2 deletionsLib/codecs.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -107,8 +107,8 @@ def __new__(cls, encode, decode, streamreader=None, streamwriter=None,
return self

def __repr__(self):
return "<%s.%s object for encoding %s at %#x>" % \
(self.__class__.__module__, self.__class__.__qualname__,
return "<%s object for encoding %s at %#x>" % \
(self.__class__.__fully_qualified_name__,
self.name, id(self))

def __getnewargs__(self):
Expand Down
4 changes: 2 additions & 2 deletionsLib/contextlib.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -525,7 +525,7 @@ def enter_context(self, cm):
_enter = cls.__enter__
_exit = cls.__exit__
except AttributeError:
raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
raise TypeError(f"'{cls.__fully_qualified_name__}' object does "
f"not support the context manager protocol") from None
result = _enter(cm)
self._push_cm_exit(cm, _exit)
Expand DownExpand Up@@ -662,7 +662,7 @@ async def enter_async_context(self, cm):
_enter = cls.__aenter__
_exit = cls.__aexit__
except AttributeError:
raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
raise TypeError(f"'{cls.__fully_qualified_name__}' object does "
f"not support the asynchronous context manager protocol"
) from None
result = await _enter(cm)
Expand Down
2 changes: 1 addition & 1 deletionLib/doctest.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1401,7 +1401,7 @@ def __run(self, test, compileflags, out):
# They start with `SyntaxError:` (or any other class name)
exception_line_prefixes = (
f"{exception[0].__qualname__}:",
f"{exception[0].__module__}.{exception[0].__qualname__}:",
f"{exception[0].__fully_qualified_name__}:",
)
exc_msg_index = next(
index
Expand Down
4 changes: 2 additions & 2 deletionsLib/inspect.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1501,9 +1501,9 @@ def repl(match):
if isinstance(annotation, types.GenericAlias):
return str(annotation)
if isinstance(annotation, type):
if annotation.__module__in ('builtins',base_module):
if annotation.__module__==base_module:
return annotation.__qualname__
return annotation.__module__+'.'+annotation.__qualname__
return annotation.__fully_qualified_name__
return repr(annotation)

def formatannotationrelativeto(object):
Expand Down
2 changes: 1 addition & 1 deletionLib/multiprocessing/pool.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -272,7 +272,7 @@ def __del__(self, _warn=warnings.warn, RUN=RUN):

def __repr__(self):
cls = self.__class__
return (f'<{cls.__module__}.{cls.__qualname__} '
return (f'<{cls.__fully_qualified_name__} '
f'state={self._state} '
f'pool_size={len(self._pool)}>')

Expand Down
2 changes: 1 addition & 1 deletionLib/pdb.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1726,7 +1726,7 @@ def do_whatis(self, arg):
return
# Is it a class?
if value.__class__ is type:
self.message('Class%s.%s' % (value.__module__, value.__qualname__))
self.message(f'Class{value.__fully_qualified_name__}')
return
# None of the above...
self.message(type(value))
Expand Down
2 changes: 1 addition & 1 deletionLib/test/support/asyncore.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -256,7 +256,7 @@ def __init__(self, sock=None, map=None):
self.socket = None

def __repr__(self):
status = [self.__class__.__module__+"."+self.__class__.__qualname__]
status = [self.__class__.__fully_qualified_name__]
if self.accepting and self.addr:
status.append('listening')
elif self.connected:
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp