|
18 | 18 | import functools |
19 | 19 | import importlib.machinery |
20 | 20 | import importlib.metadata |
| 21 | +import importlib.resources |
21 | 22 | import importlib.util |
22 | 23 | import json |
23 | 24 | import operator |
24 | 25 | import os |
| 26 | +import pathlib |
25 | 27 | import re |
26 | 28 | import shutil |
27 | 29 | import subprocess |
@@ -2671,6 +2673,25 @@ def fetch__all__(file_content) -> list[str]: |
2671 | 2673 | return _all |
2672 | 2674 |
|
2673 | 2675 |
|
| 2676 | +def _resolve_traversable(module_path): |
| 2677 | + """Return a Traversable for `module_path`.""" |
| 2678 | + transformers_module = sys.modules.get("transformers") |
| 2679 | + if transformers_module is not None and getattr(transformers_module, "__file__", None) is not None: |
| 2680 | + pkg_root = pathlib.Path(transformers_module.__file__).parent |
| 2681 | + try: |
| 2682 | + rel = pathlib.PurePath(module_path).relative_to(pkg_root) |
| 2683 | + except ValueError: |
| 2684 | + pass |
| 2685 | + else: |
| 2686 | + traversable = importlib.resources.files("transformers") |
| 2687 | + for part in rel.parts: |
| 2688 | + traversable = traversable.joinpath(part) |
| 2689 | + return traversable |
| 2690 | + |
| 2691 | + # Fall back to pathlib.Path for paths outside the transformers package. |
| 2692 | + return pathlib.Path(module_path) |
| 2693 | + |
| 2694 | + |
2674 | 2695 | @lru_cache |
2675 | 2696 | def create_import_structure_from_path(module_path): |
2676 | 2697 | """ |
@@ -2724,36 +2745,39 @@ def create_import_structure_from_path(module_path): |
2724 | 2745 | } |
2725 | 2746 | } |
2726 | 2747 | """ |
2727 | | - import_structure = {} |
2728 | | - |
2729 | | - if os.path.isfile(module_path): |
| 2748 | + module_path = str(module_path) |
| 2749 | + if module_path.endswith(".py"): |
2730 | 2750 | module_path = os.path.dirname(module_path) |
| 2751 | + return _create_import_structure_from_traversable(_resolve_traversable(module_path)) |
2731 | 2752 |
|
2732 | | - adjacent_modules = [] |
2733 | 2753 |
|
2734 | | - with os.scandir(module_path) as entries: |
2735 | | - for entry in entries: |
2736 | | - if entry.name == "__pycache__": |
2737 | | - continue |
2738 | | - if entry.is_dir(): |
2739 | | - import_structure[entry.name] = create_import_structure_from_path(entry.path) |
2740 | | - elif not entry.name.startswith(("convert_", "modular_")): |
2741 | | - adjacent_modules.append(entry.name) |
| 2754 | +def _create_import_structure_from_traversable(traversable): |
| 2755 | + """Walk a Traversable and build the import structure.""" |
| 2756 | + import_structure = {} |
| 2757 | + adjacent_entries = [] |
| 2758 | + |
| 2759 | + for entry in traversable.iterdir(): |
| 2760 | + if entry.name == "__pycache__": |
| 2761 | + continue |
| 2762 | + if entry.is_dir(): |
| 2763 | + # Recurse via the Traversable, not `files(subpackage)` — the latter would force-import the subpackage. |
| 2764 | + import_structure[entry.name] = _create_import_structure_from_traversable(entry) |
| 2765 | + elif not entry.name.startswith(("convert_", "modular_")): |
| 2766 | + adjacent_entries.append(entry) |
2742 | 2767 |
|
2743 | 2768 | # We're only taking a look at files different from __init__.py |
2744 | 2769 | # We could theoretically require things directly from the __init__.py |
2745 | 2770 | # files, but this is not supported at this time. |
2746 | | - if "__init__.py" in adjacent_modules: |
2747 | | - adjacent_modules.remove("__init__.py") |
| 2771 | + adjacent_entries = [e for e in adjacent_entries if e.name != "__init__.py"] |
2748 | 2772 |
|
2749 | 2773 | module_requirements = {} |
2750 | | - for module_name in adjacent_modules: |
| 2774 | + for entry in adjacent_entries: |
2751 | 2775 | # Only modules ending in `.py` are accepted here. |
2752 | | - if not module_name.endswith(".py"): |
| 2776 | + if not entry.name.endswith(".py"): |
2753 | 2777 | continue |
2754 | 2778 |
|
2755 | | - with open(os.path.join(module_path, module_name), encoding="utf-8") as f: |
2756 | | - file_content = f.read() |
| 2779 | + module_name = entry.name |
| 2780 | + file_content = entry.read_text(encoding="utf-8") |
2757 | 2781 |
|
2758 | 2782 | # Remove the .py suffix |
2759 | 2783 | module_name = module_name[:-3] |
|
0 commit comments