Test Python 3.15#853
Conversation
|
Thanks @hugovk! Quick question: did an existing test case for symlinks fail for you on Windows py3.15? |
|
Yes, you can see it here: ________________________________ test_symlinks ________________________________
tmp_path = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/test_symlinks0')
sdist_symlinks = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/test0/mesonpy-test-hklax70z/symlinks-1.0.0.tar.gz')
@pytest.mark.skipif(sys.version_info >= (3, 14) and MESON_VERSION < (1, 9, 2), reason='incompatible Python version')
@pytest.mark.filterwarnings('ignore:symbolic link')
def test_symlinks(tmp_path, sdist_symlinks):
with tarfile.open(sdist_symlinks, 'r:gz') as sdist:
names = {member.name for member in sdist.getmembers()}
mtimes = {member.mtime for member in sdist.getmembers()}
# Check that the symlinks `baz.py` and `qux.py` pointing outside the
# source tree are not included. These files are present in the
# meson-python git repository but cannot be included in the meson-python
# sdist. Thus this test is effective only when run from a git checkout.
> assert names == {
'symlinks-1.0.0/PKG-INFO',
'symlinks-1.0.0/meson.build',
'symlinks-1.0.0/pyproject.toml',
'symlinks-1.0.0/__init__.py',
'symlinks-1.0.0/submodule/__init__.py',
'symlinks-1.0.0/submodule/aaa.py',
'symlinks-1.0.0/submodule/bbb.py',
}
E AssertionError: assert {'symlinks-1.0.0/meson.build', 'symlinks-1.0.0/PKG-INFO', 'symlinks-1.0.0/submodule/bbb.py', 'symlinks-1.0.0/__init__.py', 'symlinks-1.0.0/submodule/aaa.py', 'symlinks-1.0.0/pyproject.toml'} == {'symlinks-1.0.0/submodule/aaa.py', 'symlinks-1.0.0/pyproject.toml', 'symlinks-1.0.0/meson.build', 'symlinks-1.0.0/PKG-INFO', 'symlinks-1.0.0/submodule/bbb.py', 'symlinks-1.0.0/submodule/__init__.py', 'symlinks-1.0.0/__init__.py'}
E
E Extra items in the right set:
E 'symlinks-1.0.0/submodule/__init__.py'
E
E Full diff:
E {
E 'symlinks-1.0.0/PKG-INFO',
E 'symlinks-1.0.0/__init__.py',
E 'symlinks-1.0.0/meson.build',
E 'symlinks-1.0.0/pyproject.toml',
E - 'symlinks-1.0.0/submodule/__init__.py',
E 'symlinks-1.0.0/submodule/aaa.py',
E 'symlinks-1.0.0/submodule/bbb.py',
E }
mtimes = {1781692825.0}
names = {'symlinks-1.0.0/PKG-INFO',
'symlinks-1.0.0/__init__.py',
'symlinks-1.0.0/meson.build',
'symlinks-1.0.0/pyproject.toml',
'symlinks-1.0.0/submodule/aaa.py',
'symlinks-1.0.0/submodule/bbb.py'}
sdist = <tarfile.TarFile object at 0x000002857D733410>
sdist_symlinks = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/test0/mesonpy-test-hklax70z/symlinks-1.0.0.tar.gz')
tmp_path = WindowsPath('C:/Users/runneradmin/AppData/Local/Temp/pytest-of-runneradmin/pytest-0/test_symlinks0')
tests\test_sdist.py:235: AssertionError
---------------------------- Captured stdout setup ----------------------------
Initialized empty Git repository in D:/a/meson-python/meson-python/tests/packages/symlinks/.git/
+ meson setup D:\a\meson-python\meson-python\tests\packages\symlinks D:\a\meson-python\meson-python\tests\packages\symlinks\.mesonpy-3wrsh3w8 -Dbuildtype=release -Db_ndebug=if-release -Db_vscrt=md --fatal-meson-warnings --native-file=D:\a\meson-python\meson-python\tests\packages\symlinks\.mesonpy-3wrsh3w8\meson-python-native-file.ini
The Meson build system
Version: 1.11.1
Source dir: D:\a\meson-python\meson-python\tests\packages\symlinks
Build dir: D:\a\meson-python\meson-python\tests\packages\symlinks\.mesonpy-3wrsh3w8
Build type: native build
Project name: symlinks
Project version: undefined
Host machine cpu family: x86_64
Host machine cpu: x86_64
Program python found: YES (C:\hostedtoolcache\windows\Python\3.15.0-beta.2\x64\python.exe)
Build targets in project: 0
symlinks undefined
User defined options
Native files: D:\a\meson-python\meson-python\tests\packages\symlinks\.mesonpy-3wrsh3w8\meson-python-native-file.ini
b_ndebug : if-release
b_vscrt : md
buildtype : release
Found ninja.EXE-1.13.0.git.kitware.jobserver-pipe-1 at C:\hostedtoolcache\windows\Python\3.15.0-beta.2\x64\Scripts\ninja.EXE
+ meson dist --allow-dirty --no-tests --formats gztar
Created D:\a\meson-python\meson-python\tests\packages\symlinks\.mesonpy-3wrsh3w8\meson-dist\symlinks-undefined.tar.gzhttps://github.com/hugovk/meson-python/actions/runs/27682956779/job/81874680435 (I had to "hack" my feature branch name as |
| name = member.name | ||
| target = posixpath.normpath(posixpath.join(posixpath.dirname(member.name), member.linkname)) | ||
| # Normalize the link target to use forward slashes. On | ||
| # Windows on Python 3.15 rewrites slashes to backslashes in |
There was a problem hiding this comment.
| # Windows on Python 3.15 rewrites slashes to backslashes in | |
| # Windows, Python 3.15 rewrites slashes to backslashes in |
| # CPython gh-57911), and Meson propagates these backslashed | ||
| # targets into the dist tarball. Without this normalization |
There was a problem hiding this comment.
I don't understand what this sentence means. I understand that Python forces \ as path separator on Windows when reading a tar archive. What does it mean that Meson "propagates these backward slashed targets into the dist tarball"? Python would return link targets using the\ path separator regardless. Also, AFAIK the only path separator for tar archives is /. Are you saying that Python 3.15 converts / to \ when reading a tar archive on Windows, but it does not do the opposite when writing it? This would be a bug in CPython.
There was a problem hiding this comment.
I really don't understand the rationale in changing the path separator on Windows for link targets but not for regular file paths.
There was a problem hiding this comment.
This python/cpython@c1a9c23 seems the commit that should have changed the behavior of the tarfile`` module. However, there only tarfile.TarFile.extractis modified to change the path separators. Here we don't useextract()butgetmembers()` thus I don't understand where the back slashes would be coming from.
| # targets into the dist tarball. Without this normalization | ||
| # the ``posixpath`` resolution below would fail to match the | ||
| # link target, dropping links that point inside the archive. | ||
| linkname = member.linkname.replace('\\', '/') |
There was a problem hiding this comment.
\ is a valid filename character on Unix systems. The replace cannot be done unconditionally.
Python 3.15 is now in beta, so it's time to start testing:
https://discuss.python.org/t/python-3-15-0-beta-2-is-here/107610
This is especially important for foundational projects such as meson-python, so libraries know they can use it for their own 3.15 testing.
Also bump GitHub Actions.