Full Code of ziglang/zig-pypi for AI

main b28791143121 cached
6 files
26.5 KB
7.0k tokens
11 symbols
1 requests
Download .txt
Repository: ziglang/zig-pypi
Branch: main
Commit: b28791143121
Files: 6
Total size: 26.5 KB

Directory structure:
gitextract_pfxqcxh1/

├── .github/
│   └── workflows/
│       └── cd.yml
├── .gitignore
├── LICENSE.txt
├── README.md
├── README.pypi.md
└── make_wheels.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/cd.yml
================================================
name: CD

on:
  workflow_dispatch:
    inputs:
      version:
        description: "The version to build Zig wheels for, use 'latest' for latest release, 'master' for nightly builds"
        required: true
        default: "latest"
      suffix:
        description: >
          Suffix to append to the version in the wheel filename, i.e., for dev versions and version specifiers
        required: false
        default: ""
      platforms:
        description: >
          Comma-separated list of specific platforms to build wheels for, or use 'all' to build for all supported platforms
        required: false
        default: "all"
      push_to_pypi:
        description: >
          Whether to push the built wheels to PyPI. Can be 'true' or 'false', defaults to 'false'.
        required: true
        default: "false"

permissions: {}

jobs:
  build_wheels:
    name: Build wheels
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
        with:
          persist-credentials: false
      - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
        with:
          python-version: "3.x"

      - uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1

      - name: Build wheels for all requested platforms
        shell: bash
        env:
          GITHUB_EVENT_INPUTS_PLATFORMS: ${{ github.event.inputs.platforms }}
          GITHUB_EVENT_INPUTS_VERSION: ${{ github.event.inputs.version }}
          GITHUB_EVENT_INPUTS_SUFFIX: ${{ github.event.inputs.suffix }}
        run: |
          platforms=${GITHUB_EVENT_INPUTS_PLATFORMS}
          IFS=',' read -r -a platform_array <<< "$platforms"
          for platform in "${platform_array[@]}"; do
            cmd="uv run make_wheels.py --outdir dist/ --version ${GITHUB_EVENT_INPUTS_VERSION} --platform $platform"
            if [ -n "${GITHUB_EVENT_INPUTS_SUFFIX}" ]; then
              cmd="$cmd --suffix ${GITHUB_EVENT_INPUTS_SUFFIX}"
            fi
            eval "$cmd"
          done

      - name: Upload wheel artifacts
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: zig_wheels
          path: dist/*.whl
          if-no-files-found: error

  deploy_wheels:
    name: Deploy wheels
    needs: [build_wheels]
    if: >-
      github.event.inputs.push_to_pypi == 'true' &&
      github.repository == 'ziglang/zig-pypi'
    environment: pypi
    runs-on: ubuntu-latest
    permissions:
      id-token: write # for OIDC trusted publishing
      attestations: write # for the GitHub Actions Attestations feature
      contents: read
    steps:
      - name: Download all wheel artifacts
        uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
        with:
          path: dist/
          merge-multiple: true

      - name: Sanity check wheel artifacts
        run: ls -R dist/

      - name: Generate artifact attestations
        uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
        with:
          subject-path: dist/*

      # This will publish the list of wheels inputted to the action to PyPI (set to
      # off, by default).
      # The workflow may be triggered multiple times with the `push_to_pypi` input
      # set to 'true' to publish the wheels for any configurable version (non-dev).
      - name: Publish wheels to PyPI
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
        with:
          packages-dir: dist/

  inspect_wheels:
    name: Inspect wheels
    needs: [build_wheels]
    runs-on: ubuntu-latest
    steps:
      - name: Download all built wheel artifacts
        uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
        with:
          path: dist/
          merge-multiple: true

      - name: Inspect wheel artifacts
        shell: bash
        run: |
          echo -e '## A list of built wheels and their SHA-256 checksums \n' >> $GITHUB_STEP_SUMMARY
          echo -e '```\n' >> $GITHUB_STEP_SUMMARY
          for wheel in dist/*.whl; do
            shasum --algorithm 256 "$wheel" >> $GITHUB_STEP_SUMMARY
          done
          echo -e '```\n' >> $GITHUB_STEP_SUMMARY


================================================
FILE: .gitignore
================================================
# Python
__pycache__/
*.egg-info
/dist
*.whl

# pdm
/.pdm-plugins
/.pdm-python
/.venv
/pdm.lock


================================================
FILE: LICENSE.txt
================================================
The MIT License (Expat)

Copyright (c) 2021, whitequark <whitequark@whitequark.org>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: README.md
================================================
Zig PyPI distribution
=====================

This repository contains the script used to repackage the [releases][zigdl] of the [Zig programming language][zig] as [Python binary wheels][wheel]. This document is intended for maintainers; see the [package README][pkgreadme] for rationale and usage instructions.

The repackaged artifacts are published as the [ziglang PyPI package][pypi].

[zig]: https://ziglang.org/
[zigdl]: https://ziglang.org/download/
[wheel]: https://github.com/pypa/wheel
[pkgreadme]: README.pypi.md
[pypi]: https://pypi.org/project/ziglang/

Preparation
-----------

The script requires Python 3.9 and later and a [PEP 723][pep723] compatible script
runner, such as [`pipx`][pipx], [`pdm`][pdm], [`hatch`][hatch], [`uv`][uv], or
similar. Please refer to their documentation for installation instructions.

[pep723]: https://peps.python.org/pep-0723/
[pipx]: https://pipx.pypa.io/stable/examples/#pipx-run-examples
[pdm]: https://pdm-project.org/en/latest/usage/scripts/#single-file-scripts
[hatch]: https://hatch.pypa.io/latest/blog/2024/05/02/hatch-v1100/#python-script-runner/
[uv]: https://docs.astral.sh/uv/#script-support/

Building wheels
---------------

Run the repackaging script. Here's an example invocation with [`pdm`][pdm]:

```shell
$ pdm run make_wheels.py --help
usage: make_wheels.py [-h] [--version VERSION] [--suffix SUFFIX] [--outdir OUTDIR]
                                                  [--platform {x86_64-windows,x86_64-macos,aarch64-macos,i386-linux,x86-linux,x86_64-linux,aarch64-linux,armv7a-linux}]

Repackage official Zig downloads as Python wheels

options:
  -h, --help            show this help message and exit
  --version VERSION     version to package, use `latest` for latest release, `master` for nightly build
  --suffix SUFFIX       wheel version suffix
  --outdir OUTDIR       target directory
  --platform {x86_64-windows,x86_64-macos,aarch64-macos,i386-linux,x86-linux,x86_64-linux,aarch64-linux,armv7a-linux}
                        platform to build for, can be repeated
```

This command will download the Zig release archives for every supported platform and convert them to binary wheels, which are placed under `dist/`. The Zig version and platforms can be passed as arguments.

The process of converting release archives to binary wheels is deterministic, and the output of the script should be bit-for-bit identical regardless of the environment and platform it runs under. To this end, it prints the SHA256 hashes of inputs and outputs; the hashes of the inputs will match the ones on the [Zig downloads page][zigdl], and the hashes of the outputs will match the ones on the [PyPI downloads page][pypidl].

[pypidl]: https://pypi.org/project/ziglang/#files

Uploading wheels to PyPI
------------------------

Trigger the publishing workflow from this repository manually (requires authorization)
with the necessary inputs as mentioned in the [workflow file](.github/workflows/cd.yml)
or in the GitHub Actions UI. The wheels are checked with `twine` before they are uploaded.

The workflow will upload the wheels to PyPI to make them available for installation. It
is possible to trigger it multiple times to upload wheels for different versions or
platforms.

Verifying the provenance of wheels uploaded to PyPI
---------------------------------------------------

To establish build provenance, the workflow generates attestations for the uploaded wheels
using the [GitHub Actions Attestations feature](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)
when it is run. Please navigate to the [Attestations interface](https://github.com/ziglang/zig-pypi/attestations)
to view the attestations for the uploaded wheels.

The attestations may be verified via the [GitHub (`gh`) CLI](https://cli.github.com/manual/gh_attestation_verify)
or via the [GitHub API](https://docs.github.com/en/rest/users/attestations).

License
-------

This script is distributed under the terms of the [MIT (Expat) license](LICENSE.txt).

Please refer to the [Zig license](https://ziglang.org/download/#license) for the terms
of use of the Zig programming language itself, or look in the `.dist-info/licenses/`
directory of the built wheels for individual licenses of the bundled components.


================================================
FILE: README.pypi.md
================================================
Zig PyPI distribution
=====================

[Zig][] is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software. The [ziglang][pypi] Python package redistributes the Zig toolchain so that it can be used as a dependency of Python projects.

[zig]: https://ziglang.org/
[pypi]: https://pypi.org/project/ziglang/

Rationale
---------

Although Zig is useful in itself, the Zig toolchain includes a drop-in C and C++ compiler, [`zig cc`][zigcc], based on [clang][]. Unlike clang itself, `zig cc` is standalone: it does not require additional development files to be installed to target any of the platforms it supports. Through `zig cc`, Python code that generates C or C++ code can build it without any external dependencies.

[clang]: https://clang.llvm.org/
[zigcc]: https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html

Usage
-----

To run the Zig toolchain from the command line, use:

```shell
python -m ziglang
```

To run the Zig toolchain from a Python program, use `sys.executable` to locate the Python binary to invoke. For example:

```python
import sys, subprocess

subprocess.call([sys.executable, "-m", "ziglang"])
```

Binary wrapper
--------------

The [ziglang][pypi] Python package installs a binary wrapper for the Zig compiler under the name `python-zig`; the name is different to avoid conflicts with any system-wide or user-wide `zig` binaries that may be already installed.


Using with `uv`
---------------

The Zig compiler distributed in this Python package can be launched by [uv](https://docs.astral.sh/uv) without installation:

```shell
uvx --from ziglang python-zig
```

License
-------

The [Zig license](https://github.com/ziglang/zig#license).


================================================
FILE: make_wheels.py
================================================
# /// script
# requires-python = "~=3.9"
# dependencies = [
#   "wheel~=0.41.0",
# ]
# ///

# Additionally, install twine to upload the wheels to PyPI.

import argparse
import logging
import io
import os
import re
import json
import hashlib
import tarfile
import urllib.request
from pathlib import Path, PurePath
from email.policy import EmailPolicy
from email.message import EmailMessage
from wheel.wheelfile import WheelFile
from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED


ZIG_VERSION_INFO_URL = 'https://ziglang.org/download/index.json'
ZIG_PYTHON_PLATFORMS = {
    'x86_64-windows': 'win_amd64',
    'aarch64-windows': 'win_arm64',
    'x86-windows':    'win32',
    'x86_64-macos':   'macosx_12_0_x86_64',
    'aarch64-macos':  'macosx_12_0_arm64',
    'i386-linux':     'manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686',
    # renamed i386 to x86 since v0.11.0, i386 was last supported in v0.10.1
    'x86-linux':      'manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686',
    'x86_64-linux':   'manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64',
    'aarch64-linux':
        'manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64',
    'armv7a-linux':   'manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l',
    # renamed armv7a to arm since v0.15.1, armv7a was last supported in v0.14.1
    'arm-linux':      'manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l',
    'powerpc64le-linux':  'manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le',
    's390x-linux':     'manylinux_2_17_s390x.manylinux2014_s390x.musllinux_1_1_s390x',
    'riscv64-linux':   'manylinux_2_31_riscv64.musllinux_1_1_riscv64',
}

_YELLOW = "\033[93m"


class ReproducibleWheelFile(WheelFile):
    def writestr(self, zinfo_or_arcname, data, *args, **kwargs):
        if isinstance(zinfo_or_arcname, ZipInfo):
            zinfo = zinfo_or_arcname
        else:
            assert isinstance(zinfo_or_arcname, str)
            zinfo = ZipInfo(zinfo_or_arcname)
            zinfo.file_size = len(data)
            zinfo.external_attr = 0o0644 << 16
            if zinfo_or_arcname.endswith(".dist-info/RECORD"):
                zinfo.external_attr = 0o0664 << 16

        zinfo.compress_type = ZIP_DEFLATED
        zinfo.date_time = (1980,1,1,0,0,0)
        zinfo.create_system = 3
        super().writestr(zinfo, data, *args, **kwargs)


def make_message(headers, payload=None):
    msg = EmailMessage(policy=EmailPolicy(max_line_length=0))
    for name, value in headers:
        if isinstance(value, list):
            for value_part in value:
                msg[name] = value_part
        else:
            msg[name] = value
    if payload:
        msg.set_payload(payload)
    return msg


def write_wheel_file(filename, contents):
    with ReproducibleWheelFile(filename, 'w') as wheel:
        for member_info, member_source in contents.items():
            wheel.writestr(member_info, bytes(member_source))
    return filename


def write_wheel(out_dir, *, name, version, tag, metadata, description, contents):
    wheel_name = f'{name}-{version}-{tag}.whl'
    dist_info  = f'{name}-{version}.dist-info'
    filtered_metadata = []
    for header, value in metadata:
        filtered_metadata.append((header, value))

    # The WHEEL file must contain the compatibility tags in their expanded form.
    # see https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-contents
    # see https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#compressed-tag-sets
    pytag, abitag, platformtag = tag.split("-")
    expanded_tags = [
        "-".join((x, y, z))
        for z in platformtag.split(".")
        for y in abitag.split(".")
        for x in pytag.split(".")
    ]

    return write_wheel_file(os.path.join(out_dir, wheel_name), {
        **contents,
        f'{dist_info}/entry_points.txt': make_message([],
            '[console_scripts]\npython-zig = ziglang.__main__:dummy'
        ),
        f'{dist_info}/METADATA': make_message([
            ('Metadata-Version', '2.4'),
            ('Name', name),
            ('Version', version),
            *filtered_metadata,
        ], description),
        f'{dist_info}/WHEEL': make_message([
            ('Wheel-Version', '1.0'),
            ('Generator', 'ziglang make_wheels.py'),
            ('Root-Is-Purelib', 'false'),
            ('Tag', expanded_tags),
        ]),
    })


def iter_archive_contents(archive):
    magic = archive[:4]
    if magic[:4] == b"\xfd7zX":
        with tarfile.open(mode="r|xz", fileobj=io.BytesIO(archive)) as tar:
            for entry in tar:
                if entry.isreg():
                    yield entry.name, entry.mode | (1 << 15), tar.extractfile(entry).read()
    elif magic[:4] == b"PK\x03\x04":
        with ZipFile(io.BytesIO(archive)) as zip_file:
            for entry in zip_file.infolist():
                if not entry.is_dir():
                    yield entry.filename, entry.external_attr >> 16, zip_file.read(entry)
    else:
        raise RuntimeError("Unsupported archive format")


def write_ziglang_wheel(out_dir, *, version, platform, archive):
    contents = {}
    contents['ziglang/__init__.py'] = b''

    license_files = {}
    found_license_files = set()
    potential_extra_licenses = set()

    # A bunch of standard license file patterns. If a file matches any of
    # these, we need to add them to required_license_paths and metadata.
    license_patterns = [
        r'COPYING.*',
        r'COPYRIGHT.*',
        r'COPYLEFT.*',
        r'LICEN[CS]E.*',
        r'LICEN[CS]E-.*',
        r'LICEN[CS]E\..*',
        r'PATENTS.*',
        r'NOTICE.*',
        r'LEGAL.*',
        r'AUTHORS.*',
        r'RIGHT*',
        r'PERMISSION*',
        r'THIRD[-_]PARTY[-_]LICENSES?.*',
        r'EULA*',
        r'MIT*',
        r'GPL*',
        r'AGPL*',
        r'LGPL*',
        r'APACHE*',
    ]
    license_regex = re.compile('|'.join(f'^{pattern}$' for pattern in license_patterns), re.IGNORECASE)

    # These file paths MUST remain in sync with the paths in the official
    # Zig tarballs and with the ones defined below in the metadata. The
    # script will raise an error if any of these files are not found in
    # the archive.
    required_license_paths = [
        'LICENSE',
        'lib/libc/glibc/LICENSES',
        'lib/libc/mingw/COPYING',
        'lib/libc/musl/COPYRIGHT',
        'lib/libc/wasi/LICENSE',
        'lib/libc/wasi/LICENSE-APACHE',
        'lib/libc/wasi/LICENSE-APACHE-LLVM',
        'lib/libc/wasi/LICENSE-MIT',
        'lib/libc/wasi/libc-bottom-half/cloudlibc/LICENSE',
        'lib/libc/wasi/libc-top-half/musl/COPYRIGHT',
        'lib/libcxx/LICENSE.TXT',
        'lib/libcxxabi/LICENSE.TXT',
        'lib/libunwind/LICENSE.TXT',
	    'lib/libc/freebsd/COPYRIGHT',
        'lib/libc/wasi/fts/musl-fts/COPYING',
    ]
    excluded_license_paths = [
        # not a license text; contains macros that generate license strings
        'lib/libc/include/generic-freebsd/sys/copyright.h',
    ]

    for entry_name, entry_mode, entry_data in iter_archive_contents(archive):
        entry_name = '/'.join(entry_name.split('/')[1:])
        if not entry_name:
            continue
        if entry_name.startswith('doc/') or entry_name in excluded_license_paths:
            continue

        # Check for additional license-like files
        potential_license_filename = PurePath(entry_name).name
        if license_regex.match(potential_license_filename):
            potential_extra_licenses.add(entry_name)

        zip_info = ZipInfo(f'ziglang/{entry_name}')
        zip_info.external_attr = (entry_mode & 0xFFFF) << 16
        contents[zip_info] = entry_data

        if entry_name in required_license_paths:
            license_files[entry_name] = entry_data
            found_license_files.add(entry_name)

        if entry_name.startswith('zig'):
            contents['ziglang/__main__.py'] = f'''\
import os, sys
argv = [os.path.join(os.path.dirname(__file__), "{entry_name}"), *sys.argv[1:]]
if os.name == 'posix':
    os.execv(argv[0], argv)
else:
    import subprocess; sys.exit(subprocess.call(argv))

def dummy(): """Dummy function for an entrypoint. Zig is executed as a side effect of the import."""
'''.encode('ascii')

    # 1. Check for missing required licenses paths
    missing_licenses = set(required_license_paths) - found_license_files
    if missing_licenses:
        error_message = (
            f"{_YELLOW}The following required license files were not found in the Zig archive: {', '.join(sorted(missing_licenses))} "
            f"\nThis may indicate a change in Zig's license file structure or an error in the listing of license files and/or paths.{_YELLOW}"
        )
        raise RuntimeError(error_message)

    # 2. Check for potentially missing license files
    extra_licenses = potential_extra_licenses - set(required_license_paths)
    if extra_licenses:
        error_message = (
            f"{_YELLOW}Found additional potential license files in the Zig archive but not included in the metadata: {', '.join(sorted(extra_licenses))} "
            f"\nPlease consider adding these to the license paths if they should be included.{_YELLOW}"
        )
        raise RuntimeError(error_message)

    with open('README.pypi.md') as f:
        description = f.read()

    dist_info = f'ziglang-{version}.dist-info'
    for license_path, license_data in license_files.items():
        contents[f'{dist_info}/licenses/ziglang/{license_path}'] = license_data

    return write_wheel(out_dir,
        name='ziglang',
        version=version,
        tag=f'py3-none-{platform}',
        metadata=[
            ('Summary', 'Zig is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.'),
            ('Description-Content-Type', 'text/markdown'),
            # The license expression and the file paths MUST remain in sync
            # with the paths in the official Zig tarballs and with the ones
            # defined above in the contents. The difference is that these
            # are prefixed with "ziglang/" to match the paths in the wheel
            # for metadata compliance.
            ('License-Expression', 'MIT'),
            ('License-File', 'ziglang/LICENSE'),
            ('License-File', 'ziglang/lib/libc/glibc/LICENSES'),
            ('License-File', 'ziglang/lib/libc/mingw/COPYING'),
            ('License-File', 'ziglang/lib/libc/musl/COPYRIGHT'),
            ('License-File', 'ziglang/lib/libc/wasi/LICENSE'),
            ('License-File', 'ziglang/lib/libc/wasi/LICENSE-APACHE'),
            ('License-File', 'ziglang/lib/libc/wasi/LICENSE-APACHE-LLVM'),
            ('License-File', 'ziglang/lib/libc/wasi/LICENSE-MIT'),
            ('License-File', 'ziglang/lib/libc/wasi/libc-bottom-half/cloudlibc/LICENSE'),
            ('License-File', 'ziglang/lib/libc/wasi/libc-top-half/musl/COPYRIGHT'),
            ('License-File', 'ziglang/lib/libcxx/LICENSE.TXT'),
            ('License-File', 'ziglang/lib/libcxxabi/LICENSE.TXT'),
            ('License-File', 'ziglang/lib/libunwind/LICENSE.TXT'),
            ('License-File', 'ziglang/lib/libc/freebsd/COPYRIGHT'),
            ('Classifier', 'Development Status :: 4 - Beta'),
            ('Classifier', 'Intended Audience :: Developers'),
            ('Classifier', 'Topic :: Software Development :: Compilers'),
            ('Classifier', 'Topic :: Software Development :: Code Generators'),
            ('Classifier', 'Topic :: Software Development :: Build Tools'),
            ('Classifier', 'Programming Language :: Zig'),
            ('Project-URL', 'Homepage, https://ziglang.org'),
            ('Project-URL', 'Source Code, https://github.com/ziglang/zig-pypi'),
            ('Project-URL', 'Bug Tracker, https://github.com/ziglang/zig-pypi/issues'),
            ('Requires-Python', '~=3.5'),
        ],
        description=description,
        contents=contents,
    )


def fetch_zig_version_info():
    with urllib.request.urlopen(ZIG_VERSION_INFO_URL) as request:
        return json.loads(request.read())


def fetch_and_write_ziglang_wheels(
    outdir='dist/', zig_version='master', wheel_version_suffix='', platforms=tuple()
):
    Path(outdir).mkdir(exist_ok=True)
    if not platforms:
        platforms = list(ZIG_PYTHON_PLATFORMS)
    zig_versions_info = fetch_zig_version_info()

    if zig_version == 'latest':
        zig_version = [version for version in zig_versions_info if version != 'master'][0]

    try:
        zig_version_info = zig_versions_info[zig_version]
    except KeyError:
        print(f"Invalid version, valid values: {list(zig_versions_info)}")
        raise

    effective_zig_version = zig_version_info.get('version', zig_version)

    for zig_platform in platforms:
        python_platform = ZIG_PYTHON_PLATFORMS[zig_platform]
        if zig_platform not in zig_version_info:
            print(f"{zig_platform} not present for "
                  f"version {zig_version} / {effective_zig_version}")
            continue
        zig_download = zig_version_info[zig_platform]
        zig_url = zig_download['tarball']
        expected_hash = zig_download['shasum']

        with urllib.request.urlopen(zig_url) as request:
            zig_archive = request.read()
            zig_archive_hash = hashlib.sha256(zig_archive).hexdigest()
            if zig_archive_hash != expected_hash:
                raise Exception(
                    f"SHA256 hash mismatch for {zig_download}! expected shasum {expected_hash}")
            print(f'{hashlib.sha256(zig_archive).hexdigest()} {zig_url}')

        wheel_version = effective_zig_version.split('+')[0].replace('-', '.')
        wheel_path = write_ziglang_wheel(outdir,
            version=wheel_version + wheel_version_suffix,
            platform=python_platform,
            archive=zig_archive)
        with open(wheel_path, 'rb') as wheel:
            print(f'  {hashlib.sha256(wheel.read()).hexdigest()} {wheel_path}')


def get_argparser():
    supported_platforms = ', '.join(sorted(ZIG_PYTHON_PLATFORMS.keys()))
    description = (f"Repackage official Zig downloads as Python wheels.\n\n"
                   f"Supported platforms: {supported_platforms}")

    parser = argparse.ArgumentParser(prog=__file__, description=description,
                                   formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('--version', default='latest',
                        help="version to package, use `latest` for latest release, `master` for nightly build")
    parser.add_argument('--suffix', default='', help="wheel version suffix")
    parser.add_argument('--outdir', default='dist/', help="target directory")
    parser.add_argument('--platform', action='append', default=[],
                        help="platform to build for, use 'all' to build for all supported platforms, can be repeated")
    return parser


def main():
    args = get_argparser().parse_args()
    logging.getLogger("wheel").setLevel(logging.WARNING)

    platforms = args.platform
    if 'all' in platforms:
        platforms = list(ZIG_PYTHON_PLATFORMS.keys())


    fetch_and_write_ziglang_wheels(outdir=args.outdir, zig_version=args.version,
                                   wheel_version_suffix=args.suffix, platforms=platforms)


if __name__ == '__main__':
    main()
Download .txt
gitextract_pfxqcxh1/

├── .github/
│   └── workflows/
│       └── cd.yml
├── .gitignore
├── LICENSE.txt
├── README.md
├── README.pypi.md
└── make_wheels.py
Download .txt
SYMBOL INDEX (11 symbols across 1 files)

FILE: make_wheels.py
  class ReproducibleWheelFile (line 50) | class ReproducibleWheelFile(WheelFile):
    method writestr (line 51) | def writestr(self, zinfo_or_arcname, data, *args, **kwargs):
  function make_message (line 68) | def make_message(headers, payload=None):
  function write_wheel_file (line 81) | def write_wheel_file(filename, contents):
  function write_wheel (line 88) | def write_wheel(out_dir, *, name, version, tag, metadata, description, c...
  function iter_archive_contents (line 126) | def iter_archive_contents(archive):
  function write_ziglang_wheel (line 142) | def write_ziglang_wheel(out_dir, *, version, platform, archive):
  function fetch_zig_version_info (line 301) | def fetch_zig_version_info():
  function fetch_and_write_ziglang_wheels (line 306) | def fetch_and_write_ziglang_wheels(
  function get_argparser (line 352) | def get_argparser():
  function main (line 368) | def main():
Condensed preview — 6 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (28K chars).
[
  {
    "path": ".github/workflows/cd.yml",
    "chars": 4347,
    "preview": "name: CD\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: \"The version to build Zig wheels for,"
  },
  {
    "path": ".gitignore",
    "chars": 96,
    "preview": "# Python\n__pycache__/\n*.egg-info\n/dist\n*.whl\n\n# pdm\n/.pdm-plugins\n/.pdm-python\n/.venv\n/pdm.lock\n"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1108,
    "preview": "The MIT License (Expat)\n\nCopyright (c) 2021, whitequark <whitequark@whitequark.org>\n\nPermission is hereby granted, free "
  },
  {
    "path": "README.md",
    "chars": 4352,
    "preview": "Zig PyPI distribution\n=====================\n\nThis repository contains the script used to repackage the [releases][zigdl]"
  },
  {
    "path": "README.pypi.md",
    "chars": 1754,
    "preview": "Zig PyPI distribution\n=====================\n\n[Zig][] is a general-purpose programming language and toolchain for maintai"
  },
  {
    "path": "make_wheels.py",
    "chars": 15438,
    "preview": "# /// script\n# requires-python = \"~=3.9\"\n# dependencies = [\n#   \"wheel~=0.41.0\",\n# ]\n# ///\n\n# Additionally, install twin"
  }
]

About this extraction

This page contains the full source code of the ziglang/zig-pypi GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 6 files (26.5 KB), approximately 7.0k tokens, and a symbol index with 11 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!