Skip to content

Commit cb01cdd

Browse files
committed
Do not include undefined Elixir variables in the expanded ~PY sigil
1 parent d646e69 commit cb01cdd

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-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+
versioned_vars = __CALLER__.versioned_vars
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. This
290+
# way, if an undefined variable is referenced in the Python
291+
# code, it results in an informative Python error, rather than
292+
# Elixir compile error.
293+
Map.has_key?(versioned_vars, {name_atom, nil}) do
294+
{name, {name_atom, [], nil}}
287295
end
288296

289297
assignments =

test/pythonx_test.exs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,23 @@ 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+
390+
end
391+
392+
end
393+
377394
test "global redefinition" do
378395
{_result, binding} =
379396
Code.eval_string(
@@ -414,7 +431,7 @@ defmodule PythonxTest do
414431
assert repr(result) == "43"
415432
end
416433

417-
test "does not result in unused variables" do
434+
test "does not result in unused variables diagnostics" do
418435
{_result, diagnostics} =
419436
Code.with_diagnostics(fn ->
420437
Code.eval_string(~s'''

0 commit comments

Comments
 (0)