|
1 | 1 | import warnings |
| 2 | +from typing import Any |
2 | 3 |
|
3 | | -try: |
4 | | - from .model import * |
5 | | - from .util import * |
6 | | - from .coordination import * |
7 | | - from .politenessStrategies import * |
8 | | - from .transformer import * |
9 | | - from .convokitPipeline import * |
10 | | - from .hyperconvo import * |
11 | | - from .speakerConvoDiversity import * |
12 | | - from .text_processing import * |
13 | | - from .phrasing_motifs import * |
14 | | - from .prompt_types import * |
15 | | - from .classifier.classifier import * |
16 | | - from .ranker import * |
17 | | - from .forecaster import * |
18 | | - from .fighting_words import * |
19 | | - from .paired_prediction import * |
20 | | - from .bag_of_words import * |
21 | | - from .expected_context_framework import * |
22 | | - from .surprise import * |
23 | | - from .convokitConfig import * |
24 | | - from .redirection import * |
25 | | - from .pivotal_framework import * |
26 | | - from .utterance_simulator import * |
27 | | -except ModuleNotFoundError as e: |
28 | | - # Don't print ModuleNotFoundError messages as they're handled by individual modules |
29 | | - if "not currently installed" not in str(e): |
30 | | - print(f"An error occurred: {e}") |
31 | | - warnings.warn( |
32 | | - "If you are using ConvoKit with Google Colab, incorrect versions of some packages (ex. scipy) may be imported while runtime start. To fix the issue, restart the session and run all codes again. Thank you!" |
33 | | - ) |
34 | | -except Exception as e: |
35 | | - print(f"An error occurred: {e}") |
36 | | - warnings.warn( |
37 | | - "If you are using ConvoKit with Google Colab, incorrect versions of some packages (ex. scipy) may be imported while runtime start. To fix the issue, restart the session and run all codes again. Thank you!" |
38 | | - ) |
39 | | - |
40 | | - |
41 | | -# __path__ = __import__('pkgutil').extend_path(__path__, __name__) |
| 4 | +# Core modules - always imported immediately |
| 5 | +from .model import * |
| 6 | +from .util import * |
| 7 | +from .transformer import * |
| 8 | +from .convokitConfig import * |
| 9 | +from .convokitPipeline import * |
| 10 | + |
| 11 | +# Module mapping for lazy loading |
| 12 | +# Each entry maps module_name -> import_path |
| 13 | +_LAZY_MODULES = { |
| 14 | + "coordination": ".coordination", |
| 15 | + "politenessStrategies": ".politenessStrategies", |
| 16 | + "hyperconvo": ".hyperconvo", |
| 17 | + "speakerConvoDiversity": ".speakerConvoDiversity", |
| 18 | + "text_processing": ".text_processing", |
| 19 | + "phrasing_motifs": ".phrasing_motifs", |
| 20 | + "prompt_types": ".prompt_types", |
| 21 | + "classifier": ".classifier", |
| 22 | + "ranker": ".ranker", |
| 23 | + "forecaster": ".forecaster", |
| 24 | + "fighting_words": ".fighting_words", |
| 25 | + "paired_prediction": ".paired_prediction", |
| 26 | + "bag_of_words": ".bag_of_words", |
| 27 | + "expected_context_framework": ".expected_context_framework", |
| 28 | + "surprise": ".surprise", |
| 29 | + "redirection": ".redirection", |
| 30 | + "pivotal_framework": ".pivotal_framework", |
| 31 | + "utterance_simulator": ".utterance_simulator", |
| 32 | + "utterance_likelihood": ".utterance_likelihood", |
| 33 | + "speaker_convo_helpers": ".speaker_convo_helpers", |
| 34 | + "politeness_collections": ".politeness_collections", |
| 35 | +} |
| 36 | + |
| 37 | +# Cache for loaded modules |
| 38 | +_loaded_modules = {} |
| 39 | + |
| 40 | + |
| 41 | +def _lazy_import(module_name: str) -> Any: |
| 42 | + """Import a module lazily and cache the result.""" |
| 43 | + if module_name in _loaded_modules: |
| 44 | + return _loaded_modules[module_name] |
| 45 | + |
| 46 | + if module_name not in _LAZY_MODULES: |
| 47 | + raise AttributeError(f"module '{__name__}' has no attribute '{module_name}'") |
| 48 | + |
| 49 | + import_path = _LAZY_MODULES[module_name] |
| 50 | + |
| 51 | + try: |
| 52 | + import importlib |
| 53 | + |
| 54 | + module = importlib.import_module(import_path, package=__name__) |
| 55 | + _loaded_modules[module_name] = module |
| 56 | + |
| 57 | + globals_dict = globals() |
| 58 | + if hasattr(module, "__all__"): |
| 59 | + for name in module.__all__: |
| 60 | + if hasattr(module, name): |
| 61 | + globals_dict[name] = getattr(module, name) |
| 62 | + else: |
| 63 | + for name in dir(module): |
| 64 | + if not name.startswith("_"): |
| 65 | + globals_dict[name] = getattr(module, name) |
| 66 | + |
| 67 | + return module |
| 68 | + |
| 69 | + except Exception as e: |
| 70 | + # Simply re-raise whatever the module throws |
| 71 | + # Let each module handle its own error messaging |
| 72 | + raise |
| 73 | + |
| 74 | + |
| 75 | +def __getattr__(name: str) -> Any: |
| 76 | + """Handle attribute access for lazy-loaded modules.""" |
| 77 | + # Check if it's a module we can lazy load |
| 78 | + if name in _LAZY_MODULES: |
| 79 | + return _lazy_import(name) |
| 80 | + |
| 81 | + # Check if it's an exported symbol from a lazy module |
| 82 | + # We need to check each module to see if it exports this symbol |
| 83 | + for module_name in _LAZY_MODULES: |
| 84 | + if module_name not in _loaded_modules: |
| 85 | + # Try to import the module to see if it has the requested attribute |
| 86 | + try: |
| 87 | + import importlib |
| 88 | + |
| 89 | + import_path = _LAZY_MODULES[module_name] |
| 90 | + module = importlib.import_module(import_path, package=__name__) |
| 91 | + |
| 92 | + # Check if this module has the requested attribute |
| 93 | + if hasattr(module, name): |
| 94 | + # Import the full module (which will add all symbols to globals) |
| 95 | + _lazy_import(module_name) |
| 96 | + # Return the requested attribute |
| 97 | + return getattr(module, name) |
| 98 | + |
| 99 | + except Exception: |
| 100 | + # If module fails to import, just skip it and try next module |
| 101 | + # The module's own error handling will take care of proper error messages |
| 102 | + continue |
| 103 | + |
| 104 | + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") |
0 commit comments