Skip to content
Sarj Code Standards

prefer-precise-object-contract

Use a precise type for declared application contracts instead of object.

Why

An object annotation hides the operations and data the caller actually supplies. It often spreads casts and handwritten shape checks into consumers.

Fix

Use a concrete domain type, Protocol, TypeVar, Pydantic model or JsonValue as appropriate. Importer callables return types.ModuleType. Keep object for genuinely opaque Python values and raw validation boundaries with an explained local exception when necessary; never replace it with Any or a cast.

Examples

Before — flagged The importer erases its module result
app.py
from collections.abc import Callable
def load(import_module: Callable[[str], object]): ...
After — preferred A module result has its standard type
app.py
from collections.abc import Callable
from types import ModuleType
def load(import_module: Callable[[str], ModuleType]): ...
Before — flagged Existing source proof permits a narrow convergent fix
app/contracts.py
def ready() -> bool:
def _value() -> object:
return "ready"
if _value():
return True
return False
After — preferred The proven private literal return already has its precise type
app/contracts.py
def ready() -> bool:
def _value() -> str:
return "ready"
if _value():
return True
return False
Autofix output
app/contracts.py
def ready() -> bool:
def _value() -> str:
return "ready"
if _value():
return True
return False