Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9f0c99b
add new wrapper plan checklist
saidctb Jul 11, 2026
948e915
add the migration plan
saidctb Jul 11, 2026
22f5081
start implementing phase 0
saidctb Jul 11, 2026
38d0dfc
finish with implementing phase 0
saidctb Jul 11, 2026
8036c54
implement stage 2 and 3
saidctb Jul 13, 2026
0166d19
improve validation plan and the visit algorithm for bridge and binding
saidctb Jul 13, 2026
e2dc7f5
codex: complete Phase 2D runtime and scalar boundary migration
saidctb Jul 13, 2026
54ef008
multiple results
saidctb Jul 13, 2026
7f239eb
add strings and arrays
saidctb Jul 13, 2026
85be1ae
implement alloctable and pointer arrays
saidctb Jul 14, 2026
9ae9741
implement derived types, magic methods and callbacks
saidctb Jul 16, 2026
e812a97
port the tests to the new implementation and remove codegen/ folder, …
saidctb Jul 16, 2026
3c964c0
port the tests to the new implementation and remove codegen/ folder, …
saidctb Jul 16, 2026
2b0cca4
github-actions
saidctb Jul 16, 2026
182a82a
github-actions
saidctb Jul 16, 2026
5889cf2
fix errors and add pass by value
saidctb Jul 16, 2026
4f66d71
fix errors
saidctb Jul 16, 2026
d3b2439
fix errors
saidctb Jul 16, 2026
c7f874c
use prototype instead of callable
saidctb Jul 17, 2026
1b6b1c2
update docs
saidctb Jul 17, 2026
24fbc36
update docs, put parsers in a new folder called parsers
saidctb Jul 17, 2026
611bdf8
remove default ORDER_F
saidctb Jul 17, 2026
9d29449
clean compiling
saidctb Jul 17, 2026
d8bcf47
improve naming
saidctb Jul 17, 2026
ff2e057
improve naming
saidctb Jul 17, 2026
4860dfa
rename the folder to native_support
saidctb Jul 17, 2026
80c6f00
add helpers in binding support and remove pyccel notice
saidctb Jul 17, 2026
f88a024
add static inline
saidctb Jul 17, 2026
0d76eb0
add more tests for module variables of scalar derived type kind
saidctb Jul 17, 2026
10a2104
fix errors
saidctb Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
31 changes: 25 additions & 6 deletions .github/workflows/parser-reference-guard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ jobs:

C_DOC="docs/developer/c-parser-reference.md"
FORTRAN_DOC="docs/developer/fortran-parser-reference.md"
PYI_DOC="docs/user/reference/semantic-pyi-format.md"

C_DOC_CHANGED=false
FORTRAN_DOC_CHANGED=false
PYI_DOC_CHANGED=false
C_PARSER_CHANGED=false
FORTRAN_PARSER_CHANGED=false
PYI_PARSER_CHANGED=false
SHARED_PARSER_CHANGED=false

if grep -Fxq "$C_DOC" <<< "$CHANGED_FILES"; then
Expand All @@ -61,30 +64,37 @@ jobs:
if grep -Fxq "$FORTRAN_DOC" <<< "$CHANGED_FILES"; then
FORTRAN_DOC_CHANGED=true
fi
if grep -Fxq "$PYI_DOC" <<< "$CHANGED_FILES"; then
PYI_DOC_CHANGED=true
fi

