feat: indie status page MVP -- FastAPI + SQLite
- 8 DB models (services, incidents, monitors, subscribers, etc.) - Full CRUD API for services, incidents, monitors - Public status page with live data - Incident detail page with timeline - API key authentication - Uptime monitoring scheduler - 13 tests passing - TECHNICAL_DESIGN.md with full spec
This commit is contained in:
commit
902133edd3
4655 changed files with 1342691 additions and 0 deletions
125
venv/lib/python3.11/site-packages/mypy/parse.py
Normal file
125
venv/lib/python3.11/site-packages/mypy/parse.py
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from librt.internal import ReadBuffer
|
||||
|
||||
from mypy import errorcodes as codes
|
||||
from mypy.cache import read_int
|
||||
from mypy.errors import Errors
|
||||
from mypy.nodes import FileRawData, MypyFile
|
||||
from mypy.options import Options
|
||||
|
||||
|
||||
def parse(
|
||||
source: str | bytes,
|
||||
fnam: str,
|
||||
module: str | None,
|
||||
errors: Errors,
|
||||
options: Options,
|
||||
raise_on_error: bool = False,
|
||||
imports_only: bool = False,
|
||||
) -> MypyFile:
|
||||
"""Parse a source file, without doing any semantic analysis.
|
||||
|
||||
Return the parse tree. If errors is not provided, raise ParseError
|
||||
on failure. Otherwise, use the errors object to report parse errors.
|
||||
|
||||
The python_version (major, minor) option determines the Python syntax variant.
|
||||
"""
|
||||
if options.native_parser:
|
||||
# Native parser only works with actual files on disk
|
||||
# Fall back to fastparse for in-memory source or non-existent files
|
||||
if os.path.exists(fnam):
|
||||
import mypy.nativeparse
|
||||
|
||||
ignore_errors = options.ignore_errors or fnam in errors.ignored_files
|
||||
# If errors are ignored, we can drop many function bodies to speed up type checking.
|
||||
strip_function_bodies = ignore_errors and not options.preserve_asts
|
||||
|
||||
errors.set_file(fnam, module, options=options)
|
||||
tree, parse_errors, type_ignores = mypy.nativeparse.native_parse(
|
||||
fnam,
|
||||
options,
|
||||
skip_function_bodies=strip_function_bodies,
|
||||
imports_only=imports_only,
|
||||
)
|
||||
# Convert type ignores list to dict
|
||||
tree.ignored_lines = dict(type_ignores)
|
||||
# Set is_stub based on file extension
|
||||
tree.is_stub = fnam.endswith(".pyi")
|
||||
# Note: tree.imports is populated directly by native_parse with deserialized
|
||||
# import metadata, so we don't need to collect imports via AST traversal
|
||||
|
||||
# Report parse errors
|
||||
for error in parse_errors:
|
||||
message = error["message"]
|
||||
# Standardize error message by capitalizing the first word
|
||||
message = re.sub(r"^(\s*\w)", lambda m: m.group(1).upper(), message)
|
||||
# Respect blocker status from error, default to True for syntax errors
|
||||
is_blocker = error.get("blocker", True)
|
||||
error_code = error.get("code")
|
||||
if error_code is None:
|
||||
error_code = codes.SYNTAX
|
||||
else:
|
||||
# Fallback to [syntax] for backwards compatibility.
|
||||
error_code = codes.error_codes.get(error_code) or codes.SYNTAX
|
||||
errors.report(
|
||||
error["line"], error["column"], message, blocker=is_blocker, code=error_code
|
||||
)
|
||||
if raise_on_error and errors.is_errors():
|
||||
errors.raise_error()
|
||||
return tree
|
||||
# Fall through to fastparse for non-existent files
|
||||
|
||||
assert not imports_only
|
||||
if options.transform_source is not None:
|
||||
source = options.transform_source(source)
|
||||
import mypy.fastparse
|
||||
|
||||
tree = mypy.fastparse.parse(source, fnam=fnam, module=module, errors=errors, options=options)
|
||||
if raise_on_error and errors.is_errors():
|
||||
errors.raise_error()
|
||||
return tree
|
||||
|
||||
|
||||
def load_from_raw(
|
||||
fnam: str, module: str | None, raw_data: FileRawData, errors: Errors, options: Options
|
||||
) -> MypyFile:
|
||||
"""Load AST from parsed binary data.
|
||||
|
||||
This essentially replicates parse() above but expects FileRawData instead of actually
|
||||
parsing the source code in the file.
|
||||
"""
|
||||
from mypy.nativeparse import State, deserialize_imports, read_statements
|
||||
|
||||
# This part mimics the logic in native_parse().
|
||||
data = ReadBuffer(raw_data.defs)
|
||||
n = read_int(data)
|
||||
state = State(options)
|
||||
defs = read_statements(state, data, n)
|
||||
imports = deserialize_imports(raw_data.imports)
|
||||
|
||||
tree = MypyFile(defs, imports)
|
||||
tree.path = fnam
|
||||
tree.ignored_lines = raw_data.ignored_lines
|
||||
tree.is_partial_stub_package = raw_data.is_partial_stub_package
|
||||
tree.uses_template_strings = raw_data.uses_template_strings
|
||||
tree.is_stub = fnam.endswith(".pyi")
|
||||
|
||||
# Report parse errors, this replicates the logic in parse().
|
||||
all_errors = raw_data.raw_errors + state.errors
|
||||
errors.set_file(fnam, module, options=options)
|
||||
for error in all_errors:
|
||||
message = error["message"]
|
||||
message = re.sub(r"^(\s*\w)", lambda m: m.group(1).upper(), message)
|
||||
is_blocker = error.get("blocker", True)
|
||||
error_code = error.get("code")
|
||||
if error_code is None:
|
||||
error_code = codes.SYNTAX
|
||||
else:
|
||||
error_code = codes.error_codes.get(error_code) or codes.SYNTAX
|
||||
# Note we never raise in this function, so it should not be called in coordinator.
|
||||
errors.report(error["line"], error["column"], message, blocker=is_blocker, code=error_code)
|
||||
return tree
|
||||
Loading…
Add table
Add a link
Reference in a new issue