Skip to content

Release 0.12.1 — fix package mode and build.zig templates #50

Release 0.12.1 — fix package mode and build.zig templates

Release 0.12.1 — fix package mode and build.zig templates #50

Workflow file for this run

name: CI
on:
pull_request:
branches: [main]
paths:
- "src/lib/**"
- "src/cli/**"
- "src/tests.zig"
- "src/tests_abi3.zig"
- "examples/**"
- "build.zig"
- "build.zig.zon"
- ".github/workflows/ci.yml"
jobs:
format:
name: Check Formatting
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2
- name: Check format
run: zig fmt --check src/ build.zig examples/
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install numpy
run: pip install numpy
- name: Cache Zig
uses: actions/cache@v4
with:
path: |
~/.cache/zig
zig-cache
key: zig-cache-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('build.zig', 'build.zig.zon') }}
restore-keys: |
zig-cache-${{ runner.os }}-py${{ matrix.python-version }}-
- name: Run tests
run: zig build test
test-abi3:
name: Test ABI3 (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install numpy
run: pip install numpy
- name: Cache Zig
uses: actions/cache@v4
with:
path: |
~/.cache/zig
zig-cache
key: zig-cache-${{ runner.os }}-abi3-py${{ matrix.python-version }}-${{ hashFiles('build.zig', 'build.zig.zon') }}
restore-keys: |
zig-cache-${{ runner.os }}-abi3-py${{ matrix.python-version }}-
- name: Run ABI3 tests
run: zig build test_abi3
build:
name: Build Library & CLI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Cache Zig
uses: actions/cache@v4
with:
path: |
~/.cache/zig
zig-cache
key: zig-cache-${{ runner.os }}-build-${{ hashFiles('build.zig', 'build.zig.zon') }}
restore-keys: |
zig-cache-${{ runner.os }}-build-
- name: Build library
run: zig build
- name: Build CLI
run: zig build cli
example-module:
name: Example Module (${{ matrix.os }}, Python ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Zig
uses: goto-bus-stop/setup-zig@v2
with:
version: 0.15.2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install numpy
run: pip install numpy
- name: Cache Zig
uses: actions/cache@v4
with:
path: |
~/.cache/zig
zig-cache
key: zig-cache-${{ runner.os }}-example-py${{ matrix.python-version }}-${{ hashFiles('build.zig', 'build.zig.zon') }}
restore-keys: |
zig-cache-${{ runner.os }}-example-py${{ matrix.python-version }}-
- name: Build example module
run: zig build example
- name: Test example module (Unix)
if: runner.os != 'Windows'
run: |
python -c "
import sys
sys.path.insert(0, 'zig-out/lib')
import example
# Basic functions
assert example.add(2, 3) == 5, 'add failed'
assert example.multiply(4, 5) == 20.0, 'multiply failed'
assert example.is_even(4) == True, 'is_even failed'
assert example.greet('World') == 'Hello from Zig!', 'greet failed'
assert example.answer() == 42, 'answer failed'
# Point class
p1 = example.Point(3.0, 4.0)
assert p1.x == 3.0 and p1.y == 4.0, 'Point init failed'
assert p1.magnitude() == 5.0, 'magnitude failed'
p2 = example.Point(1.0, 2.0)
p3 = p1 + p2
assert p3.x == 4.0 and p3.y == 6.0, 'Point add failed'
assert (p1 == example.Point(3.0, 4.0)), 'Point eq failed'
# FrozenPoint (immutable)
fp = example.FrozenPoint(1.0, 2.0)
try:
fp.x = 5.0
assert False, 'FrozenPoint should be immutable'
except AttributeError:
pass
# Stack (__base__ inheritance from list)
s = example.Stack()
s.push(1)
s.push(2)
s.append(3) # inherited from list
assert len(s) == 3, 'Stack len failed'
assert list(s) == [1, 2, 3], 'Stack content failed'
# DefaultDict (__base__ inheritance from dict)
dd = example.DefaultDict()
dd['key'] = 100
assert dd['key'] == 100, 'DefaultDict get failed'
assert dd['missing'] == 'missing', 'DefaultDict __missing__ failed'
# Circle class attributes
assert example.Circle.PI > 3.14, 'Circle.PI failed'
c = example.Circle(5.0)
assert c.area() > 78, 'Circle.area failed'
# Iterator views
assert example.iter_sum([1, 2, 3, 4, 5]) == 15, 'iter_sum failed'
assert example.iter_sum(x for x in range(1, 6)) == 15, 'iter_sum generator failed'
assert example.iter_max([3, 1, 4, 1, 5, 9]) == 9, 'iter_max failed'
# Dict/Set views
assert example.dict_len({'a': 1, 'b': 2}) == 2, 'dict_len failed'
assert example.sum_dict_values({'a': 1, 'b': 2, 'c': 3}) == 6, 'sum_dict_values failed'
assert example.set_len({1, 2, 3}) == 3, 'set_len failed'
assert example.sum_set({1, 2, 3, 4, 5}) == 15, 'sum_set failed'
# DateTime types (make_date returns hardcoded 2024-07-04)
d = example.make_date()
assert d.year == 2024 and d.month == 7 and d.day == 4, 'make_date failed'
# Error handling
try:
example.divide(1.0, 0.0)
assert False, 'divide by zero should raise'
except RuntimeError:
pass
# Custom exception
try:
example.validate_positive(-5)
assert False, 'validate_positive should raise'
except example.ValidationError:
pass
# NumPy (if available)
import numpy as np
arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0], dtype=np.float64)
assert example.numpy_sum(arr) == 15.0, 'numpy_sum failed'
assert example.numpy_mean(arr) == 3.0, 'numpy_mean failed'
arr2 = np.array([1.0, 2.0, 3.0], dtype=np.float64)
example.numpy_scale(arr2, 2.0)
assert list(arr2) == [2.0, 4.0, 6.0], 'numpy_scale failed'
# Submodule
assert example.math.factorial(5) == 120, 'math.factorial failed'
assert example.math.gcd(12, 8) == 4, 'math.gcd failed'
assert example.math.is_prime(17) == True, 'math.is_prime failed'
print('All tests passed!')
"
- name: Test example module (Windows)
if: runner.os == 'Windows'
run: |
python -c "import sys; sys.path.insert(0, 'zig-out/bin'); import example; assert example.add(2, 3) == 5; print('Basic import works')"
python -c @"
import sys
sys.path.insert(0, 'zig-out/bin')
import example
# Basic functions
assert example.add(2, 3) == 5, 'add failed'
assert example.multiply(4, 5) == 20.0, 'multiply failed'
assert example.is_even(4) == True, 'is_even failed'
assert example.greet('World') == 'Hello from Zig!', 'greet failed'
assert example.answer() == 42, 'answer failed'
# Point class
p1 = example.Point(3.0, 4.0)
assert p1.x == 3.0 and p1.y == 4.0, 'Point init failed'
assert p1.magnitude() == 5.0, 'magnitude failed'
p2 = example.Point(1.0, 2.0)
p3 = p1 + p2
assert p3.x == 4.0 and p3.y == 6.0, 'Point add failed'
assert (p1 == example.Point(3.0, 4.0)), 'Point eq failed'
# FrozenPoint (immutable)
fp = example.FrozenPoint(1.0, 2.0)
try:
fp.x = 5.0
assert False, 'FrozenPoint should be immutable'
except AttributeError:
pass
# Stack (__base__ inheritance from list)
s = example.Stack()
s.push(1)
s.push(2)
s.append(3)
assert len(s) == 3, 'Stack len failed'
assert list(s) == [1, 2, 3], 'Stack content failed'
# DefaultDict (__base__ inheritance from dict)
dd = example.DefaultDict()
dd['key'] = 100
assert dd['key'] == 100, 'DefaultDict get failed'
assert dd['missing'] == 'missing', 'DefaultDict __missing__ failed'
# Circle class attributes
assert example.Circle.PI > 3.14, 'Circle.PI failed'
c = example.Circle(5.0)
assert c.area() > 78, 'Circle.area failed'
# Iterator views
assert example.iter_sum([1, 2, 3, 4, 5]) == 15, 'iter_sum failed'
assert example.iter_sum(x for x in range(1, 6)) == 15, 'iter_sum generator failed'
assert example.iter_max([3, 1, 4, 1, 5, 9]) == 9, 'iter_max failed'
# Dict/Set views
assert example.dict_len({'a': 1, 'b': 2}) == 2, 'dict_len failed'
assert example.sum_dict_values({'a': 1, 'b': 2, 'c': 3}) == 6, 'sum_dict_values failed'
assert example.set_len({1, 2, 3}) == 3, 'set_len failed'
assert example.sum_set({1, 2, 3, 4, 5}) == 15, 'sum_set failed'
# DateTime types (make_date returns hardcoded 2024-07-04)
d = example.make_date()
assert d.year == 2024 and d.month == 7 and d.day == 4, 'make_date failed'
# Error handling
try:
example.divide(1.0, 0.0)
assert False, 'divide by zero should raise'
except RuntimeError:
pass
# Custom exception
try:
example.validate_positive(-5)
assert False, 'validate_positive should raise'
except example.ValidationError:
pass
# NumPy (if available)
import numpy as np
arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0], dtype=np.float64)
assert example.numpy_sum(arr) == 15.0, 'numpy_sum failed'
assert example.numpy_mean(arr) == 3.0, 'numpy_mean failed'
arr2 = np.array([1.0, 2.0, 3.0], dtype=np.float64)
example.numpy_scale(arr2, 2.0)
assert list(arr2) == [2.0, 4.0, 6.0], 'numpy_scale failed'
# Submodule
assert example.math.factorial(5) == 120, 'math.factorial failed'
assert example.math.gcd(12, 8) == 4, 'math.gcd failed'
assert example.math.is_prime(17) == True, 'math.is_prime failed'
print('All tests passed!')
"@