Skip to content

Commit

Permalink
Generates type-hints for non-scalar parameters.
Browse files Browse the repository at this point in the history
Adds tests to verify that we do in fact support non-scalar parameters.

Removes legacy test that is no longer necessary.
  • Loading branch information
Daverball committed Sep 3, 2024
1 parent 4e21bb0 commit 1780bfd
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 122 deletions.
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ Latest Release
Changelog
---------

- Generates type hints for non-scalar parameters
[Daverball]

0.20.0 (2024-08-28)
~~~~~~~~~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ log_level = "INFO"
testpaths = ["tests"]
filterwarnings = [
"ignore:The _yaml extension module is now located at yaml._yaml",
"ignore:AnsibleCollectionFinder has already been configured"
]

[tool.coverage.run]
Expand Down
27 changes: 21 additions & 6 deletions scripts/generate_module_hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
'raw': 'str',
'str': 'str',
'int': 'int',
'float': 'float',
'bool': 'bool',
# NOTE: Technically you can construct a `PathLike` that will not work
# but since pretty much all of them convert to str just fine
# we accept it anyways
'path': 'StrPath',
# FIXME: We don't support complex parameter types
'list': 'NotSupported',
'dict': 'NotSupported',
'list': 'Sequence',
'dict': 'Mapping',
}


Expand Down Expand Up @@ -81,7 +81,7 @@ def write_function_parameter_list(
# if the type is not set it appears to always be str
type_name = type_map.get(meta.get('type', 'string'), 'Incomplete')
if print_default := (
type_name not in ('NotSupported', 'Incomplete')
type_name not in ('Mapping', 'Sequence', 'Incomplete')
and 'default' in meta
and (default := meta['default']) is not None
):
Expand All @@ -106,7 +106,22 @@ def write_function_parameter_list(
else:
type_name = f'{default_type} | {type_name}'

if (
if type_name == 'Sequence':
element_type = type_map.get(meta.get('elements', ''), 'Incomplete')
if element_type == 'Mapping':
element_type = 'Mapping[str, Incomplete]'
type_name = f'{type_name}[{element_type}]'
# NOTE: Technically Ansible will turn scalar values into
# 1-element lists automatically, so we could accept
# `sequence | scalar`, but that probably defeats the
# purpose of static typing. I'd rather be a little bit
# more strict here. There's already plenty of other
# argument types where Ansible is more forgiviing.

elif type_name == 'Mapping':
type_name = 'Mapping[str, Incomplete]'

elif (
type_name == 'str'
and 'choices' in meta
# this means we need to support arbitrary strings
Expand Down Expand Up @@ -491,12 +506,12 @@ def write_return_type(returns: dict[str, Any] | None) -> None:
if TYPE_CHECKING:
from _typeshed import StrPath
from collections.abc import Mapping, Sequence
from suitable._module_types import (
''')
modules_py.write('''\
)
from suitable.types import Incomplete
from typing_extensions import Never as NotSupported
# HACK: Get Sphinx to display the default values we don't
Expand Down
Loading

0 comments on commit 1780bfd

Please sign in to comment.