pypa / distutils

distutils as found in cpython

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

test_home_installation_scheme fails on Python 3.11 on Windows

jaraco opened this issue · comments

  tox
  shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"
  env:
    pythonLocation: C:\hostedtoolcache\windows\Python\3.11.0-beta.3\x64
python create: D:\a\distutils\distutils\.tox\python
python installdeps: pytest, jaraco.envs>=2.4
python installed: atomicwrites==1.4.0,attrs==21.4.0,colorama==0.4.4,distlib==0.3.4,filelock==3.7.1,iniconfig==1.1.1,jaraco.envs==2.4.0,packaging==21.3,path==16.4.0,platformdirs==2.5.2,pluggy==1.0.0,py==1.11.0,pyparsing==3.0.9,pytest==7.1.2,six==1.16.0,toml==0.10.2,tomli==2.0.1,tox==3.25.0,virtualenv==20.14.1
python run-test-pre: PYTHONHASHSEED='249'
python run-test: commands[0] | pytest
============================= test session starts =============================
platform win32 -- Python 3.11.0b3, pytest-7.1.2, pluggy-1.0.0
cachedir: .tox\python\.pytest_cache
rootdir: D:\a\distutils\distutils, configfile: pytest.ini
collected 306 items
distutils\_collections.py .                                              [  0%]
distutils\_functools.py .                                                [  0%]
distutils\unixccompiler.py ...                                           [  1%]
distutils\versionpredicate.py ..                                         [  2%]
distutils\command\sdist.py .                                             [  2%]
distutils\tests\test_archive_util.py .s...............s..                [  9%]
distutils\tests\test_bdist.py ...                                        [ 10%]
distutils\tests\test_bdist_dumb.py ..                                    [ 10%]
distutils\tests\test_bdist_msi.py ..                                     [ 11%]
distutils\tests\test_bdist_rpm.py ss.                                    [ 12%]
distutils\tests\test_bdist_wininst.py ..                                 [ 13%]
distutils\tests\test_build.py ..                                         [ 13%]
distutils\tests\test_build_clib.py ....s.                                [ 15%]
distutils\tests\test_build_ext.py s..sss........s..sss.........          [ 25%]
distutils\tests\test_build_py.py .......                                 [ 27%]
distutils\tests\test_build_scripts.py ....                               [ 28%]
distutils\tests\test_check.py ..s.ss.                                    [ 31%]
distutils\tests\test_clean.py ..                                         [ 31%]
distutils\tests\test_cmd.py ........                                     [ 34%]
distutils\tests\test_config.py ....                                      [ 35%]
distutils\tests\test_config_cmd.py ...s.                                 [ 37%]
distutils\tests\test_core.py ........                                    [ 39%]
distutils\tests\test_cygwinccompiler.py .s..                             [ 41%]
distutils\tests\test_dep_util.py ....                                    [ 42%]
distutils\tests\test_dir_util.py ......s.                                [ 45%]
distutils\tests\test_dist.py ........s......................             [ 55%]
distutils\tests\test_extension.py ...                                    [ 56%]
distutils\tests\test_file_util.py ......                                 [ 58%]
distutils\tests\test_filelist.py ..............                          [ 62%]
distutils\tests\test_install.py ...F.s..                                 [ 65%]
distutils\tests\test_install_data.py ..                                  [ 66%]
distutils\tests\test_install_headers.py ..                               [ 66%]
distutils\tests\test_install_lib.py ......                               [ 68%]
distutils\tests\test_install_scripts.py ...                              [ 69%]
distutils\tests\test_log.py ..                                           [ 70%]
distutils\tests\test_msvc9compiler.py .....                              [ 71%]
distutils\tests\test_msvccompiler.py s......                             [ 74%]
distutils\tests\test_register.py .....s..s.                              [ 77%]
distutils\tests\test_sdist.py ........s.......                           [ 82%]
distutils\tests\test_spawn.py ....                                       [ 83%]
distutils\tests\test_sysconfig.py .s...s....s...s..                      [ 89%]
distutils\tests\test_text_file.py ..                                     [ 90%]
distutils\tests\test_unixccompiler.py sss.s.                             [ 92%]
distutils\tests\test_upload.py .......                                   [ 94%]
distutils\tests\test_util.py ..s.........                                [ 98%]
distutils\tests\test_version.py ....                                     [ 99%]
distutils\tests\test_versionpredicate.py .                               [100%]
================================== FAILURES ===================================
________________ InstallTestCase.test_home_installation_scheme ________________
self = <distutils.tests.test_install.InstallTestCase testMethod=test_home_installation_scheme>
    def test_home_installation_scheme(self):
        # This ensure two things:
        # - that --home generates the desired set of directory names
        # - test --home is supported on all platforms
        builddir = self.mkdtemp()
        destination = os.path.join(builddir, "installation")
        dist = Distribution({"name": "foopkg"})
        # script_name need not exist, it just need to be initialized
        dist.script_name = os.path.join(builddir, "setup.py")
        dist.command_obj["build"] = support.DummyCommand(
            build_base=builddir,
            build_lib=os.path.join(builddir, "lib"),
            )
        cmd = install(dist)
        cmd.home = destination
        cmd.ensure_finalized()
        self.assertEqual(cmd.install_base, destination)
        self.assertEqual(cmd.install_platbase, destination)
        def check_path(got, expected):
            got = os.path.normpath(got)
            expected = os.path.normpath(expected)
            self.assertEqual(got, expected)
        impl_name = sys.implementation.name.replace("cpython", "python")
        libdir = os.path.join(destination, "lib", impl_name)
        check_path(cmd.install_lib, libdir)
        _platlibdir = getattr(sys, "platlibdir", "lib")
        platlibdir = os.path.join(destination, _platlibdir, impl_name)
