@@ -92,7 +92,10 @@ def _create_python_info_from_py_launcher(
9292 Create a PythonInfo object from py launcher information.
9393
9494 Args:
95- version: The Python version (e.g. "3.11").
95+ version: The Python version reported by the py launcher (e.g. "3.11").
96+ This is typically only major.minor; the full patch version is
97+ resolved by querying the executable so that searches for a
98+ specific full version (e.g. "3.11.9") succeed.
9699 path: The path to the Python executable.
97100 is_default: "*" if this is the default version, "" otherwise.
98101
@@ -102,14 +105,30 @@ def _create_python_info_from_py_launcher(
102105 if not path or not os .path .exists (path ):
103106 return None
104107
105- # Parse the version
108+ # Parse the version reported by the py launcher (usually major.minor only).
106109 try :
107110 version_data = parse_python_version (version )
108111 except InvalidPythonVersion :
109112 if not self .ignore_unsupported :
110113 raise
111114 return None
112115
116+ # `py --list-paths` only reports major.minor (e.g. "3.11"). Resolve the
117+ # real patch version by querying the executable so that callers searching
118+ # for a full version string like "3.11.9" can match correctly.
119+ if version_data .get ("patch" ) is None :
120+ try :
121+ from ..utils .version_utils import get_python_version
122+
123+ full_version = get_python_version (path )
124+ full_version_data = parse_python_version (full_version )
125+ version_data = full_version_data
126+ version = full_version
127+ except Exception :
128+ # If we can't run the executable, fall back to the major.minor
129+ # version string provided by the py launcher.
130+ pass
131+
113132 # Create the PythonInfo object
114133 return PythonInfo (
115134 path = Path (path ),
0 commit comments