Skip to content

Commit 2106844

Browse files
authored
Bump mypy to 1.16.1 (#6858)
* mypy: use --pretty for nicer error messages! * Fix bug in existing archive import validation! * Use cast * Fix typing of shared_options in src/aiida/cmdline/groups/dynamic.py * Mark ctx positional-only in profile_configure_rabbitmq
1 parent a392f5c commit 2106844

File tree

15 files changed

+82
-65
lines changed

15 files changed

+82
-65
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ repos:
7878
- id: mypy
7979
name: mypy
8080
entry: mypy
81-
args: [--config-file=pyproject.toml]
81+
args: [--config-file=pyproject.toml, --pretty]
8282
language: python
8383
types: [python]
8484
require_serial: true

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ notebook = [
229229
]
230230
pre-commit = [
231231
'aiida-core[atomic_tools,rest,tests,tui]',
232-
'mypy~=1.13.0',
232+
'mypy~=1.16.0',
233233
'packaging~=23.0',
234234
'pre-commit~=3.5',
235235
'sqlalchemy[mypy]~=2.0',

src/aiida/cmdline/commands/cmd_profile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def profile_setup():
131131
"""Set up a new profile."""
132132

133133

134-
@verdi_profile.command('configure-rabbitmq') # type: ignore[arg-type]
134+
@verdi_profile.command('configure-rabbitmq')
135135
@arguments.PROFILE(default=defaults.get_default_profile)
136136
@options.FORCE()
137137
@setup.SETUP_BROKER_PROTOCOL()
@@ -142,7 +142,7 @@ def profile_setup():
142142
@setup.SETUP_BROKER_VIRTUAL_HOST()
143143
@options.NON_INTERACTIVE(default=True, show_default='--non-interactive')
144144
@click.pass_context
145-
def profile_configure_rabbitmq(ctx, profile, non_interactive, force, **kwargs):
145+
def profile_configure_rabbitmq(ctx, /, profile, non_interactive, force, **kwargs):
146146
"""Configure RabbitMQ for a profile.
147147
148148
Enable RabbitMQ for a profile that was created without a broker, or reconfigure existing connection details.

src/aiida/cmdline/groups/dynamic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def __init__(
4747
command: t.Callable,
4848
entry_point_group: str,
4949
entry_point_name_filter: str = r'.*',
50-
shared_options: list[click.Option] | None = None,
50+
shared_options: list[t.Callable[[t.Any], t.Any]] | None = None,
5151
**kwargs,
5252
):
5353
super().__init__(**kwargs)
@@ -143,7 +143,7 @@ def apply_options(func):
143143

144144
return apply_options
145145

146-
def list_options(self, entry_point: str) -> list:
146+
def list_options(self, entry_point: str) -> list[t.Callable[[t.Any], t.Any]]:
147147
"""Return the list of options that should be applied to the command for the given entry point.
148148
149149
:param entry_point: The entry point.

src/aiida/engine/processes/functions.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,11 @@ def build(func: FunctionType, node_class: t.Type['ProcessNode']) -> t.Type['Func
355355
"""
356356
if (
357357
not issubclass(node_class, ProcessNode) # type: ignore[redundant-expr]
358-
or not issubclass(node_class, FunctionCalculationMixin) # type: ignore[unreachable]
358+
or not issubclass(node_class, FunctionCalculationMixin)
359359
):
360360
raise TypeError('the node_class should be a sub class of `ProcessNode` and `FunctionCalculationMixin`')
361361

362-
signature = inspect.signature(func) # type: ignore[unreachable]
362+
signature = inspect.signature(func)
363363

364364
args: list[str] = []
365365
var_positional: str | None = None
@@ -373,17 +373,21 @@ def build(func: FunctionType, node_class: t.Type['ProcessNode']) -> t.Type['Func
373373
LOGGER.warning(f'function `{func.__name__}` has invalid type hints: {exception}')
374374
annotations = {}
375375

376-
try:
377-
parsed_docstring = docstring_parser.parse(func.__doc__)
378-
except Exception as exception:
379-
LOGGER.warning(f'function `{func.__name__}` has a docstring that could not be parsed: {exception}')
380-
param_help_string = {}
376+
if func.__doc__ is None:
377+
param_help_string: dict[str, str | None] = {}
381378
namespace_help_string = None
382379
else:
383-
param_help_string = {param.arg_name: param.description for param in parsed_docstring.params}
384-
namespace_help_string = parsed_docstring.short_description if parsed_docstring.short_description else ''
385-
if parsed_docstring.long_description is not None:
386-
namespace_help_string += f'\n\n{parsed_docstring.long_description}'
380+
try:
381+
parsed_docstring = docstring_parser.parse(func.__doc__)
382+
except Exception as exception:
383+
LOGGER.warning(f'function `{func.__name__}` has a docstring that could not be parsed: {exception}')
384+
param_help_string = {}
385+
namespace_help_string = None
386+
else:
387+
param_help_string = {param.arg_name: param.description for param in parsed_docstring.params}
388+
namespace_help_string = parsed_docstring.short_description if parsed_docstring.short_description else ''
389+
if parsed_docstring.long_description is not None:
390+
namespace_help_string += f'\n\n{parsed_docstring.long_description}'
387391

388392
for key, parameter in signature.parameters.items():
389393
if parameter.kind in [parameter.POSITIONAL_ONLY, parameter.POSITIONAL_OR_KEYWORD, parameter.KEYWORD_ONLY]:
@@ -435,7 +439,7 @@ def define(cls, spec):
435439
def indirect_default(value=default):
436440
return to_aiida_type(value)
437441
else:
438-
indirect_default = default
442+
indirect_default = default # type: ignore[assignment]
439443

440444
spec.input(
441445
parameter.name,

src/aiida/engine/processes/process.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class Process(PlumpyProcess):
8383
class SaveKeys(enum.Enum):
8484
"""Keys used to identify things in the saved instance state bundle."""
8585

86-
CALC_ID: str = 'calc_id'
86+
CALC_ID = 'calc_id'
8787

8888
@classmethod
8989
def spec(cls) -> ProcessSpec:
@@ -379,7 +379,7 @@ def kill(self, msg_text: str | None = None, force_kill: bool = False) -> Union[b
379379
continue
380380
try:
381381
result = self.runner.controller.kill_process(child.pk, msg_text=f'Killed by parent<{self.node.pk}>')
382-
result = asyncio.wrap_future(result) # type: ignore[arg-type]
382+
result = asyncio.wrap_future(result)
383383
if asyncio.isfuture(result):
384384
killing.append(result)
385385
except ConnectionClosed:

src/aiida/orm/nodes/data/code/installed.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from __future__ import annotations
1818

1919
import pathlib
20+
from typing import cast
2021

2122
from pydantic import field_serializer, field_validator
2223

@@ -47,15 +48,15 @@ class Model(AbstractCode.Model):
4748
...,
4849
title='Computer',
4950
description='The remote computer on which the executable resides.',
50-
orm_to_model=lambda node, _: node.computer.label,
51+
orm_to_model=lambda node, _: cast('InstalledCode', node).computer.label,
5152
short_name='-Y',
5253
priority=2,
5354
)
5455
filepath_executable: str = MetadataField(
5556
...,
5657
title='Filepath executable',
5758
description='Filepath of the executable on the remote computer.',
58-
orm_to_model=lambda node, _: str(node.filepath_executable), # type: ignore[attr-defined]
59+
orm_to_model=lambda node, _: str(cast('InstalledCode', node).filepath_executable),
5960
short_name='-X',
6061
priority=1,
6162
)
@@ -83,7 +84,7 @@ def __init__(self, computer: Computer, filepath_executable: str, **kwargs):
8384
"""
8485
super().__init__(**kwargs)
8586
self.computer = computer
86-
self.filepath_executable = filepath_executable # type: ignore[assignment]
87+
self.filepath_executable = filepath_executable
8788

8889
def _validate(self):
8990
"""Validate the instance by checking that a computer has been defined.
@@ -159,7 +160,7 @@ def get_executable(self) -> pathlib.PurePath:
159160
"""
160161
return self.filepath_executable
161162

162-
@property # type: ignore[override]
163+
@property
163164
def computer(self) -> Computer:
164165
"""Return the computer of this code."""
165166
assert self.backend_entity.computer is not None

src/aiida/orm/nodes/data/code/legacy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def get_code_helper(cls, label, machinename=None, backend=None):
231231
return result[0]
232232

233233
@classmethod
234-
def get(cls, pk=None, label=None, machinename=None):
234+
def get(cls, pk=None, label=None, machinename=None): # type: ignore[override]
235235
"""Get a Computer object with given identifier string, that can either be
236236
the numeric ID (pk), or the label (and computername) (if unique).
237237

src/aiida/orm/nodes/data/code/portable.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def __init__(
104104
if not filepath_files_path.is_dir():
105105
raise ValueError(f'The filepath `{filepath_files}` is not a directory.')
106106

107-
self.filepath_executable = filepath_executable # type: ignore[assignment] # should be fixed in mypy 1.15 see mypy/commit/1eb9d4c
107+
self.filepath_executable = filepath_executable
108108
self.base.repository.put_object_from_tree(str(filepath_files))
109109

110110
def _validate(self):

src/aiida/orm/nodes/process/calculation/calcfunction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def validate_outgoing(self, target: 'Node', link_type: LinkType, link_label: str
4747
)
4848

4949

50-
class CalcFunctionNode(FunctionCalculationMixin, CalculationNode): # type: ignore[misc]
50+
class CalcFunctionNode(FunctionCalculationMixin, CalculationNode):
5151
"""ORM class for all nodes representing the execution of a calcfunction."""
5252

5353
_CLS_NODE_LINKS = CalcFunctionNodeLinks

0 commit comments

Comments
 (0)