#7656·modin

BUG: modin.pandas.eval() does not work at all

Author: sfc-gh-mvashishthaCreated Sep 2, 2025Updated Sep 9, 2025
Labelsbug 🦗P2

Modin version checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest released version of Modin.

  • I have confirmed this bug exists on the main branch of Modin. (In order to do this you can follow this guide.)

Reproducible Example

python
import modin.pandas as pd
df = pd.DataFrame([1])
pd.eval('df + 1')

Issue Description

Basic modin.pandas.eval() invocations produce errors like UndefinedVariableError: name 'df' is not defined.

Expected Behavior

eval should work as it does in pandas.

Error Logs

python-traceback

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/scope.py:236, in Scope.resolve(self, key, is_local)
    235     assert not is_local and not self.has_resolvers
--> 236     return self.scope[key]
    237 except KeyError:

File ~/miniconda3/envs/modin-dev/lib/python3.9/collections/__init__.py:941, in ChainMap.__getitem__(self, key)
    940         pass
--> 941 return self.__missing__(key)

File ~/miniconda3/envs/modin-dev/lib/python3.9/collections/__init__.py:933, in ChainMap.__missing__(self, key)
    932 def __missing__(self, key):
--> 933     raise KeyError(key)

KeyError: 'df'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/scope.py:242, in Scope.resolve(self, key, is_local)
    238 try:
    239     # last ditch effort we look in temporaries
    240     # these are created when parsing indexing expressions
    241     # e.g., df[df > 0]
--> 242     return self.temps[key]
    243 except KeyError as err:

KeyError: 'df'

The above exception was the direct cause of the following exception:

UndefinedVariableError                    Traceback (most recent call last)
Cell In[3], line 1
----> 1 pd.eval('df + 1')

File ~/sources/modin/modin/core/storage_formats/pandas/query_compiler_caster.py:1070, in wrap_function_in_argument_caster.<locals>.f_with_argument_casting(*args, **kwargs)
   1056 if len(input_backends) < 2 and (
   1057     not AutoSwitchBackend.get() or pin_target_backend is not None
   1058 ):
   1059     f_to_apply = _get_extension_for_method(
   1060         name=name,
   1061         extensions=extensions,
   (...)
   1068         wrapping_function_type=wrapping_function_type,
   1069     )
-> 1070     result = f_to_apply(*args, **kwargs)
   1071     if (
   1072         isinstance(result, QueryCompilerCaster)
   1073         and pin_target_backend is not None
   1074     ):
   1075         result._set_backend_pinned(True, inplace=True)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/eval.py:336, in eval(expr, parser, engine, local_dict, global_dict, resolvers, level, target, inplace)
    327 # get our (possibly passed-in) scope
    328 env = ensure_scope(
    329     level + 1,
    330     global_dict=global_dict,
   (...)
    333     target=target,
    334 )
--> 336 parsed_expr = Expr(expr, engine=engine, parser=parser, env=env)
    338 if engine == "numexpr" and (
    339     is_extension_array_dtype(parsed_expr.terms.return_type)
    340     or getattr(parsed_expr.terms, "operand_types", None) is not None
   (...)
    344     )
    345 ):
    346     warnings.warn(
    347         "Engine has switched to 'python' because numexpr does not support "
    348         "extension array dtypes. Please set your engine to python manually.",
    349         RuntimeWarning,
    350         stacklevel=find_stack_level(),
    351     )

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:805, in Expr.__init__(self, expr, engine, parser, env, level)
    803 self.parser = parser
    804 self._visitor = PARSERS[parser](self.env, self.engine, self.parser)
--> 805 self.terms = self.parse()

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:824, in Expr.parse(self)
    820 def parse(self):
    821     """
    822     Parse an expression.
    823     """
--> 824     return self._visitor.visit(self.expr)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:411, in BaseExprVisitor.visit(self, node, **kwargs)
    409 method = f"visit_{type(node).__name__}"
    410 visitor = getattr(self, method)
