/ dreamtalk_init.py
dreamtalk_init.py
1 """ 2 DreamTalk Path Resolver 3 4 This module enables the holarchic submodule pattern for DreamTalk symbols. 5 It finds the nearest initialized DreamTalk library by walking up the directory 6 tree, ensuring all code in a symbol holarchy uses the same module instance. 7 8 Usage (at the top of any sovereign symbol's .py file): 9 10 from dreamtalk_init import init 11 init() 12 13 from DreamTalk.imports import * 14 15 Or use the one-liner for standalone scripts: 16 17 import dreamtalk_init; dreamtalk_init.init() 18 from DreamTalk.imports import * 19 """ 20 21 import sys 22 from pathlib import Path 23 24 _initialized = False 25 _dreamtalk_path = None 26 27 28 def find_dreamtalk(start_path=None): 29 """ 30 Walk up the directory tree to find an initialized DreamTalk submodule. 31 32 An initialized DreamTalk is identified by the presence of imports.py 33 (empty submodule pointers won't have this file). 34 35 Args: 36 start_path: Starting directory for search. Defaults to caller's location. 37 38 Returns: 39 Path to the submodules/ directory containing initialized DreamTalk. 40 41 Raises: 42 ImportError: If no initialized DreamTalk is found. 43 """ 44 if start_path is None: 45 # Get the caller's file location 46 import inspect 47 frame = inspect.currentframe() 48 if frame and frame.f_back and frame.f_back.f_back: 49 caller_file = frame.f_back.f_back.f_globals.get('__file__') 50 if caller_file: 51 start_path = Path(caller_file).parent 52 if start_path is None: 53 start_path = Path.cwd() 54 55 current = Path(start_path).resolve() 56 57 while current != current.parent: 58 # Check for DreamTalk in submodules/ 59 candidate = current / "submodules" / "DreamTalk" 60 if (candidate / "imports.py").exists(): 61 return current / "submodules" 62 63 # Also check if we ARE in DreamTalk (for development/testing) 64 if (current / "imports.py").exists() and current.name == "DreamTalk": 65 return current.parent 66 67 current = current.parent 68 69 raise ImportError( 70 "No initialized DreamTalk found in parent hierarchy.\n" 71 "Ensure DreamTalk is added as a submodule and initialized:\n" 72 " git submodule add <dreamtalk-url> submodules/DreamTalk\n" 73 " git submodule update --init submodules/DreamTalk" 74 ) 75 76 77 def init(start_path=None): 78 """ 79 Initialize the Python path to use the nearest DreamTalk. 80 81 This should be called at the top of any sovereign symbol's Python file, 82 before importing from DreamTalk. 83 84 Args: 85 start_path: Starting directory for search. Defaults to caller's location. 86 87 Returns: 88 Path to the DreamTalk directory that was added to sys.path. 89 """ 90 global _initialized, _dreamtalk_path 91 92 if _initialized: 93 return _dreamtalk_path 94 95 submodules_path = find_dreamtalk(start_path) 96 97 # Add to sys.path if not already present 98 submodules_str = str(submodules_path) 99 if submodules_str not in sys.path: 100 sys.path.insert(0, submodules_str) 101 102 _dreamtalk_path = submodules_path / "DreamTalk" 103 _initialized = True 104 105 return _dreamtalk_path 106 107 108 def get_dreamtalk_path(): 109 """ 110 Get the path to the initialized DreamTalk, or None if not yet initialized. 111 """ 112 return _dreamtalk_path 113 114 115 def is_initialized(): 116 """ 117 Check if DreamTalk path resolution has been performed. 118 """ 119 return _initialized