Skip to content

SG-43269 Fix sys.path and sys.meta_path isolation during core swap#1101

Open
julien-lang wants to merge 1 commit into
masterfrom
ticket/SG-43269-fix-sys-path-isolation-during-core-swap
Open

SG-43269 Fix sys.path and sys.meta_path isolation during core swap#1101
julien-lang wants to merge 1 commit into
masterfrom
ticket/SG-43269-fix-sys-path-isolation-during-core-swap

Conversation

@julien-lang
Copy link
Copy Markdown
Member

What

Fixes a sys.path and sys.meta_path isolation bug in _swap_core() that caused project bootstrapping to fail when the site core is newer (pkgs.zip-style, e.g. v0.23.8) and the project core is older (vendored-style, e.g. v0.22.4).

Two things are now cleaned up in _swap_core() before handing off to the incoming core:

  1. sys.path cleanup — removes all entries that live under the outgoing core's root directory. This ensures the site core's pkgs.zip is no longer on sys.path when the project core loads, so direct imports like import shotgun_api3 resolve to the project core's vendored copy rather than the site's.

  2. sys.meta_path cleanup — removes the stale _TankVendorMetaFinder instance registered by the outgoing core's tank_vendor/__init__.py. The incoming core's tank_vendor/__init__.py installs a fresh one when import tank loads it.

Why

Two distinct customer-facing failures traced to the same root cause:

SGD 3.0 + project config ≤ v1.7.5 → ModuleNotFoundError: No module named 'tank_vendor.six.moves'

  • Site core (v0.23.8) boots → tank_vendor/__init__.py inserts its pkgs.zip at sys.path[0] and registers _TankVendorMetaFinder in sys.meta_path.
  • _swap_core() runs → stashes sys.modules entries but leaves sys.path and sys.meta_path untouched.
  • Project core (v0.22.4) has six.py as a plain file; six.__path__ == []. When tank_vendor.six.moves is requested, CoreImportHandler.find_spec returns None (empty package_path), and the stale _TankVendorMetaFinder intercepts the import — but the site pkgs.zip has no six, so it fails.

Flame 2025.1 + project config ≤ v1.10.20 → ImportError: cannot import name 'sgsix' from 'shotgun_api3.lib'

  • Same root cause: after the swap, the site pkgs.zip is still at sys.path[0].
  • shotgun_api3 is not in NAMESPACES_TO_TRACK, so CoreImportHandler ignores it.
  • Python's default PathFinder resolves shotgun_api3 from the site pkgs.zip, which has a newer version without sgsix. Project code that expects sgsix fails.

Changes

  • python/tank/bootstrap/import_handler.py_swap_core(): strip outgoing-core sys.path entries and remove stale _TankVendorMetaFinder before resetting self._core_path.

Related

Closes / supersedes the diagnostic-only approach in #1099.

When the site core (e.g. v0.23.8 bundled with SGD 3.0) boots, its
tank_vendor/__init__.py inserts its pkgs.zip into sys.path[0] and
registers a _TankVendorMetaFinder in sys.meta_path.

Previously, _swap_core() cleaned up sys.modules but left both of those
in place. This caused two distinct failures when swapping to an older
project core:

1. sys.path pollution: direct imports like Version: ImageMagick 7.1.2-23 Q16-HDRI aarch64 6c51b2de5:20260516 https://imagemagick.org

By default, 'file' is written in the MIFF image format.  To
specify a particular image format, precede the filename with an image
format name and a colon (i.e. ps:image) or specify the image type as
the filename suffix (i.e. image.ps).  Specify 'file' as '-' for
standard input or output. (not
   via tank_vendor.*) resolved to the site core's pkgs.zip instead of
   the project core's vendored copy. The site pkgs.zip lacks packages
   removed in newer releases (e.g. sgsix), causing ImportError.

2. Stale _TankVendorMetaFinder: when six.__path__ == [] caused
   CoreImportHandler to return None for , the
   stale meta finder intercepted the import and tried to resolve it
   against the old sys.path state (site pkgs.zip, no six), causing
   ModuleNotFoundError.

Fix: in _swap_core(), before resetting self._core_path:
- Strip all sys.path entries that live under the outgoing core root.
- Remove any _TankVendorMetaFinder instances from sys.meta_path and
  delete sys._tank_vendor_meta_finder.

The incoming core's tank_vendor/__init__.py will then insert its own
pkgs.zip and register a fresh finder when Version: ImageMagick 7.1.2-23 Q16-HDRI aarch64 6c51b2de5:20260516 https://imagemagick.org

By default, 'file' is written in the MIFF image format.  To
specify a particular image format, precede the filename with an image
format name and a colon (i.e. ps:image) or specify the image type as
the filename suffix (i.e. image.ps).  Specify 'file' as '-' for
standard input or output. loads it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
norm_p = os.path.normpath(p)
try:
if os.path.commonpath([norm_p, current_core_root]) == current_core_root:
log.debug("Removing sys.path entry belonging to outgoing core: %s" % p)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Black would make changes.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.46%. Comparing base (5abb812) to head (2cb865a).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1101      +/-   ##
==========================================
+ Coverage   79.45%   79.46%   +0.01%     
==========================================
  Files         198      198              
  Lines       20769    20785      +16     
==========================================
+ Hits        16502    16517      +15     
- Misses       4267     4268       +1     
Flag Coverage Δ
Linux 78.91% <87.50%> (+<0.01%) ⬆️
Python-3.10 79.27% <100.00%> (+0.01%) ⬆️
Python-3.11 79.18% <100.00%> (+0.01%) ⬆️
Python-3.13 79.19% <100.00%> (+0.01%) ⬆️
Python-3.9 79.24% <100.00%> (+0.01%) ⬆️
Windows 78.98% <100.00%> (+0.01%) ⬆️
macOS 78.92% <87.50%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant