Skip to content
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
906254f
explicitly import `fbuiltin` members in `gt4py.next`
DropD Feb 18, 2026
28fdaa2
fix typos in gtx, add failing external typing tests
DropD Feb 26, 2026
8681dec
fix typo in external typing CI
DropD Feb 26, 2026
3964075
Merge branch 'main' into explicit-fbuiltins-imports
DropD Feb 26, 2026
9854f2b
fix 'name-defined' mypy error for fbuiltins imported through gt4py.next
DropD Feb 26, 2026
7b1ed38
Merge branch 'main' into explicit-fbuiltins-imports
DropD Feb 27, 2026
e0e6c9f
fix 'arg-type' and 'call-overload' errors from using 'field_operator'
DropD Feb 27, 2026
02bc14d
add plugin to effectively ignore field dimension types
DropD Mar 2, 2026
ef038b8
Merge branch 'main' into explicit-fbuiltins-imports
DropD Mar 2, 2026
bcb960e
roll back experimental changes
DropD Mar 2, 2026
d7bb4a8
add more tests, partially fix 'where' type hints
DropD Mar 4, 2026
d56ce33
cleanup
DropD Mar 5, 2026
e9fdf85
fix type hints for program and scan_operator
DropD Mar 5, 2026
a0db128
add field ops and defer numeric precision type checking to dsl
DropD Mar 6, 2026
4c252e8
Merge branch 'main' into explicit-fbuiltins-imports
DropD Mar 6, 2026
da6aaf0
help mypy infer `astype` return type
DropD Mar 6, 2026
b9cce17
add a "default-tag" config for versioningit to get rid of NoTagError
DropD Mar 6, 2026
383a8e8
fix default-tag
DropD Mar 6, 2026
fa995be
make default tag conform to the vX.Y.Z convention
DropD Mar 6, 2026
564f98c
make external typing nox session call pytest with -sv
DropD Mar 6, 2026
3f55492
Merge branch 'main' into explicit-fbuiltins-imports
DropD Mar 9, 2026
d48e307
fix default tag interfering with installability
DropD Mar 9, 2026
415a435
edit default tag to indicate dev version (only used in shallow clones)
DropD Mar 10, 2026
c9ac562
Fix versioningit complaints
egparedes Mar 10, 2026
71ab1e1
Merge branch 'main' into explicit-fbuiltins-imports
DropD Mar 10, 2026
fc84bb0
replace Callable -> FunctionType casts with assert isinstance
DropD Mar 10, 2026
ed42283
added typing precision for field comparison ops
DropD Mar 10, 2026
82d25be
Merge branch 'build/fix-versioningit-complaints' into explicit-fbuilt…
DropD Mar 10, 2026
4e2a08e
experiment with default tag again
DropD Mar 10, 2026
e29bff0
get rid of local version info in default tag for now
DropD Mar 10, 2026
b9a2fde
static __all__ in fbuiltins, direct assert replaces test module
DropD Mar 10, 2026
5428507
remove need for attr-defined ignores for fbuiltins members
DropD Mar 10, 2026
725f3cc
experiment with removing extraneous local version info
DropD Mar 11, 2026
7399d4e
revert failed experiment
DropD Mar 11, 2026
fc0911f
rename "external typing" -> "typing exports"
DropD Mar 11, 2026
456bf81
use actual (non-any) dimension types while type checking
DropD Mar 11, 2026
abb72ca
[wip] fix dimension types
DropD Mar 11, 2026
17d5eef
Fix local version part
egparedes Mar 12, 2026
a529bbc
Merge branch 'main' into build/fix-versioningit-complaints
egparedes Mar 12, 2026
34ed14a
Update to current version
egparedes Mar 12, 2026
1180628
Fix unit test
egparedes Mar 12, 2026
043c2be
Fallback to a different strategy wrapping the versioningit calls to a…
egparedes Mar 12, 2026
5216972
mypy plugin: stop blocking variadic 'Dims' types
DropD Mar 12, 2026
264fef6
mypy plugin: give up on Dim types in case of error
DropD Mar 12, 2026
bf2f7aa
Merge branch 'build/fix-versioningit-complaints' into explicit-fbuilt…
DropD Mar 12, 2026
065ea19
mypy plugin: add a clarifying comment
DropD Mar 12, 2026
cec6dcc
Merge branch 'main' into explicit-fbuiltins-imports
egparedes Mar 12, 2026
239ac13
document mypy plugin, test gt4py.next exporting all public fbuiltins
DropD Mar 13, 2026
2e1422e
upgrade CI actions
DropD Mar 13, 2026
9889ed0
improve type hints and mypy plugin
DropD Mar 13, 2026
da20631
test for missing builtin functions in fbuiltins
DropD Mar 13, 2026
e527c29
fix typo in one of the typing export tests
DropD Mar 17, 2026
b3b2eac
Merge branch 'main' into explicit-fbuiltins-imports
DropD Mar 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,24 @@ jobs:

