@@ -104,7 +104,20 @@ def _extract_bundled_template(zip_name: str, destination: str) -> None:
104104 Extract a bundled template zip into the destination directory.
105105 Tries package resources first; falls back to repo root `templates/` at dev time.
106106 """
107- # Try to load from installed package resources first (if templates are packaged inside the module)
107+ # Dev-first: prefer repository templates if running from a checkout (avoid stale packaged zips)
108+ try :
109+ # __file__ -> src/pythonnative/cli/pn.py, so go up to src/, then to repo root
110+ src_dir = os .path .dirname (os .path .dirname (os .path .dirname (__file__ )))
111+ repo_root = os .path .abspath (os .path .join (src_dir , ".." ))
112+ repo_templates = os .path .join (repo_root , "templates" )
113+ candidate = os .path .join (repo_templates , zip_name )
114+ if os .path .exists (candidate ):
115+ _extract_zip_to_destination (candidate , destination )
116+ return
117+ except Exception :
118+ pass
119+
120+ # Try to load from installed package resources next (if templates are packaged inside the module)
108121 try :
109122 cand = resources .files ("pythonnative" ).joinpath ("templates" ).joinpath (zip_name )
110123 with resources .as_file (cand ) as p :
@@ -139,14 +152,6 @@ def _extract_bundled_template(zip_name: str, destination: str) -> None:
139152 except Exception :
140153 pass
141154
142- # Fallback: use repository-level templates directory
143- repo_templates = os .path .join (os .path .dirname (os .path .dirname (os .path .dirname (__file__ ))), ".." , ".." , "templates" )
144- repo_templates = os .path .abspath (repo_templates )
145- candidate = os .path .join (repo_templates , zip_name )
146- if os .path .exists (candidate ):
147- _extract_zip_to_destination (candidate , destination )
148- return
149-
150155 raise FileNotFoundError (f"Could not find bundled template { zip_name } . Ensure templates are packaged." )
151156
152157
@@ -206,6 +211,25 @@ def run_project(args: argparse.Namespace) -> None:
206211 os .makedirs (dest_dir , exist_ok = True )
207212 shutil .copytree (src_dir , dest_dir , dirs_exist_ok = True )
208213
214+ # During local development (running from repository), also bundle the
215+ # local library sources so the app uses the in-repo version instead of
216+ # the PyPI package. This provides faster inner-loop iteration and avoids
217+ # version skew during development.
218+ try :
219+ # __file__ -> src/pythonnative/cli/pn.py, so repo root is one up from src/
220+ src_root = os .path .abspath (os .path .join (os .path .dirname (os .path .dirname (__file__ )), ".." ))
221+ local_lib = os .path .join (src_root , "pythonnative" )
222+ if os .path .isdir (local_lib ):
223+ if platform == "android" :
224+ python_root = os .path .join (build_dir , "android_template" , "app" , "src" , "main" , "python" )
225+ else :
226+ python_root = os .path .join (build_dir ) # staged at build/ios/app for iOS below
227+ os .makedirs (python_root , exist_ok = True )
228+ shutil .copytree (local_lib , os .path .join (python_root , "pythonnative" ), dirs_exist_ok = True )
229+ except Exception :
230+ # Non-fatal; fallback to the packaged PyPI dependency if present
231+ pass
232+
209233 # Install any necessary Python packages into the project environment
210234 # Skip installation during prepare-only to avoid network access and speed up scaffolding
211235 if not prepare_only :
@@ -291,6 +315,11 @@ def run_project(args: argparse.Namespace) -> None:
291315 staged_app_src = os .path .join (build_dir , "app" )
292316 if os .path .isdir (staged_app_src ):
293317 shutil .copytree (staged_app_src , os .path .join (app_path , "app" ), dirs_exist_ok = True )
318+ # Also copy local library sources if present for dev flow
319+ src_root = os .path .abspath (os .path .join (os .path .dirname (os .path .dirname (__file__ )), ".." ))
320+ local_lib = os .path .join (src_root , "pythonnative" )
321+ if os .path .isdir (local_lib ):
322+ shutil .copytree (local_lib , os .path .join (app_path , "pythonnative" ), dirs_exist_ok = True )
294323 except Exception :
295324 # Non-fatal; fallback UI will appear if import fails
296325 pass
0 commit comments