def negate(op):
"""Return the negation of the provided operator"""
if op == None:
return None
top = type(op)
neg = not op.negated if hasattr(op, "negated") else True
if top == ast.And:
newOp = ast.Or()
elif top == ast.Or:
newOp = ast.And()
elif top == ast.Eq:
newOp = ast.NotEq()
elif top == ast.NotEq:
newOp = ast.Eq()
elif top == ast.Lt:
newOp = ast.GtE()
elif top == ast.GtE:
newOp = ast.Lt()
elif top == ast.Gt:
newOp = ast.LtE()
elif top == ast.LtE:
newOp = ast.Gt()
elif top == ast.Is:
newOp = ast.IsNot()
elif top == ast.IsNot:
newOp = ast.Is()
elif top == ast.In:
newOp = ast.NotIn()
elif top == ast.NotIn:
newOp = ast.In()
elif top == ast.NameConstant and op.value in [True, False]:
op.value = not op.value
op.negated = neg
return op
elif top == ast.Compare:
if len(op.ops) == 1:
op.ops[0] = negate(op.ops[0])
op.negated = neg
return op
else:
values = []
allOperands = [op.left] + op.comparators
for i in range(len(op.ops)):
values.append(ast.Compare(allOperands[i], [negate(op.ops[i])],
[allOperands[i+1]], multiCompPart=True))
newOp = ast.BoolOp(ast.Or(multiCompOp=True), values, multiComp=True)
elif top == ast.UnaryOp and type(op.op) == ast.Not and \
eventualType(op.operand) == bool: # this can mess things up type-wise
return op.operand
else:
# this is a normal value, so put a not around it
newOp = ast.UnaryOp(ast.Not(addedNot=True), op)
transferMetaData(op, newOp)
newOp.negated = neg
return newOp
python类Eq()的实例源码
def _visit_compare(self, left, op, right):
swap = False
if not isinstance(left, ast.Attribute):
left, right = right, left
swap = True
if not isinstance(left, ast.Attribute):
return
hardcoded_errno = (
left.attr == 'errno' and
op in astaux.equality_ops and
isinstance(right, ast.Num) and
isinstance(right.n, int) and
right.n in errno_constants
)
if hardcoded_errno:
yield self.tag(right, '*hardcoded-errno-value', right.n)
sys_attr_comparison = (
isinstance(left.value, ast.Name) and
left.value.id == 'sys'
)
if sys_attr_comparison:
if left.attr == 'version':
tpl = None
if isinstance(right, ast.Str):
if op in astaux.inequality_ops:
try:
tpl = sysversion.version_to_tuple(right.s)
except (TypeError, ValueError):
pass
elif swap and (op in astaux.in_ops):
if right.s == 'PyPy':
tpl = False
op = ast.Eq if isinstance(op, ast.In) else ast.NotEq
yield self.tag(left, 'sys.version-comparison',
format_cmp('platform.python_implementation()', op, repr('PyPy'))
)
if tpl is False:
pass
elif tpl is None:
yield self.tag(left, 'sys.version-comparison')
else:
yield self.tag(left, 'sys.version-comparison',
format_cmp('sys.version_info', op, tpl, swap=swap)
)
elif left.attr == 'hexversion':
tpl = None
if isinstance(right, ast.Num) and (op in astaux.numeric_cmp_ops):
try:
tpl = sysversion.hexversion_to_tuple(right.n)
except (TypeError, ValueError):
pass
if tpl is None:
yield self.tag(left, 'sys.hexversion-comparison')
else:
yield self.tag(left, 'sys.hexversion-comparison',
format_cmp('sys.version_info', op, tpl, swap=swap)
)