-
Notifications
You must be signed in to change notification settings - Fork 4
✅ test: add tests & CI #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
name: CI | ||
permissions: read-all | ||
|
||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
push: | ||
branches: [main] | ||
|
||
concurrency: | ||
group: ${{ github.workflow }}-${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
env: | ||
# Many color libraries just need this to be set to any value, but at least | ||
# one distinguishes color depth, where "3" -> "256-bit color". | ||
FORCE_COLOR: 3 | ||
jorenham marked this conversation as resolved.
Show resolved
Hide resolved
jorenham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
jobs: | ||
format: | ||
name: Format | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Install uv | ||
uses: astral-sh/setup-uv@v6 | ||
|
||
- name: Install the project | ||
run: uv sync --locked --group test | ||
|
||
- name: Run lefthook hooks | ||
run: uv run --frozen lefthook run pre-commit | ||
|
||
checks: | ||
name: Check Python ${{ matrix.python-version }} on ${{ matrix.runs-on }} | ||
runs-on: ${{ matrix.runs-on }} | ||
needs: [format] | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
python-version: ["3.11", "3.12", "3.13"] | ||
runs-on: [ubuntu-latest, macos-latest, windows-latest] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Install uv | ||
uses: astral-sh/setup-uv@v6 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Install the project | ||
run: uv sync --locked --group test | ||
|
||
- name: Test package | ||
run: >- | ||
uv run --frozen pytest | ||
-cov --cov-report=xml --cov-report=term --durations=20 | ||
src docs tests | ||
|
||
- name: Upload coverage report | ||
uses: codecov/[email protected] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think we should we go major-only ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Defer to Dependabot, with grouped updates and filtering on inclusions in releases? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might become mildy annoying to have to merge many dependabot PR though. But that's just speculation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you could enable automerge for dependabot Also, we should be using full commit hashes (check out https://scientific-python.org/specs/spec-0008/). FWIW, in array-api-extra I have set up renovate to send a monthly PR to update actions, it works well: data-apis/array-api-extra#293 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SGTM. @lucascolley do you want to commit directly this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think I have commit access |
||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} | ||
|
||
check_oldest: | ||
name: Check Oldest Dependencies | ||
runs-on: ${{ matrix.runs-on }} | ||
needs: [format] | ||
jorenham marked this conversation as resolved.
Show resolved
Hide resolved
|
||
strategy: | ||
fail-fast: false | ||
matrix: | ||
python-version: ["3.11"] | ||
runs-on: [ubuntu-latest] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Install uv | ||
uses: astral-sh/setup-uv@v6 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install the project | ||
run: uv sync --locked --group test --resolution lowest-direct | ||
|
||
- name: Test package | ||
run: >- | ||
uv run --frozen pytest | ||
--cov --cov-report=xml --cov-report=term --durations=20 | ||
src docs tests | ||
|
||
- name: Upload coverage report | ||
uses: codecov/[email protected] | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,18 @@ | ||
"""Pytest configuration file.""" | ||
|
||
from typing import Final | ||
|
||
from sybil import Sybil | ||
from sybil.parsers.doctest import DocTestParser | ||
|
||
readme_tester = Sybil( | ||
readme_tester: Final = Sybil( | ||
parsers=[DocTestParser()], | ||
pattern="README.md", | ||
) | ||
|
||
python_file_tester = Sybil( | ||
python_file_tester: Final = Sybil( | ||
parsers=[DocTestParser()], | ||
pattern="src/**/*.py", | ||
) | ||
|
||
pytest_collect_file = (readme_tester + python_file_tester).pytest() | ||
pytest_collect_file: Final = (readme_tester + python_file_tester).pytest() |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -51,6 +51,9 @@ | |||||
"pytest-github-actions-annotate-failures>=0.3.0", | ||||||
"sybil>=8.0.0", | ||||||
] | ||||||
mypy = [ | ||||||
"mypy>=1.13.0" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can matter quite a bit
Suggested change
|
||||||
] | ||||||
|
||||||
|
||||||
[tool.hatch] | ||||||
|
@@ -74,6 +77,7 @@ version_tuple = {version_tuple!r} | |||||
[tool.mypy] | ||||||
files = ["src", "tests"] | ||||||
python_version = "3.10" | ||||||
mypy_path = "src" | ||||||
jorenham marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
strict = true | ||||||
disallow_incomplete_defs = true | ||||||
|
@@ -90,6 +94,10 @@ version_tuple = {version_tuple!r} | |||||
module = "sybil.*" | ||||||
ignore_missing_imports = true | ||||||
|
||||||
[[tool.mypy.overrides]] | ||||||
module = "tests.*" | ||||||
disallow_untyped_defs = false | ||||||
jorenham marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
|
||||||
[tool.pytest.ini_options] | ||||||
addopts = [ | ||||||
|
@@ -130,6 +138,9 @@ version_tuple = {version_tuple!r} | |||||
"ISC001", # Conflicts with formatter | ||||||
] | ||||||
|
||||||
[tool.ruff.lint.per-file-ignores] | ||||||
"tests/*.py" = ["ANN201", "D1", "S101"] | ||||||
|
||||||
[tool.ruff.lint.flake8-import-conventions] | ||||||
banned-from = ["array_api_typing"] | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
"""Static typing support for the array API standard.""" | ||
|
||
__all__ = ["HasArrayNamespace", "__version__", "__version_tuple__"] | ||
__all__ = ( | ||
"HasArrayNamespace", | ||
"__version__", | ||
"__version_tuple__", | ||
) | ||
|
||
from ._namespace import HasArrayNamespace | ||
from ._version import version as __version__, version_tuple as __version_tuple__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from types import SimpleNamespace | ||
from typing import Protocol, runtime_checkable | ||
|
||
import array_api_typing as xpt | ||
|
||
|
||
@runtime_checkable | ||
class CheckableHasArrayNamespace(xpt.HasArrayNamespace, Protocol): # type: ignore[misc] | ||
"""Runtime checkable version of HasArrayNamespace.""" | ||
|
||
|
||
class GoodArray: | ||
"""Example class that implements the HasArrayNamespace protocol.""" | ||
|
||
def __array_namespace__(self) -> object: # noqa: PLW3201 | ||
return SimpleNamespace() | ||
|
||
|
||
class BadArray: | ||
"""Example class that does not implement the HasArrayNamespace protocol.""" | ||
|
||
|
||
def test_has_namespace_class(): | ||
"""Test that GoodArray is a subclass of HasArrayNamespace.""" | ||
assert issubclass(GoodArray, CheckableHasArrayNamespace) | ||
|
||
|
||
def test_has_namespace_instance(): | ||
"""Test that an instance of GoodArray is recognized as HasArrayNamespace.""" | ||
x = GoodArray() | ||
assert isinstance(x, CheckableHasArrayNamespace) | ||
|
||
|
||
def test_not_has_namespace_class(): | ||
"""Test that BadArray is not a subclass of HasArrayNamespace.""" | ||
assert not issubclass(BadArray, CheckableHasArrayNamespace) | ||
|
||
|
||
def test_not_has_namespace_instance(): | ||
"""Test that an instance of BadArray is not recognized as HasArrayNamespace.""" | ||
y = BadArray() | ||
assert not isinstance(y, CheckableHasArrayNamespace) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.