You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MF4Writer reports "asammdf package was not found" when asammdf is imported before can #2122
If asammdf is imported before can, and canopen is also installed, can.io.mf4 decides that
asammdf is missing. Every MF4Writer created later in that process raises:
NotImplementedError: The asammdf package was not found. Install python-can with the optional
dependency [mf4] to use the MF4Writer.
asammdf is installed. The message hides the real cause, which is a circular import.
To Reproduce
The environment needs python-can, asammdf (which pulls in canmatrix) and canopen.
importasammdffromcan.ioimportMF4WriterMF4Writer("out.mf4") # NotImplementedError: The asammdf package was not found...
Importing can first avoids the error:
importcanimportasammdffromcan.ioimportMF4WriterMF4Writer("out.mf4").stop() # works
Cause
import asammdf pulls in can.io.mf4 before asammdf has finished initialising:
asammdf/blocks/types.py:5 from canmatrix import CanMatrix
canmatrix/formats/__init__.py:24 importlib.import_module("canmatrix.formats." + module) # every format
canmatrix/formats/eds.py:4 import canopen.objectdictionary.eds
canopen/network.py:8 import can
can/__init__.py:100 from .io import (...)
can/io/logger.py:36 from .mf4 import MF4Writer
can/io/mf4.py from asammdf import Signal, Source # asammdf partially initialised
The from asammdf import Signal, Source raises ImportError because asammdf is only partly
initialised. The optional-dependency guard catches it:
This guard treats "asammdf is not installed" and "asammdf failed to import" as the same thing. asammdf = None is then stored as a module global, so the wrong answer lasts for the whole
process, even after asammdf finishes importing.
Suggested Fix
Either of these would avoid the problem:
Import asammdf lazily inside MF4Writer.__init__ / MF4Reader.__init__ instead of at module
import. The cycle can no longer form, and import can gets cheaper too.
Narrow the guard so that only a genuinely missing package counts as missing
Expected behavior
asammdf and can can be imported regardless of order.
Additional context
python-can 4.6.1. The same guard is in can/io/mf4.py on main.
Activity