>       check_path(cmd.install_platlib, platlibdir)
distutils\tests\test_install.py:64: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
distutils\tests\test_install.py:57: in check_path
    self.assertEqual(got, expected)
E   AssertionError: 'C:\\[16 chars]\AppData\\Local\\Temp\\tmpv2abfuj4\\installation\\lib\\python' != 'C:\\[16 chars]\AppData\\Local\\Temp\\tmpv2abfuj4\\installation\\DLLs\\python'
E   - C:\Users\RUNNER~1\AppData\Local\Temp\tmpv2abfuj4\installation\lib\python
E   ?                                                               ^^^
E   + C:\Users\RUNNER~1\AppData\Local\Temp\tmpv2abfuj4\installation\DLLs\python
E   ?                                                               ^^^^
============================== warnings summary ===============================
distutils\command\bdist_msi.py:19
  D:\a\distutils\distutils\distutils\command\bdist_msi.py:19: DeprecationWarning: 'msilib' is deprecated and slated for removal in Python 3.13
    import msilib
distutils/tests/test_bdist.py::BuildTestCase::test_skip_build
  D:\a\distutils\distutils\distutils\dist.py:859: DeprecationWarning: bdist_msi command is deprecated since Python 3.9, use bdist_wheel (wheel packages) instead
bj = self.command_obj[command] = klass(self)
distutils/tests/test_register.py::RegisterTestCase::test_create_pypirc
  D:\a\distutils\distutils\distutils\config.py:114: DeprecationWarning: 'cgi' is deprecated and slated for removal in Python 3.13
    import cgi
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ===========================
FAILED distutils/tests/test_install.py::InstallTestCase::test_home_installation_scheme
====== 1 failed, 271 passed, 34 skipped, 3 warnings in 92.06s (0:01:32) =======
ERROR: InvocationError for command 'D:\a\distutils\distutils\.tox\python\Scripts\pytest.EXE' (exited with code 1)
___________________________________ summary ___________________________________
ERROR:   python: commands failed

When I inspect Python 3.11.0b1 on my local machine, I do see that platlibdir is DLLs... so I don't understand why the test fails.

PS C:\Users\jaraco> py -3.11
Python 3.11.0b1 (main, May  7 2022, 22:42:44) [MSC v.1931 64 bit (ARM64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sysconfig
>>> import sys
>>> sys.platlibdir
'DLLs'
>>> sysconfig.get_config_var('platlibdir')
'DLLs'

Aha. So it seems the value of sys.platlibdir has changed in Python 3.11:

PS C:\Users\jaraco> py -3.10 -c "import sys; print(sys.platlibdir)"
lib
PS C:\Users\jaraco> py -3.11 -c "import sys; print(sys.platlibdir)"
DLLs

But the install scheme used is posix_home, and that install scheme indicates "lib" in the path:

>>>  sysconfig._INSTALL_SCHEMES['posix_home']['platlib']
'{base}/lib/python'

So the assumption that previously held which was that the install scheme included platlibdir only held when platlibdir was "lib".

@zooba Can you help here? In particular, why has platlibdir changed on Windows in Python 3.11, and what does that imply for 'home' dir installs? Should Python get a platlibdir in the install scheme as seen in distutils? Maybe distutils should stop expecting platlibdir to appear? Or does sysconfig/distutils need yet another scheme for nt_home?

platlibdir was meaningless on Windows before, but its meaning everywhere else was "where is the platform-specific stdlib kept". Since we now only have a single codepath for initialising everything, the more we can align the definitions of constants, the less we need to use platform-specific quirks (in getpath.py).

The POSIX schemes on Windows don't use sys.platlibdir anymore, because it was never correct anyway (and isn't ever correct unless you're on the specific machine you want the scheme for - you can't request it from a different machine).

I'm not actually sure what this option is trying to achieve here, but I suspect you just need to define an nt_home scheme and probably copy it from the regular nt scheme?

I'm also unsure what finalize_other is meant to do here. I wonder if anybody even cares about the _home install scheme on Windows. I would think not, because the scheme includes unixisms like bin instead of Scripts. I'm a little reluctant to create schemes for use cases that are unwanted, especially since I want Python to own the install schemes and not distutils.

Are you expecting that in Python 3.11, platform-specific libraries will begin to be installed to $base/DLLs/site-packages instead of $base/Lib/site-packages?

Nevermind - I see that the default schemes still use Lib, so it's only these --home schemes that are affected.

Maybe the best thing to do is just leave this test to xfail until we can figure out if home has any meaning on non-posix systems.