dissect.target icon indicating copy to clipboard operation
dissect.target copied to clipboard

Fix circular imports error during Loader registration

Open Horofic opened this issue 1 year ago • 2 comments

During Loader registration some loaders incorrectly fail to import due to ImportError's caused by circular imports, such as the RemoteLoader (remote.py).

\*\*\* ImportError: Failed to lazily import dissect.target.loaders.remote: cannot import name 'Target' from partially initialized module 'dissect.target.target' (most likely due to a circular import) (/projects/dissect/dissect.target/dissect/target/target.py)
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.9.15/Frameworks/Python.framework/Versions/3.9/lib/python3.9/pdb.py", line 366, in displayhook
    self.message(repr(obj))
  File "/projects/dissect/dissect.target/dissect/target/helpers/lazy.py", line 66, in __repr__
    return f"<lazyattr {self.module._module_name}.{self.attr} loaded={self.realattr is not None}>"
  File "/projects/dissect/dissect.target/dissect/target/helpers/lazy.py", line 51, in realattr
    self._realattr = getattr(self.module._module, self.attr)
  File "/projects/dissect/dissect.target/dissect/target/helpers/lazy.py", line 38, in __getattr__
    self._error()
  File "/projects/dissect/dissect.target/dissect/target/helpers/lazy.py", line 32, in _error
    raise ImportError(f"Failed to lazily import {self.module._module_name}: {self.exc}")  # noqa

Horofic avatar Oct 17 '24 14:10 Horofic

I ended up here because I wanted to run target-query via the debugger. Upon running:

python3 dissect/target/tools/shell.py

I get:

Traceback (most recent call last):
  File "/Users/ohaalstra/Repositories/research/dissect.target/dissect/target/tools/shell.py", line 9, in <module>
    import logging
  File "/Users/ohaalstra/Repositories/research/dissect.target/dissect/target/tools/logging.py", line 5, in <module>
    import structlog
  File "/opt/homebrew/Caskroom/miniforge/base/envs/dissect-dev/lib/python3.11/site-packages/structlog/__init__.py", line 9, in <module>
    from structlog import (
  File "/opt/homebrew/Caskroom/miniforge/base/envs/dissect-dev/lib/python3.11/site-packages/structlog/stdlib.py", line 14, in <module>
    import asyncio
  File "/opt/homebrew/Caskroom/miniforge/base/envs/dissect-dev/lib/python3.11/asyncio/__init__.py", line 8, in <module>
    from .base_events import *
  File "/opt/homebrew/Caskroom/miniforge/base/envs/dissect-dev/lib/python3.11/asyncio/base_events.py", line 18, in <module>
    import concurrent.futures
  File "/opt/homebrew/Caskroom/miniforge/base/envs/dissect-dev/lib/python3.11/concurrent/futures/__init__.py", line 8, in <module>
    from concurrent.futures._base import (FIRST_COMPLETED,
  File "/opt/homebrew/Caskroom/miniforge/base/envs/dissect-dev/lib/python3.11/concurrent/futures/_base.py", line 43, in <module>
    LOGGER = logging.getLogger("concurrent.futures")
             ^^^^^^^^^^^^^^^^^
AttributeError: partially initialized module 'logging' has no attribute 'getLogger' (most likely due to a circular import)

Is this related? Or am I doing something wrong?

OlafHaalstra avatar Dec 12 '24 10:12 OlafHaalstra

This is probably because of how you execute the script. By running it as a regular Python script, the import logging statement will try to import dissect/target/tools/logging.py instead of the Python standard library logging module. Arguably a resolvable error on our end (it's generally bad practise to name files similarly to standard library modules), but also not something that will happen with normal execution of these scripts.

Try running python3 -m dissect.target.tools.shell or target-shell instead.

Schamper avatar Dec 12 '24 11:12 Schamper