--> 411 return visitor(node, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:417, in BaseExprVisitor.visit_Module(self, node, **kwargs)
    415     raise SyntaxError("only a single expression is allowed")
    416 expr = node.body[0]
--> 417 return self.visit(expr, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:411, in BaseExprVisitor.visit(self, node, **kwargs)
    409 method = f"visit_{type(node).__name__}"
    410 visitor = getattr(self, method)
--> 411 return visitor(node, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:420, in BaseExprVisitor.visit_Expr(self, node, **kwargs)
    419 def visit_Expr(self, node, **kwargs):
--> 420     return self.visit(node.value, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:411, in BaseExprVisitor.visit(self, node, **kwargs)
    409 method = f"visit_{type(node).__name__}"
    410 visitor = getattr(self, method)
--> 411 return visitor(node, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:531, in BaseExprVisitor.visit_BinOp(self, node, **kwargs)
    530 def visit_BinOp(self, node, **kwargs):
--> 531     op, op_class, left, right = self._maybe_transform_eq_ne(node)
    532     left, right = self._maybe_downcast_constants(left, right)
    533     return self._maybe_evaluate_binop(op, op_class, left, right)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:451, in BaseExprVisitor._maybe_transform_eq_ne(self, node, left, right)
    449 def _maybe_transform_eq_ne(self, node, left=None, right=None):
    450     if left is None:
--> 451         left = self.visit(node.left, side="left")
    452     if right is None:
    453         right = self.visit(node.right, side="right")

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:411, in BaseExprVisitor.visit(self, node, **kwargs)
    409 method = f"visit_{type(node).__name__}"
    410 visitor = getattr(self, method)
--> 411 return visitor(node, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/expr.py:541, in BaseExprVisitor.visit_Name(self, node, **kwargs)
    540 def visit_Name(self, node, **kwargs) -> Term:
--> 541     return self.term_type(node.id, self.env, **kwargs)

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/ops.py:91, in Term.__init__(self, name, env, side, encoding)
     89 tname = str(name)
     90 self.is_local = tname.startswith(LOCAL_TAG) or tname in DEFAULT_GLOBALS
---> 91 self._value = self._resolve_name()
     92 self.encoding = encoding

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/ops.py:115, in Term._resolve_name(self)
    110 if local_name in self.env.scope and isinstance(
    111     self.env.scope[local_name], type
    112 ):
    113     is_local = False
--> 115 res = self.env.resolve(local_name, is_local=is_local)
    116 self.update(res)
    118 if hasattr(res, "ndim") and res.ndim > 2:

File ~/miniconda3/envs/modin-dev/lib/python3.9/site-packages/pandas/core/computation/scope.py:244, in Scope.resolve(self, key, is_local)
    242     return self.temps[key]
    243 except KeyError as err:
--> 244     raise UndefinedVariableError(key, is_local) from err

UndefinedVariableError: name 'df' is not defined

Installed Versions

INSTALLED VERSIONS

commit : 8d468dcbf4a83203c2b250d67e86a8c1db4cc82b python : 3.9.21 python-bits : 64 OS : Darwin OS-release : 24.6.0 Version : Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:30 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6020 machine : arm64 processor : arm byteorder : little LC_ALL : None LANG : en_US.UTF-8 LOCALE : en_US.UTF-8

Modin dependencies

modin : 0.35.0+1.g8d468dcb ray : 2.44.1 dask : 2024.8.0 distributed : 2024.8.0

pandas dependencies

pandas : 2.2.3 numpy : 2.0.2 pytz : 2025.2 dateutil : 2.9.0.post0 pip : 24.2 Cython : None sphinx : 7.4.7 IPython : 8.18.1 adbc-driver-postgresql: None adbc-driver-sqlite : None bs4 : 4.13.4 blosc : None bottleneck : None dataframe-api-compat : None fastparquet : 2024.11.0 fsspec : 2025.3.2 html5lib : None hypothesis : None gcsfs : None jinja2 : 3.1.6 lxml.etree : 5.3.2 matplotlib : 3.9.4 numba : None numexpr : 2.10.2 odfpy : None openpyxl : 3.1.5 pandas_gbq : 0.28.0 psycopg2 : 2.9.10 pymysql : None pyarrow : 18.1.0 pyreadstat : None pytest : 8.4.0 python-calamine : None pyxlsb : None s3fs : 2025.3.2 scipy : 1.13.1 sqlalchemy : 2.0.40 tables : N/A tabulate : 0.9.0 xarray : 2024.7.0 xlrd : 2.0.1 xlsxwriter : None zstandard : None tzdata : 2025.2 qtpy : None pyqt5 : None