PEP 698: Fix typos and suggest edits (#2990)
- Some simple typo fixes. - Harmonizing the code formatting of some functions & packages - Some suggested punctuation changes - Change to the external link to `overrides` package to allow code formatting in the link - Converting uses of "get" to "set" when referring to adding `__override__` to decorated objects, for semantic consistency Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
This commit is contained in:
parent
673c0999c8
commit
42c33bb982
35
pep-0698.rst
35
pep-0698.rst
|
@ -91,14 +91,14 @@ introducing bugs:
|
||||||
|
|
||||||
This code will type check, but there are two potential sources of bugs:
|
This code will type check, but there are two potential sources of bugs:
|
||||||
|
|
||||||
- If we pass a ``Child`` instance to the parent_callsite function, it will
|
- If we pass a ``Child`` instance to the ``parent_callsite`` function, it will
|
||||||
invoke the implementation in ``Parent.new_foo``. rather than ``Child.foo``.
|
invoke the implementation in ``Parent.new_foo``. rather than ``Child.foo``.
|
||||||
This is probably a bug - we presumably would not have written ``Child.foo`` in
|
This is probably a bug - we presumably would not have written ``Child.foo`` in
|
||||||
the first place if we didn’t need custom behavior.
|
the first place if we didn’t need custom behavior.
|
||||||
- Our system was likely relying on ``Child.foo`` behaving in a similar way to
|
- Our system was likely relying on ``Child.foo`` behaving in a similar way to
|
||||||
``Parent.foo``. But unless we catch this early, we have now forked the
|
``Parent.foo``. But unless we catch this early, we have now forked the
|
||||||
methods, and future refactors it is likely no one will realize that major
|
methods, and in future refactors it is likely no one will realize that major
|
||||||
changes to the behavior of new_foo likely require updating ``Child.foo`` as
|
changes to the behavior of ``new_foo`` likely require updating ``Child.foo`` as
|
||||||
well, which could lead to major bugs later.
|
well, which could lead to major bugs later.
|
||||||
|
|
||||||
The incorrectly-refactored code is type-safe, but is probably not what we
|
The incorrectly-refactored code is type-safe, but is probably not what we
|
||||||
|
@ -148,7 +148,7 @@ Runtime Override Checks in Python
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Today, there is an `Overrides library <https://pypi.org/project/overrides/>`_
|
Today, there is an `Overrides library <https://pypi.org/project/overrides/>`_
|
||||||
that provides decorators ``@overrides`` (sic) and ``@final`` and will enforce
|
that provides decorators ``@overrides`` [sic] and ``@final`` and will enforce
|
||||||
them at runtime.
|
them at runtime.
|
||||||
|
|
||||||
:pep:`591` added a ``@final`` decorator with the same semantics as those in the
|
:pep:`591` added a ``@final`` decorator with the same semantics as those in the
|
||||||
|
@ -156,7 +156,7 @@ Overrides library. But the override component of the runtime library is not
|
||||||
supported statically at all, which has added some confusion around the
|
supported statically at all, which has added some confusion around the
|
||||||
mix/matched support.
|
mix/matched support.
|
||||||
|
|
||||||
Providing support for ``@override`` in static checks would add value because
|
Providing support for ``@override`` in static checks would add value because:
|
||||||
|
|
||||||
- Bugs can be caught earlier, often in-editor.
|
- Bugs can be caught earlier, often in-editor.
|
||||||
- Static checks come with no performance overhead, unlike runtime checks.
|
- Static checks come with no performance overhead, unlike runtime checks.
|
||||||
|
@ -309,7 +309,7 @@ because the input is a descriptor type with fixed slots) we will silently
|
||||||
return the argument as-is.
|
return the argument as-is.
|
||||||
|
|
||||||
This is exactly what the ``@typing.final`` decorator does, and the motivation
|
This is exactly what the ``@typing.final`` decorator does, and the motivation
|
||||||
is similar - it gives runtime libraries the ability to use ``@override``. As a
|
is similar: it gives runtime libraries the ability to use ``@override``. As a
|
||||||
concrete example, a runtime library could check ``__override__`` in order
|
concrete example, a runtime library could check ``__override__`` in order
|
||||||
to automatically populate the ``__doc__`` attribute of child class methods
|
to automatically populate the ``__doc__`` attribute of child class methods
|
||||||
using the parent method docstring.
|
using the parent method docstring.
|
||||||
|
@ -320,10 +320,10 @@ Limitations of setting ``__override__``
|
||||||
As described above, adding ``__override__`` may fail at runtime, in which
|
As described above, adding ``__override__`` may fail at runtime, in which
|
||||||
case we will simply return the argument as-is.
|
case we will simply return the argument as-is.
|
||||||
|
|
||||||
In addition, even in cases where it does work it may be difficult for users
|
In addition, even in cases where it does work, it may be difficult for users to
|
||||||
to correctly work with multiple decorators, because getting the ``__override__``
|
correctly work with multiple decorators, because successfully ensuring the
|
||||||
field to exist on the final output requires understanding the implementation
|
``__override__`` attribute is set on the final output requires understanding the
|
||||||
of each decorator:
|
implementation of each decorator:
|
||||||
|
|
||||||
- The ``@override`` decorator needs to execute *after* ordinary decorators
|
- The ``@override`` decorator needs to execute *after* ordinary decorators
|
||||||
like ``@functools.lru_cache`` that use wrapper functions, since we want to
|
like ``@functools.lru_cache`` that use wrapper functions, since we want to
|
||||||
|
@ -332,7 +332,7 @@ of each decorator:
|
||||||
- But ``@override`` needs to execute *before* many special descriptor-based
|
- But ``@override`` needs to execute *before* many special descriptor-based
|
||||||
decorators like ``@property``, ``@staticmethod``, and ``@classmethod``.
|
decorators like ``@property``, ``@staticmethod``, and ``@classmethod``.
|
||||||
- As discussed above, in some cases (for example a descriptor with fixed
|
- As discussed above, in some cases (for example a descriptor with fixed
|
||||||
slots or a descriptor that also wraps) it may be impossible to get the
|
slots or a descriptor that also wraps) it may be impossible to set the
|
||||||
``__override__`` attribute at all.
|
``__override__`` attribute at all.
|
||||||
|
|
||||||
As a result, runtime support for setting ``__override__`` is best effort
|
As a result, runtime support for setting ``__override__`` is best effort
|
||||||
|
@ -382,7 +382,7 @@ We rejected this for four reasons:
|
||||||
problem). We expect static enforcement to be simple and reliable.
|
problem). We expect static enforcement to be simple and reliable.
|
||||||
- The implementation approaches we know of are not simple. The decorator
|
- The implementation approaches we know of are not simple. The decorator
|
||||||
executes before the class is finished evaluating, so the options we know of
|
executes before the class is finished evaluating, so the options we know of
|
||||||
are either to inspect the bytecode of the caller (as ``@overrides.overrrides``
|
are either to inspect the bytecode of the caller (as ``@overrides.overrides``
|
||||||
does) or to use a metaclass-based approach. Neither approach seems ideal.
|
does) or to use a metaclass-based approach. Neither approach seems ideal.
|
||||||
|
|
||||||
|
|
||||||
|
@ -391,9 +391,9 @@ Mark a base class to force explicit overrides on subclasses
|
||||||
|
|
||||||
We considered including a class decorator ``@require_explicit_overrides``, which
|
We considered including a class decorator ``@require_explicit_overrides``, which
|
||||||
would have provided a way for base classes to declare that all subclasses must
|
would have provided a way for base classes to declare that all subclasses must
|
||||||
use the ``@override`` decorator on method overrides. The overrides library has a
|
use the ``@override`` decorator on method overrides. The
|
||||||
mixin class, ``EnforceExplicitOverrides``, which provides similar behavior in
|
`Overrides library <https://pypi.org/project/overrides/>`_ has a mixin class,
|
||||||
runtime checks.
|
``EnforceExplicitOverrides``, which provides similar behavior in runtime checks.
|
||||||
|
|
||||||
We decided against this because we expect owners of large codebases will benefit
|
We decided against this because we expect owners of large codebases will benefit
|
||||||
most from ``@override``, and for these use cases having a strict mode where
|
most from ``@override``, and for these use cases having a strict mode where
|
||||||
|
@ -447,8 +447,9 @@ We decided against it because:
|
||||||
be considerable benefits.
|
be considerable benefits.
|
||||||
- We believe that it would be rarely used and catch relatively few bugs.
|
- We believe that it would be rarely used and catch relatively few bugs.
|
||||||
|
|
||||||
- The author of the ``overrides`` package
|
- The author of the
|
||||||
`has noted <https://discuss.python.org/t/pep-698-a-typing-override-decorator/20839/4>`_
|
`Overrides package <https://pypi.org/project/overrides/>`_ has
|
||||||
|
`noted <https://discuss.python.org/t/pep-698-a-typing-override-decorator/20839/4>`__
|
||||||
that early versions of his library included this capability but it was
|
that early versions of his library included this capability but it was
|
||||||
rarely useful and seemed to have little benefit. After it was removed, the
|
rarely useful and seemed to have little benefit. After it was removed, the
|
||||||
ability was never requested by users.
|
ability was never requested by users.
|
||||||
|
|
Loading…
Reference in New Issue