diff --git a/pandas/compat/chainmap.py b/pandas/compat/chainmap.py index 83f1da597d6a6..84824207de2a9 100644 --- a/pandas/compat/chainmap.py +++ b/pandas/compat/chainmap.py @@ -15,9 +15,3 @@ def __delitem__(self, key): del mapping[key] return raise KeyError(key) - - # override because the m parameter is introduced in Python 3.4 - def new_child(self, m=None): - if m is None: - m = {} - return self.__class__(m, *self.maps) diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py index 1046401850963..3e1e5ed89d877 100644 --- a/pandas/core/computation/align.py +++ b/pandas/core/computation/align.py @@ -9,6 +9,7 @@ from pandas.errors import PerformanceWarning import pandas as pd +from pandas.core.base import PandasObject import pandas.core.common as com from pandas.core.computation.common import _result_type_many @@ -34,7 +35,7 @@ def _zip_axes_from_type(typ, new_axes): def _any_pandas_objects(terms): """Check a sequence of terms for instances of PandasObject.""" - return any(isinstance(term.value, pd.core.generic.PandasObject) for term in terms) + return any(isinstance(term.value, PandasObject) for term in terms) def _filter_special_cases(f): @@ -132,7 +133,8 @@ def _align(terms): def _reconstruct_object(typ, obj, axes, dtype): - """Reconstruct an object given its type, raw value, and possibly empty + """ + Reconstruct an object given its type, raw value, and possibly empty (None) axes. Parameters @@ -157,7 +159,7 @@ def _reconstruct_object(typ, obj, axes, dtype): res_t = np.result_type(obj.dtype, dtype) - if not isinstance(typ, partial) and issubclass(typ, pd.core.generic.PandasObject): + if not isinstance(typ, partial) and issubclass(typ, PandasObject): return typ(obj, dtype=res_t, **axes) # special case for pathological things like ~True/~False diff --git a/pandas/core/computation/common.py b/pandas/core/computation/common.py index 2a4277e4e0a20..bd32c8bee1cdf 100644 --- a/pandas/core/computation/common.py +++ b/pandas/core/computation/common.py @@ -36,8 +36,3 @@ def _remove_spaces_column_name(name): class NameResolutionError(NameError): pass - - -class StringMixin: - # TODO: delete this class. Removing this ATM caused a failure. - pass diff --git a/pandas/core/computation/engines.py b/pandas/core/computation/engines.py index 2c94b142a45b3..3cc34ea1f4ed7 100644 --- a/pandas/core/computation/engines.py +++ b/pandas/core/computation/engines.py @@ -17,7 +17,8 @@ class NumExprClobberingError(NameError): def _check_ne_builtin_clash(expr): - """Attempt to prevent foot-shooting in a helpful way. + """ + Attempt to prevent foot-shooting in a helpful way. Parameters ---------- @@ -53,7 +54,8 @@ def convert(self): return printing.pprint_thing(self.expr) def evaluate(self): - """Run the engine on the expression + """ + Run the engine on the expression. This method performs alignment which is necessary no matter what engine is being used, thus its implementation is in the base class. @@ -78,7 +80,8 @@ def _is_aligned(self): @abc.abstractmethod def _evaluate(self): - """Return an evaluated expression. + """ + Return an evaluated expression. Parameters ---------- @@ -94,7 +97,6 @@ def _evaluate(self): class NumExprEngine(AbstractEngine): - """NumExpr engine class""" has_neg_frac = True @@ -127,8 +129,8 @@ def _evaluate(self): class PythonEngine(AbstractEngine): - - """Evaluate an expression in Python space. + """ + Evaluate an expression in Python space. Mostly for testing purposes. """ diff --git a/pandas/core/computation/expr.py b/pandas/core/computation/expr.py index d0d87c23e9346..a58f256cf61d4 100644 --- a/pandas/core/computation/expr.py +++ b/pandas/core/computation/expr.py @@ -41,7 +41,8 @@ def tokenize_string(source): - """Tokenize a Python source code string. + """ + Tokenize a Python source code string. Parameters ---------- diff --git a/pandas/core/computation/expressions.py b/pandas/core/computation/expressions.py index 0ecf56cf6fe96..5b6d275001d36 100644 --- a/pandas/core/computation/expressions.py +++ b/pandas/core/computation/expressions.py @@ -99,15 +99,13 @@ def _evaluate_numexpr(op, op_str, a, b, truediv=True, reversed=False, **eval_kwa result = None if _can_use_numexpr(op, op_str, a, b, "evaluate"): - try: - - # we were originally called by a reversed op - # method - if reversed: - a, b = b, a + if reversed: + # we were originally called by a reversed op method + a, b = b, a - a_value = getattr(a, "values", a) - b_value = getattr(b, "values", b) + a_value = getattr(a, "values", a) + b_value = getattr(b, "values", b) + try: result = ne.evaluate( "a_value {op} b_value".format(op=op_str), local_dict={"a_value": a_value, "b_value": b_value}, @@ -138,11 +136,11 @@ def _where_numexpr(cond, a, b): result = None if _can_use_numexpr(None, "where", a, b, "where"): + cond_value = getattr(cond, "values", cond) + a_value = getattr(a, "values", a) + b_value = getattr(b, "values", b) try: - cond_value = getattr(cond, "values", cond) - a_value = getattr(a, "values", a) - b_value = getattr(b, "values", b) result = ne.evaluate( "where(cond_value, a_value, b_value)", local_dict={ @@ -209,7 +207,8 @@ def evaluate(op, op_str, a, b, use_numexpr=True, **eval_kwargs): Parameters ---------- op : the actual operand - op_str : the string version of the op + op_str : str + The string version of the op. a : left operand b : right operand use_numexpr : bool, default True @@ -224,11 +223,11 @@ def evaluate(op, op_str, a, b, use_numexpr=True, **eval_kwargs): def where(cond, a, b, use_numexpr=True): """ - Evaluate the where condition cond on a and b + Evaluate the where condition cond on a and b. Parameters ---------- - cond : ndarray[bool] + cond : np.ndarray[bool] a : return if cond is True b : return if cond is False use_numexpr : bool, default True diff --git a/pandas/core/computation/ops.py b/pandas/core/computation/ops.py index b49220ae701bc..28b6aef693bfe 100644 --- a/pandas/core/computation/ops.py +++ b/pandas/core/computation/ops.py @@ -476,8 +476,8 @@ def isnumeric(dtype): class Div(BinOp): - - """Div operator to special case casting. + """ + Div operator to special case casting. Parameters ---------- @@ -508,8 +508,8 @@ def __init__(self, lhs, rhs, truediv, *args, **kwargs): class UnaryOp(Op): - - """Hold a unary operator and its operands + """ + Hold a unary operator and its operands. Parameters ---------- diff --git a/pandas/core/computation/scope.py b/pandas/core/computation/scope.py index 8ddd0dd7622e7..b11411eb2dc66 100644 --- a/pandas/core/computation/scope.py +++ b/pandas/core/computation/scope.py @@ -15,9 +15,6 @@ from pandas._libs.tslibs import Timestamp from pandas.compat.chainmap import DeepChainMap -import pandas.core.computation as compu -from pandas.core.computation.common import StringMixin - def _ensure_scope( level, global_dict=None, local_dict=None, resolvers=(), target=None, **kwargs @@ -67,7 +64,8 @@ def _raw_hex_id(obj): def _get_pretty_string(obj): - """Return a prettier version of obj + """ + Return a prettier version of obj. Parameters ---------- @@ -84,9 +82,9 @@ def _get_pretty_string(obj): return sio.getvalue() -class Scope(StringMixin): - - """Object to hold scope, with a few bells to deal with some custom syntax +class Scope: + """ + Object to hold scope, with a few bells to deal with some custom syntax and contexts added by pandas. Parameters @@ -105,7 +103,7 @@ class Scope(StringMixin): temps : dict """ - __slots__ = "level", "scope", "target", "temps" + __slots__ = ["level", "scope", "target", "resolvers", "temps"] def __init__( self, level, global_dict=None, local_dict=None, resolvers=(), target=None @@ -163,7 +161,8 @@ def has_resolvers(self): return bool(len(self.resolvers)) def resolve(self, key, is_local): - """Resolve a variable name in a possibly local context + """ + Resolve a variable name in a possibly local context. Parameters ---------- @@ -198,10 +197,14 @@ def resolve(self, key, is_local): # e.g., df[df > 0] return self.temps[key] except KeyError: - raise compu.ops.UndefinedVariableError(key, is_local) + # runtime import because ops imports from scope + from pandas.core.computation.ops import UndefinedVariableError + + raise UndefinedVariableError(key, is_local) def swapkey(self, old_key, new_key, new_value=None): - """Replace a variable name, with a potentially new value. + """ + Replace a variable name, with a potentially new value. Parameters ---------- @@ -225,7 +228,8 @@ def swapkey(self, old_key, new_key, new_value=None): return def _get_vars(self, stack, scopes): - """Get specifically scoped variables from a list of stack frames. + """ + Get specifically scoped variables from a list of stack frames. Parameters ---------- @@ -247,7 +251,8 @@ def _get_vars(self, stack, scopes): del frame def update(self, level): - """Update the current scope by going back `level` levels. + """ + Update the current scope by going back `level` levels. Parameters ---------- @@ -266,7 +271,8 @@ def update(self, level): del stack[:], stack def add_tmp(self, value): - """Add a temporary variable to the scope. + """ + Add a temporary variable to the scope. Parameters ---------- @@ -297,7 +303,8 @@ def ntemps(self): @property def full_scope(self): - """Return the full scope for use with passing to engines transparently + """ + Return the full scope for use with passing to engines transparently as a mapping. Returns