Skip to content

Commit b07752f

Browse files
Do not include undefined Elixir variables in the expanded ~PY sigil (#12)
1 parent d646e69 commit b07752f

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

lib/pythonx.ex

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,17 @@ defmodule Pythonx do
281281
defmacro sigil_PY({:<<>>, _meta, [code]}, []) when is_binary(code) do
282282
%{referenced: referenced, defined: defined} = Pythonx.AST.scan_globals(code)
283283

284+
caller = __CALLER__
285+
284286
globals_entries =
285-
for name <- referenced do
286-
{name, {String.to_atom(name), [], nil}}
287+
for name <- referenced,
288+
name_atom = String.to_atom(name),
289+
# We only reference variables that are actually defined.
290+
# This way, if an undefined variable is referenced in the
291+
# Python code, it results in an informative Python error,
292+
# rather than Elixir compile error.
293+
Macro.Env.has_var?(caller, {name_atom, nil}) do
294+
{name, {name_atom, [], nil}}
287295
end
288296

289297
assignments =

test/pythonx_test.exs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,21 @@ defmodule PythonxTest do
374374
assert Keyword.keys(binding) == [:x]
375375
end
376376

377+
test "results in a Python error when a variable is undefined" do
378+
assert_raise Pythonx.Error, ~r/NameError: name 'x' is not defined/, fn ->
379+
Code.eval_string(
380+
~S'''
381+
import Pythonx
382+
383+
~PY"""
384+
x + 1
385+
"""
386+
''',
387+
[]
388+
)
389+
end
390+
end
391+
377392
test "global redefinition" do
378393
{_result, binding} =
379394
Code.eval_string(
@@ -414,7 +429,7 @@ defmodule PythonxTest do
414429
assert repr(result) == "43"
415430
end
416431

417-
test "does not result in unused variables" do
432+
test "does not result in unused variables diagnostics" do
418433
{_result, diagnostics} =
419434
Code.with_diagnostics(fn ->
420435
Code.eval_string(~s'''

0 commit comments

Comments
 (0)