Avoid late (non-top-level) imports

Avoiding late imports helps to isolate Blender add-ons bundling BAT from
each other.

There was one late/lazy import to avoid a dependency cycle. This was
solved by simply copying that one tiny function.
This commit is contained in:
Sybren A. Stüvel 2022-03-11 17:03:08 +01:00
parent 4899766943
commit cd3f9ce671
3 changed files with 32 additions and 4 deletions

View File

@ -3,7 +3,12 @@
This file logs the changes that are actually interesting to users (new features, This file logs the changes that are actually interesting to users (new features,
changed functionality, fixed bugs). changed functionality, fixed bugs).
# Version 1.11 (in development) # Version 1.12 (in development)
- Removed "late imports", to help isolate Blender add-ons bundling BAT from each other.
# Version 1.11 (2022-02-18)
- Support UDIM images. - Support UDIM images.

View File

@ -115,3 +115,19 @@ To understand the naming of the properties, look at Blender's `DNA_xxxx.h` files
definitions. It is those names that are accessed via `blender_asset_tracer.blendfile`. The definitions. It is those names that are accessed via `blender_asset_tracer.blendfile`. The
mapping to the names accessible in Blender's Python interface can be found in the `rna_yyyy.c` mapping to the names accessible in Blender's Python interface can be found in the `rna_yyyy.c`
files. files.
## Code Guidelines
This section documents some guidelines for the code in BAT.
### Avoiding Late Imports
All imports should be done at the top level of the file, and not inside
functions. The goal is to ensure that, once imported, a (sub)module of BAT can
be used without having to import more parts of BAT.
This requirement helps to keep Blender add-ons separated, as an add-on can
import the modules of BAT it needs, then remove them from `sys.modules` and
`sys.path` so that other add-ons don't see them. This should reduce problems
with various add-ons shipping different versions of BAT.

View File

@ -28,6 +28,7 @@ import typing
from blender_asset_tracer import trace, bpathlib, blendfile from blender_asset_tracer import trace, bpathlib, blendfile
from blender_asset_tracer.trace import file_sequence, result from blender_asset_tracer.trace import file_sequence, result
from . import filesystem, transfer, progress from . import filesystem, transfer, progress
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -121,9 +122,7 @@ class Packer:
self._exclude_globs = set() # type: typing.Set[str] self._exclude_globs = set() # type: typing.Set[str]
from blender_asset_tracer.cli import common self._shorten = functools.partial(shorten_path, self.project)
self._shorten = functools.partial(common.shorten, self.project)
if noop: if noop:
log.warning("Running in no-op mode, only showing what will be done.") log.warning("Running in no-op mode, only showing what will be done.")
@ -618,3 +617,11 @@ class Packer:
) )
self._file_transferer.queue_move(infopath, self._target_path / infoname) self._file_transferer.queue_move(infopath, self._target_path / infoname)
def shorten_path(cwd: pathlib.Path, somepath: pathlib.Path) -> pathlib.Path:
"""Return 'somepath' relative to CWD if possible."""
try:
return somepath.relative_to(cwd)
except ValueError:
return somepath