Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/how-to/pyserial-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
12 changes: 11 additions & 1 deletion serialx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion serialx/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion serialx/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
36 changes: 35 additions & 1 deletion tests/test_pyserial_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading