[Zope-CVS] CVS: Packages/pypes/pypes - expression.py:1.12
Casey Duncan
casey at zope.com
Wed Apr 21 01:26:23 EDT 2004
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv11141
Modified Files:
expression.py
Log Message:
Add __eq__, __and__ and __or__ support for comparing and combining expressions
=== Packages/pypes/pypes/expression.py 1.11 => 1.12 ===
--- Packages/pypes/pypes/expression.py:1.11 Tue Apr 13 00:21:31 2004
+++ Packages/pypes/pypes/expression.py Wed Apr 21 01:25:52 2004
@@ -18,10 +18,12 @@
import sys
import __builtin__
from sets import Set
+from copy import deepcopy
from compiler import parse, ast
from compiler.pycodegen import ExpressionCodeGenerator
from zope.interface import implements
from pypes.interfaces import IExpression
+from pypes.exceptions import PypesError
class Expression(object):
"""Encapsulation of an expression and namespace for later evaluation"""
@@ -65,6 +67,10 @@
tree.filename = '<pypes expression>' # ECG requires filename attr
self._code = ExpressionCodeGenerator(tree).getCode()
self._tree = tree
+
+ def ast(self):
+ """Return the AST root node for the expression"""
+ return self._tree
def names(self, _tree=None, _names=None):
"""Return a set of the names used in the expression"""
@@ -214,6 +220,41 @@
the expression when constructed.
"""
return eval(self._code, self._bindings, namespace)
+
+ def __eq__(self, other):
+ return self is other or (nodesEqual(self._tree, other._tree)
+ and self._bindings == other._bindings)
+
+ def _combineBindings(self, other):
+ """Combine the bindings between self and other. Bindings can only be
+ combined if names common between them are assigned the same values
+ and unbound names in one are not bound by the other.
+ """
+ self_bound = Set(self._bindings)
+ other_bound = Set(other._bindings)
+ for name in other_bound & self_bound:
+ if self._bindings[name] != other._bindings[name]:
+ raise PypesError('cannot combine expressions, '
+ '%s is bound to different values')
+ if ((other_bound - self_bound) & self.names()
+ or (self_bound - other_bound) & other.names()):
+ raise PypesError('cannot combine expressions, '
+ 'unbound names in one are bound by the other')
+ bindings = self._bindings.copy()
+ bindings.update(other._bindings)
+ return bindings
+
+ def __or__(self, other):
+ left = self.ast().getChildNodes()[0]
+ right = other.ast().getChildNodes()[0]
+ return self.fromAstNode(
+ ast.Or((left, right)), self._combineBindings(other))
+
+ def __and__(self, other):
+ left = self.ast().getChildNodes()[0]
+ right = other.ast().getChildNodes()[0]
+ return self.fromAstNode(
+ ast.And((left, right)), self._combineBindings(other))
def __str__(self):
return "Expression('%s')" % self._expr
More information about the Zope-CVS
mailing list