8080 CACHE_FOLDER = os .path .join (USER_FOLDER , ".cache" , "ducktools" , "pythonfinder" )
8181
8282
83- CACHE_VERSION = 1
83+ CACHE_VERSION = 2
8484DETAILS_CACHE_PATH = os .path .join (CACHE_FOLDER , f"runtime_cache_v{ CACHE_VERSION } .json" )
8585INSTALLER_CACHE_PATH = os .path .join (CACHE_FOLDER , "installer_details.json" )
8686
@@ -321,6 +321,7 @@ class PythonInstall(Prefab):
321321 implementation : str = "cpython"
322322 managed_by : str | None = None
323323 metadata : dict = attribute (default_factory = dict )
324+ paths : dict [str , str ] = attribute (default_factory = dict )
324325 shadowed : bool = attribute (default = False , serialize = False )
325326 _implementation_version : tuple [int , int , int , str , int ] | None = attribute (default = None , private = True )
326327
@@ -365,9 +366,13 @@ def from_str(
365366 implementation : str = "cpython" ,
366367 managed_by : str | None = None ,
367368 metadata : dict | None = None ,
369+ paths : dict | None = None ,
368370 ):
369371 version_tuple = version_str_to_tuple (version )
370372
373+ metadata = {} if metadata is None else metadata
374+ paths = {} if paths is None else paths
375+
371376 # noinspection PyArgumentList
372377 return cls (
373378 version = version_tuple ,
@@ -376,6 +381,7 @@ def from_str(
376381 implementation = implementation ,
377382 managed_by = managed_by ,
378383 metadata = metadata ,
384+ paths = paths ,
379385 )
380386
381387 @classmethod
@@ -386,11 +392,14 @@ def from_json(
386392 architecture ,
387393 implementation ,
388394 metadata ,
395+ paths = None ,
389396 managed_by = None ,
390397 ):
391398 if arch_ver := metadata .get (f"{ implementation } _version" ):
392399 metadata [f"{ implementation } _version" ] = tuple (arch_ver )
393400
401+ paths = {} if paths is None else paths
402+
394403 # noinspection PyArgumentList
395404 return cls (
396405 version = tuple (version ), # type: ignore
@@ -399,6 +408,7 @@ def from_json(
399408 implementation = implementation ,
400409 managed_by = managed_by ,
401410 metadata = metadata ,
411+ paths = paths ,
402412 )
403413
404414 def get_pip_version (self ) -> str | None :
@@ -430,14 +440,16 @@ def _python_exe_regex(basename: str = "python"):
430440
431441def get_folder_pythons (
432442 base_folder : str | os .PathLike ,
433- basenames : tuple [str ] = ("python" , "pypy" ),
443+ basenames : tuple [str , ... ] = ("python" , "pypy" , "micropython " ),
434444 finder : DetailFinder | None = None ,
435445 managed_by : str | None = None ,
436446):
437447 regexes = [_python_exe_regex (name ) for name in basenames ]
438448
439449 finder = DetailFinder () if finder is None else finder
440450
451+ base_folder = str (base_folder )
452+
441453 with finder , os .scandir (base_folder ) as fld :
442454 for file_path in fld :
443455 try :
@@ -452,11 +464,13 @@ def get_folder_pythons(
452464 p = file_path .path
453465 if file_path .is_symlink ():
454466 # Might be a venv - look for pyvenv.cfg in parent
455- fld = os .path .dirname (p )
456- if os .path .exists (os .path .join (fld , "../pyvenv.cfg" )):
467+ dirname = os .path .dirname (p )
468+
469+ if os .path .exists (os .path .join (dirname , "../pyvenv.cfg" )):
457470 continue
458471 else :
459472 p = file_path .path
473+
460474 install = finder .get_install_details (p , managed_by = managed_by )
461475 if install :
462476 yield install
0 commit comments