@@ -195,37 +195,38 @@ def _safe_realpath(path):
195195 # unable to retrieve the real program name
196196 _PROJECT_BASE = _safe_realpath (os .getcwd ())
197197
198- if (os .name == 'nt' and
199- _PROJECT_BASE .lower ().endswith (('\\ pcbuild\\ win32' , '\\ pcbuild\\ amd64' ))):
200- _PROJECT_BASE = _safe_realpath (os .path .join (_PROJECT_BASE , pardir , pardir ))
198+ # In a virtual environment, `sys._home` gives us the target directory
199+ # `_PROJECT_BASE` for the executable that created it when the virtual
200+ # python is an actual executable ('venv --copies' or Windows).
201+ _sys_home = getattr (sys , '_home' , None )
202+ if _sys_home :
203+ _PROJECT_BASE = _sys_home
204+
205+ if os .name == 'nt' :
206+ # In a source build, the executable is in a subdirectory of the root
207+ # that we want (<root>\PCbuild\<platname>).
208+ # `_BASE_PREFIX` is used as the base installation is where the source
209+ # will be. The realpath is needed to prevent mount point confusion
210+ # that can occur with just string comparisons.
211+ if _safe_realpath (_PROJECT_BASE ).startswith (
212+ _safe_realpath (f'{ _BASE_PREFIX } \\ PCbuild' )):
213+ _PROJECT_BASE = _BASE_PREFIX
201214
202215# set for cross builds
203216if "_PYTHON_PROJECT_BASE" in os .environ :
204217 _PROJECT_BASE = _safe_realpath (os .environ ["_PYTHON_PROJECT_BASE" ])
205218
206- def _is_python_source_dir (d ):
219+ def is_python_build (check_home = None ):
220+ if check_home is not None :
221+ import warnings
222+ warnings .warn ("check_home argument is deprecated and ignored." ,
223+ DeprecationWarning , stacklevel = 2 )
207224 for fn in ("Setup" , "Setup.local" ):
208- if os .path .isfile (os .path .join (d , "Modules" , fn )):
225+ if os .path .isfile (os .path .join (_PROJECT_BASE , "Modules" , fn )):
209226 return True
210227 return False
211228
212- _sys_home = getattr (sys , '_home' , None )
213-
214- if os .name == 'nt' :
215- def _fix_pcbuild (d ):
216- if d and os .path .normcase (d ).startswith (
217- os .path .normcase (os .path .join (_PREFIX , "PCbuild" ))):
218- return _PREFIX
219- return d
220- _PROJECT_BASE = _fix_pcbuild (_PROJECT_BASE )
221- _sys_home = _fix_pcbuild (_sys_home )
222-
223- def is_python_build (check_home = False ):
224- if check_home and _sys_home :
225- return _is_python_source_dir (_sys_home )
226- return _is_python_source_dir (_PROJECT_BASE )
227-
228- _PYTHON_BUILD = is_python_build (True )
229+ _PYTHON_BUILD = is_python_build ()
229230
230231if _PYTHON_BUILD :
231232 for scheme in ('posix_prefix' , 'posix_home' ):
@@ -442,7 +443,7 @@ def _parse_makefile(filename, vars=None, keep_unresolved=True):
442443def get_makefile_filename ():
443444 """Return the path of the Makefile."""
444445 if _PYTHON_BUILD :
445- return os .path .join (_sys_home or _PROJECT_BASE , "Makefile" )
446+ return os .path .join (_PROJECT_BASE , "Makefile" )
446447 if hasattr (sys , 'abiflags' ):
447448 config_dir_name = f'config-{ _PY_VERSION_SHORT } { sys .abiflags } '
448449 else :
@@ -587,9 +588,9 @@ def get_config_h_filename():
587588 """Return the path of pyconfig.h."""
588589 if _PYTHON_BUILD :
589590 if os .name == "nt" :
590- inc_dir = os .path .join (_sys_home or _PROJECT_BASE , "PC" )
591+ inc_dir = os .path .join (_PROJECT_BASE , "PC" )
591592 else :
592- inc_dir = _sys_home or _PROJECT_BASE
593+ inc_dir = _PROJECT_BASE
593594 else :
594595 inc_dir = get_path ('platinclude' )
595596 return os .path .join (inc_dir , 'pyconfig.h' )
0 commit comments