diff --git a/odoo-stubs/fields.pyi b/odoo-stubs/fields.pyi index df62623..f515628 100644 --- a/odoo-stubs/fields.pyi +++ b/odoo-stubs/fields.pyi @@ -1,6 +1,6 @@ import datetime import enum -from typing import Any, Callable, Container, Collection, Iterable, Iterator, Sequence, TypeVar, Union +from typing import Any, Callable, Container, Collection, Iterator, Sequence, TypeVar, Union import psycopg2 from markupsafe import Markup diff --git a/odoo-stubs/http.pyi b/odoo-stubs/http.pyi index c5d90ac..535f43e 100644 --- a/odoo-stubs/http.pyi +++ b/odoo-stubs/http.pyi @@ -1,77 +1,80 @@ -from logging import Logger -from typing import Any, Callable, Generator, Sequence, TypeVar +from abc import ABC, abstractmethod +from collections import defaultdict +from collections.abc import MutableMapping +from contextlib import nullcontext +from typing import Any, Callable, Generator, Iterable, Literal, Mapping, Sequence, TypeVar import werkzeug -from werkzeug.datastructures import CombinedMultiDict +from werkzeug.datastructures import Headers from werkzeug.exceptions import NotFound from werkzeug.local import LocalStack -from werkzeug.routing import Map +from werkzeug.middleware.proxy_fix import ProxyFix as ProxyFix_ +from werkzeug.routing import Map, Rule +from werkzeug.urls import URL from .api import Environment +from .models import BaseModel from .modules.registry import Registry from .sql_db import Cursor from .tools._vendor import sessions +from .tools.geoipresolver import GeoIPResolver +from .tools.profiler import Profiler _T = TypeVar('_T') -rpc_request: Logger -rpc_response: Logger +ProxyFix: Callable[..., ProxyFix_] +CORS_MAX_AGE: int +CSRF_FREE_METHODS: tuple[str, ...] +CSRF_TOKEN_SALT: int +DEFAULT_LANG: str + +def get_default_session() -> dict[str, Any]: ... + +JSON_MIMETYPES: tuple[str, ...] +MISSING_CSRF_WARNING: str +ROUTING_KEYS: set[str] +SESSION_LIFETIME: int STATIC_CACHE: int STATIC_CACHE_LONG: int -ALLOWED_DEBUG_MODES: list[str] -_request_stack: LocalStack -request: HttpRequest | JsonRequest -def replace_request_password(args) -> tuple: ... +class SessionExpiredException(Exception): ... -NO_POSTMORTEM: tuple[type[Exception], ...] +def content_disposition(filename: str) -> str: ... +def db_list(force: bool = ..., host: str | None = ...) -> list[str]: ... +def db_filter(dbs: Iterable[str], host: str | None = ...) -> list[str]: ... +def is_cors_preflight(request: Request, endpoint) -> bool: ... +def serialize_exception(exception: Exception): ... +def send_file(filepath_or_fp, mimetype: str | None = ..., as_attachment: bool = ..., filename: str | None = ..., + mtime: str | None = ..., add_etags: bool = ..., cache_timeout: int = ..., conditional: bool = ...) -> werkzeug.Response: ... -def dispatch_rpc(service_name: str, method: str, params): ... +class Stream: + type: str + data: bytes | None + path: str | None + url: str | None + mimetype: str | None + as_attachment: bool + download_name: str | None + conditional: bool + etag: bool + last_modified: float | None + max_age: int | None + immutable: bool + size: int | None + def __init__(self, **kwargs) -> None: ... + @classmethod + def from_path(cls, path: str, filter_ext: tuple[str, ...] = ...) -> Stream: ... + @classmethod + def from_attachment(cls, attachment: 'odoo.model.ir_attachment') -> Stream: ... + @classmethod + def from_binary_field(cls, record: BaseModel, field_name: str) -> Stream: ... + def read(self) -> bytes: ... + def get_response(self, as_attachment: bool | None = ..., immutable: bool | None = ..., **send_file_kwargs) -> werkzeug.Response: ... -class WebRequest: - httprequest: werkzeug.Request - httpresponse: Response | None - disable_db: bool - endpoint: EndPoint | None - endpoint_arguments: Any - auth_method: str | None - website: 'odoo.model.website' - lang: 'odoo.model.res_lang' - _cr: Cursor | None - _uid: int | None - _context: dict | None - _env: Environment | None - _failed: Exception | None - def __init__(self, httprequest: werkzeug.Request) -> None: ... - @property - def cr(self) -> Cursor: ... - @property - def uid(self) -> int: ... - @uid.setter - def uid(self, val) -> None: ... - @property - def context(self) -> dict: ... - @context.setter - def context(self, val) -> None: ... - @property - def env(self) -> Environment: ... - @property - def session(self) -> OpenERPSession: ... - def __enter__(self: _T) -> _T: ... - def __exit__(self, exc_type, exc_value, traceback) -> None: ... - def set_handler(self, endpoint: EndPoint, arguments, auth) -> None: ... - def _handle_exception(self, exception: Exception) -> None: ... - def redirect(self, location, code: int = ..., local: bool = ...) -> Response: ... - def redirect_query(self, location, query: Any | None = ..., code: int = ..., local: bool = ...) -> Response: ... - def _is_cors_preflight(self, endpoint: EndPoint) -> bool: ... - def _call_function(self, *args, **kwargs): ... - def registry_cr(self) -> Generator[tuple[Registry, Cursor], None, None]: ... - @property - def registry(self) -> Registry: ... - @property - def db(self) -> str | None: ... - def csrf_token(self, time_limit: int | None = ...): ... - def validate_csrf(self, csrf) -> bool: ... +class Controller: + children_classes: defaultdict[Any, list] + @classmethod + def __init_subclass__(cls) -> None: ... def route(route: str | list[str] | None = ..., type: str = ..., @@ -80,89 +83,48 @@ def route(route: str | list[str] | None = ..., cors: str = ..., csrf: bool = ..., **kw): ... +def _generate_routing_rules(modules: Sequence[str], nodb_only: bool, converters: Any | None = ...) -> Generator[tuple[str, Any], None, None]: ... -class JsonRequest(WebRequest): - _request_type: str - params: dict - jsonrequest: Any - context: dict - def __init__(self, *args) -> None: ... - def _json_response(self, result: Any | None = ..., error: dict | None = ...) -> Response: ... - def _handle_exception(self, exception: Exception) -> Response: ... - def dispatch(self) -> Response: ... +class FilesystemSessionStore(sessions.FilesystemSessionStore): + def get_session_filename(self, sid: str) -> str: ... + def save(self, session: Session) -> None: ... + def get(self, sid: str) -> Session: ... + def rotate(self, session: Session, env: Environment) -> None: ... + def vacuum(self) -> None: ... -def serialize_exception(e: Exception) -> dict[str, Any]: ... - -class HttpRequest(WebRequest): - _request_type: str - params: dict - def __init__(self, *args) -> None: ... - def _handle_exception(self, exception: Exception): ... - def _is_cors_preflight(self, endpoint: EndPoint) -> bool: ... - def dispatch(self): ... - def make_response(self, data, headers: list[tuple[str, str]] | None = ..., cookies: dict | None = ...) -> Response: ... - def render(self, template, qcontext: dict | None = ..., lazy: bool = ..., **kw) -> Response: ... - def not_found(self, description: str | Any | None = ...) -> NotFound: ... - -addons_manifest: dict -controllers_per_module: dict[str, list] - -class ControllerType(type): - def __init__(cls, name: str, bases: tuple, attrs: dict) -> None: ... - -Controller = ControllerType('Controller', (object,), {}) - -class EndPoint: - method: Callable - original: Callable - routing: dict - arguments: dict - def __init__(self, method, routing) -> None: ... - @property - def first_arg_is_req(self) -> bool: ... - def __call__(self, *args, **kw): ... - def __eq__(self, other) -> bool: ... - def __hash__(self) -> int: ... - def _as_tuple(self) -> tuple[Callable, dict]: ... - def __repr__(self) -> str: ... - -def _generate_routing_rules(modules: Sequence[str], nodb_only: bool, converters: Any | None = ...) -> Generator[tuple[str, EndPoint, dict], None, None]: ... - -class AuthenticationError(Exception): ... -class SessionExpiredException(Exception): ... - -class OpenERPSession(sessions.Session): - inited: bool - modified: bool - rotate: bool - def __init__(self, *args, **kwargs) -> None: ... - def __getattr__(self, attr): ... - def __setattr__(self, k, v): ... +class Session(MutableMapping): + __slots__ = ('can_save', 'data', 'is_dirty', 'is_explicit', 'is_new', 'should_rotate', 'sid') + can_save: bool + data: dict + is_dirty: bool + is_explicit: bool + is_new: bool + should_rotate: bool + sid: str + def __init__(self, data: dict, sid: str, new: bool = ...) -> None: ... + def __getitem__(self, item: str): ... + def __setitem__(self, item: str, value) -> None: ... + def __delitem__(self, item: str) -> None: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterable[str]: ... + def __getattr__(self, attr: str): ... + def __setattr__(self, key: str, val) -> None: ... + uid: int | None + pre_login: str | None pre_uid: int - uid: int - db: str - login: str | None - def authenticate(self, db: str, login: str | None = ..., password: str | None = ...) -> int: ... - session_token: str | None - def finalize(self) -> None: ... - def check_security(self) -> None: ... + def authenticate(self, dbname: str, login: str | None = ..., password: str | None = ...) -> int: ... + def finalize(self, env: Environment) -> None: ... def logout(self, keep_db: bool = ...) -> None: ... - def _default_values(self) -> None: ... - context: dict - def get_context(self) -> dict: ... - def _fix_lang(self, context: dict) -> None: ... - def save_action(self, action) -> int: ... - def get_action(self, key: int): ... - def save_request_data(self) -> None: ... - def load_request_data(self) -> Generator[CombinedMultiDict | None, None, None]: ... + def touch(self) -> None: ... -def session_gc(session_store: sessions.FilesystemSessionStore) -> None: ... - -ODOO_DISABLE_SESSION_GC: bool +_request_stack: LocalStack +request: Request class Response(werkzeug.Response): default_mimetype: str def __init__(self, *args, **kw) -> None: ... + @classmethod + def load(cls, result, fname: str = ...): ... template: Any qcontext: dict uid: int @@ -171,36 +133,122 @@ class Response(werkzeug.Response): def is_qweb(self) -> bool: ... def render(self): ... def flatten(self) -> None: ... + def set_cookie(self, key: str, value: str = ..., max_age: Any | None = ..., expires: Any | None = ..., + path: str = ..., domain: str | None = ..., secure: bool = ..., httponly: bool = ..., + samesite: str | None = ..., cookie_type: str = ...) -> None: ... -class DisableCacheMiddleware: - app: Callable - def __init__(self, app: Callable) -> None: ... - def __call__(self, environ: dict, start_response: Callable): ... - -class Root: - _loaded: bool +class FutureResponse: + charset: str + max_cookie_size: int + headers: Headers def __init__(self) -> None: ... + def set_cookie(self, key: str, value: str = ..., max_age: Any | None = ..., expires: Any | None = ..., + path: str = ..., domain: str | None = ..., secure: bool = ..., httponly: bool = ..., + samesite: str | None = ..., cookie_type: str = ...) -> None: ... + +class Request: + httprequest: werkzeug.Request + future_response: FutureResponse | None + dispatcher: Dispatcher + registry: Registry | None + session: Session + db: str | None + env: Environment | None + website: 'odoo.model.website' + lang: 'odoo.model.res_lang' + def __init__(self, httprequest: werkzeug.Request) -> None: ... + def _get_session_and_dbname(self) -> tuple[Session, str]: ... + def update_env(self, user: 'odoo.model.res_users | int | None' = ..., context: dict[str, Any] | None = ..., + su: bool | None = ...) -> None: ... + def update_context(self, **overrides) -> None: ... @property - def session_store(self) -> sessions.FilesystemSessionStore: ... + def context(self) -> dict[str, Any]: ... + @context.setter + def context(self, value) -> None: ... + @property + def uid(self) -> int: ... + @uid.setter + def uid(self, value) -> None: ... + @property + def cr(self) -> Cursor: ... + @cr.setter + def cr(self, value) -> None: ... + _cr: Cursor + @property + def geoip(self) -> dict[str, Any]: ... + def csrf_token(self, time_limit: int | None = ...) -> str: ... + def validate_csrf(self, csrf: str) -> bool: ... + def default_context(self) -> dict: ... + def default_lang(self) -> str: ... + def _geoip_resolve(self) -> dict[str, Any]: ... + def get_http_params(self) -> dict: ... + def get_json_data(self): ... + def _get_profiler_context_manager(self) -> Profiler | nullcontext: ... + def _inject_future_response(self, response: werkzeug.Response): ... + def make_response(self, data: str, headers: list[tuple[str, Any]] | None = ..., cookies: Mapping | None = ..., + status: int = ...) -> Response: ... + def make_json_response(self, data, headers: list[tuple[str, Any]] | None = ..., cookies: Mapping | None = ..., + status: int = ...) -> Response: ... + def not_found(self, description: str | None = ...) -> NotFound: ... + def redirect(self, location: URL | str, code: int = ..., local: bool = ...) -> werkzeug.Response: ... + def redirect_query(self, location: str, query: Mapping[str, str] | Iterable[tuple[str, str]] | None = ..., + code: int = ..., local: bool = ...) -> werkzeug.Response: ... + def render(self, template: str, qcontext: dict | None = ..., lazy: bool = ..., **kw): ... + def _save_session(self) -> None: ... + def _set_request_dispatcher(self, rule: Rule) -> None: ... + def _serve_static(self) -> werkzeug.Response: ... + def _serve_nodb(self): ... + def _serve_db(self): ... + params: dict + def _serve_ir_http(self): ... + +_dispatchers: dict[str, type[Dispatcher]] + +class Dispatcher(ABC): + routing_type: str + @classmethod + def __init_subclass__(cls) -> None: ... + request: Request + def __init__(self, request: Request) -> None: ... + @classmethod + @abstractmethod + def is_compatible_with(cls, request: Request) -> bool: ... + def pre_dispatch(self, rule: Rule, args) -> None: ... + @abstractmethod + def dispatch(self, endpoint, args): ... + def post_dispatch(self, response: werkzeug.Response) -> None: ... + @abstractmethod + def handle_error(self, exc: Exception): ... + +class HttpDispatcher(Dispatcher): + routing_type: str + @classmethod + def is_compatible_with(cls, request: Request) -> Literal[True]: ... + def dispatch(self, endpoint, args): ... + def handle_error(self, exc: Exception): ... + +class JsonRPCDispatcher(Dispatcher): + routing_type: str + jsonrequest: dict + def __init__(self, request: Request) -> None: ... + @classmethod + def is_compatible_with(cls, request: Request) -> bool: ... + def dispatch(self, endpoint, args): ... + def handle_error(self, exc: Exception) -> Response: ... + def _response(self, result: Any | None = ..., error: Any | None = ...) -> Response: ... + +class Application: + @property + def statics(self) -> dict[str, str]: ... + def get_static_file(self, url: str, host: str = ...) -> str | None: ... @property def nodb_routing_map(self) -> Map: ... - def __call__(self, environ: dict, start_response: Callable): ... - def load_addons(self) -> None: ... - def setup_session(self, httprequest: werkzeug.Request) -> bool: ... - def setup_db(self, httprequest: werkzeug.Request) -> None: ... - def setup_lang(self, httprequest: werkzeug.Request) -> None: ... - def get_request(self, httprequest: werkzeug.Request) -> HttpRequest | JsonRequest: ... - def get_response(self, httprequest: werkzeug.Request, result, explicit_session: bool) -> Any: ... + @property + def session_store(self) -> FilesystemSessionStore: ... + @property + def geoip_resolver(self) -> GeoIPResolver | None: ... + def get_db_router(self, db: str): ... def set_csp(self, response: werkzeug.Response) -> None: ... - def dispatch(self, environ: dict, start_response: Callable): ... - def get_profiler_context_manager(self, request: WebRequest): ... - def get_db_router(self, db: str) -> Map: ... + def __call__(self, environ: dict, start_response: Callable): ... -def db_list(force: bool = ..., httprequest: werkzeug.Request | None = ...) -> list[str]: ... -def db_filter(dbs, httprequest: werkzeug.Request | None = ...) -> list[str]: ... -def db_monodb(httprequest: werkzeug.Request | None = ...) -> str | None: ... -def send_file(filepath_or_fp, mimetype: str | None = ..., as_attachment: bool = ..., filename: str | None = ..., mtime: Any | None = ..., add_etags: bool = ..., cache_timeout: int =..., conditional: bool = ...) -> Response: ... -def content_disposition(filename: str) -> str: ... -def set_safe_image_headers(headers, content): ... - -root: Root +root: Application