- name: "Run pre-commit"
uses: pre-commit/action@v3.0.1

typing-exports:
needs: [get-python-versions]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ fromJSON(needs.get-python-versions.outputs.python-versions) }}

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"

- name: "Run typing checks on exported entities"
run: |
./noxfile.py -s 'test_typing_exports-${{ fromJson(needs.get-python-versions.outputs.python-versions) }}'
16 changes: 16 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,5 +330,21 @@ def test_storage(
)


@nox.session(python=PYTHON_VERSIONS, tags=["next"])
def test_typing_exports(session: nox.Session) -> None:
"""Test GT4Py usability in a typed client context."""
install_session_venv(session, extras=["standard"], groups=["test", "typing_exports"])

session.run(
"pytest",
"-sv",
"--mypy-testing-base",
"typing_tests",
"--mypy-only-local-stub",
"typing_tests",
*session.posargs,
)


if __name__ == "__main__":
nox.main()
15 changes: 14 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ typing = [
'types-docutils>=0.21.0',
'types-pytz>=2024.2.0'
]
typing_exports = [
{include-group = "typing"},
'types-six',
'pytest-mypy-plugins',
"xarray"
]

# -- Standard project description options (PEP 621) --
[project]
Expand Down Expand Up @@ -187,12 +193,13 @@ source_pkgs = ['gt4py']
[tool.mypy]
disallow_incomplete_defs = true
disallow_untyped_defs = true
exclude = ['^setup\.py$', 'build/.*$', 'ci/*.$', 'docs/.*$', 'tests/.*$']
exclude = ['^setup\.py$', 'build/.*$', 'ci/*.$', 'docs/.*$', '^tests/.*$']
ignore_missing_imports = true
implicit_optional = false
implicit_reexport = false
install_types = true
namespace_packages = false
plugins = ['gt4py.next.type_system.mypy_plugin']
# pretty = true
show_column_numbers = true
show_error_codes = true
Expand Down Expand Up @@ -261,6 +268,12 @@ implicit_reexport = true
# factory-boy is broken, see https://github.com/FactoryBoy/factory_boy/pull/1114
module = "factory.*"

[[tool.mypy.overrides]]
disallow_incomplete_defs = false
disallow_untyped_defs = false
ignore_errors = false
module = "typing_tests.test_next_exports"

# -- pytest --
[tool.pytest]

