From 42c33bb982ee70bbc9f8c5f7b5697c76ebe780aa Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Sat, 11 Mar 2023 10:17:51 -0500 Subject: [PATCH] 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 --- pep-0698.rst | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/pep-0698.rst b/pep-0698.rst index 14c32336e..9363c4493 100644 --- a/pep-0698.rst +++ b/pep-0698.rst @@ -91,14 +91,14 @@ introducing 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``. This is probably a bug - we presumably would not have written ``Child.foo`` in the first place if we didn’t need custom behavior. - 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 - methods, and future refactors it is likely no one will realize that major - changes to the behavior of new_foo likely require updating ``Child.foo`` as + 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 well, which could lead to major bugs later. 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 `_ -that provides decorators ``@overrides`` (sic) and ``@final`` and will enforce +that provides decorators ``@overrides`` [sic] and ``@final`` and will enforce them at runtime. :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 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. - 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. 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 to automatically populate the ``__doc__`` attribute of child class methods using the parent method docstring. @@ -320,10 +320,10 @@ Limitations of setting ``__override__`` As described above, adding ``__override__`` may fail at runtime, in which case we will simply return the argument as-is. -In addition, even in cases where it does work it may be difficult for users -to correctly work with multiple decorators, because getting the ``__override__`` -field to exist on the final output requires understanding the implementation -of each decorator: +In addition, even in cases where it does work, it may be difficult for users to +correctly work with multiple decorators, because successfully ensuring the +``__override__`` attribute is set on the final output requires understanding the +implementation of each decorator: - The ``@override`` decorator needs to execute *after* ordinary decorators 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 decorators like ``@property``, ``@staticmethod``, and ``@classmethod``. - 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. 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. - The implementation approaches we know of are not simple. The decorator 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. @@ -391,9 +391,9 @@ Mark a base class to force explicit overrides on subclasses We considered including a class decorator ``@require_explicit_overrides``, which 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 -mixin class, ``EnforceExplicitOverrides``, which provides similar behavior in -runtime checks. +use the ``@override`` decorator on method overrides. The +`Overrides library `_ has a mixin class, +``EnforceExplicitOverrides``, which provides similar behavior in runtime checks. 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 @@ -447,8 +447,9 @@ We decided against it because: be considerable benefits. - We believe that it would be rarely used and catch relatively few bugs. - - The author of the ``overrides`` package - `has noted `_ + - The author of the + `Overrides package `_ has + `noted `__ 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 ability was never requested by users.