From 89e9f6a24a173cf108c95038ef7f5cbe492127b9 Mon Sep 17 00:00:00 2001 From: Marc Lehner Date: Tue, 15 Sep 2026 15:19:47 +0200 Subject: [PATCH] Import utils relative-first to avoid cross-extension shadowing KNIME puts the module directory of every registered Python port-object converter on the sys.path of every Python gateway, not just the one belonging to the contributing extension. Another extension (PM4KNIME) contributes a top-level `utils` namespace package, so the bare `import utils` here bound the wrong module and `utils.category` raised AttributeError, breaking extension loading in any KNIME installation that has both extensions. Trying the relative import first binds this extension's own utils. The absolute import stays as the fallback for the test suite, which imports these modules without a package context. Co-Authored-By: Claude Opus 5 --- src/rdkit_descriptors.py | 9 +++++---- src/standardizer_parent.py | 9 +++++---- src/stereoisomer_enumeration.py | 9 +++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/rdkit_descriptors.py b/src/rdkit_descriptors.py index 6d21a0f..5a7a5cb 100644 --- a/src/rdkit_descriptors.py +++ b/src/rdkit_descriptors.py @@ -64,12 +64,13 @@ import NP_Score from NP_Score import npscorer -# this is pretty gross, but we need to be able to import utils both when -# running as part of the node/package and when running the test suite +# Relative import first: extensions share a Python gateway's sys.path, so a bare +# `import utils` can bind another extension's top-level utils module. The fallback +# covers the test suite, which runs these modules without package context. try: - import utils -except ImportError: from . import utils +except ImportError: + import utils LOGGER = logging.getLogger(__name__) diff --git a/src/standardizer_parent.py b/src/standardizer_parent.py index 89ac460..cd93f43 100644 --- a/src/standardizer_parent.py +++ b/src/standardizer_parent.py @@ -53,12 +53,13 @@ import knime.extension as knext from rdkit import Chem -# this is pretty gross, but we need to be able to import utils both when -# running as part of the node/package and when running the test suite +# Relative import first: extensions share a Python gateway's sys.path, so a bare +# `import utils` can bind another extension's top-level utils module. The fallback +# covers the test suite, which runs these modules without package context. try: - import utils -except ImportError: from . import utils +except ImportError: + import utils import logging diff --git a/src/stereoisomer_enumeration.py b/src/stereoisomer_enumeration.py index 016b3b9..0729e44 100644 --- a/src/stereoisomer_enumeration.py +++ b/src/stereoisomer_enumeration.py @@ -56,12 +56,13 @@ import numpy as np LOGGER = logging.getLogger(__name__) -# this is pretty gross, but we need to be able to import utils both when -# running as part of the node/package and when running the test suite +# Relative import first: extensions share a Python gateway's sys.path, so a bare +# `import utils` can bind another extension's top-level utils module. The fallback +# covers the test suite, which runs these modules without package context. try: - import utils -except ImportError: from . import utils +except ImportError: + import utils @knext.node( name="Stereoisomer Enumeration",