From db9788a58ee94116264cdedc2e9560cff2f546ce Mon Sep 17 00:00:00 2001 From: kouyouqi123 <1696906464@qq.com> Date: Sun, 31 May 2026 13:56:41 +0800 Subject: [PATCH 1/3] fix: implement __iter__ on VarLookupDict to prevent CPython crash VarLookupDict is a dict-like object but does not implement __iter__, __len__, or keys(). This causes a CPython crash (via a KeyError: 0) when Python's C-level error display code tries to iterate over the locals dict during traceback formatting. Fixes pydata/patsy#259 --- patsy/eval.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/patsy/eval.py b/patsy/eval.py index 9d1fba02..f878d05a 100644 --- a/patsy/eval.py +++ b/patsy/eval.py @@ -72,6 +72,20 @@ def get(self, key, default=None): except KeyError: return default + def __iter__(self): + seen = set() + for d in self._dicts: + for key in d: + if key not in seen: + seen.add(key) + yield key + + def __len__(self): + return len(list(iter(self))) + + def keys(self): + return list(iter(self)) + def __repr__(self): return "%s(%r)" % (self.__class__.__name__, self._dicts) From 611e50962d53e0ab67271f78c441366aef23db3f Mon Sep 17 00:00:00 2001 From: kouyouqi123 <1696906464@qq.com> Date: Sun, 31 May 2026 14:38:01 +0800 Subject: [PATCH 2/3] fix: use np.asarray(result).dtype instead of result.dtype for DataFrame compat When _eval_factor receives a pandas DataFrame as result and tries to raise a PatsyError, it accesses result.dtype which doesn't exist on DataFrames (only .dtypes). This causes a confusing secondary AttributeError instead of the intended error message. Fixes #232 --- patsy/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patsy/build.py b/patsy/build.py index cbe25248..fe5ba79a 100644 --- a/patsy/build.py +++ b/patsy/build.py @@ -80,7 +80,7 @@ def _eval_factor(factor_info, data, NA_action): if not safe_issubdtype(np.asarray(result).dtype, np.number): raise PatsyError( "when evaluating numeric factor %s, " - "I got non-numeric data of type '%s'" % (factor.name(), result.dtype), + "I got non-numeric data of type '%s'" % (factor.name(), np.asarray(result).dtype), factor, ) return result, NA_action.is_numerical_NA(result) From 128b51db431d303a270b44053f2718df045024d0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 06:38:55 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- patsy/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patsy/build.py b/patsy/build.py index fe5ba79a..4749e179 100644 --- a/patsy/build.py +++ b/patsy/build.py @@ -80,7 +80,8 @@ def _eval_factor(factor_info, data, NA_action): if not safe_issubdtype(np.asarray(result).dtype, np.number): raise PatsyError( "when evaluating numeric factor %s, " - "I got non-numeric data of type '%s'" % (factor.name(), np.asarray(result).dtype), + "I got non-numeric data of type '%s'" + % (factor.name(), np.asarray(result).dtype), factor, ) return result, NA_action.is_numerical_NA(result)