Package: oop-ext
What is OOP Extensions ?OOP Extensions is a set of utilities for object oriented programming which is missing on Python core libraries.Usageoop_extbrings a set of object oriented utilities, it supports the concept of interfaces,
abstract/overridable methods and more.oop_extcarefully 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:fromoop_ext.interfaceimportInterface,ImplementsInterfaceclassIDisposable(Interface):defdispose(self):"""
        Clears this object
        """defis_disposed(self)->bool:"""
        Returns True if the object has been cleared
        """@ImplementsInterface(IDisposable)classMyObject(Disposable):def__init__(self):super().__init__()self._data=[0]*100self._is_disposed=Falsedefis_disposed(self)->bool:returnself._is_disposeddefdispose(self):self._is_disposed=Trueself._data=[]If any of the two methods inMyObjectare not implemented or have differ signatures than
the ones declared inIDisposable, theImplementsInterfacedecorator will raise an
error during import.Arbitrary objects can be verified if they implement a certain interface by usingIsImplementation:fromoop_ext.interfaceimportIsImplementationmy_object=MyObject()ifIsImplementation(my_object,IDisposable):# my_object is guaranteed to implement IDisposable completelymy_object.dispose()Alternatively you can assert that an object implements the desired interface withAssertImplements:fromoop_ext.interfaceimportAssertImplementsmy_object=MyObject()AssertImplements(my_object,IDisposable)my_object.dispose()Type CheckingAs of1.1.0,oop-extincludes 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 againstmypyversion 0.800.Seethe docsfor more information.ContributingFor guidance on setting up a development environment and how to make a
contribution to oop_ext, see thecontributing guidelines.ReleaseA reminder for the maintainers on how to make a new release.Note that the VERSION should follow the semantic versioning as X.Y.Z
Ex.: v1.0.5Create arelease-VERSIONbranch fromupstream/master.UpdateCHANGELOG.rst.Push a branch with the changes.Once all builds pass, push aVERSIONtag toupstream.Merge the PR.2.1.0 (2021-03-19)#48: New type-checker friendlyproxy = GetProxy(I, obj)function as an alternative toproxy = 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 withAsssertImplements:Only concrete class can be given where "Type[Interface]" is expectedThis happens due topython/mypy#5374.2.0.0 (2021-03-10)#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 thanoop-extdid before.1.2.0 (2021-03-09)#43: Fix support for type annotatedAttributeandReadOnlyAttribute:classIFoo(Interface):value:int=Attribute(int)1.1.2 (2021-02-23)#41: Fix regression introduced in1.1.0where installing a callback usingcallback.Afterorcallback.Beforewould make a method no longer compliant with
the signature required by its interface.1.1.1 (2021-02-23)#38: Reintroduceextra_argsargument toCallback._GetKey, so subclasses can make use
of it.#36: Fix regression introduced in1.1.0whereAbstractandImplementsdecorators
could no longer be used in interfaces implementations.1.1.0 (2021-02-19)#25:oop-extnow 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 againstmypyversion 0.800.#26: New type-checkedCallbackvariants,Callback0,Callback1,Callback2, etc, providing
type checking for all operations(calling,Register, etc) at nearly zero runtime cost.Example:fromoop_ext.foundation.callbackimportCallback2defchanged(x:int,v:float)->None:...on_changed=Callback2[int,float]()on_changed(10,5.25)FixedCallbacks.BeforeandCallbacks.Aftersignatures: 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 thesender_as_parameterparameter, which
was forwarded toAfterandBeforefunctions of the_shortcuts.pymodule.1.0.0 (2020-10-01)Callbackscan be used as context manager, which provides aRegister(callback, function),
which automatically unregisters all functions when the context manager ends.Callback.Register(function)now returns an object with aUnregister()method, which
can be used to undo the register call.0.6.0 (2020-01-31)Change back the default value ofrequires_declarationtoTrueand fix an error (#22) where the cache wasn’t properly cleared.0.5.1 (2019-12-20)Fixes an issue (#20) where mockedclassmethodsweren’t considered a valid method during internal checks.0.5.0 (2019-12-12)Add optional argumentrequires_declarationso users can decide whether or not@ImplementsInterfacedeclarations are necessary.0.4.0 (2019-12-03)Implementations no longer need to explicitly declare that they declare an interface with@ImplementsInterface: the check is done implicitly (and cached) byAssertImplementsand equivalent functions.0.3.2 (2019-08-22)Interface and implementation methods can no longer contain mutable defaults, as this is considered
a bad practice in general.Nullinstances are now hashable.0.3.1 (2019-08-16)Fix mismatching signatures when creating “interface stubs” for instances:foo=IFoo(Foo())0.3.0 (2019-08-08)Interfaces now support keyword-only arguments.0.2.4 (2019-03-22)RemoveFunctionNotRegisteredErrorexception, which has not been in use for a few years.0.2.3 (2019-03-22)Fix issues of ignored exception on nested callback.0.2.1 (2019-03-14)Fix issues and remove obsolete code.0.1.8 (2019-03-12)First release on PyPI.