Skip to content

Commit

Permalink
Have another shot at vendoring pymodbus
Browse files Browse the repository at this point in the history
We failed if pymodbus was already loaded, because Python doesn't load
anything already present in sys.modules.

Inspired by https://stackoverflow.com/a/76021423/1086121
  • Loading branch information
canton7 committed Feb 1, 2025
1 parent 7a88ed4 commit c4a9086
Showing 1 changed file with 40 additions and 18 deletions.
58 changes: 40 additions & 18 deletions custom_components/foxess_modbus/vendor/pymodbus/__init__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,46 @@
import sys
from pathlib import Path
from contextlib import contextmanager
from typing import Iterator


@contextmanager
def _load(path: Path, name: str) -> Iterator[None]:
def _remove_modules(name: str) -> None:
old_modules = {n: m for n, m in sys.modules.items(
) if n == name or n.startswith(name + ".")}
for n in old_modules:
del sys.modules[n]
return old_modules

# Save and remove any existing loaded modules
old_modules = _remove_modules(name)

# Load the vendored module
sys.path.insert(0, str(path.absolute()))
yield ()
sys.path.pop(0)

# Remove anything we've added to the global modules
_remove_modules(name)
# Re-add any existing loaded modules
sys.modules.update(old_modules)


with _load(Path(__file__).parent / "pymodbus-3.6.9", "pymodbus"):
from pymodbus.client import ModbusSerialClient
from pymodbus.client import ModbusTcpClient
from pymodbus.client import ModbusUdpClient
from pymodbus.exceptions import ConnectionException
from pymodbus.exceptions import ModbusIOException
from pymodbus.register_read_message import ReadHoldingRegistersResponse
from pymodbus.register_read_message import ReadInputRegistersResponse
from pymodbus.register_write_message import WriteMultipleRegistersResponse
from pymodbus.register_write_message import WriteSingleRegisterResponse
from pymodbus.pdu import ModbusResponse
from pymodbus.transaction import ModbusRtuFramer
from pymodbus.transaction import ModbusSocketFramer

# Update python.analysis.extraPaths in .vscode/settings.json if you change this.
# If changed, make sure subclasses in modbus_client are still valid!
sys.path.insert(0, str((Path(__file__).parent / "pymodbus-3.6.9").absolute()))

from pymodbus.client import ModbusSerialClient
from pymodbus.client import ModbusTcpClient
from pymodbus.client import ModbusUdpClient
from pymodbus.exceptions import ConnectionException
from pymodbus.exceptions import ModbusIOException
from pymodbus.register_read_message import ReadHoldingRegistersResponse
from pymodbus.register_read_message import ReadInputRegistersResponse
from pymodbus.register_write_message import WriteMultipleRegistersResponse
from pymodbus.register_write_message import WriteSingleRegisterResponse
from pymodbus.pdu import ModbusResponse
from pymodbus.transaction import ModbusRtuFramer
from pymodbus.transaction import ModbusSocketFramer

sys.path.pop(0)

__all__ = [
"ModbusSerialClient",
Expand Down

0 comments on commit c4a9086

Please sign in to comment.