Shared ABCs for the IO implementation
![](https://secure.gravatar.com/avatar/db5f70d2f2520ef725839f046bdc32fb.jpg?s=120&d=mm&r=g)
Hello, I would like to know if both IO implementations (the C one and the Python one) should share their ABCs (IOBase, RawIOBase, etc.). It looks preferable to me but since I'm not very familiar with ABCs I'd like to be sure it's the good choice. (of course, the *implementations* won't be shared at all. Just the virtual inheritance information) Regards Antoine.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Feb 25, 2009 at 7:35 AM, Antoine Pitrou <solipsis@pitrou.net> wrote:
I would like to know if both IO implementations (the C one and the Python one) should share their ABCs (IOBase, RawIOBase, etc.). It looks preferable to me but since I'm not very familiar with ABCs I'd like to be sure it's the good choice.
(of course, the *implementations* won't be shared at all. Just the virtual inheritance information)
Without a shared ABC you'd defeat the whole point of having ABCs. However, importing ABCs (which are defined in Python) from C code (especially such fundamental C code as the I/O library) is really subtle and best avoided. In io.py I solved this by having a Python class inherit from both the ABC (RawIOBase) and the implementation (_fileio._FileIO). Another way to solve it would be to use the registration API for ABCs, as found in _abcoll.py (e.g. MutableSequence.register(list)). -- --Guido van Rossum (home page: http://www.python.org/~guido/)
![](https://secure.gravatar.com/avatar/db5f70d2f2520ef725839f046bdc32fb.jpg?s=120&d=mm&r=g)
Guido van Rossum <guido <at> python.org> writes:
Without a shared ABC you'd defeat the whole point of having ABCs.
However, importing ABCs (which are defined in Python) from C code (especially such fundamental C code as the I/O library) is really subtle and best avoided.
In io.py I solved this by having a Python class inherit from both the ABC (RawIOBase) and the implementation (_fileio._FileIO).
My plan (let's call it "the Operation") is to define the ABCs in Python by deriving the C concrete base classes (that is, have io.XXXIOBase derive _io.XXXIOBase). This way, by inheriting io.XXXIOBase, user code will benefit both from ABC inheritance and fast C concrete implementations. In turn, the concrete implementations in _pyio (the Python version) would register() those ABCs. The reason I think the Python implementations shouldn't be involved in the default inheritance tree is that we don't want user classes to inherit a __del__ method. All this is assuming I haven't made any logic error. Otherwise, I'll have to launch "the new Operation". Regards Antoine.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Feb 25, 2009 at 1:03 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Guido van Rossum <guido <at> python.org> writes:
Without a shared ABC you'd defeat the whole point of having ABCs.
However, importing ABCs (which are defined in Python) from C code (especially such fundamental C code as the I/O library) is really subtle and best avoided.
In io.py I solved this by having a Python class inherit from both the ABC (RawIOBase) and the implementation (_fileio._FileIO).
My plan (let's call it "the Operation") is to define the ABCs in Python by deriving the C concrete base classes (that is, have io.XXXIOBase derive _io.XXXIOBase). This way, by inheriting io.XXXIOBase, user code will benefit both from ABC inheritance and fast C concrete implementations.
However that's hardly an ABC. You need to provide a path for someone who wants to implement the ABC without inheriting your implementation.
In turn, the concrete implementations in _pyio (the Python version) would register() those ABCs. The reason I think the Python implementations shouldn't be involved in the default inheritance tree is that we don't want user classes to inherit a __del__ method.
All this is assuming I haven't made any logic error. Otherwise, I'll have to launch "the new Operation".
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
Guido van Rossum wrote:
On Wed, Feb 25, 2009 at 1:03 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Guido van Rossum <guido <at> python.org> writes:
Without a shared ABC you'd defeat the whole point of having ABCs.
However, importing ABCs (which are defined in Python) from C code (especially such fundamental C code as the I/O library) is really subtle and best avoided.
In io.py I solved this by having a Python class inherit from both the ABC (RawIOBase) and the implementation (_fileio._FileIO). My plan (let's call it "the Operation") is to define the ABCs in Python by deriving the C concrete base classes (that is, have io.XXXIOBase derive _io.XXXIOBase). This way, by inheriting io.XXXIOBase, user code will benefit both from ABC inheritance and fast C concrete implementations.
However that's hardly an ABC. You need to provide a path for someone who wants to implement the ABC without inheriting your implementation.
Don't they already have that through register()? However, the other problem with setting up the inheritance as Antoine suggests is that it makes it impossible to import a pure Python version of the module. Once the Python code inherits from something provided only by the C module then the C version isn't optional any more. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Feb 25, 2009 at 1:31 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Guido van Rossum wrote:
On Wed, Feb 25, 2009 at 1:03 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Guido van Rossum <guido <at> python.org> writes:
Without a shared ABC you'd defeat the whole point of having ABCs.
However, importing ABCs (which are defined in Python) from C code (especially such fundamental C code as the I/O library) is really subtle and best avoided.
In io.py I solved this by having a Python class inherit from both the ABC (RawIOBase) and the implementation (_fileio._FileIO). My plan (let's call it "the Operation") is to define the ABCs in Python by deriving the C concrete base classes (that is, have io.XXXIOBase derive _io.XXXIOBase). This way, by inheriting io.XXXIOBase, user code will benefit both from ABC inheritance and fast C concrete implementations.
However that's hardly an ABC. You need to provide a path for someone who wants to implement the ABC without inheriting your implementation.
Don't they already have that through register()?
I'd like the ABCs to remain just as abstract or concrete as they are in 3.0. As long as the C version implements the same methods with the same semantics as the 3.0 io.py I don't care.
However, the other problem with setting up the inheritance as Antoine suggests is that it makes it impossible to import a pure Python version of the module. Once the Python code inherits from something provided only by the C module then the C version isn't optional any more.
I think this should be taken care of by having separate _pyio.py and _cio.py modules which are unified by io.py, right? (Or whatever naming convention is agreed upon; I skipped that thread. :-) -- --Guido van Rossum (home page: http://www.python.org/~guido/)
![](https://secure.gravatar.com/avatar/db5f70d2f2520ef725839f046bdc32fb.jpg?s=120&d=mm&r=g)
Guido van Rossum <guido <at> python.org> writes:
However that's hardly an ABC. You need to provide a path for someone who wants to implement the ABC without inheriting your implementation.
I may missing something, but it's exactly the same as today's io.py: if you derive the ABC, you inherit the implementations at the same time. OTOH, as Nick says, one can just use register(). Regards Antoine.
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Feb 25, 2009 at 1:46 PM, Antoine Pitrou <solipsis@pitrou.net> wrote:
Guido van Rossum <guido <at> python.org> writes:
However that's hardly an ABC. You need to provide a path for someone who wants to implement the ABC without inheriting your implementation.
I may missing something, but it's exactly the same as today's io.py: if you derive the ABC, you inherit the implementations at the same time.
OTOH, as Nick says, one can just use register().
OK then. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (3)
-
Antoine Pitrou
-
Guido van Rossum
-
Nick Coghlan