Expand Down
2 changes: 1 addition & 1 deletion src/gt4py/_core/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def dtype_kind(


@overload
def dtype_kind(sc_type: Type[UnsignedIntT]) -> Literal[DTypeKind.UINT]: ...
def dtype_kind(sc_type: Type[UnsignedIntT]) -> Literal[DTypeKind.UINT]: ... # type: ignore[overload-cannot-match] # precision blurring from mypy plugin seems to interfere


@overload
Expand Down
110 changes: 106 additions & 4 deletions src/gt4py/next/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,59 @@
)
from .ffront import fbuiltins
from .ffront.decorator import field_operator, program, scan_operator
from .ffront.fbuiltins import * # noqa: F403 [undefined-local-with-import-star] explicitly reexport all from fbuiltins.__all__
from .ffront.fbuiltins import FieldOffset
from .ffront.fbuiltins import (
FieldOffset,
IndexType,
abs, # noqa: A004 # shadowing
arccos,
arccosh,
arcsin,
arcsinh,
arctan,
arctanh,
astype,
bool, # noqa: A004 # shadowing
broadcast,
cbrt,
ceil,
cos,
cosh,
exp,
float, # noqa: A004 # shadowing
float32,
float64,
floor,
fmod,
gamma,
int, # noqa: A004 # shadowing
int8,
int16,
int32,
int64,
isfinite,
isinf,
isnan,
log,
max_over,
maximum,
min_over,
minimum,
neg,
neighbor_sum,
power,
sin,
sinh,
sqrt,
tan,
tanh,
trunc,
tuple, # noqa: A004 # shadowing
uint8,
uint16,
uint32,
uint64,
where,
)
from .otf.compiled_program import wait_for_compilation
from .program_processors.runners.gtfn import (
run_gtfn_cached as gtfn_cpu,
Expand All @@ -49,7 +100,7 @@
from .program_processors.runners.roundtrip import default as itir_python


__all__ = [
__all__ = [ # noqa: RUF022 [unsorted-dunder-all]
# submodules
"common",
"ffront",
Expand Down Expand Up @@ -91,5 +142,56 @@
"gtfn_cpu",
"gtfn_gpu",
"itir_python",
*fbuiltins.__all__,
# from fbuiltins
"FieldOffset",
"IndexType",
"abs",
"arccos",
"arccosh",
"arcsin",
"arcsinh",
"arctan",
"arctanh",
"astype",
"bool",
"broadcast",
"cbrt",
"ceil",
"cos",
"cosh",
"exp",
"float",
"float32",
"float64",
"floor",
"fmod",
"gamma",
"int",
"int8",
"int16",
"int32",
"int64",
"isfinite",
"isinf",
"isnan",
"log",
"max_over",
"min_over",
"maximum",
"minimum",
"neg",
"neighbor_sum",
"power",
"sin",
"sinh",
"sqrt",
"tan",
"tanh",
"trunc",
"tuple",
"uint8",
"uint16",
"uint32",
"uint64",
"where",
]
54 changes: 48 additions & 6 deletions src/gt4py/next/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,24 @@ def __sub__(self, offset: int) -> Connectivity:
return self + (-offset)


if TYPE_CHECKING:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question: since this is only used in the mypy plugin, would it be possible to move these definitions into the the plugin module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that first, but it seems the type has to be reachable from the context that is being checked. The only safe place for it is in the same module that defines Dimension.


@dataclasses.dataclass(frozen=True)
class DimA(Dimension): ...

@dataclasses.dataclass(frozen=True)
class DimB(Dimension): ...

@dataclasses.dataclass(frozen=True)
class DimC(Dimension): ...

@dataclasses.dataclass(frozen=True)
class DimD(Dimension): ...

@dataclasses.dataclass(frozen=True)
class AnyDim(Dimension): ...


class Infinity(enum.Enum):
"""Describes an unbounded `UnitRange`."""

Expand Down Expand Up @@ -772,6 +790,18 @@ def __rtruediv__(self, other: Field | core_defs.ScalarT) -> Field: ...
@abc.abstractmethod
def __pow__(self, other: Field | core_defs.ScalarT) -> Field: ...

@abc.abstractmethod
def __lt__(self, other: Field | core_defs.ScalarT) -> Field[Any, bool]: ...

@abc.abstractmethod
def __le__(self, other: Field | core_defs.ScalarT) -> Field[Any, bool]: ...

@abc.abstractmethod
def __gt__(self, other: Field | core_defs.ScalarT) -> Field[Any, bool]: ...

@abc.abstractmethod
def __ge__(self, other: Field | core_defs.ScalarT) -> Field[Any, bool]: ...

@abc.abstractmethod
def __and__(self, other: Field | core_defs.ScalarT) -> Field:
"""Only defined for `Field` of value type `bool`."""
Expand Down Expand Up @@ -994,36 +1024,48 @@ def __ne__(self, other: Any) -> Never:
def __add__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __radd__(self, other: Field | core_defs.IntegralScalar) -> Never: # type: ignore[misc] # Forward operator not callalbe
def __radd__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __sub__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __rsub__(self, other: Field | core_defs.IntegralScalar) -> Never: # type: ignore[misc] # Forward operator not callalbe
def __rsub__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __mul__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __rmul__(self, other: Field | core_defs.IntegralScalar) -> Never: # type: ignore[misc] # Forward operator not callalbe
def __rmul__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __truediv__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __rtruediv__(self, other: Field | core_defs.IntegralScalar) -> Never: # type: ignore[misc] # Forward operator not callalbe
def __rtruediv__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __floordiv__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __rfloordiv__(self, other: Field | core_defs.IntegralScalar) -> Never: # type: ignore[misc] # Forward operator not callalbe
def __rfloordiv__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __pow__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __lt__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __le__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __gt__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __ge__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

def __and__(self, other: Field | core_defs.IntegralScalar) -> Never:
raise TypeError("'Connectivity' does not support this operation.")

Expand Down Expand Up @@ -1205,7 +1247,7 @@ def __gt_origin__(self) -> Never:

@property
def dtype(self) -> core_defs.DType[core_defs.IntegralScalar]:
return core_defs.Int32DType() # type: ignore[return-value]
return core_defs.Int32DType()

# This is a workaround to make this class concrete, since `codomain` is an
# abstract property of the `Connectivity` Protocol.
Expand Down
12 changes: 6 additions & 6 deletions src/gt4py/next/embedded/nd_array_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,11 +797,11 @@ def _hyperslice(
# -- Specialized implementations for builtin operations on array fields --

NdArrayField.register_builtin_func(
fbuiltins.abs, # type: ignore[attr-defined]
fbuiltins.abs,
NdArrayField.__abs__,
)
NdArrayField.register_builtin_func(
fbuiltins.power, # type: ignore[attr-defined]
fbuiltins.power,
NdArrayField.__pow__,
)
# TODO gamma
Expand All @@ -816,15 +816,15 @@ def _hyperslice(
NdArrayField.register_builtin_func(getattr(fbuiltins, name), _make_builtin(name, name))

NdArrayField.register_builtin_func(
fbuiltins.minimum, # type: ignore[attr-defined]
fbuiltins.minimum,
_make_builtin("minimum", "minimum"),
)
NdArrayField.register_builtin_func(
fbuiltins.maximum, # type: ignore[attr-defined]
fbuiltins.maximum,
_make_builtin("maximum", "maximum"),
)
NdArrayField.register_builtin_func(
fbuiltins.fmod, # type: ignore[attr-defined]
fbuiltins.fmod,
_make_builtin("fmod", "fmod"),
)
NdArrayField.register_builtin_func(fbuiltins.where, _make_builtin("where", "where"))
Expand Down Expand Up @@ -1159,7 +1159,7 @@ def _astype(field: common.Field | core_defs.ScalarT | tuple, type_: type) -> NdA
raise AssertionError("This is the NdArrayField implementation of 'fbuiltins.astype'.")


NdArrayField.register_builtin_func(fbuiltins.astype, _astype)
NdArrayField.register_builtin_func(fbuiltins.astype, _astype) # type: ignore[arg-type] # because fbuiltins.astype is overloaded


def _get_slices_from_domain_slice(
Expand Down
Loading
Loading