Skip to content
4 changes: 4 additions & 0 deletions common/ayon_common/distribution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
)
from .control import AYONDistribution
from .utils import (
get_addons_dir,
get_dependencies_dir,
show_missing_permissions,
show_blocked_auto_update,
show_missing_bundle_information,
Expand All @@ -18,6 +20,8 @@

"AYONDistribution",

"get_addons_dir",
"get_dependencies_dir",
"show_missing_permissions",
"show_blocked_auto_update",
"show_missing_bundle_information",
Expand Down
20 changes: 10 additions & 10 deletions common/ayon_common/distribution/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -2538,38 +2538,38 @@ def get_sys_paths(self) -> list[str]:
output.append(runtime_dir)
return output

def get_python_paths(self) -> list[str]:
def get_python_paths(self) -> tuple[list[str], Optional[str]]:
"""Get all paths to python packages that should be added to python.

These paths lead to addon directories and python dependencies in
dependency package.

Returns:
List[str]: Paths that should be added to 'sys.path' and
'PYTHONPATH'.
tuple[list[str], Optional[str]]: Paths that should be added
to 'sys.path' and 'PYTHONPATH'.

"""
output = []
addon_paths = []
for item in self.get_addon_dist_items():
dist_item = item["dist_item"]
if dist_item.state != UpdateState.UPDATED:
continue
target_dirpath = dist_item.target_dirpath
if target_dirpath and os.path.exists(target_dirpath):
output.append(target_dirpath)
addon_paths.append(target_dirpath)

output.extend(self._get_dev_sys_paths())
addon_paths.extend(self._get_dev_sys_paths())

dependencies_dir = None
dependency_dist_item = self.get_dependency_dist_item()
if dependency_dist_item is not None:
dependencies_dir = None
target_dirpath = dependency_dist_item.target_dirpath
if target_dirpath:
dependencies_dir = os.path.join(target_dirpath, "dependencies")

if dependencies_dir and os.path.exists(dependencies_dir):
output.append(dependencies_dir)
return output
if not dependencies_dir or not os.path.exists(dependencies_dir):
dependencies_dir = None
return addon_paths, dependencies_dir

def _get_dev_sys_paths(self) -> list[str]:
output = []
Expand Down
40 changes: 32 additions & 8 deletions start.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
import traceback
import subprocess
from contextlib import contextmanager
from pathlib import Path
from urllib.parse import urlencode, urlparse, parse_qs

from version import __version__
Expand Down Expand Up @@ -377,6 +378,8 @@ def _print(message: str):
from ayon_common.distribution import ( # noqa E402
AYONDistribution,
BundleNotFoundError,
get_addons_dir,
get_dependencies_dir,
show_missing_bundle_information,
show_blocked_auto_update,
show_missing_permissions,
Expand Down Expand Up @@ -799,16 +802,37 @@ def _start_distribution():
os.environ["AYON_STUDIO_BUNDLE_NAME"] = studio_bundle_name

# TODO probably remove paths to other addons?
python_paths = [
path
for path in os.getenv("PYTHONPATH", "").split(os.pathsep)
if path
]
addons_dir = Path(get_addons_dir())
dependencies_dir = Path(get_dependencies_dir())
dep_dir_idx = None
python_paths = []
for idx, path in enumerate(os.getenv("PYTHONPATH", "").split(os.pathsep)):
if not path:
continue

p_path = Path(path)
# Ignore addons
if p_path.is_relative_to(addons_dir):
continue

# Ignore dependencies dir and store index of the path
if p_path.is_relative_to(dependencies_dir):
if dep_dir_idx is None:
dep_dir_idx = idx
continue
python_paths.append(path)
Copy link
Contributor

@BigRoy BigRoy Feb 19, 2026

Choose a reason for hiding this comment

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

I'm not convinced the idx here will work, or at least in any meaningful way, because the idx will be shifted wrong due to some paths being skipped here while the idx counter continues forward. As such, the index in python_paths list would not match it? Because we're essentially 'inserting it' at the new python_paths that we're generating 🤔

Why do need the whole idx tracking, seems redundant/wrong? Seems we want to put in same order - but since we're building the full list - doesn't that just mean to .append directly here?

Copy link
Member Author

Choose a reason for hiding this comment

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

From my perspective we should always prepend it... But you said it is not good idea 🙂


addon_paths, dep_package_path = distribution.get_python_paths()

sys.path.insert(0, dep_package_path)
if dep_dir_idx is not None:
python_paths.insert(dep_dir_idx, dep_package_path)
else:
python_paths.append(dep_package_path)
Comment on lines 812 to 837
Copy link
Contributor

@BigRoy BigRoy Feb 19, 2026

Choose a reason for hiding this comment

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

Can you elaborate a bit on the what and how? :) Why does it need to be before the dependencies dir path?

Copy link
Member Author

@iLLiCiTiT iLLiCiTiT Feb 19, 2026

Choose a reason for hiding this comment

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

It removes all paths in PYTHONPATH that leads to addons dir or dependecy packages dir.
(ignore paths %LOCALAPPDATA%/Ynput/AYON/addons/* & %LOCALAPPDATA%/Ynput/AYON/dependency_packages/*)

If there was dependency package, then remember it's position, and replace it with current dependency package dir path.


for path in distribution.get_python_paths():
for path in addon_paths:
sys.path.insert(0, path)
if path not in python_paths:
python_paths.append(path)
python_paths.insert(0, path)

for path in distribution.get_sys_paths():
sys.path.insert(0, path)
Expand Down