mirror of
https://github.com/modelscope/modelscope.git
synced 2026-09-01 19:49:03 +02:00
fix: derive valid module names from snapshot revision paths
Path(model_dir).stem on revisions like v1.0.4 produced v1.0, so importlib treated it as package v1 and raised ModuleNotFoundError. Use the owner--name (+ revision) segment and sanitize to an identifier. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -374,6 +374,30 @@ def create_module_from_files(file_list, file_prefix, module_name):
|
||||
importlib.invalidate_caches()
|
||||
|
||||
|
||||
def _module_name_from_model_dir(model_dir: str) -> str:
|
||||
"""Derive a valid Python package name from a local model directory.
|
||||
|
||||
modelscope_hub 0.1.x returns paths like
|
||||
``{cache}/models/{owner}--{name}/snapshots/{revision}``. Using
|
||||
``Path(model_dir).stem`` on a revision such as ``v1.0.4`` yields
|
||||
``v1.0``, and ``importlib.import_module('v1.0.xxx')`` fails with
|
||||
``ModuleNotFoundError: No module named 'v1'`` because dots are package
|
||||
separators. Prefer the ``{owner}--{name}`` segment (plus revision for
|
||||
isolation) and sanitize to a valid identifier.
|
||||
"""
|
||||
path = Path(model_dir).resolve()
|
||||
if path.parent.name == 'snapshots':
|
||||
base = f'{path.parent.parent.name}__{path.name}'
|
||||
else:
|
||||
# Use the full directory name, not .stem, so dotted names are kept
|
||||
# intact before sanitization (stem would turn ``v1.0.4`` into ``v1.0``).
|
||||
base = path.name
|
||||
module_name = re.sub(r'[^0-9A-Za-z_]', '_', base)
|
||||
if not module_name or module_name[0].isdigit():
|
||||
module_name = f'm_{module_name}'
|
||||
return module_name
|
||||
|
||||
|
||||
def import_module_from_model_dir(model_dir):
|
||||
""" import all the necessary module from a model dir
|
||||
|
||||
@@ -383,7 +407,6 @@ def import_module_from_model_dir(model_dir):
|
||||
No returns, raise error if failed
|
||||
|
||||
"""
|
||||
from pathlib import Path
|
||||
file_scanner = FilesAstScanning()
|
||||
file_scanner.traversal_files(model_dir, include_init=True)
|
||||
file_dirs = file_scanner.file_dirs
|
||||
@@ -395,7 +418,7 @@ def import_module_from_model_dir(model_dir):
|
||||
if BASE_MODULE_DIR not in sys.path:
|
||||
sys.path.append(BASE_MODULE_DIR)
|
||||
|
||||
module_name = Path(model_dir).stem
|
||||
module_name = _module_name_from_model_dir(model_dir)
|
||||
|
||||
# in order to keep forward compatibility, we add module path to
|
||||
# sys.path so that submodule can be imported directly as before
|
||||
|
||||
Reference in New Issue
Block a user