summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormontezdesousa <79287829+montezdesousa@users.noreply.github.com>2024-03-22 17:53:40 +0000
committerGitHub <noreply@github.com>2024-03-22 17:53:40 +0000
commit23135abf1b3e42bf5438dc9003b20966ce01e5cf (patch)
tree4d25bcd933ffa8f30613cbd6bc0309cd851a4aef
parent80d3ac613101886e210ee1d6f9d5506cf3a6ae07 (diff)
[BugFix] - Bring back mypy (#6242)
* first batch * another * another * another batch unyped defs * final untyped defs * update yml * pylint * remove unecessary __init__.py files * Revert "remove unecessary __init__.py files" This reverts commit 5977eccfee7e2f536d7f2d039ba7a753d4c66695. * fix company_news typing * rename func * fix tests * tests
-rw-r--r--.github/workflows/linting.yml2
-rw-r--r--openbb_platform/core/openbb_core/api/router/commands.py15
-rw-r--r--openbb_platform/core/openbb_core/app/command_runner.py8
-rw-r--r--openbb_platform/core/openbb_core/app/deprecation.py4
-rw-r--r--openbb_platform/core/openbb_core/app/model/abstract/singleton.py2
-rw-r--r--openbb_platform/core/openbb_core/app/model/example.py4
-rw-r--r--openbb_platform/core/openbb_core/app/model/metadata.py24
-rw-r--r--openbb_platform/core/openbb_core/app/model/obbject.py73
-rw-r--r--openbb_platform/core/openbb_core/app/provider_interface.py118
-rw-r--r--openbb_platform/core/openbb_core/app/router.py10
-rw-r--r--openbb_platform/core/openbb_core/app/static/account.py10
-rw-r--r--openbb_platform/core/openbb_core/app/static/utils/decorators.py10
-rw-r--r--openbb_platform/core/openbb_core/app/utils.py8
-rw-r--r--openbb_platform/core/openbb_core/provider/abstract/fetcher.py2
-rw-r--r--openbb_platform/core/openbb_core/provider/registry_map.py12
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/cpi.py2
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/spot.py2
-rw-r--r--openbb_platform/core/openbb_core/provider/utils/helpers.py48
-rw-r--r--openbb_platform/core/tests/api/test_auth/test_user_auth.py2
-rw-r--r--openbb_platform/core/tests/api/test_dependency/test_coverage.py2
-rw-r--r--openbb_platform/core/tests/api/test_dependency/test_system.py2
-rw-r--r--openbb_platform/core/tests/app/logs/formatters/test_formatter_with_exceptions.py2
-rw-r--r--openbb_platform/core/tests/app/logs/test_handlers_manager.py2
-rw-r--r--openbb_platform/core/tests/app/logs/test_logging_service.py46
-rw-r--r--openbb_platform/core/tests/app/logs/utils/test_expired_files.py3
-rw-r--r--openbb_platform/core/tests/app/model/abstract/test_tagged.py2
-rw-r--r--openbb_platform/core/tests/app/model/abstract/test_warning.py2
-rw-r--r--openbb_platform/core/tests/app/model/charts/test_chart.py2
-rw-r--r--openbb_platform/core/tests/app/model/hub/test_hub_session.py5
-rw-r--r--openbb_platform/core/tests/app/model/test_command_context.py2
-rw-r--r--openbb_platform/core/tests/app/model/test_defaults.py4
-rw-r--r--openbb_platform/core/tests/app/model/test_metadata.py2
-rw-r--r--openbb_platform/core/tests/app/model/test_obbject.py18
-rw-r--r--openbb_platform/core/tests/app/model/test_system_settings.py36
-rw-r--r--openbb_platform/core/tests/app/service/test_user_service.py11
-rw-r--r--openbb_platform/core/tests/app/static/test_filters.py4
-rw-r--r--openbb_platform/core/tests/app/test_command_runner.py17
-rw-r--r--openbb_platform/core/tests/app/test_deprecation.py10
-rw-r--r--openbb_platform/core/tests/app/test_extension_loader.py25
-rw-r--r--openbb_platform/core/tests/app/test_platform_router.py2
-rw-r--r--openbb_platform/core/tests/app/test_utils.py12
-rw-r--r--openbb_platform/core/tests/provider/abstract/test_data.py10
-rw-r--r--openbb_platform/core/tests/provider/abstract/test_provider.py5
-rw-r--r--openbb_platform/core/tests/provider/abstract/test_query_params.py6
-rw-r--r--openbb_platform/core/tests/provider/standard_models/test_standard_models.py4
-rw-r--r--openbb_platform/core/tests/provider/utils/test_client.py18
-rw-r--r--openbb_platform/core/tests/provider/utils/test_helpers.py2
-rw-r--r--openbb_platform/providers/fmp/openbb_fmp/models/company_news.py2
-rw-r--r--openbb_platform/providers/intrinio/openbb_intrinio/models/company_news.py8
49 files changed, 343 insertions, 279 deletions
diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml
index edf6025d597..ccabe3a349d 100644
--- a/.github/workflows/linting.yml
+++ b/.github/workflows/linting.yml
@@ -68,8 +68,8 @@ jobs:
- run: |
# Run linters for openbb_platform
if [ -n "${{ env.platform_files }}" ]; then
- # TODO: Add mypy to this part of the linting workflow once we're ready
pylint ${{ env.platform_files }}
+ mypy ${{ env.platform_files }} --ignore-missing-imports --check-untyped-defs
else
echo "No Python files changed in openbb_platform"
fi
diff --git a/openbb_platform/core/openbb_core/api/router/commands.py b/openbb_platform/core/openbb_core/api/router/commands.py
index 96334f549fa..7b644cca372 100644
--- a/openbb_platform/core/openbb_core/api/router/commands.py
+++ b/openbb_platform/core/openbb_core/api/router/commands.py
@@ -134,19 +134,26 @@ def validate_output(c_out: OBBject) -> OBBject:
json_schema_extra = field.json_schema_extra if field else None
# case where 1st layer field needs to be excluded
- if json_schema_extra and json_schema_extra.get("exclude_from_api", None):
+ if (
+ json_schema_extra
+ and isinstance(json_schema_extra, dict)
+ and json_schema_extra.get("exclude_from_api", None)
+ ):
delattr(c_out, key)
# if it's a model with nested fields
elif is_model(type_):
for field_name, field in type_.__fields__.items():
- if field.json_schema_extra and field.json_schema_extra.get(
- "exclude_from_api", None
+ extra = getattr(field, "json_schema_extra", None)
+ if (
+ extra
+ and isinstance(extra, dict)
+ and extra.get("exclude_from_api", None)
):
delattr(value, field_name)
# if it's a yet a nested model we need to go deeper in the recursion
- elif is_model(field.annotation):
+ elif is_model(getattr(field, "annotation", None)):
exclude_fields_from_api(field_name, getattr(value, field_name))
for k, v in c_out.model_copy():
diff --git a/openbb_platform/core/openbb_core/app/command_runner.py b/openbb_platform/core/openbb_core/app/command_runner.py
index c8d7f43e377..33fb4def99f 100644
--- a/openbb_platform/core/openbb_core/app/command_runner.py
+++ b/openbb_platform/core/openbb_core/app/command_runner.py
@@ -6,7 +6,7 @@ from datetime import datetime
from inspect import Parameter, signature
from sys import exc_info
from time import perf_counter_ns
-from typing import Any, Callable, Dict, List, Optional, Tuple
+from typing import Any, Callable, Dict, List, Optional, Tuple, Type
from warnings import catch_warnings, showwarning, warn
from fastapi.params import Query
@@ -181,7 +181,7 @@ class ParametersBuilder:
def _warn_kwargs(
provider_choices: Dict[str, Any],
extra_params: Dict[str, Any],
- model: BaseModel,
+ model: Type[BaseModel],
) -> None:
"""Warn if kwargs received and ignored by the validation model."""
# We only check the extra_params annotation because ignored fields
@@ -247,7 +247,7 @@ class ParametersBuilder:
@classmethod
def build(
cls,
- args: Tuple[Any],
+ args: Tuple[Any, ...],
execution_context: ExecutionContext,
func: Callable,
route: str,
@@ -317,7 +317,7 @@ class StaticCommandRunner:
async def _execute_func(
cls,
route: str,
- args: Tuple[Any],
+ args: Tuple[Any, ...],
execution_context: ExecutionContext,
func: Callable,
kwargs: Dict[str, Any],
diff --git a/openbb_platform/core/openbb_core/app/deprecation.py b/openbb_platform/core/openbb_core/app/deprecation.py
index 482338bf32d..5dd38c1ae54 100644
--- a/openbb_platform/core/openbb_core/app/deprecation.py
+++ b/openbb_platform/core/openbb_core/app/deprecation.py
@@ -12,10 +12,10 @@ from openbb_core.app.version import VERSION, get_major_minor
class DeprecationSummary(str):
"""A string subclass that can be used to store deprecation metadata."""
- def __new__(cls, value, metadata):
+ def __new__(cls, value: str, metadata: DeprecationWarning):
"""Create a new instance of the class."""
obj = str.__new__(cls, value)
- obj.metadata = metadata
+ setattr(obj, "metadata", metadata)
return obj
diff --git a/openbb_platform/core/openbb_core/app/model/abstract/singleton.py b/openbb_platform/core/openbb_core/app/model/abstract/singleton.py
index 7d6bad71a1b..3575186ee22 100644
--- a/openbb_platform/core/openbb_core/app/model/abstract/singleton.py
+++ b/openbb_platform/core/openbb_core/app/model/abstract/singleton.py
@@ -7,7 +7,7 @@ class SingletonMeta(type, Generic[T]):
# TODO : check if we want to update this to be thread safe
_instances: Dict[T, T] = {}
- def __call__(cls, *args, **kwargs):
+ def __call__(cls: "SingletonMeta", *args, **kwargs):
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
diff --git a/openbb_platform/core/openbb_core/app/model/example.py b/openbb_platform/core/openbb_core/app/model/example.py
index 27f0e77084a..25772107824 100644
--- a/openbb_platform/core/openbb_core/app/model/example.py
+++ b/openbb_platform/core/openbb_core/app/model/example.py
@@ -2,7 +2,7 @@
from abc import abstractmethod
from datetime import date, datetime, timedelta
-from typing import Any, Dict, List, Literal, Optional, Union, _GenericAlias
+from typing import Any, Dict, List, Literal, Optional, Union, _GenericAlias # type: ignore
from pydantic import (
BaseModel,
@@ -58,7 +58,7 @@ class APIEx(Example):
@staticmethod
def _unpack_type(type_: type) -> set:
- """Unpack types from types, example Union[List[str], int] -> {str, int}."""
+ """Unpack types from types, example Union[List[str], int] -> {typing._GenericAlias, int}."""
if (
hasattr(type_, "__args__")
and type(type_) # pylint: disable=unidiomatic-typecheck
diff --git a/openbb_platform/core/openbb_core/app/model/metadata.py b/openbb_platform/core/openbb_core/app/model/metadata.py
index e5ea6a0f5bf..cf421fca7e0 100644
--- a/openbb_platform/core/openbb_core/app/model/metadata.py
+++ b/openbb_platform/core/openbb_core/app/model/metadata.py
@@ -1,6 +1,6 @@
from datetime import datetime
from inspect import isclass
-from typing import Any, Dict
+from typing import Any, Dict, Optional, Sequence, Union
import numpy as np
import pandas as pd
@@ -36,7 +36,7 @@ class Metadata(BaseModel):
value is kept or trimmed to 80 characters.
"""
for arg, arg_val in v.items():
- new_arg_val = None
+ new_arg_val: Optional[Union[str, dict[str, Sequence[Any]]]] = None
# Data
if isclass(type(arg_val)) and issubclass(type(arg_val), Data):
@@ -47,30 +47,32 @@ class Metadata(BaseModel):
# List[Data]
if isinstance(arg_val, list) and issubclass(type(arg_val[0]), Data):
- columns = [list(d.model_dump().keys()) for d in arg_val]
- columns = (item for sublist in columns for item in sublist) # flatten
+ _columns = [list(d.model_dump().keys()) for d in arg_val]
+ ld_columns = (
+ item for sublist in _columns for item in sublist
+ ) # flatten
new_arg_val = {
"type": f"List[{type(arg_val[0]).__name__}]",
- "columns": list(set(columns)),
+ "columns": list(set(ld_columns)),
}
# DataFrame
elif isinstance(arg_val, pd.DataFrame):
- columns = (
+ df_columns = (
list(arg_val.index.names) + arg_val.columns.tolist()
if any(index is not None for index in list(arg_val.index.names))
else arg_val.columns.tolist()
)
new_arg_val = {
"type": f"{type(arg_val).__name__}",
- "columns": columns,
+ "columns": df_columns,
}
# List[DataFrame]
elif isinstance(arg_val, list) and issubclass(
type(arg_val[0]), pd.DataFrame
):
- columns = [
+ ldf_columns = [
(
list(df.index.names) + df.columns.tolist()
if any(index is not None for index in list(df.index.names))
@@ -80,7 +82,7 @@ class Metadata(BaseModel):
]
new_arg_val = {
"type": f"List[{type(arg_val[0]).__name__}]",
- "columns": columns,
+ "columns": ldf_columns,
}
# Series
@@ -92,7 +94,7 @@ class Metadata(BaseModel):
# List[Series]
elif isinstance(arg_val, list) and isinstance(arg_val[0], pd.Series):
- columns = [
+ ls_columns = [
(
list(series.index.names) + [series.name]
if any(index is not None for index in list(series.index.names))
@@ -102,7 +104,7 @@ class Metadata(BaseModel):
]
new_arg_val = {
"type": f"List[{type(arg_val[0]).__name__}]",
- "columns": columns,
+ "columns": ls_columns,
}
# ndarray
diff --git a/openbb_platform/core/openbb_core/app/model/obbject.py b/openbb_platform/core/openbb_core/app/model/obbject.py
index 9f2a2da8746..89232702405 100644
--- a/openbb_platform/core/openbb_core/app/model/obbject.py
+++ b/openbb_platform/core/openbb_core/app/model/obbject.py
@@ -8,6 +8,7 @@ from typing import (
ClassVar,
Dict,
Generic,
+ Hashable,
List,
Literal,
Optional,
@@ -82,30 +83,32 @@ class OBBject(Tagged, Generic[T]):
@classmethod
def results_type_repr(cls, params: Optional[Any] = None) -> str:
- """Return the results type name."""
+ """Return the results type representation."""
results_field = cls.model_fields.get("results")
- type_ = params[0] if params else results_field.annotation
- name = type_.__name__ if hasattr(type_, "__name__") else str(type_)
+ type_repr = "Any"
+ if results_field:
+ type_ = params[0] if params else results_field.annotation
+ type_repr = getattr(type_, "__name__", str(type_))
- if (json_schema_extra := results_field.json_schema_extra) is not None:
- model = json_schema_extra.get("model")
+ if json_schema_extra := getattr(results_field, "json_schema_extra", {}):
+ model = json_schema_extra.get("model", "Any")
- if json_schema_extra.get("is_union"):
- return f"Union[List[{model}], {model}]"
- if json_schema_extra.get("has_list"):
- return f"List[{model}]"
+ if json_schema_extra.get("is_union"):
+ return f"Union[List[{model}], {model}]"
+ if json_schema_extra.get("has_list"):
+ return f"List[{model}]"
- return model
+ return model
- if "typing." in str(type_):
- unpack_optional = sub(r"Optional\[(.*)\]", r"\1", str(type_))
- name = sub(
- r"(\w+\.)*(\w+)?(\, NoneType)?",
- r"\2",
- unpack_optional,
- )
+ if "typing." in str(type_):
+ unpack_optional = sub(r"Optional\[(.*)\]", r"\1", str(type_))
+ type_repr = sub(
+ r"(\w+\.)*(\w+)?(\, NoneType)?",
+ r"\2",
+ unpack_optional,
+ )
- return name
+ return type_repr
@classmethod
def model_parametrized_name(cls, params: Any) -> str:
@@ -189,9 +192,9 @@ class OBBject(Tagged, Generic[T]):
# List[List | str | int | float] | Dict[str, Dict | List | BaseModel]
else:
try:
- df = pd.DataFrame(res)
+ df = pd.DataFrame(res) # type: ignore[call-overload]
# Set index, if any
- if index is not None and index in df.columns:
+ if df is not None and index is not None and index in df.columns:
df.set_index(index, inplace=True)
except ValueError:
@@ -245,7 +248,7 @@ class OBBject(Tagged, Generic[T]):
orient: Literal[
"dict", "list", "series", "split", "tight", "records", "index"
] = "list",
- ) -> Dict[str, List]:
+ ) -> Union[Dict[Hashable, Any], List[Dict[Hashable, Any]]]:
"""Convert results field to a dictionary using any of pandas to_dict options.
Parameters
@@ -256,25 +259,21 @@ class OBBject(Tagged, Generic[T]):
Returns
-------
- Dict[str, List]
- Dictionary of lists.
+ Union[Dict[Hashable, Any], List[Dict[Hashable, Any]]]
+ Dictionary of lists or list of dictionaries if orient is "records".
"""
- df = self.to_dataframe(index=None) # type: ignore
- transpose = False
- if orient == "list":
-