Files
OpenBB/openbb_terminal/portfolio/portfolio_optimization/parameters/Parameter.py
Colin Delahunty cebf454cdf Added flake8-simplify (#4227)
* Added flake8-simplify

* Update linting.yml

* update.  left 1 for you colin

* Fix that one

* Missed

* Fix

* mypy

---------

Co-authored-by: james <jmaslek11@gmail.com>
2023-02-20 19:27:34 -05:00

87 lines
2.7 KiB
Python

from dataclasses import dataclass
from typing import Any, List, Optional
# pylint: disable=unidiomatic-typecheck
@dataclass(frozen=True)
class Parameter:
"""Class for storing parameters. This dataclass is frozen so no attributes can be changed after initialization.
Parameters
----------
name : str
Name of the parameter.
type_ : type
Type of the parameter.
default : Any
Default value of the parameter.
choices : Optional[List[Any]]
List of possible values for the parameter.
"""
name: str
type_: Any
default: Any
choices: Optional[List[Any]] = None
def __post_init__(self):
"""Post initialization."""
self.validate()
def validate(self):
"""Validate the value of the parameter.
Parameters
----------
value : Any
Value of the parameter.
Raises
------
TypeError
If the value is not of the correct type.
ValueError
If the value is not in the list of possible values.
"""
if not self.validate_type(self.default):
raise TypeError(
f"Default for '{self.name}' must be of type '{self.type_.__name__}'."
)
if self.choices is not None and not all(
self.validate_type(choice) for choice in self.choices
):
raise TypeError(
f"Choices must be of the same type as the parameter.\n"
f"'{self.name}': '{self.choices}' -> '{self.type_.__name__}'"
)
if self.choices is not None and self.default not in self.choices:
raise ValueError(
f"Parameter '{self.name}' must be one of type '{self.choices}'."
)
def validate_type(self, value: Any) -> bool:
"""Check if the value is of the correct type.
Parameters
----------
value : Any
Value of the parameter.
Returns
-------
bool
True if the value is of the correct type, False otherwise.
"""
# Temporary workaround until we drop Python 3.9 for:
# Error: Subscripted generics cannot be used with class and instance checks
#
# isinstance for subscripted generics (e.g. List[str]) is only available
# in Python 3.10, so this method does not check for the type of subscripted generics.
# TODO: Though we should implement it.
# See https://stackoverflow.com/questions/70825351/python-3-typeerror-subscripted-generics-cannot-be-used-with-class-and-instance # noqa: E501
try:
return isinstance(value, self.type_)
except Exception as _: # noqa: F841
return True