while IFS= read -r changed_file; do
case "$changed_file" in
c_parser/*|x2py/c_parser/*|tests/parser/c/*|tests/parsing/c/*|tests/data/c/*|tests/probes/test_c_types.py)
x2py/parsers/c/*|tests/parser/c/*|tests/parsing/c/*|tests/data/c/*|tests/probes/test_c_types.py)
C_PARSER_CHANGED=true
;;
fortran_parser/*|x2py/fortran_parser/*|tests/parser/fortran/*|tests/parsing/fortran/*|tests/data/fortran/*|tests/probes/test_fortran_types.py)
x2py/parsers/fortran/*|tests/parser/fortran/*|tests/parsing/fortran/*|tests/data/fortran/*|tests/probes/test_fortran_types.py)
FORTRAN_PARSER_CHANGED=true
;;
x2py/parsers/pyi/*|tests/parsing/pyi/*|tests/pipeline/pyi_builds/*)
PYI_PARSER_CHANGED=true
;;
tests/parser/conftest.py|\
tests/cli/*|\
tests/pipeline/preprocessing/*|\
x2py/parsers/__init__.py|\
x2py/preprocessing.py)
SHARED_PARSER_CHANGED=true
;;
esac
done <<< "$CHANGED_FILES"

if [[ ",${PR_LABELS}," == *",${FORCE_LABEL},"* ]]; then
if [ "$C_DOC_CHANGED" = true ] || [ "$FORTRAN_DOC_CHANGED" = true ]; then
if [ "$C_DOC_CHANGED" = true ] || [ "$FORTRAN_DOC_CHANGED" = true ] || [ "$PYI_DOC_CHANGED" = true ]; then
echo "${FORCE_LABEL} label present and at least one parser reference changed."
else
echo "${FORCE_LABEL} label present, but no parser reference changed."
echo "Update ${C_DOC} or ${FORTRAN_DOC}, or remove ${FORCE_LABEL}."
echo "Update ${C_DOC}, ${FORTRAN_DOC}, or ${PYI_DOC}, or remove ${FORCE_LABEL}."
exit 1
fi
fi
Expand All @@ -101,11 +111,17 @@ jobs:
FAILED=true
fi

if [ "$PYI_PARSER_CHANGED" = true ] && [ "$PYI_DOC_CHANGED" != true ]; then
echo "Semantic .pyi parser-related files changed without updating ${PYI_DOC}."
FAILED=true
fi

if [ "$SHARED_PARSER_CHANGED" = true ] && \
[ "$C_DOC_CHANGED" != true ] && \
[ "$FORTRAN_DOC_CHANGED" != true ]; then
[ "$FORTRAN_DOC_CHANGED" != true ] && \
[ "$PYI_DOC_CHANGED" != true ]; then
echo "Shared parser workflow files changed without updating a parser reference."
echo "Update ${C_DOC} or ${FORTRAN_DOC}, whichever behavior changed."
echo "Update ${C_DOC}, ${FORTRAN_DOC}, or ${PYI_DOC}, whichever behavior changed."
FAILED=true
fi

Expand All @@ -120,5 +136,8 @@ jobs:
if [ "$FORTRAN_DOC_CHANGED" = true ]; then
echo "${FORTRAN_DOC} changed."
fi
if [ "$PYI_DOC_CHANGED" = true ]; then
echo "${PYI_DOC} changed."
fi

echo "Parser reference guard passed."
142 changes: 65 additions & 77 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ on:
env:
X2PY_GFORTRAN_BINARY: gfortran-13
X2PY_GFORTRAN_PACKAGE: gfortran-13
X2PY_REAL_LIBRARY_NATIVE_CACHE_PATH: .pytest_cache/x2py/real-library-native

jobs:
static-analysis:
Expand All @@ -50,6 +49,8 @@ jobs:
run: python -m ruff check .
- name: Ruff format
run: python -m ruff format --check .
- name: Wrapper-plan generator contracts
run: python tools/check_wrapper_codegen_complexity.py
- name: Bandit security scan
run: python -m bandit -c pyproject.toml -r c_parser fortran_parser semantics x2py --severity-level medium --confidence-level medium
- name: Vulture dead-code scan
Expand All @@ -66,67 +67,10 @@ jobs:
continue-on-error: true
run: python -m radon mi c_parser fortran_parser semantics x2py -s

real-library-native-cache:
name: Real-Library Native Cache
if: ${{ !inputs.static_analysis_only }}
needs: static-analysis
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[qa]"
- name: Install pinned GFortran
shell: bash
run: |
if ! command -v "$X2PY_GFORTRAN_BINARY" >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes "$X2PY_GFORTRAN_PACKAGE"
fi
compiler_dir="$RUNNER_TEMP/x2py-gfortran"
mkdir -p "$compiler_dir"
ln -sf "$(command -v "$X2PY_GFORTRAN_BINARY")" "$compiler_dir/gfortran"
echo "$compiler_dir" >> "$GITHUB_PATH"
"$compiler_dir/gfortran" --version
- name: Capture native cache key facts
id: native-cache-facts
shell: bash
run: |
echo "gfortran_hash=$(gfortran --version | head -n 1 | sha256sum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
- name: Restore real-library native cache
id: restore-real-library-native-cache
uses: actions/cache/restore@v4
with:
path: ${{ env.X2PY_REAL_LIBRARY_NATIVE_CACHE_PATH }}
key: real-library-native-${{ runner.os }}-${{ runner.arch }}-${{ steps.native-cache-facts.outputs.gfortran_hash }}-${{ hashFiles('tests/data/fortran/blas/**', 'tests/data/fortran/lapack/**', 'tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py', 'tools/warm_real_library_native_cache.py') }}
restore-keys: |
real-library-native-${{ runner.os }}-${{ runner.arch }}-${{ steps.native-cache-facts.outputs.gfortran_hash }}-
- name: Warm real-library native cache
env:
PYTHONPATH: .
X2PY_REAL_LIBRARY_NATIVE_CACHE_DIR: ${{ github.workspace }}/${{ env.X2PY_REAL_LIBRARY_NATIVE_CACHE_PATH }}
run: python tools/warm_real_library_native_cache.py
- name: Save real-library native cache
if: steps.restore-real-library-native-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ env.X2PY_REAL_LIBRARY_NATIVE_CACHE_PATH }}
key: real-library-native-${{ runner.os }}-${{ runner.arch }}-${{ steps.native-cache-facts.outputs.gfortran_hash }}-${{ hashFiles('tests/data/fortran/blas/**', 'tests/data/fortran/lapack/**', 'tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py', 'tools/warm_real_library_native_cache.py') }}

test:
name: Tests (Python ${{ matrix.python-version }})
if: ${{ !inputs.static_analysis_only }}
needs: [static-analysis, real-library-native-cache]
needs: static-analysis
runs-on: ubuntu-24.04
permissions:
contents: read
Expand Down Expand Up @@ -159,36 +103,25 @@ jobs:
ln -sf "$(command -v "$X2PY_GFORTRAN_BINARY")" "$compiler_dir/gfortran"
echo "$compiler_dir" >> "$GITHUB_PATH"
"$compiler_dir/gfortran" --version
- name: Capture native cache key facts
id: native-cache-facts
shell: bash
run: |
echo "gfortran_hash=$(gfortran --version | head -n 1 | sha256sum | cut -d' ' -f1)" >> "$GITHUB_OUTPUT"
- name: Restore real-library native cache
uses: actions/cache/restore@v4
with:
path: ${{ env.X2PY_REAL_LIBRARY_NATIVE_CACHE_PATH }}
key: real-library-native-${{ runner.os }}-${{ runner.arch }}-${{ steps.native-cache-facts.outputs.gfortran_hash }}-${{ hashFiles('tests/data/fortran/blas/**', 'tests/data/fortran/lapack/**', 'tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py', 'tools/warm_real_library_native_cache.py') }}
restore-keys: |
real-library-native-${{ runner.os }}-${{ runner.arch }}-${{ steps.native-cache-facts.outputs.gfortran_hash }}-
- name: Run tests
shell: bash
env:
PYTHONPATH: .
HYPOTHESIS_PROFILE: ci
X2PY_COVERAGE_REQUESTED: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-coverage')) || (github.event_name == 'workflow_call' && inputs.coverage) }}
X2PY_REAL_LIBRARY_NATIVE_CACHE_DIR: ${{ github.workspace }}/${{ env.X2PY_REAL_LIBRARY_NATIVE_CACHE_PATH }}
run: |
pytest_args=(
--ignore=tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py
)

if [[ "${{ matrix.python-version }}" == "3.12" ]]; then
test_paths=(tests)
else
test_paths=(
tests/architecture
tests/benchmarks
tests/cli
tests/codegen
tests/docs
tests/lowering
tests/naming
tests/parsing
tests/pipeline
Expand All @@ -197,6 +130,7 @@ jobs:
tests/semantics
tests/tools
tests/types
tests/wrapper_codegen
tests/wrapper/fortran/arrays
tests/wrapper/fortran/build_from_pyi
tests/wrapper/fortran/build_from_source
Expand All @@ -212,7 +146,6 @@ jobs:
tests/wrapper/fortran/runtime_behavior
tests/wrapper/fortran/scalars
tests/wrapper/fortran/strings
"tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py::test_full_library_wrapper_imports_every_root_procedure_from_cached_shared_library[blas]"
tests/wrapper/fortran/real_libraries/test_stage7_native_bundles.py
)
fi
Expand All @@ -221,11 +154,13 @@ jobs:
COVERAGE_PROCESS_START="${{ github.workspace }}/pyproject.toml" \
python -m coverage run -m pytest -q --randomly-seed=1 \
-o junit_family=legacy \
--junitxml="$RUNNER_TEMP/pytest-results.xml" "${test_paths[@]}"
--junitxml="$RUNNER_TEMP/pytest-results.xml" \
"${pytest_args[@]}" "${test_paths[@]}"
else
python -m pytest -q --randomly-seed=1 \
-o junit_family=legacy \
--junitxml="$RUNNER_TEMP/pytest-results.xml" "${test_paths[@]}"
--junitxml="$RUNNER_TEMP/pytest-results.xml" \
"${pytest_args[@]}" "${test_paths[@]}"
fi
- name: Upload coverage data
if: matrix.python-version == '3.12' && ((github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-coverage')) || (github.event_name == 'workflow_call' && inputs.coverage))
Expand All @@ -239,6 +174,59 @@ jobs:
if: failure()
run: python tools/print_pytest_failures.py "$RUNNER_TEMP/pytest-results.xml"

real-library-wrappers:
name: Real library wrappers (BLAS + LAPACK)
if: >-
${{
!inputs.static_analysis_only &&
(github.event_name != 'pull_request' ||
!contains(github.event.pull_request.labels.*.name, 'ignore-real-library-wrappers'))
}}
needs: static-analysis
runs-on: ubuntu-24.04
timeout-minutes: 120
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[qa]"
- name: Install pinned GFortran
shell: bash
run: |
if ! command -v "$X2PY_GFORTRAN_BINARY" >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes "$X2PY_GFORTRAN_PACKAGE"
fi
compiler_dir="$RUNNER_TEMP/x2py-gfortran"
mkdir -p "$compiler_dir"
ln -sf "$(command -v "$X2PY_GFORTRAN_BINARY")" "$compiler_dir/gfortran"
echo "$compiler_dir" >> "$GITHUB_PATH"
"$compiler_dir/gfortran" --version
- name: Restore compiled native library cache
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/x2py-real-library-native
key: real-libraries-${{ runner.os }}-gfortran13-${{ hashFiles('tests/data/fortran/blas/**', 'tests/data/fortran/lapack/**') }}
- name: Run full BLAS and LAPACK wrapper tests
env:
PYTHONPATH: .
HYPOTHESIS_PROFILE: ci
X2PY_REAL_LIBRARY_NATIVE_CACHE_DIR: ${{ runner.temp }}/x2py-real-library-native
run: |
python -m pytest -q --randomly-seed=1 \
"tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py::test_full_library_wrapper_imports_every_root_procedure_from_cached_shared_library[blas]" \
"tests/wrapper/fortran/real_libraries/test_real_blas_lapack.py::test_full_library_wrapper_imports_every_root_procedure_from_cached_shared_library[lapack]"

coverage-report:
name: Coverage Report
if: ${{ !inputs.static_analysis_only && ((github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-coverage')) || (github.event_name == 'workflow_call' && inputs.coverage)) }}
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
This repo includes a CI guard that may require updating parser reference docs
when parser-related files change.

- **C parser changes**: if you change `x2py/c_parser/`, `tests/parser/c/`, or
- **C parser changes**: if you change `x2py/parsers/c/`, `tests/parser/c/`, or
`tests/data/c/`, update `docs/c_parser.md` when the change affects the
documented feature inventory, public API, diagnostics, fixtures, semantic
handoff, or maintenance workflow. The guard also treats
`tests/probes/test_c_types.py` as C parser related.
- **Fortran parser changes**: if you change `x2py/fortran_parser/`,
- **Fortran parser changes**: if you change `x2py/parsers/fortran/`,
`tests/parser/fortran/`, or `tests/data/fortran/`, update
`docs/fortran_parser.md` when the change affects the documented feature
inventory, public API, diagnostics, fixtures, semantic handoff, or
Expand Down
Loading
Loading