Skip to main content

A decorator to automatically detect mismatch when overriding a method.

Project description

https://img.shields.io/pypi/v/overrides.svg http://pepy.tech/badge/overrides

A decorator @override that verifies that a method that should override an inherited method actually does it.

Copies the docstring of the inherited method to the overridden method.

Since signature validation and docstring inheritance are performed on class creation and not on class instantiation, this library significantly improves the safety and experience of creating class hierarchies in Python without significantly impacting performance. See https://stackoverflow.com/q/1167617 for the initial inspiration for this library.

Motivation

Python has no standard mechanism by which to guarantee that (1) a method that previously overrode an inherited method continues to do so, and (2) a method that previously did not override an inherited will not override now. This opens the door for subtle problems as class hierarchies evolve over time. For example,

  1. A method that is added to a superclass is shadowed by an existing method with the same name in a subclass.

  2. A method of a superclass that is overridden by a subclass is renamed in the superclass but not in the subclass.

  3. A method of a superclass that is overridden by a subclass is removed in the superclass but not in the subclass.

  4. A method of a superclass that is overridden by a subclass but the signature of the overridden method is incompatible with that of the inherited one.

These can be only checked by explicitly marking method override in the code.

Python also has no standard mechanism by which to inherit docstrings in overridden methods. Because most standard linters (e.g., flake8) have rules that require all public methods to have a docstring, this inevitably leads to a proliferation of See parent class for usage docstrings on overridden methods, or, worse, to a disabling of these rules altogether. In addition, mediocre or missing docstrings degrade the quality of tooltips and completions that can be provided by an editor.

Installation

Compatible with Python 3.6+.

$ pip install overrides

Usage

Use @override to indicate that a subclass method should override a superclass method.

from overrides import override

class SuperClass:

    def foo(self):
        """This docstring will be inherited by any method that overrides this!"""
        return 1

    def bar(self, x) -> str:
        return x

class SubClass(SuperClass):

    @override
    def foo(self):
        return 2

    @override
    def bar(self, y) -> int: # Raises, because the signature is not compatible.
        return y

    @override
    def zoo(self): # Raises, because does not exist in the super class.
        return "foobarzoo"

Use EnforceOverrides to require subclass methods that shadow superclass methods to be decorated with @override.

from overrides import EnforceOverrides

class SuperClass(EnforceOverrides):

    def foo(self):
        return 1

class SubClass(SuperClass):

    def foo(self): # Raises, because @override is missing.
        return 2

Use @final to indicate that a superclass method cannot be overriden. With Python 3.11 and above @final is directly typing.final.

from overrides import EnforceOverrides, final, override

class SuperClass(EnforceOverrides):

    @final
    def foo(self):
        return 1

class SubClass(SuperClass):

    @override
    def foo(self): # Raises, because overriding a final method is forbidden.
        return 2

Note that @classmethod and @staticmethod must be declared before @override.

from overrides import override

class SuperClass:

    @staticmethod
    def foo(x):
        return 1

class SubClass(SuperClass):

    @staticmethod
    @override
    def foo(x):
        return 2

Flags of control

# To prevent all signature checks do:
@override(check_signature=False)
def some_method(self, now_this_can_be_funny_and_wrong: str, what_ever: int) -> "Dictirux":
    pass

# To do the check only at runtime and solve some forward reference problems
@override(check_at_runtime=True)
def some_other_method(self, ..) -> "SomethingDefinedLater":
    pass

a.some_other_method() # Kaboom if not SomethingDefinedLater

Contributors

This project exists only through the work of all the people who contribute.

mkorpela, drorasaf, ngoodman90, TylerYep, leeopop, donpatrice, jayvdb, joelgrus, lisyarus, soulmerge, rkr-at-dbx, ashwin153, brentyi, jobh, tjsmart, bersbersbers, LysanderGG, mgorny.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

overrides-7.6.0.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

overrides-7.6.0-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file overrides-7.6.0.tar.gz.

File metadata

  • Download URL: overrides-7.6.0.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.7

File hashes

Hashes for overrides-7.6.0.tar.gz
Algorithm Hash digest
SHA256 01e15bbbf15b766f0675c275baa1878bd1c7dc9bc7b9ee13e677cdba93dc1bd9
MD5 9da28f0ca3b2ef156c33f78dbc0edf52
BLAKE2b-256 85dcaac79b2b5dd94c4e0542615bc2e6211fafc1173c7c3be9395400f5a2b49c

See more details on using hashes here.

Provenance

File details

Details for the file overrides-7.6.0-py3-none-any.whl.

File metadata

  • Download URL: overrides-7.6.0-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.7

File hashes

Hashes for overrides-7.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c36e6635519ea9c5b043b65c36d4b886aee8bd45b7d4681d2a6df0898df4b654
MD5 882cdc91e758ec78133844d04846e5d4
BLAKE2b-256 adc3f5f590a982ca2cbe29b570de61d6f387a41e7020a8340309901d769066e0

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page