-
Notifications
You must be signed in to change notification settings - Fork 3
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
MAINT: Add static type checking #28
Conversation
@effigies I see that in this repository the nifreeze/.github/workflows/contrib.yml Lines 22 to 25 in 7a48118
vs https://github.com/nipreps/nireports/blob/main/tox.ini#L72 https://github.com/nipreps/nireports/blob/main/.github/workflows/build_test_deploy.yml#L159 https://github.com/nipreps/nireports/actions/runs/12416179089/job/34664200380 The latter seems to be more elegant and self-contained. Is there a canonical way to do this through the |
8baa17c
to
fdf477e
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #28 +/- ##
==========================================
+ Coverage 67.45% 68.10% +0.65%
==========================================
Files 20 20
Lines 977 994 +17
Branches 129 130 +1
==========================================
+ Hits 659 677 +18
+ Misses 265 263 -2
- Partials 53 54 +1 ☔ View full report in Codecov by Sentry. |
9e3f60a
to
e050924
Compare
Looks like the I would have thought that Any clue @effigies ? |
363c6e8
to
470c510
Compare
Spent a few hours on this; solved all those warnings that I could: down to
|
We should then upgrade the pinning. |
470c510
to
e518c42
Compare
Do you want that to be done in this PR or in a separate one so as to avoid the change going unnoticed among all these commits? The potential new PR could be merged before this one, then this one rebased. |
39bbf76
to
516d0d7
Compare
d5268d7
to
88d2565
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mypy is now passing on this project. I think the changes I made were in the spirit of what is intended here.
@@ -52,7 +58,7 @@ def _cmp(lh: Any, rh: Any) -> bool: | |||
|
|||
|
|||
@attr.s(slots=True) | |||
class BaseDataset: | |||
class BaseDataset(Generic[*Ts]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the main new thing I introduced. This BaseDataset
class needs to permit a dynamic number of return values for __getitem__
, dependent on the subclass. In the future, we should be able to set this as a default:
class BaseDataset[*Ts=Unpack[tuple[()]]]:
...
Which, while not particularly pretty, will allow us not to have to type BaseDataset[()]
when annotating a variable that is actually this superclass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reviewed the whole thing, including my own contributions, and I'm good with this. It could probably do with another pair of eyes.
bd38772
to
c5ac831
Compare
Group keyword arguments into a single dictionary. Fixes: ``` scripts/optimize_registration.py:133: error: Argument "output_transform_prefix" to "generate_command" has incompatible type "str"; expected "dict[Any, Any]" [arg-type] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:141
Use `str` instead of `Path` for `_parse_yaml_config` parameter since `argparse` passes the argument as a string, not as a `Path`. Fixes: ``` src/nifreeze/cli/parser.py:74: error: Argument "type" to "add_argument" of "_ActionsContainer" has incompatible type "Callable[[Path], dict[Any, Any]]"; expected "Callable[[str], Any] | FileType | str" [arg-type] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:47
Use arrays in NumPy's `percentile` function arguments. Fixes: ``` src/nifreeze/data/filtering.py:80: error: Argument 1 to "percentile" has incompatible type "ndarray[Any, dtype[number[Any] | bool_]] | ndarray[tuple[int, ...], dtype[number[Any] | bool_]]"; expected "_SupportsArray[dtype[bool_ | integer[Any] | floating[Any]]] | _NestedSequence[_SupportsArray[dtype[bool_ | integer[Any] | floating[Any]]]] | bool | int | float | _NestedSequence[bool | int | float]" [arg-type] src/nifreeze/data/filtering.py:81: error: Argument 1 to "percentile" has incompatible type "ndarray[Any, dtype[number[Any] | bool_]] | ndarray[tuple[int, ...], dtype[number[Any] | bool_]]"; expected "_SupportsArray[dtype[bool_ | integer[Any] | floating[Any]]] | _NestedSequence[_SupportsArray[dtype[bool_ | integer[Any] | floating[Any]]]] | bool | int | float | _NestedSequence[bool | int | float]" [arg-type] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:130
List `sigma_sq` in the GP model slots. Fixes: ``` src/nifreeze/model/_dipy.py:128: error: Trying to assign name "sigma_sq" that is not in "__slots__" of type "nifreeze.model._dipy.GaussianProcessModel" [misc] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:102
Add the dimensionality to the `mask` ndarray parameter annotation. Fixes: ``` src/nifreeze/model/_dipy.py:140: error: "ndarray" expects 2 type arguments, but 1 given [type-arg] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:103
Fix type hint for `figsize` parameter: use `float` as values can be floating point numbers. Fixes: ``` src/nifreeze/viz/signals.py:40: error: Incompatible default for argument "figsize" (default has type "tuple[float, float]", argument has type "tuple[int, int]") [assignment] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:49
Provide appropriate type hints to the `reg_target_type` parameter of the `ants._run_registration` function. The expression is set to a tuple in https://github.com/nipreps/nifreeze/blob/6b6ba707c47b2763c040f3d3a2ceabdcf450eefe/src/nifreeze/estimator.py#L103 Fixes: ``` src/nifreeze/registration/ants.py:459: error: Incompatible types in assignment (expression has type "tuple[str, str]", variable has type "str") [assignment] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:133
Import `Bounds` from `scipy.optimize`. Fixes: ``` src/nifreeze/model/gpr.py:32: error: Module "scipy.optimize._minimize" does not explicitly export attribute "Bounds" [attr-defined] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:70
Avoid type checking for private function import statement. Fixes: ``` src/nifreeze/model/gpr.py:215: error: Module "sklearn.utils.optimize" has no attribute "_check_optimize_result" [attr-defined] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:73
Remove unused `namedtuple` definition in test. Fixes: ``` test/test_gpr.py:31: error: First argument to namedtuple() should be "GradientTablePatch", not "gtab" [name-match] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:129
Use `ClassVar` for type hinting the `GaussianProcessRegressor` `_parameter_constraints` class variable in child class. Fixes: ``` src/nifreeze/model/gpr.py:156: error: Cannot override class variable (previously declared on base class "GaussianProcessRegressor") with instance variable [misc] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:71
Annotate the `optimizer` attribute type in the DiffusionGPR GPR child class. Fixes: ``` src/nifreeze/model/gpr.py:234: error: "DiffusionGPR" has no attribute "optimizer" [attr-defined] ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:82
e03f7f2
to
126a5bb
Compare
Requires making BaseDataset generic on indexable fields
model.predict can return 1, 2 or 3 arrays
Annotate `Kernel.diag()` argument `X`: use `npt.ArrayLike`. Fixes: ``` src/nifreeze/model/gpr.py:335: error: Argument 1 of "diag" is incompatible with supertype "Kernel"; supertype defines the argument type as "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]" [override] src/nifreeze/model/gpr.py:335: note: This violates the Liskov substitution principle src/nifreeze/model/gpr.py:335: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides src/nifreeze/model/gpr.py:445: error: Argument 1 of "diag" is incompatible with supertype "Kernel"; supertype defines the argument type as "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]" [override] src/nifreeze/model/gpr.py:445: note: This violates the Liskov substitution principle src/nifreeze/model/gpr.py:335: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/12437972140/job/34728973936#step:8:93 Documentation: https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
126a5bb
to
02ff9c4
Compare
Add static type checking: use
mypy
to ensure that variable and function calls are using the appropriate types.Configure and run
mypy
checks in CI, including the spell checking.Documentation:
https://mypy.readthedocs.io/en/stable/index.html