summaryrefslogtreecommitdiff
path: root/setuptools/tests/test_wheelbuilder.py
blob: 046fccc48699fd3f1738418e89bfe95b27e84123 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# This test is based on the `test_wheelfile.py` from pypa/wheel,
# which was initially distributed under the MIT License:
# Copyright (c) 2012 Daniel Holth <dholth@fastmail.fm> and contributors
import stat
import sys
import textwrap
from zipfile import ZipFile, ZIP_DEFLATED

import pytest

from setuptools._wheelbuilder import WheelBuilder


def test_write_str(tmp_path):
    with WheelBuilder(tmp_path / "test-1.0-py3-none-any.whl") as builder:
        builder.new_file("hello/héllö.py", 'print("Héllö, world!")\n')
        builder.new_file("hello/h,ll,.py", 'print("Héllö, world!")\n')

    with ZipFile(tmp_path / "test-1.0-py3-none-any.whl", "r") as zf:
        infolist = zf.infolist()
        assert len(infolist) == 4  # RECORD + WHEEL
        assert infolist[0].filename == "hello/héllö.py"
        assert infolist[0].file_size == 25
        assert infolist[1].filename == "hello/h,ll,.py"
        assert infolist[1].file_size == 25
        assert infolist[2].filename == "test-1.0.dist-info/WHEEL"
        assert infolist[3].filename == "test-1.0.dist-info/RECORD"

        record = "\n".join(
            line
            for line in str(zf.read("test-1.0.dist-info/RECORD"), "utf-8").splitlines()
            if not line.startswith("test-1.0.dist-info/WHEEL")
            # Avoid changes in setuptools versions messing with the test
        )

        expected = """\
        hello/héllö.py,sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25
        "hello/h,ll,.py",sha256=bv-QV3RciQC2v3zL8Uvhd_arp40J5A9xmyubN34OVwo,25
        test-1.0.dist-info/RECORD,,
        """
        assert record.strip() == textwrap.dedent(expected).strip()


def test_timestamp(tmp_path_factory, tmp_path, monkeypatch):
    build_dir = tmp_path_factory.mktemp("build")
    for filename in ("one", "two", "three"):
        (build_dir / filename).write_text(filename + "\n", encoding="utf-8")

    # The earliest date representable in TarInfos, 1980-01-01
    monkeypatch.setenv("SOURCE_DATE_EPOCH", "315576060")

    wheel_path = tmp_path / "test-1.0-py3-none-any.whl"
    with WheelBuilder(wheel_path) as builder:
        builder.add_tree(build_dir)

    with ZipFile(wheel_path, "r") as zf:
        for info in zf.infolist():
            assert info.date_time[:3] == (1980, 1, 1)
            assert info.compress_type == ZIP_DEFLATED


@pytest.mark.skipif(
    sys.platform == "win32", reason="Windows does not support UNIX-like permissions"
)
def test_attributes(tmp_path_factory, tmp_path):
    # With the change from ZipFile.write() to .writestr(), we need to manually
    # set member attributes.
    build_dir = tmp_path_factory.mktemp("build")
    files = (("foo", 0o644), ("bar", 0o755))
    for filename, mode in files:
        path = build_dir / filename
        path.write_text(filename + "\n", encoding="utf-8")
        path.chmod(mode)

    wheel_path = tmp_path / "test-1.0-py3-none-any.whl"
    with WheelBuilder(wheel_path) as builder:
        builder.add_tree(build_dir)

    with ZipFile(wheel_path, "r") as zf:
        for filename, mode in files:
            info = zf.getinfo(filename)
            assert info.external_attr == (mode | stat.S_IFREG) << 16
            assert info.compress_type == ZIP_DEFLATED

        info = zf.getinfo("test-1.0.dist-info/RECORD")
        assert info.external_attr == (0o664 | stat.S_IFREG) << 16