class

Analyzer::Python::Litestar

Inherits Analyzer::Python::PythonEngine < Analyzer < FileHelper < Reference < Object

Constants

CLASS_HEAD_RE = /^\s*class\s+(#{PYTHON_VAR_NAME_REGEX})\s*\(/
CONTROLLER_CLASS_RE = /^\s*class\s+(#{PYTHON_VAR_NAME_REGEX})\s*\(([^)]*)\)/
DECORATOR_PATH_KW_REGEX = /path\s*=\s*[rf]?['"]([^'"]*)['"]/
DECORATOR_PATH_LIST_KW_RE = /path\s*=\s*\[([^\]]*)\]/
DECORATOR_PATH_LIST_REGEX = /^\s*\[([^\]]*)\]/
DECORATOR_PATH_REGEX = /^\s*[rf]?['"]([^'"]*)['"]/

Path literal inside a decorator. Litestar accepts both a positional path and an explicit path= keyword argument. List forms (@get(["/a", "/b"]), @get(path=["/a", "/b"])) and omitted paths (@get(), @get(sync_to_thread=False) → default "" / /) are handled by extract_decorator_paths.

DECORATOR_REGEX = /@(get|post|put|patch|delete|head|options|route|websocket(?:_listener|_stream)?)\s*\(([^)]*)/

Decorator matching: @get("/path"), @post("/path"), etc. The tail after the path literal is captured so extra kwargs (like methods=) can be inspected for multi-method @route decorators. websocket(?:_listener|_stream)? also matches Litestar's @websocket_listener("/ws") and @websocket_stream("/ws") decorators (the listener/stream class-based WS handlers), which take a positional path just like @websocket — without the variants every listener/stream endpoint was silently dropped.

DOTTED_HANDLER_RE = /(#{PYTHON_VAR_NAME_REGEX})\.(#{PYTHON_VAR_NAME_REGEX})/

Hoisted out of the per-line/per-param loops: an interpolated regex literal recompiles (PCRE2 JIT) on every evaluation, and these interpolate only constants or fixed sets. The .to_s expansion is byte-identical to the previous inline form, so matching behaviour is unchanged.

HTTP_METHOD_KW_REGEX = /http_method\s*=\s*(?:\[([^\]]*)\]|['"]([^'"]+)['"])/
PATH_PARAM_REGEX = /\{([a-zA-Z_][a-zA-Z0-9_]*)(?::[a-zA-Z_][a-zA-Z0-9_]*)?\}/

Path param: {name} or {name:type}. Litestar uses the :type suffix as a converter (int, str, uuid, path, float); strip it when exposing the param.

PRIMITIVE_TYPE_PATTERNS = ["str", "int", "float", "bool", "bytes", "UUID", "date", "datetime"].map do |t| /\b#{t}\b/ end

classify_param runs once per typed handler parameter and rebuilt one PCRE2 pattern per primitive type on every call.

REQUEST_ATTR_PATTERNS = (["query_params", "path_params", "headers", "cookies"] of ::String).to_h do |attr| {attr, {/request\.#{attr}\[\s*[rf]?['"]([^'"]+)['"]\s*\]/, /request\.#{attr}\.get\(\s*[rf]?['"]([^'"]+)['"]/}} end

collect_request_attr_params runs twice per handler-body line per attribute; the attribute set is fixed, so precompile the patterns.

ROUTER_REGEX = /(#{PYTHON_VAR_NAME_REGEX})\s*=\s*Router\s*\(([^)]*)\)/m

Router(path="/prefix", route_handlers=[...])

TYPED_PATH_PARAM_REGEX = /\{([a-zA-Z_][a-zA-Z0-9_]*):[a-zA-Z_][a-zA-Z0-9_]*\}/

Class methods

tech_name
Source

Instance methods

analyze
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source