Skip to content
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

Add mypy tests for basic use cases of public functions #304

Merged
merged 4 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 17 additions & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,20 @@ jobs:
- name: Run pyright basic on src
run: pyright --lib tests/annotations/ src/
- name: (pyright) verify type completeness
run: pyright --ignoreexternal --verifytypes hydra_zen
run: pyright --ignoreexternal --verifytypes hydra_zen

run-mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mypy
pip install -e .
- name: Run mypy on test script
run: mypy --warn-unused-ignores tests/annotations/mypy_checks.py
18 changes: 17 additions & 1 deletion .github/workflows/tox_run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,20 @@ jobs:
- name: Run pyright basic on src
run: pyright --lib tests/annotations/ src/
- name: (pyright) verify type completeness
run: pyright --ignoreexternal --verifytypes hydra_zen
run: pyright --ignoreexternal --verifytypes hydra_zen

run-mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mypy
pip install -e .
- name: Run mypy on test script
run: mypy --warn-unused-ignores tests/annotations/mypy_checks.py
2 changes: 1 addition & 1 deletion docs/source/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ If you depended on the previous default behavior, you can recreate it by using t
Improvements
------------
- Adds auto-config support for `dataclasses.dataclass` (as highlighted above). (See :pull:`301`)
- We now verify that basic use cases of our config-creation and instantiation functions type-check correctly via mypy. Previously, we had only assured type-checking behavior via pyright
- Adds support for using `builds(<target>, populate_full_signature=True)` where `<target>` is a dataclass type that has a field with a default factory. (See :pull:`299`)
- Adds auto-config support for `pydantic.Field`, improving hydra-zen's ability to automatically construct configs that describe pydantic models and dataclasses. (See :pull:`303`)
- :func:`~hydra_zen.builds` no longer has restrictions on inheritance patterns involving `PartialBuilds`-type configs. (See :pull:`290`)
- Two new utility functions were added to the public API: :func:`~hydra_zen.is_partial_builds` and :func:`~hydra_zen.uses_zen_processing`
- The :ref:`automatic type refinement <type-support>` performed by :func:`~hydra_zen.builds` now has enhanced support for ``typing.Annotated``, ``typing.NewType``, and ``typing.TypeVarTuple``. (See :pull:`283`)


**Support for New Hydra/OmegaConf Features**

- OmegaConf ``v2.2.1`` added native support for :py:class:`pathlib.Path`. hydra-zen :ref:`already provides support for these <additional-types>`, but will now defer to OmegaConf's native support when possible. (See :pull:`276`)
Expand Down
21 changes: 2 additions & 19 deletions src/hydra_zen/structured_configs/_implementations.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
)

from omegaconf import DictConfig, ListConfig
from typing_extensions import Final, Literal, ParamSpec, TypeAlias
from typing_extensions import Final, Literal, ParamSpec, TypeAlias, dataclass_transform

from hydra_zen._compatibility import (
HYDRA_SUPPORTED_PRIMITIVES,
Expand Down Expand Up @@ -176,24 +176,7 @@ def mutable_value(x: _T, *, zen_convert: Optional[ZenConvert] = None) -> _T:
return field(default_factory=lambda: cast(x))


# Alternate form, from PEP proposal:
# https://github.com/microsoft/pyright/blob/master/specs/dataclass_transforms.md
#
# This enables static checkers to work with third-party decorators that create
# dataclass-like objects
def __dataclass_transform__(
*,
eq_default: bool = True,
order_default: bool = False,
kw_only_default: bool = False,
field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
) -> Callable[[_T], _T]:
# If used within a stub file, the following implementation can be
# replaced with "...".
return lambda a: a


@__dataclass_transform__()
@dataclass_transform()
def hydrated_dataclass(
target: Callable[..., Any],
*pos_args: SupportedPrimitive,
Expand Down
68 changes: 68 additions & 0 deletions tests/annotations/mypy_checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (c) 2022 Massachusetts Institute of Technology
# SPDX-License-Identifier: MIT
from typing import Type

from typing_extensions import assert_type

from hydra_zen import builds, instantiate, make_custom_builds_fn


def check_builds() -> None:
class A:
...

def f(x: int) -> str:
...

assert_type(instantiate(builds(A)), A)
assert_type(instantiate(builds(A, populate_full_signature=True)), A)
assert_type(instantiate(builds(A, zen_partial=True))(), A)

assert_type(instantiate(builds(f)), str)
assert_type(instantiate(builds(f, populate_full_signature=True)), str)
assert_type(instantiate(builds(f, zen_partial=True))(), str)

builds(f, populate_full_signature=True)(y=2) # type: ignore [call-arg]


def check_make_custom_builds() -> None:
class A:
...

def f(x: int) -> str:
...

builds_ = make_custom_builds_fn()
partial_builds = make_custom_builds_fn(zen_partial=True)
full_builds = make_custom_builds_fn(populate_full_signature=True)

assert_type(instantiate(builds_(A)), A)
assert_type(instantiate(full_builds(A)), A)
assert_type(instantiate(partial_builds(A))(), A)

assert_type(instantiate(builds_(f)), str)
assert_type(instantiate(full_builds(f)), str)
assert_type(instantiate(partial_builds(f))(), str)

full_builds(f)(y=2) # type: ignore [call-arg]


# def check_just() -> None:
# from hydra_zen import just

# class A:
# ...

# # fails due to: https://github.com/python/mypy/issues/13623
# assert_type(instantiate(just(A)), Type[A])


## hydrated_dataclass not yet supported: https://github.com/python/mypy/issues/12840
# def check_hydrated_dataclass() -> None:
# from hydra_zen import hydrated_dataclass

# @hydrated_dataclass(dict)
# class A:
# x: int

# assert_type(A(1).x, int)