Skip to content
Advertisement

How does pySerial implement the “with” statement without __enter__ and __exit__?

pySerial can be used with Python’s with statement like this:

with serial.Serial("/dev/ttyS1") as ser:
    ser.write("AAAA")
    ser.read(8)

I tried to see exactly what it is pySerial does to make this work, but I couldn’t find an __enter__ or __exit__ function anywhere! I ran grep -e '(__enter__)|(__exit__)' *.py from the pySerial directory, and grep didn’t find either function. How does pySerial do it?

Edit: I also tried the following to see what was called next:

import serial, pdb
with serial.Serial("/dev/ttyUSB0") as ser:
    pdb.set_trace()

This brought me directly to line 433 of serialposix.py, the close() function. Does the with statement also look for open() and close() functions?

Advertisement

Answer

Serial class doesn’t implement these methods, it inherits them from io.IOBase. The relevant part from /serial/serialposix.py:

try:
    import io
except ImportError:
    # classic version with our own file-like emulation
    class Serial(PosixSerial, FileLike):
        pass
else:
    # io library present
    class Serial(PosixSerial, io.RawIOBase):
        pass
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement