init
This commit is contained in:
@@ -337,6 +337,69 @@ def _append_missing_methods(
|
|||||||
return runtime_block.rstrip() + "\n\n" + "".join(additions).rstrip() + "\n"
|
return runtime_block.rstrip() + "\n\n" + "".join(additions).rstrip() + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def _sync_generated_method_docstrings(
|
||||||
|
runtime_block: str, generated_block: str, method_names: set[str]
|
||||||
|
) -> str:
|
||||||
|
"""Use generated method docstrings while preserving runtime method bodies."""
|
||||||
|
runtime_class = ast.parse(runtime_block).body[0]
|
||||||
|
generated_class = ast.parse(generated_block).body[0]
|
||||||
|
if not isinstance(runtime_class, ast.ClassDef) or not isinstance(generated_class, ast.ClassDef):
|
||||||
|
return runtime_block
|
||||||
|
|
||||||
|
runtime_methods = {
|
||||||
|
statement.name: statement
|
||||||
|
for statement in runtime_class.body
|
||||||
|
if isinstance(statement, (ast.FunctionDef, ast.AsyncFunctionDef))
|
||||||
|
}
|
||||||
|
generated_methods = {
|
||||||
|
statement.name: statement
|
||||||
|
for statement in generated_class.body
|
||||||
|
if isinstance(statement, (ast.FunctionDef, ast.AsyncFunctionDef))
|
||||||
|
}
|
||||||
|
runtime_lines = runtime_block.splitlines(keepends=True)
|
||||||
|
generated_lines = generated_block.splitlines(keepends=True)
|
||||||
|
replacements: list[tuple[int, int, list[str]]] = []
|
||||||
|
|
||||||
|
def docstring_statement(method: ast.FunctionDef | ast.AsyncFunctionDef) -> ast.Expr | None:
|
||||||
|
if not method.body:
|
||||||
|
return None
|
||||||
|
statement = method.body[0]
|
||||||
|
if (
|
||||||
|
isinstance(statement, ast.Expr)
|
||||||
|
and isinstance(statement.value, ast.Constant)
|
||||||
|
and isinstance(statement.value.value, str)
|
||||||
|
):
|
||||||
|
return statement
|
||||||
|
return None
|
||||||
|
|
||||||
|
for name in method_names:
|
||||||
|
runtime_method = runtime_methods.get(name)
|
||||||
|
generated_method = generated_methods.get(name)
|
||||||
|
if runtime_method is None or generated_method is None:
|
||||||
|
continue
|
||||||
|
generated_doc = docstring_statement(generated_method)
|
||||||
|
if generated_doc is None:
|
||||||
|
continue
|
||||||
|
generated_source = generated_lines[
|
||||||
|
generated_doc.lineno - 1:generated_doc.end_lineno
|
||||||
|
]
|
||||||
|
runtime_doc = docstring_statement(runtime_method)
|
||||||
|
if runtime_doc is not None:
|
||||||
|
replacements.append(
|
||||||
|
(runtime_doc.lineno - 1, runtime_doc.end_lineno, generated_source)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# A method without a docstring starts directly with executable
|
||||||
|
# code. Insert the generated VP description before that code.
|
||||||
|
replacements.append(
|
||||||
|
(runtime_method.body[0].lineno - 1, runtime_method.body[0].lineno - 1, generated_source)
|
||||||
|
)
|
||||||
|
|
||||||
|
for start, end, replacement in sorted(replacements, reverse=True):
|
||||||
|
runtime_lines[start:end] = replacement
|
||||||
|
return "".join(runtime_lines)
|
||||||
|
|
||||||
|
|
||||||
def _ensure_get_data_import(source: str) -> str:
|
def _ensure_get_data_import(source: str) -> str:
|
||||||
if not re.search(r"(?m)^\s*data\d+\s*=\s*get_data\(", source):
|
if not re.search(r"(?m)^\s*data\d+\s*=\s*get_data\(", source):
|
||||||
return source
|
return source
|
||||||
@@ -433,6 +496,9 @@ def merge(generated_path: Path, character_path: Path) -> tuple[str, dict[str, in
|
|||||||
block = _set_generated_field(block, "position", generated_skill.position)
|
block = _set_generated_field(block, "position", generated_skill.position)
|
||||||
block = _set_generated_field(block, "cellPos", generated_skill.cell_pos)
|
block = _set_generated_field(block, "cellPos", generated_skill.cell_pos)
|
||||||
block = _append_missing_methods(block, generated_block, {"vp_1", "vp_2"})
|
block = _append_missing_methods(block, generated_block, {"vp_1", "vp_2"})
|
||||||
|
block = _sync_generated_method_docstrings(
|
||||||
|
block, generated_block, {"vp_1", "vp_2"}
|
||||||
|
)
|
||||||
chunks.append(block.rstrip() + "\n")
|
chunks.append(block.rstrip() + "\n")
|
||||||
matched += 1
|
matched += 1
|
||||||
cursor = generated_skill.end
|
cursor = generated_skill.end
|
||||||
|
|||||||
Reference in New Issue
Block a user