diff --git a/docs/how-to/pyserial-migration.md b/docs/how-to/pyserial-migration.md index f99ad81..9a92606 100644 --- a/docs/how-to/pyserial-migration.md +++ b/docs/how-to/pyserial-migration.md @@ -85,6 +85,26 @@ with serialx.serial_for_url("/dev/ttyUSB0", baudrate=115200) as serial: There is no equivalent for async code because the default `create_serial_connection` and `open_serial_connection` functions already transparently accept URIs. +## Constants +pyserial exposes parity, stop bit, and byte size settings as module-level constants (`serial.PARITY_NONE`, `serial.STOPBITS_ONE`, etc.). serialx replaces them with the `Parity` and `StopBits` enums. Properties like `serial.parity` and `serial.stopbits` now return enum members instead of raw strings or numbers. + +| Old Name | New Name | +| --- | --- | +| `PARITY_NONE` | `Parity.NONE` | +| `PARITY_EVEN` | `Parity.EVEN` | +| `PARITY_ODD` | `Parity.ODD` | +| `PARITY_MARK` | `Parity.MARK` | +| `PARITY_SPACE` | `Parity.SPACE` | +| `STOPBITS_ONE` | `StopBits.ONE` | +| `STOPBITS_ONE_POINT_FIVE` | `StopBits.ONE_POINT_FIVE` | +| `STOPBITS_TWO` | `StopBits.TWO` | +| `FIVEBITS` | `5` | +| `SIXBITS` | `6` | +| `SEVENBITS` | `7` | +| `EIGHTBITS` | `8` | + +Migrate to the enum members. `Parity` is a `str` enum and `StopBits` is a `float` enum, so any lingering comparisons against raw values (`parity == "N"`, `stopbits == 1`) still hold during the transition. These direct comparisons should be migrated to use the enum members instead of assuming their values. + ## Exceptions pyserial re-raises all errors as `serial.SerialException`, including OS-level failures and timeouts. serialx raises native exceptions directly so callers can handle them granularly: diff --git a/serialx/__init__.py b/serialx/__init__.py index 2cba6cc..8e482d0 100644 --- a/serialx/__init__.py +++ b/serialx/__init__.py @@ -25,12 +25,17 @@ from .compat import ( CR, EIGHTBITS, + FIVEBITS, LF, PARITY_EVEN, + PARITY_MARK, PARITY_NONE, PARITY_ODD, + PARITY_SPACE, SEVENBITS, + SIXBITS, STOPBITS_ONE, + STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO, SerialTimeoutException, ) @@ -59,12 +64,17 @@ "StopBits", # Compatibility with pyserial "SerialTimeoutException", - "EIGHTBITS", + "FIVEBITS", + "SIXBITS", "SEVENBITS", + "EIGHTBITS", "PARITY_NONE", "PARITY_EVEN", "PARITY_ODD", + "PARITY_MARK", + "PARITY_SPACE", "STOPBITS_ONE", + "STOPBITS_ONE_POINT_FIVE", "STOPBITS_TWO", "CR", "LF", diff --git a/serialx/common.py b/serialx/common.py index 02a11ed..273466e 100644 --- a/serialx/common.py +++ b/serialx/common.py @@ -176,7 +176,7 @@ class UnknownUriScheme(SerialException): """Raised when a URI scheme has no registered handler.""" -class StopBits(Enum): +class StopBits(float, Enum): """Stop bits configuration.""" ONE = 1 diff --git a/serialx/compat.py b/serialx/compat.py index 0e5537c..ada2869 100644 --- a/serialx/compat.py +++ b/serialx/compat.py @@ -4,14 +4,19 @@ SerialTimeoutException = TimeoutError -EIGHTBITS = 8 +FIVEBITS = 5 +SIXBITS = 6 SEVENBITS = 7 +EIGHTBITS = 8 PARITY_NONE = Parity.NONE PARITY_EVEN = Parity.EVEN PARITY_ODD = Parity.ODD +PARITY_MARK = Parity.MARK +PARITY_SPACE = Parity.SPACE STOPBITS_ONE = StopBits.ONE +STOPBITS_ONE_POINT_FIVE = StopBits.ONE_POINT_FIVE STOPBITS_TWO = StopBits.TWO CR = b"\r" diff --git a/tests/test_pyserial_compat.py b/tests/test_pyserial_compat.py index 3ff1711..ec823b7 100644 --- a/tests/test_pyserial_compat.py +++ b/tests/test_pyserial_compat.py @@ -11,7 +11,23 @@ allow_module_level=True, ) -from serialx import Parity, Serial, SerialPortInfo +from serialx import ( + EIGHTBITS, + FIVEBITS, + PARITY_EVEN, + PARITY_MARK, + PARITY_NONE, + PARITY_ODD, + PARITY_SPACE, + SEVENBITS, + SIXBITS, + STOPBITS_ONE, + STOPBITS_ONE_POINT_FIVE, + STOPBITS_TWO, + Parity, + Serial, + SerialPortInfo, +) from serialx.tools.list_ports import comports, grep from serialx.tools.list_ports_common import ListPortInfo from tests.common import SerialPair @@ -143,6 +159,24 @@ def test_compat_do_not_open(serial_pair: SerialPair) -> None: assert not s.is_open +def test_compat_constants() -> None: + """Test that pyserial module-level constants are re-exported with correct values.""" + assert FIVEBITS == 5 + assert SIXBITS == 6 + assert SEVENBITS == 7 + assert EIGHTBITS == 8 + + assert PARITY_NONE == "N" + assert PARITY_EVEN == "E" + assert PARITY_ODD == "O" + assert PARITY_MARK == "M" + assert PARITY_SPACE == "S" + + assert STOPBITS_ONE == 1 # type: ignore[comparison-overlap] + assert STOPBITS_ONE_POINT_FIVE == 1.5 + assert STOPBITS_TWO == 2 + + def test_compat_tools_module() -> None: """Test that serialx.tools.list_ports provides pyserial-compatible API.""" # comports is list_serial_ports