Skip to content

PyCyphal v2#379

Merged
pavel-kirienko merged 32 commits intomasterfrom
v2
Apr 11, 2026
Merged

PyCyphal v2#379
pavel-kirienko merged 32 commits intomasterfrom
v2

Conversation

@pavel-kirienko
Copy link
Copy Markdown
Member

@pavel-kirienko pavel-kirienko commented Apr 7, 2026

This is the new implementation that was first announced in #351 almost a year ago.

While Cyphal/CAN is wire-compatible between the two versions, the API is completely different, and so is the design philosophy. PyCyphal v2 does not attempt to be a one-stop shop for Cyphal, rather it focuses on connectivity only, intentionally omitting application-level concerns. As a result, the new API is a tiny fraction of the old.

The new version is not yet ready for use but it will be soon staged on the main branch nevertheless, while we will continue to maintain v1 on a dedicated branch.

Merge checklist

  • Add Cyphal/CAN. Currently, only Cyphal/UDP is available. An attempt will be made to reuse the extensive CAN media drivers from v1. One thing to focus on is Properly handle global state changes like network interface becoming unavailable #227
    • No attempt will be made to populate all of the CAN media implementations yet. This will be postponed for future work. For now, SocketCAN is considered sufficient.
  • Implement name remapping like in Cy, seeded from CYPHAL_REMAP by default.
  • Provide the updated docs, but not using Sphinx this time but rather something much simpler, likely pdoc, at most MkDocs.
  • Set up auto-publish when a new __version__ tag is pushed on the master branch.

pavel-kirienko and others added 2 commits April 7, 2026 23:55
The src layout means `coverage run` cannot find the package at the
top-level `pycyphal` path.  Use `source_pkgs` so coverage locates the
installed package wherever pip placed it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pavel-kirienko and others added 12 commits April 8, 2026 22:09
Triggers on pushes to master that change __init__.py. Skips tagging
if the version tag already exists, skips PyPI upload if already published.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New pycyphal2.can.pythoncan module wraps any python-can BusABC as a v2
Interface. A daemon RX thread bridges the blocking bus.recv() into an
asyncio queue; TX goes through a PriorityQueue with deadline enforcement
and executor-based bus.send(). Malformed wire input (overlength, non-
extended, error/remote frames) is silently dropped per project policy.

FD capability is resolved at construction from bus.protocol, with an
explicit fd= override. The pythoncan optional dependency (python-can~=4.0)
is added to pyproject.toml and installed in nox test/mypy sessions.

The State enum and abstract state property are removed from the Interface
ABC and all implementations (YAGNI -- no backend implemented it).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pavel-kirienko pavel-kirienko marked this pull request as ready for review April 10, 2026 21:30
pavel-kirienko and others added 8 commits April 11, 2026 00:31
The last Windows CI failure was a flaky Python-CAN transport test:
paired virtual-bus transports could randomly pick the same local CAN
node-ID, trigger collision handling, and intermittently drop the
expected delivery. This change removes that nondeterminism from the
affected transport-level tests.

- **Root cause**
- Paired `CANTransport` instances created on the same virtual bus were
relying on randomized local node-ID assignment.
- When both transports selected the same node-ID, collision handling
could reroll IDs during the test and race with message delivery.

- **Change**
- Added a small test helper in `tests/can/test_pythoncan.py` to force
distinct local node-IDs for paired transports.
- Applied it to the paired Python-CAN transport tests that exchange
traffic over a shared virtual channel:
    - pub/sub
    - unicast
    - multi-message delivery
    - multi-subject delivery
    - large multi-frame pub/sub
    - bidirectional unicast

- **Effect**
- The tests continue to exercise the same transport behavior, but no
longer depend on randomized node-ID selection.
- This keeps the Windows path deterministic without changing transport
implementation behavior.

```python
def _force_distinct_ids(a: CANTransport, b: CANTransport) -> None:
    if a.id != b.id:
        return
    b._local_node_id = (a.id % 127) + 1  # type: ignore[attr-defined]
    b._refresh_filters()  # type: ignore[attr-defined]
```

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: pavel-kirienko <3298404+pavel-kirienko@users.noreply.github.com>
@pavel-kirienko pavel-kirienko merged commit 8ba101d into master Apr 11, 2026
22 checks passed
@pavel-kirienko pavel-kirienko deleted the v2 branch April 11, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants