pyo3 0.14.5

Bindings to Python interpreter
Documentation
name: CI

on:
  push:
    branches:
      - main
  pull_request:

env:
  CARGO_TERM_COLOR: always

jobs:
  fmt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      - run: pip install black==20.8b1
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          profile: minimal
          components: rustfmt
      - name: Check python formatting (black)
        run: black --check .
      - name: Check rust formatting (rustfmt)
        run: cargo fmt --all -- --check

  clippy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          profile: minimal
          components: clippy
      - run: make clippy

  check-target:
    needs: [fmt]
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false # If one platform fails, allow the rest to keep testing.
      matrix:
        target: [powerpc64le-unknown-linux-gnu, s390x-unknown-linux-gnu, wasm32-wasi]
    name: check-${{ matrix.target }}
    steps:
      - uses: actions/checkout@v2
      - name: Install Rust toolchain
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          target: ${{ matrix.target }}
          profile: minimal
          default: true

      - name: Run cargo checks
        run: |
          set -x
          VERSIONS=("3.6" "3.7" "3.8" "3.9" "3.10")
          for VERSION in ${VERSIONS[@]}; do
            echo "version=$VERSION" > config.txt
            # TODO suppress linking using config file rather than extension-module feature
            PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --features "extension-module"
            PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --features "extension-module abi3"
            PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --features "extension-module macros num-bigint num-complex hashbrown indexmap serde multiple-pymethods"
            PYO3_BUILD_CONFIG=$(pwd)/config.txt cargo check --all-targets --features "extension-module abi3 macros num-bigint num-complex hashbrown indexmap serde multiple-pymethods"
          done

  build:
    needs: [fmt] # don't wait for clippy as fails rarely and takes longer
    name: python${{ matrix.python-version }}-${{ matrix.platform.python-architecture }} ${{ matrix.platform.os }} ${{ matrix.msrv }}
    runs-on: ${{ matrix.platform.os }}
    strategy:
      fail-fast: false # If one platform fails, allow the rest to keep testing.
      matrix:
        rust: [stable]
        python-version: [3.6, 3.7, 3.8, 3.9, 3.10-dev, pypy-3.6, pypy-3.7]
        platform:
          [
            {
              os: "macos-latest",
              python-architecture: "x64",
              rust-target: "x86_64-apple-darwin",
            },
            {
              os: "ubuntu-latest",
              python-architecture: "x64",
              rust-target: "x86_64-unknown-linux-gnu",
            },
            {
              os: "windows-latest",
              python-architecture: "x64",
              rust-target: "x86_64-pc-windows-msvc",
            },
            {
              os: "windows-latest",
              python-architecture: "x86",
              rust-target: "i686-pc-windows-msvc",
            },
          ]
        exclude:
          # There is no 64-bit pypy on windows for pypy-3.6
          - python-version: pypy-3.6
            platform: { os: "windows-latest", python-architecture: "x64" }
          # PyPy 3.7 on Windows doesn't release 32-bit builds any more
          - python-version: pypy-3.7
            platform: { os: "windows-latest", python-architecture: "x86" }
        include:
          # Test minimal supported Rust version
          - rust: 1.41.1
            python-version: 3.9
            platform:
              {
                os: "ubuntu-latest",
                python-architecture: "x64",
                rust-target: "x86_64-unknown-linux-gnu",
              }
            msrv: "MSRV"

    steps:
      - uses: actions/checkout@v2

      # macos: install gnu-tar because BSD tar is buggy for github actions
      # https://github.com/actions/cache/issues/403
      - name: Install GNU tar (macOS only)
        if: matrix.platform.os == 'macos-latest'
        run: |
          brew install gnu-tar
          echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH

      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: cargo-${{ matrix.python-version }}-${{ matrix.platform.python-architecture }}-${{ matrix.platform.os }}-${{ matrix.msrv }}-${{ hashFiles('**/Cargo.toml') }}
        continue-on-error: true

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
          architecture: ${{ matrix.platform.python-architecture }}

      - name: Install Rust toolchain
        uses: actions-rs/toolchain@v1
        with:
          toolchain: ${{ matrix.rust }}
          target: ${{ matrix.platform.rust-target }}
          profile: minimal
          default: true

      - if: matrix.platform.os == 'ubuntu-latest'
        name: Prepare LD_LIBRARY_PATH (Ubuntu only)
        run: echo LD_LIBRARY_PATH=${pythonLocation}/lib >> $GITHUB_ENV

      - name: Prepare workflow settings
        id: settings
        shell: bash
        run: |
          echo "::set-output name=all_additive_features::macros num-bigint num-complex hashbrown indexmap serde multiple-pymethods"

      - if: matrix.msrv == 'MSRV'
        name: Prepare minimal package versions (MSRV only)
        run: |
          cargo update -p indexmap --precise 1.6.2
          cargo update -p hashbrown:0.11.2 --precise 0.9.1
          cargo update -p bitflags --precise 1.2.1
          cargo update -p parking_lot --precise 0.11.1
          cargo update -p parking_lot_core --precise 0.8.3

      - name: Build docs
        run: cargo doc --no-deps --no-default-features --features "${{ steps.settings.outputs.all_additive_features }}"

      - name: Build (no features)
        run: cargo build --lib --tests --no-default-features

      # --no-default-features when used with `cargo build/test -p` doesn't seem to work!
      - name: Build pyo3-build-config (no features)
        run: |
          cd pyo3-build-config
          cargo build --no-default-features

      # Run tests (except on PyPy, because no embedding API).
      - if: ${{ !startsWith(matrix.python-version, 'pypy') }}
        name: Test (no features)
        run: cargo test --no-default-features

      # --no-default-features when used with `cargo build/test -p` doesn't seem to work!
      - name: Test pyo3-build-config (no features)
        run: |
          cd pyo3-build-config
          cargo test --no-default-features

      - name: Build (all additive features)
        run: cargo build --lib --tests --no-default-features --features "${{ steps.settings.outputs.all_additive_features }}"

      # Run tests (except on PyPy, because no embedding API).
      - if: ${{ !startsWith(matrix.python-version, 'pypy') }}
        name: Test
        run: cargo test --no-default-features --features "${{ steps.settings.outputs.all_additive_features }}"

      # Run tests again, but in abi3 mode
      - if: ${{ !startsWith(matrix.python-version, 'pypy') }}
        name: Test (abi3)
        run: cargo test --no-default-features --features "abi3 ${{ steps.settings.outputs.all_additive_features }}"

      # Run tests again, for abi3-py36 (the minimal Python version)
      - if: ${{ (!startsWith(matrix.python-version, 'pypy')) && (matrix.python-version != '3.6') }}
        name: Test (abi3-py36)
        run: cargo test --no-default-features --features "abi3-py36 ${{ steps.settings.outputs.all_additive_features }}"

      - name: Test proc-macro code
        run: cargo test --manifest-path=pyo3-macros-backend/Cargo.toml

      - name: Test build config
        run: cargo test --manifest-path=pyo3-build-config/Cargo.toml

      - name: Install python test dependencies
        run: python -m pip install -U pip tox

      - name: Test example extension modules
        shell: bash
        run: |
          for example_dir in examples/*/; do
              tox -c $example_dir -e py
          done
        env:
          TOX_TESTENV_PASSENV: "CARGO_BUILD_TARGET"

      - name: Test cross compilation
        if: ${{ matrix.platform.os == 'ubuntu-latest' && matrix.python-version == '3.9' }}
        uses: messense/maturin-action@v1
        env:
          PYO3_CROSS_LIB_DIR: /opt/python/cp39-cp39/lib
        with:
          target: aarch64-unknown-linux-gnu
          manylinux: auto
          args: --release -i python3.9 --no-sdist -m examples/maturin-starter/Cargo.toml

    env:
      CARGO_TERM_VERBOSE: true
      CARGO_BUILD_TARGET: ${{ matrix.platform.rust-target }}
      RUST_BACKTRACE: 1
      RUSTFLAGS: "-D warnings"
      RUSTDOCFLAGS: "-D warnings"
      # TODO: this is a hack to workaround compile_error! warnings about auto-initialize on PyPy
      # Once cargo's `resolver = "2"` is stable (~ MSRV Rust 1.52), remove this.
      PYO3_CI: 1

  coverage:
    needs: [fmt]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
          key: coverage-cargo-${{ hashFiles('**/Cargo.toml') }}
        continue-on-error: true
      - name: install cargo-llvm-cov
        run: |
          wget https://github.com/taiki-e/cargo-llvm-cov/releases/download/v${CARGO_LLVM_COV_VERSION}/cargo-llvm-cov-x86_64-unknown-linux-gnu.tar.gz -qO- | tar -xzvf -
          mv cargo-llvm-cov ~/.cargo/bin
        env:
          CARGO_LLVM_COV_VERSION: 0.1.0-alpha.5
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: nightly
          override: true
          profile: minimal
          components: llvm-tools-preview
      # TODO: workaround for
      # https://github.com/taiki-e/cargo-llvm-cov/issues/48, shouldn't be needed
      # in next cargo-llvm-cov release.
      - run: cargo clean
      - run: |
          cargo llvm-cov \
            --package pyo3 pyo3-build-config pyo3-macros-backend pyo3-macros \
            --features "macros num-bigint num-complex hashbrown indexmap serde" \
            --lcov --output-path coverage.lcov
      - uses: codecov/codecov-action@v1
        with:
          file: coverage.lcov