Summary
The current s7/ package tries to unify legacy S7 (snap7) and S7CommPlus behind a single Client that auto-negotiates the protocol. In practice the two protocols differ too much — different capabilities (browse is S7CommPlus-only), different connection requirements (TLS, SessionKey handshake), and different failure modes. The silent fallback from S7CommPlus to legacy creates confusing errors (#760, #710) and makes it hard for users to understand what's happening.
Plan
-
Create a new top-level s7commplus/ package containing the S7CommPlus-specific code currently in s7/:
_s7commplus_client.py → s7commplus/client.py
_s7commplus_async_client.py → s7commplus/async_client.py
_s7commplus_server.py → s7commplus/server.py
s7/connection.py → s7commplus/connection.py
s7/protocol.py → s7commplus/protocol.py
s7/codec.py, s7/vlq.py, s7/legitimation.py → s7commplus/
-
Keep snap7/ unchanged — it remains the legacy S7 package for S7-300/400 and PUT/GET on S7-1200/1500.
-
Shared code (TPKT/COTP transport in snap7/connection.py) stays in snap7 — s7commplus imports from it.
-
Remove the unified s7/ package — no more s7/client.py with auto-negotiation and silent fallback. Users explicitly choose snap7.Client or s7commplus.Client.
-
Update examples, docs, tests, and CLAUDE.md to reflect the new structure.
Motivation
- Users should explicitly choose their protocol rather than getting silent fallback behavior
- The two protocols have fundamentally different capabilities and requirements
- Cleaner API surface — no more "browse() requires S7CommPlus connection" errors after silent fallback
- Easier to document and maintain each protocol independently
Timing
Do this after all current open PRs are merged (#761, #763, #764, #768) since they touch s7/client.py and s7/connection.py heavily.
Breaking change
This removes the s7 package entirely. Users importing from s7 will need to switch to either snap7 or s7commplus. This should be part of a major or minor version bump with migration notes.
Summary
The current
s7/package tries to unify legacy S7 (snap7) and S7CommPlus behind a singleClientthat auto-negotiates the protocol. In practice the two protocols differ too much — different capabilities (browse is S7CommPlus-only), different connection requirements (TLS, SessionKey handshake), and different failure modes. The silent fallback from S7CommPlus to legacy creates confusing errors (#760, #710) and makes it hard for users to understand what's happening.Plan
Create a new top-level
s7commplus/package containing the S7CommPlus-specific code currently ins7/:_s7commplus_client.py→s7commplus/client.py_s7commplus_async_client.py→s7commplus/async_client.py_s7commplus_server.py→s7commplus/server.pys7/connection.py→s7commplus/connection.pys7/protocol.py→s7commplus/protocol.pys7/codec.py,s7/vlq.py,s7/legitimation.py→s7commplus/Keep
snap7/unchanged — it remains the legacy S7 package for S7-300/400 and PUT/GET on S7-1200/1500.Shared code (TPKT/COTP transport in
snap7/connection.py) stays insnap7—s7commplusimports from it.Remove the unified
s7/package — no mores7/client.pywith auto-negotiation and silent fallback. Users explicitly choosesnap7.Clientors7commplus.Client.Update examples, docs, tests, and CLAUDE.md to reflect the new structure.
Motivation
Timing
Do this after all current open PRs are merged (#761, #763, #764, #768) since they touch
s7/client.pyands7/connection.pyheavily.Breaking change
This removes the
s7package entirely. Users importing froms7will need to switch to eithersnap7ors7commplus. This should be part of a major or minor version bump with migration notes.