Skip to content

Commit 3132786

Browse files
committed
Add lint check for v.get(...) and simlar errors.
1 parent 561c4ff commit 3132786

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

Tools/configure/transpiler/lint_transpilable.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@
174174
}
175175
)
176176

177+
# Allowed Vars (v) method calls. The Vars object uses __getattr__ to
178+
# return env/empty-string for unknown attributes, so calling anything
179+
# other than these real methods (e.g. v.get()) silently returns a string
180+
# and then fails at runtime with "TypeError: 'str' object is not callable".
181+
ALLOWED_VARS_METHODS = frozenset(
182+
{
183+
"export",
184+
"is_set",
185+
}
186+
)
187+
177188
# Allowed string methods that have shell equivalents.
178189
ALLOWED_STR_METHODS = frozenset(
179190
{
@@ -810,11 +821,18 @@ def _check_call(self, node):
810821
self._check_expr(kw.value)
811822
return
812823

813-
# v.export(...) and other Vars methods — allowed
824+
# v.export(...) / v.is_set(...) — allowed Vars methods
814825
if isinstance(func, ast.Attribute) and isinstance(
815826
func.value, ast.Name
816827
):
817828
if func.value.id == "v":
829+
if func.attr not in ALLOWED_VARS_METHODS:
830+
self._warn(
831+
node,
832+
f"v.{func.attr}(): not in allowed Vars methods"
833+
f" ({', '.join(sorted(ALLOWED_VARS_METHODS))})"
834+
" — use v.ATTR for attribute access instead",
835+
)
818836
for arg in node.args:
819837
self._check_expr(arg)
820838
for kw in node.keywords:

Tools/configure/transpiler/transpile.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from . import py_to_pysh
1515
from .pysh_ast import ModuleInfo, OptionInfo
1616
from .py_to_pysh import parse_option_decl
17+
from .lint_transpilable import lint_file
1718

1819
from . import pysh_to_awk
1920
from . import awk_emit
@@ -41,6 +42,20 @@
4142

4243

4344
def transpile_configure(script_dir: str) -> str:
45+
# Lint conf_*.py files before transpiling
46+
import glob as _glob
47+
48+
conf_files = sorted(_glob.glob(os.path.join(script_dir, "conf_*.py")))
49+
all_violations = []
50+
for filepath in conf_files:
51+
result = lint_file(filepath)
52+
all_violations.extend(result.violations)
53+
if all_violations:
54+
msgs = "\n".join(f" {v}" for v in all_violations)
55+
raise ValueError(
56+
f"lint check failed with {len(all_violations)} violation(s):\n{msgs}"
57+
)
58+
4459
# Parse Python source, produce Python AST, transform to pysh AST
4560
program = py_to_pysh.parse_program(script_dir)
4661
# Transform pysh AST → AWK AST

0 commit comments

Comments
 (0)