Skip to content

Commit

Permalink
Adds support for typing.Dict types (#231)
Browse files Browse the repository at this point in the history
* Adds support for typing.Dict types.
* Additional unit tests.
* Additional docs.
* restricted dep version for pydoc-markdown to < 4.6.* as these versions require yapf which breaks docs
* linted
  • Loading branch information
ncilfone committed Mar 17, 2022
1 parent a761359 commit 8617af6
Show file tree
Hide file tree
Showing 31 changed files with 837 additions and 402 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@ See [Releases](https://github.com/fidelity/spock/releases) for more information.

<details>

#### March 11th, 2022
* Added support for simple `typing.Callable` types (WIP: advanced versions)
#### March 17th, 2022
* Added support for `typing.Callable` types (includes advanced types such as `List[List[Callable]]`)
* Added support for `typing.Dict` types with type checking for types of both keys and values (includes advanced types
such as `Dict[str, Tuple[Callable, Callable]]`)
* Added support for post init hooks that allow for validation on parameters defined within `@spock` decorated classes.
Additionally, added some common validation check to utils (within, greater than, less than, etc.)
* Updated unit tests to support Python 3.10
Expand Down
4 changes: 2 additions & 2 deletions requirements/DEV_REQUIREMENTS.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
black~=22.1 ; python_version >= '3.7'
black~=21.4b0 ; python_version == '3.6'
coveralls~=3.3
coverage~=6.1
coverage[toml]~=6.1
isort~=5.10
moto~=3.0
pydoc-markdown~=4.3 ; python_version >= '3.7'
pydoc-markdown~=4.3, < 4.6.* ; python_version >= '3.7'
pydoc-markdown~=3.13 ; python_version == '3.6'
pytest~=7.0
pytest-cov~=3.0
Expand Down
24 changes: 13 additions & 11 deletions spock/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"""Handles mapping config arguments to a payload with both general and class specific sets"""


from typing import Any, Dict, Iterable

from _warnings import warn

from spock.exceptions import _SpockDuplicateArgumentError
Expand All @@ -20,7 +22,7 @@ class SpockArguments:
"""

def __init__(self, arguments: dict, config_dag: Graph):
def __init__(self, arguments: Dict, config_dag: Graph):
"""Init call for SpockArguments class
Handles creating a clean arguments dictionary that can be cleanly mapped to spock classes
Expand All @@ -39,7 +41,7 @@ def __init__(self, arguments: dict, config_dag: Graph):
general_arguments, attribute_name_to_config_name_mapping
)

def __getitem__(self, key: str):
def __getitem__(self, key: str) -> Any:
"""Gets value from the _arguments dictionary
Args:
Expand All @@ -51,7 +53,7 @@ def __getitem__(self, key: str):
"""
return self._arguments[key]

def __iter__(self):
def __iter__(self) -> Iterable[str]:
"""Returns the next value of the keys within the _arguments dictionary
Returns:
Expand All @@ -77,7 +79,7 @@ def values(self):
return self._arguments.values()

@staticmethod
def _get_general_arguments(arguments: dict, config_dag: Graph):
def _get_general_arguments(arguments: Dict, config_dag: Graph) -> Dict:
"""Creates a dictionary of config file parameters that are defined at the general level (not class specific)
Args:
Expand All @@ -96,8 +98,8 @@ def _get_general_arguments(arguments: dict, config_dag: Graph):
}

def _attribute_name_to_config_name_mapping(
self, config_dag: Graph, general_arguments: dict
):
self, config_dag: Graph, general_arguments: Dict
) -> Dict:
"""Returns a mapping of names to spock config class parameter names
Args:
Expand Down Expand Up @@ -125,8 +127,8 @@ def _attribute_name_to_config_name_mapping(

@staticmethod
def _is_duplicated_key(
attribute_name_to_config_name_mapping: dict, attr_name: str, config_name: str
):
attribute_name_to_config_name_mapping: Dict, attr_name: str, config_name: str
) -> bool:
"""Checks if a duplicated key exists in multiple classes
Args:
Expand All @@ -144,8 +146,8 @@ def _is_duplicated_key(
)

