
Security News
npm Adopts OIDC for Trusted Publishing in CI/CD Workflows
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.
OOP Extensions is a set of utilities for object oriented programming not found on Python's standard library.
.. image:: https://img.shields.io/pypi/v/oop-ext.svg :target: https://pypi.python.org/pypi/oop-ext
.. image:: https://img.shields.io/pypi/pyversions/oop-ext.svg :target: https://pypi.org/project/oop-ext
.. image:: https://github.com/ESSS/oop-ext/workflows/build/badge.svg :target: https://github.com/ESSS/oop-ext/actions
.. image:: https://codecov.io/gh/ESSS/oop-ext/branch/master/graph/badge.svg :target: https://codecov.io/gh/ESSS/oop-ext
.. image:: https://img.shields.io/readthedocs/oop-extensions.svg :target: https://oop-extensions.readthedocs.io/en/latest/
.. image:: https://results.pre-commit.ci/badge/github/ESSS/oop-ext/master.svg :target: https://results.pre-commit.ci/latest/github/ESSS/oop-ext/master
.. image:: https://sonarcloud.io/api/project_badges/measure?project=ESSS_oop-ext&metric=alert_status :target: https://sonarcloud.io/project/overview?id=ESSS_oop-ext
OOP Extensions is a set of utilities for object oriented programming which is missing on Python core libraries.
oop_ext
brings a set of object oriented utilities, it supports the concept of interfaces,
abstract/overridable methods and more. oop_ext
carefully checks that implementations
have the same method signatures as the interface it implements and raises exceptions otherwise.
Here's a simple example showing some nice features:
.. code-block:: python
from oop_ext.interface import Interface, ImplementsInterface
class IDisposable(Interface):
def dispose(self):
"""
Clears this object
"""
def is_disposed(self) -> bool:
"""
Returns True if the object has been cleared
"""
@ImplementsInterface(IDisposable)
class MyObject(Disposable):
def __init__(self):
super().__init__()
self._data = [0] * 100
self._is_disposed = False
def is_disposed(self) -> bool:
return self._is_disposed
def dispose(self):
self._is_disposed = True
self._data = []
If any of the two methods in MyObject
are not implemented or have differ signatures than
the ones declared in IDisposable
, the ImplementsInterface
decorator will raise an
error during import.
Arbitrary objects can be verified if they implement a certain interface by using IsImplementation
:
.. code-block:: python
from oop_ext.interface import IsImplementation
my_object = MyObject()
if IsImplementation(my_object, IDisposable):
# my_object is guaranteed to implement IDisposable completely
my_object.dispose()
Alternatively you can assert that an object implements the desired interface with AssertImplements
:
.. code-block:: python
from oop_ext.interface import AssertImplements
my_object = MyObject()
AssertImplements(my_object, IDisposable)
my_object.dispose()
As of 1.1.0
, oop-ext
includes inline type annotations and exposes them to user programs.
If you are running a type checker such as mypy on your tests, you may start noticing type errors indicating incorrect usage. If you run into an error that you believe to be incorrect, please let us know in an issue.
The types were developed against mypy
version 0.800.
See the docs <https://oop-extensions.readthedocs.io/en/latest/interfaces.html#static-type-checking>
__
for more information.
For guidance on setting up a development environment and how to make a
contribution to oop_ext, see the contributing guidelines
_.
.. _contributing guidelines: https://github.com/ESSS/oop-ext/blob/master/CONTRIBUTING.rst
A reminder for the maintainers on how to make a new release.
Note that the VERSION should follow the semantic versioning as X.Y.Z
(e.g. v1.0.5
).
Create a release-VERSION
branch from upstream/master
.
Update CHANGELOG.rst
.
Push the branch to upstream
.
Once all tests pass, start the deploy
workflow manually or via::
gh workflow run deploy.yml --repo ESSS/oop-ext --ref release-VERSION -f version=VERSION
Merge the PR.
Release: 2025-08-06
Fix type annotations:
oop_ext.foundation.weak_ref.IsWeakProxy
.oop_ext.foundation.weak_ref.IsWeakRef
.oop_ext.foundation.weak_ref.GetWeakProxy
.Release: 2025-08-05
Broken Release
This version contains the incorrect patch -- nothing serious, just the master
version instead of the expected patch.
Release: 2025-08-01
Broken Release
This version contains the incorrect patch -- nothing serious, just the master
version instead of the expected patch.
Not released due to a problem during deploy.
Release: 2024-10-24
PriorityCallback
now has type checking support, similar to Callback
, with type checked variants: PriorityCallback0
, PriorityCallback1
, etc (#128
_).UnregisterContext
is now public, meant to be used in type annotations... _#128: https://github.com/ESSS/oop-ext/pull/128
#48: New type-checker friendly proxy = GetProxy(I, obj)
function as an alternative to proxy = I(obj)
. The
latter is not accepted by type checkers in general because interfaces are protocols, which can't be instantiated.
Also fixed a type-checking error with AsssertImplements
::
Only concrete class can be given where "Type[Interface]" is expected
This happens due to python/mypy#5374 <https://github.com/python/mypy/issues/5374>
__.
#47: Interfaces no longer check type annotations at all.
It was supported initially, but in practice this feature has shown up to be an impediment to adopting type annotations incrementally, as it discourages adding type annotations to improve existing interfaces, or annotating existing implementations without having to update the interface (and all other implementations by consequence).
It was decided to let the static type checker correctly deal with matching type annotations, as
it can do so more accurately than oop-ext
did before.
#43: Fix support for type annotated Attribute
and ReadOnlyAttribute
:
.. code-block:: python
class IFoo(Interface):
value: int = Attribute(int)
1.1.0
where installing a callback using
callback.After
or callback.Before
would make a method no longer compliant with
the signature required by its interface.#38: Reintroduce extra_args
argument to Callback._GetKey
, so subclasses can make use
of it.
#36: Fix regression introduced in 1.1.0
where Abstract
and Implements
decorators
could no longer be used in interfaces implementations.
#25: oop-ext
now includes inline type annotations and exposes them to user programs.
If you are running a type checker such as mypy on your tests, you may start noticing type errors indicating incorrect usage. If you run into an error that you believe to be incorrect, please let us know in an issue.
The types were developed against mypy
version 0.800.
#26: New type-checked Callback
variants, Callback0
, Callback1
, Callback2
, etc, providing
type checking for all operations(calling, Register
, etc) at nearly zero runtime cost.
Example:
.. code-block:: python
from oop_ext.foundation.callback import Callback2
def changed(x: int, v: float) -> None: ...
on_changed = Callback2[int, float]()
on_changed(10, 5.25)
Fixed Callbacks.Before
and Callbacks.After
signatures: previously their signature conveyed
that they supported multiple callbacks, but it was a mistake which would break callers because
every parameter after the 2nd would be considered the sender_as_parameter
parameter, which
was forwarded to After
and Before
functions of the _shortcuts.py
module.
Callbacks
can be used as context manager, which provides a Register(callback, function)
,
which automatically unregisters all functions when the context manager ends.
Callback.Register(function)
now returns an object with a Unregister()
method, which
can be used to undo the register call.
requires_declaration
to True
and fix an error (#22) where the cache wasn't properly cleared.classmethods
weren't considered a valid method during internal checks.requires_declaration
so users can decide whether or not @ImplementsInterface
declarations are necessary.@ImplementsInterface
: the check is done implicitly (and cached) by AssertImplements
and equivalent functions.Interface and implementation methods can no longer contain mutable defaults, as this is considered a bad practice in general.
Null
instances are now hashable.
Fix mismatching signatures when creating "interface stubs" for instances:
.. code-block:: python
foo = IFoo(Foo())
FunctionNotRegisteredError
exception, which has not been in use for a few years.FAQs
OOP Extensions is a set of utilities for object oriented programming not found on Python's standard library.
We found that oop-ext demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
npm now supports Trusted Publishing with OIDC, enabling secure package publishing directly from CI/CD workflows without relying on long-lived tokens.
Research
/Security News
A RubyGems malware campaign used 60 malicious packages posing as automation tools to steal credentials from social media and marketing tool users.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.