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:
Brian Skinn 2023-03-11 10:17:51 -05:00 committed by GitHub
parent 673c0999c8
commit 42c33bb982
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 17 deletions

View File

@ -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 didnt need custom behavior. the first place if we didnt 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.