def _assign_general_arguments_to_config(
self, general_arguments: dict, attribute_name_to_config_name_mapping: dict
):
self, general_arguments: Dict, attribute_name_to_config_name_mapping: Dict
) -> None:
"""Assigns the values from general definitions to values within specific classes if the specific definition
doesn't exist
Expand All @@ -172,7 +174,7 @@ def _assign_general_arguments_to_config(
self._arguments[config_name] = {arg: value}

@staticmethod
def _clean_arguments(arguments: dict, general_arguments: dict):
def _clean_arguments(arguments: Dict, general_arguments: Dict) -> Dict:
"""Sets up a clean dictionary for those not in the general dictionary
Args:
Expand Down
27 changes: 16 additions & 11 deletions spock/backend/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
# SPDX-License-Identifier: Apache-2.0

"""Handles the building/saving of the configurations from the Spock config classes"""
import sys
import typing
import argparse
from abc import ABC, abstractmethod
from enum import EnumMeta
from typing import List
from typing import Dict, List

import attr

Expand All @@ -18,7 +17,7 @@
from spock.backend.spaces import BuilderSpace
from spock.backend.wrappers import Spockspace
from spock.graph import Graph
from spock.utils import _SpockVariadicGenericAlias, make_argument
from spock.utils import _C, _T, _SpockVariadicGenericAlias, make_argument


class BaseBuilder(ABC): # pylint: disable=too-few-public-methods
Expand Down Expand Up @@ -75,7 +74,9 @@ def graph(self):

@staticmethod
@abstractmethod
def _make_group_override_parser(parser, class_obj, class_name):
def _make_group_override_parser(
parser: argparse.ArgumentParser, class_obj: _C, class_name: str
) -> argparse.ArgumentParser:
"""Makes a name specific override parser for a given class obj
Takes a class object of the backend and adds a new argument group with argument names given with name
Expand All @@ -91,7 +92,7 @@ def _make_group_override_parser(parser, class_obj, class_name):
"""

def handle_help_info(self):
def handle_help_info(self) -> None:
"""Handles walking through classes to get help info
For each class this function will search __doc__ and attempt to pull out help information for both the class
Expand All @@ -108,7 +109,7 @@ def handle_help_info(self):
max_indent=self._max_indent,
)

def generate(self, dict_args):
def generate(self, dict_args: Dict) -> Spockspace:
"""Method to auto-generate the actual class instances from the generated args
Based on the generated arguments groups and the args read in from the config file(s)
Expand All @@ -123,7 +124,7 @@ def generate(self, dict_args):
spock_space_kwargs = self.resolve_spock_space_kwargs(self._graph, dict_args)
return Spockspace(**spock_space_kwargs)

def resolve_spock_space_kwargs(self, graph: Graph, dict_args: dict) -> dict:
def resolve_spock_space_kwargs(self, graph: Graph, dict_args: Dict) -> Dict:
"""Build the dictionary that will define the spock space.
Args:
Expand Down Expand Up @@ -152,7 +153,9 @@ def resolve_spock_space_kwargs(self, graph: Graph, dict_args: dict) -> dict:

return spock_space

def build_override_parsers(self, parser):
def build_override_parsers(
self, parser: argparse.ArgumentParser
) -> argparse.ArgumentParser:
"""Creates parsers for command-line overrides
Builds the basic command line parser for configs and help then iterates through each attr instance to make
Expand All @@ -172,7 +175,7 @@ def build_override_parsers(self, parser):
)
return parser

def _extract_other_types(self, typed, module_name):
def _extract_other_types(self, typed: _T, module_name: str) -> List:
"""Takes a high level type and recursively extracts any enum or class types
Args:
Expand Down Expand Up @@ -237,7 +240,9 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, module_name="spock.backend.config", **kwargs)

@staticmethod
def _make_group_override_parser(parser, class_obj, class_name):
def _make_group_override_parser(
parser: argparse.ArgumentParser, class_obj: _C, class_name: str
) -> argparse.ArgumentParser:
"""Makes a name specific override parser for a given class obj
Takes a class object of the backend and adds a new argument group with argument names given with name
Expand Down
Loading

0 comments on commit 8617af6

Please sign in to comment.