[Python-Dev] Inheritance vs composition in backcompat (PEP521)

Koos Zevenhoven k7hoven at gmail.com
Wed Oct 4 08:45:15 EDT 2017


On Wed, Oct 4, 2017 at 3:33 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> On 4 October 2017 at 20:22, Koos Zevenhoven <k7hoven at gmail.com> wrote:
> > On Wed, Oct 4, 2017 at 8:07 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> >>
> >> On 3 October 2017 at 03:13, Koos Zevenhoven <k7hoven at gmail.com> wrote:
> >> > Well, it's not completely unrelated to that. The problem I'm talking
> >> > about
> >> > is perhaps most easily seen from a simple context manager wrapper that
> >> > uses
> >> > composition instead of inheritance:
> >> >
> >> > class Wrapper:
> >> >     def __init__(self):
> >> >         self._wrapped = SomeContextManager()
> >> >
> >> >     def __enter__(self):
> >> >         print("Entering context")
> >> >         return self._wrapped.__enter__()
> >> >
> >> >     def __exit__(self):
> >> >         self._wrapped.__exit__()
> >> >         print("Exited context")
> >> >
> >> >
> >> > Now, if the wrapped contextmanager becomes a PEP 521 one with
> >> > __suspend__
> >> > and __resume__, the Wrapper class is broken, because it does not
> respect
> >> > __suspend__ and __resume__. So actually this is a backwards
> compatiblity
> >> > issue.
> >>
> >> This is a known problem, and one of the main reasons that having a
> >> truly transparent object proxy like
> >> https://wrapt.readthedocs.io/en/latest/wrappers.html#object-proxy as
> >> part of the standard library would be highly desirable.
> >>
> >
> > This is barely related to the problem I describe. The wrapper is not
> > supposed to pretend to *be* the underlying object. It's just supposed to
> > extend its functionality.
>
> If a wrapper *isn't* trying to act as a transparent object proxy, and
> is instead adapting it to a particular protocol, then yes, you'll need
> to update the wrapper when the protocol is extended.
>
>
​Yes, but it still means that the change in the dependency (in this case a
standard Python protocol) breaks the wrapper code.​

Remember that the wrappeR class and the wrappeD class can be implemented in
different libraries.



> That's not a backwards compatibility problem, because the only way to
> encounter it is to update your code to rely on the new extended
> protocol - your *existing* code will continue to work fine, since
> that, by definition, can't be relying on the new protocol extension.
>
>
​No, not all code is "your" code. Clearly this is not a well-known problem.
This is a backwards-compatibility problem for the author of the wrappeR,
not for the author of the wrappeD object.

––Koos
​

-- 
+ Koos Zevenhoven + http://twitter.com/k7hoven +
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20171004/9079644a/attachment.html>


More information about the Python-Dev mailing list