- example.py: mark the base Example.scope field frozen so the (#7798)

Literal[api]/Literal[python] subclass overrides are covariant
  read-only narrowings. Subclass fields stay writable at runtime.
- method_definition.py, options_chains.py: pydantic 2.14 types
  FieldInfo.annotation as TypeForm[Any] | None, which ty rejects in
  Union[]/Annotated[] and where  is expected; bind it as Any.
  Use FieldInfo.get_default(call_default_factory=True) instead of
  calling the default_factory union directly.
- economy_views.py: read data/obbject_item without None defaults in the
  IMF shipping views. charting always sets obbject_item, and data is
  only popped when present and not None.- finra, jodi, eia: annotate @asynccontextmanager/@contextmanager
  functions with AsyncGenerator/Generator instead of the deprecated
  AsyncIterator/Iterator return types.
- charting: cast the darts forecast dataset to TimeSeries before
  indexing so .all_values resolves instead of hitting ndarray.
- fred, imf, nasdaq, sec, tmx: turn off invalid-attribute-override and
  invalid-mutable-override for models/** only, following the cboe
  precedent. Provider models extend the standard models by narrowing
  query params to Literals or widening fields to Optional, which these
  rules flag by design.

Co-authored-by: dlee-bq <325002271+dlee-bq@users.noreply.github.com>
This commit is contained in:
dlee-bq
2026-10-17 20:50:39 +00:00
committed by GitHub
parent d67b32e2f9
commit 7f04334398
13 changed files with 55 additions and 17 deletions

View File

@@ -18,7 +18,7 @@ QUOTE_TYPES = {str, date}
class Example(BaseModel):
"""Example model."""
scope: str
scope: str = Field(frozen=True)
model_config = ConfigDict(validate_assignment=True)

View File

@@ -791,7 +791,7 @@ class MethodDefinition:
qp_model := MethodDefinition.query_params_model(param.annotation)
) is not None:
for field_name, field in qp_model.model_fields.items():
field_anno = field.annotation
field_anno: Any = field.annotation
new_type = MethodDefinition.get_expanded_type(
field_name, None, field_anno
)
@@ -807,7 +807,7 @@ class MethodDefinition:
if field.is_required():
field_default: Any = Parameter.empty
elif field.default_factory is not None:
field_default = field.default_factory()
field_default = field.get_default(call_default_factory=True)
else:
field_default = field.default
formatted[field_name] = Parameter(

View File

@@ -390,7 +390,7 @@ class OptionsChainsData(OptionsChainsProperties):
row_fields: dict[str, Any] = {}
for field_name, field_info in cls.model_fields.items():
annotation = field_info.annotation
annotation: Any = field_info.annotation
inner = (
get_args(annotation)[0]
if get_origin(annotation) is list

View File

@@ -567,9 +567,9 @@ class EconomyViews:
or getattr(kwargs["charting_settings"], "chart_style", "dark")
)
data = (
kwargs.pop("data", None)
kwargs.pop("data")
if "data" in kwargs and kwargs["data"] is not None
else kwargs.get("obbject_item")
else kwargs["obbject_item"]
)
fig = plot_chokepoint_annual_avg_vessels(data, theme=theme)
fig.update_layout(
@@ -601,9 +601,9 @@ class EconomyViews:
raise RuntimeError("Unable to import the required module.") from e
data = (
kwargs.pop("data", None)
kwargs.pop("data")
if "data" in kwargs and kwargs["data"] is not None
else kwargs.get("obbject_item")
else kwargs["obbject_item"]
)
fig = plot_port_info_map(data)
fig.update_layout(

View File

@@ -11,6 +11,7 @@ from typing import (
Literal,
TypeVar,
Union,
cast,
)
from warnings import warn
@@ -325,7 +326,9 @@ class OpenBBFigure(go.Figure):
if forecast: # pragma: no cover - darts forecast path (darts is an optional dependency)
components = list(dataset.components[:4]) # ty: ignore[unresolved-attribute]
values = (
dataset[components].all_values(copy=False).flatten(order="F")
cast("TimeSeries", dataset)[components]
.all_values(copy=False)
.flatten(order="F")
)
n_components = len(components)
n_entries = len(values) // n_components

View File

@@ -2,7 +2,7 @@
import re
import threading
from collections.abc import AsyncIterator
from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager
from pathlib import Path
from typing import Annotated, Any
@@ -2062,7 +2062,7 @@ async def render_browser(
@asynccontextmanager
async def lifespan(_app) -> AsyncIterator[None]:
async def lifespan(_app) -> AsyncGenerator[None, None]:
"""Warm the proxy cache for the lifetime of the API, cleaning up on shutdown."""
_schedule_warm()
try:

View File

@@ -1,6 +1,6 @@
"""HTTP transport for the FINRA data services."""
from collections.abc import AsyncIterator, Awaitable, Callable
from collections.abc import AsyncGenerator, Awaitable, Callable
from contextlib import asynccontextmanager
from typing import Any
@@ -243,7 +243,7 @@ class QueryApiSession:
@asynccontextmanager
async def query_api_session() -> AsyncIterator[QueryApiSession]:
async def query_api_session() -> AsyncGenerator[QueryApiSession, None]:
"""Open a session on the public FINRA Query API.
Yields
@@ -412,7 +412,7 @@ async def _trace_token(session: Any) -> str:
@asynccontextmanager
async def trace_session() -> AsyncIterator[TraceSession]:
async def trace_session() -> AsyncGenerator[TraceSession, None]:
"""Open a session on the public TRACE data service.
Yields
@@ -590,7 +590,7 @@ class MarketDataSession:
@asynccontextmanager
async def market_data_session() -> AsyncIterator[MarketDataSession]:
async def market_data_session() -> AsyncGenerator[MarketDataSession, None]:
"""Open a seeded session on the FINRA Market Data Center.
Yields

View File

@@ -83,6 +83,13 @@ exclude = ["tests", "integration"]
[tool.ty.rules]
unresolved-import = "warn"
[[tool.ty.overrides]]
include = ["openbb_fred/models/**"]
[tool.ty.overrides.rules]
invalid-attribute-override = "ignore"
invalid-mutable-override = "ignore"
[tool.coverage.run]
branch = true
source = ["openbb_fred"]

View File

@@ -110,6 +110,13 @@ exclude = ["tests", "integration", "openbb_imf/utils/generate_cache.py"]
[tool.ty.rules]
unresolved-import = "ignore"
[[tool.ty.overrides]]
include = ["openbb_imf/models/**"]
[tool.ty.overrides.rules]
invalid-attribute-override = "ignore"
invalid-mutable-override = "ignore"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q --strict-markers"

View File

@@ -14,7 +14,7 @@ from openbb_jodi.utils.constants import (
if TYPE_CHECKING:
import asyncio # noqa
from collections.abc import Iterator, Mapping # noqa
from collections.abc import Generator, Mapping # noqa
from datetime import date as dateType # noqa
from pathlib import Path # noqa
from typing import IO # noqa
@@ -361,7 +361,7 @@ def bump_checked_at(table: str, snapshot: dict) -> dict:
@contextmanager
def open_archive_csv(path: "Path") -> "Iterator":
def open_archive_csv(path: "Path") -> "Generator":
"""Open the CSV stream inside a raw source file, unzipping when needed."""
import zipfile

View File

@@ -77,6 +77,13 @@ exclude = ["tests", "integration"]
[tool.ty.rules]
unresolved-import = "ignore"
[[tool.ty.overrides]]
include = ["openbb_nasdaq/models/**"]
[tool.ty.overrides.rules]
invalid-attribute-override = "ignore"
invalid-mutable-override = "ignore"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q --strict-markers"

View File

@@ -90,6 +90,13 @@ exclude = ["tests", "integration"]
[tool.ty.rules]
unresolved-import = "ignore"
[[tool.ty.overrides]]
include = ["openbb_sec/models/**"]
[tool.ty.overrides.rules]
invalid-attribute-override = "ignore"
invalid-mutable-override = "ignore"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q --strict-markers"

View File

@@ -91,6 +91,13 @@ exclude = ["tests", "integration"]
[tool.ty.rules]
unresolved-import = "warn"
[[tool.ty.overrides]]
include = ["openbb_tmx/models/**"]
[tool.ty.overrides.rules]
invalid-attribute-override = "ignore"
invalid-mutable-override = "ignore"
[tool.coverage.report]
exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:", "raise NotImplementedError", "@overload"]