diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index ec2bbcb..ad9796a 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -13,7 +13,6 @@ on: workflow_dispatch: env: - MAIN_PYTHON_VERSION: '3.12' DOCUMENTATION_CNAME: 'python-wrapper.scade.docs.pyansys.com' LIBRARY_NAME: 'ansys-scade-python-wrapper' @@ -38,10 +37,10 @@ jobs: library-name: "ansys-scade-python-wrapper" repository-name: "ansys/scade-python-wrapper" is-public: true - main-python-version: '3.12' - # strategies - build-wheelhouse-versions: "['3.10']" - python-tests-versions: "['3.10']" + main-python-version: '3.14' + # 3.7 can't be built anymore + build-wheelhouse-versions: "['3.10', '3.12']" + scade-tests-versions: "['23.1', '25.2', '26.1']" secrets: PYANSYS_CI_BOT_TOKEN: ${{ secrets.PYANSYS_CI_BOT_TOKEN }} PYANSYS_CI_BOT_USERNAME: ${{ secrets.PYANSYS_CI_BOT_USERNAME }} diff --git a/.gitignore b/.gitignore index f958743..cd4f258 100644 --- a/.gitignore +++ b/.gitignore @@ -118,8 +118,7 @@ celerybeat.pid # Environments .env -.venv -.venv37 +.venv* env/ venv/ ENV/ diff --git a/README.rst b/README.rst index 50b2a17..b12afbe 100644 --- a/README.rst +++ b/README.rst @@ -49,7 +49,8 @@ The ``ansys-scade-python-wrapper`` package supports only the versions of Python Ansys SCADE, starting from 2021 R2: * 2021 R2 through 2023 R1: Python 3.7 -* 2023 R2 and later: Python 3.10 +* 2023 R2 through 2025 R2: Python 3.10 +* 2026 R1 and later: Python 3.12 Ansys SCADE Python Wrapper has two installation modes: user and developer. To install for use, see `Getting started `_. diff --git a/doc/changelog.d/58.maintenance.md b/doc/changelog.d/58.maintenance.md new file mode 100644 index 0000000..46d9cc5 --- /dev/null +++ b/doc/changelog.d/58.maintenance.md @@ -0,0 +1 @@ +Bump Python and SCADE versions diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst index feae170..15d7b0a 100644 --- a/doc/source/contributing.rst +++ b/doc/source/contributing.rst @@ -86,10 +86,12 @@ to guarantee the project's integrity. The following ``tox`` commands are provided: -- ``tox -e style``: Checks for coding style quality. -- ``tox -e py``: Checks for unit tests. -- ``tox -e py-coverage``: Checks for unit testing and code coverage. -- ``tox -e doc``: Checks for the documentation-building process. +* ``tox -e code-style``: Checks for coding style quality. +* ``tox -e py-tests``: Checks for unit testing without code coverage. +* ``tox -e py-tests-coverage``: Checks for unit testing with code coverage. +* ``tox -e doc``: Checks for the documentation-building process. + * ``tox -e doc-html``: Builds the HTML documentation. + * ``tox -e doc-links``: Checks for broken links in the documentation. Use raw testing ^^^^^^^^^^^^^^^ diff --git a/doc/source/getting_started/index.rst b/doc/source/getting_started/index.rst index 370e983..8a68c91 100644 --- a/doc/source/getting_started/index.rst +++ b/doc/source/getting_started/index.rst @@ -11,8 +11,9 @@ Requirements The ``ansys-scade-python-wrapper`` package supports only the versions of Python delivered with Ansys SCADE, starting from 2021 R2: -* 2021 R2 to 2023 R1: Python 3.7 -* 2023 R2 and later: Python 3.10 +* 2021 R2 through 2023 R1: Python 3.7 +* 2023 R2 through 2025 R2: Python 3.10 +* 2026 R1 and later: Python 3.12 Install in user mode -------------------- diff --git a/doc/source/usage/wrapper.rst b/doc/source/usage/wrapper.rst index 42ad2b2..8acdbcf 100644 --- a/doc/source/usage/wrapper.rst +++ b/doc/source/usage/wrapper.rst @@ -1,5 +1,5 @@ Wrapper -======= +======== Settings -------- diff --git a/pyproject.toml b/pyproject.toml index e9a9808..1148a30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["flit_core >=3.2,<3.13"] +requires = ["flit_core >=3.2,<4"] build-backend = "flit_core.buildapi" [project] @@ -8,9 +8,10 @@ version="2.0.dev0" description="SCADE code generation target to produce a Python proxy to a SCADE application." readme="README.rst" -# only 3.7. and 3.10 -requires-python = ">=3.7,!=3.8.*,!=3.9.*,<3.11" -license = {file = "LICENSE"} +# only 3.7, 3.10, or >= 3.12 +requires-python = ">=3.7,!=3.8.*,!=3.9.*,!=3.11.*" +license = "MIT" +license-files = ["LICENSE"] authors = [ {name = "ANSYS, Inc.", email = "pyansys.core@ansys.com"}, ] @@ -20,13 +21,14 @@ maintainers = [ dependencies=[ "importlib-metadata >= 1.0; python_version < '3.8'", "importlib-metadata >= 4.0; python_version >= '3.8'", - "ansys-scade-apitools", - "ansys-scade-wux", + "ansys-scade-apitools >= 0.5", + "ansys-scade-wux >= 2.3.0", ] classifiers=[ "Development Status :: 4 - Beta", - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.12", "Operating System :: Microsoft :: Windows", ] keywords=["Scade", "Wrapper", "Integration"] @@ -37,9 +39,10 @@ build = [ "twine==6.2.0" ] tests = [ - # 8.0.2 at most: https://github.com/microsoft/PTVS/issues/7853 - "pytest==8.4.2", - "pytest-cov==7.0.0" + "pytest >= 8.3.4; python_version >= '3.8'", + "pytest <= 7.4.4; python_version < '3.8'", + "pytest-cov >= 6.0.0; python_version >= '3.8'", + "pytest-cov <= 4.1.0; python_version < '3.8'", ] doc = [ "ansys-sphinx-theme[autoapi]==1.7.0; python_version >= '3.12'", diff --git a/tests/conftest.py b/tests/conftest.py index 9859245..68cc535 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,11 +22,14 @@ """Unit tests utils.""" +import os from pathlib import Path from subprocess import run +import sys +from typing import Optional # note: importing apitools modifies sys.path to access SCADE APIs -from ansys.scade.apitools.info import get_scade_home +from ansys.scade.apitools.info import get_scade_home, get_scade_version # must be imported after apitools # isort: split @@ -79,14 +82,15 @@ def find_configuration(project: std.Project, name: str) -> std.Configuration: assert False -def build_kcg_proxy(path: Path, configuration: str) -> Path | None: +def build_kcg_proxy(path: Path, configuration: str) -> Optional[Path]: """ Build the Python proxy if obsolete or not present. - This requires the package to be registered to the version of SCADE used - to run the tests, which is possible only on host systems, with a manual - installation step. + Requires SCADE 2026 R1/Python 3.12 """ + if get_scade_version() < 261: + return None + project = load_project(path) # retrieve the configuration conf = find_configuration(project, configuration) @@ -114,10 +118,18 @@ def build_kcg_proxy(path: Path, configuration: str) -> Path | None: else: obsolete = False if obsolete: + env = os.environ + if not env.get('VIRTUAL_ENV'): + # variable not set when tests are run from VS Code or VS 2022 + venv = Path(sys.executable).parent.parent.as_posix() + print('setting VIRTUAL_ENV to', venv) + env = env.copy() + env['VIRTUAL_ENV'] = venv # run scade -code to rebuild the python proxy exe = get_scade_home() / 'SCADE' / 'bin' / 'scade.exe' - cmd = [exe, '-code', str(path), '-conf', configuration, '-sim'] - cp = run(cmd, capture_output=True, encoding='utf-8') + cmd = [str(exe), '-code', str(path), '-conf', configuration, '-sim'] + print('cmd:', cmd) + cp = run(cmd, capture_output=True, encoding='utf-8', env=env) if cp.stdout: print(cp.stdout) if cp.stderr: diff --git a/tests/test_int_cvt.py b/tests/test_int_cvt.py index daf0cb6..f23db3b 100644 --- a/tests/test_int_cvt.py +++ b/tests/test_int_cvt.py @@ -35,9 +35,11 @@ import ctypes from pathlib import Path import sys +from typing import Optional import pytest +from ansys.scade.apitools.info import get_scade_version from conftest import build_kcg_proxy @@ -64,18 +66,20 @@ def append(self, text: bytes) -> int: @pytest.fixture(scope='session') -def proxy_types() -> Path | None: +def proxy_types() -> Optional[Path]: """Ensure the proxy is built and up-to-date.""" path = test_dir / 'Types' / 'Model' / 'Model.etp' return build_kcg_proxy(path, 'Python') def test_int_cvt(proxy_types): - if proxy_types is None: - # DLL can't be built on GH runners - print('test skipped') + version = get_scade_version() + if version < 261: + print(f'test skipped: requires at least SCADE 2026 R1 (current: v{version})') return + assert proxy_types is not None + # update sys.path to access the generated files old_path = sys.path.copy() sys.path.append(str(proxy_types.parent)) diff --git a/tests/test_int_types.py b/tests/test_int_types.py index 8129ac4..6acc79a 100644 --- a/tests/test_int_types.py +++ b/tests/test_int_types.py @@ -27,16 +27,15 @@ Verify the output values are identical to the input values for a significant set of types. - -Reminder: The tests using build_kcg_proxy require specific installation -steps, that can't be executed for automated tests on ci-cd runners. """ from pathlib import Path import sys +from typing import Optional import pytest +from ansys.scade.apitools.info import get_scade_version from conftest import build_kcg_proxy # fixtures @@ -44,14 +43,14 @@ @pytest.fixture(scope='session') -def proxy_kcg_types() -> Path | None: +def proxy_kcg_types() -> Optional[Path]: """Ensure the proxy is built and up-to-date.""" path = test_dir / 'Types' / 'Model' / 'Model.etp' return build_kcg_proxy(path, 'Python') @pytest.fixture(scope='session') -def proxy_kcg_types_io() -> Path | None: +def proxy_kcg_types_io() -> Optional[Path]: """Ensure the proxy is built and up-to-date.""" path = test_dir / 'Types' / 'Model' / 'Model.etp' return build_kcg_proxy(path, 'Python IO') @@ -113,11 +112,13 @@ def check_outputs(root, t): # unit tests def test_int_kcg_types(proxy_kcg_types): - if proxy_kcg_types is None: - # DLL can't be built on GH runners - print('test skipped') + version = get_scade_version() + if version < 261: + print(f'test skipped: requires at least SCADE 2026 R1 (current: v{version})') return + assert proxy_kcg_types is not None + # update sys.path to access the generated files old_path = sys.path.copy() sys.path.append(str(proxy_kcg_types.parent)) @@ -140,11 +141,13 @@ def test_int_kcg_types(proxy_kcg_types): def test_int_kcg_types_io(proxy_kcg_types_io): - if proxy_kcg_types_io is None: - # DLL can't be built on GH runners - print('test skipped') + version = get_scade_version() + if version < 261: + print(f'test skipped: requires at least Python 3.12 (current: v{version})') return + assert proxy_kcg_types_io is not None + # update sys.path to access the generated files old_path = sys.path.copy() sys.path.append(str(proxy_kcg_types_io.parent)) diff --git a/tox.ini b/tox.ini index 9ab714f..6155b42 100644 --- a/tox.ini +++ b/tox.ini @@ -1,42 +1,52 @@ [tox] description = Default tox environments list -envlist = style, tests-coverage, doc-html +# coverage is optional but includes tests: by default run only coverage +# env_list = code-style, py{37,310,312}-tests{-coverage,}, doc-{links,html} +env_list = code-style, py{37,310,312}-tests-coverage, doc-{links,html} skip_missing_interpreters = true -isolated_build = true isolated_build_env = build -[testenv] -description = Checks for project unit tests and coverage (if desired) -basepython = - tests310: python3.10 - {style,tests,doc}: python3 -extras = - tests +[testenv:py{37, 310, 312}-tests{-coverage,}] +description = + Checks for project unit tests + coverage: and coverage + py37: with python version 3.7 + py310: with python version 3.10 + py312: with python version 3.12 +base_python = + py37: python3.7 + py310: python3.10 + py312: python3.12 +extras = tests setenv = + TEMP = {env_tmp_dir} + TMP = {env_tmp_dir} PYTHONUNBUFFERED = yes - coverage: PYTEST_EXTRA_ARGS = --cov=ansys.scade.python_wrapper --cov-report=term --cov-report=xml:.cov/xml --cov-report=html:.cov/html --cov-branch + coverage: PYTEST_EXTRA_ARGS = --cov=ansys.scade.python_wrapper --cov-report=term --cov-report=xml:.cov/.{env_name}/xml --cov-report=html:.cov/.{env_name}/html --cov-branch passenv = ANSYSLMD_LICENSE_FILE commands = - pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} + python -m pytest -o addopts= {env:PYTEST_EXTRA_ARGS:} {posargs:-vv} -[testenv:style] +[testenv:code-style] description = Checks project code style skip_install = true deps = pre-commit commands = - pre-commit install pre-commit run --all-files --show-diff-on-failure [testenv:doc-{links,html}] -description = Check if documentation links generate properly +description = + Checks + links: the integrity of all external links + html: if html documentation generates properly +base_python = python3 setenv = - links: SPHINXBUILDER = linkcheck - html: SPHINXBUILDER = html + links: BUILDER = linkcheck + html: BUILDER = html passenv = BUILD_API BUILD_EXAMPLES -extras = - doc +extras = doc commands = - sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxinidir}/doc/_build/{env:SPHINXBUILDER}" --color -vW -b{env:SPHINXBUILDER} + sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxinidir}/doc/_build/{env:BUILDER}" --color -vW -b{env:BUILDER}