assert reinterpretation: try mangling attributes that look like private class vars (fixes #514)

This commit is contained in:
Benjamin Peterson 2014-05-31 14:37:02 -07:00
parent fd4b461290
commit 780bdda95a
4 changed files with 39 additions and 2 deletions

View File

@ -1,6 +1,8 @@
NEXT (2.6) NEXT (2.6)
----------------------------------- -----------------------------------
- fix issue514: teach assertion reinterpretation about private class attributes
- change -v output to include full node IDs of tests. Users can copy - change -v output to include full node IDs of tests. Users can copy
a node ID from a test run, including line number, and use it as a a node ID from a test run, including line number, and use it as a
positional argument in order to run only a single test. positional argument in order to run only a single test.

View File

@ -286,6 +286,18 @@ class DebugInterpreter(ast.NodeVisitor):
source = "__exprinfo_expr.%s" % (attr.attr,) source = "__exprinfo_expr.%s" % (attr.attr,)
co = self._compile(source) co = self._compile(source)
try: try:
try:
result = self.frame.eval(co, __exprinfo_expr=source_result)
except AttributeError:
# Maybe the attribute name needs to be mangled?
if not attr.attr.startswith("__") or attr.attr.endswith("__"):
raise
source = "getattr(__exprinfo_expr.__class__, '__name__', '')"
co = self._compile(source)
class_name = self.frame.eval(co, __exprinfo_expr=source_result)
mangled_attr = "_" + class_name + attr.attr
source = "__exprinfo_expr.%s" % (mangled_attr,)
co = self._compile(source)
result = self.frame.eval(co, __exprinfo_expr=source_result) result = self.frame.eval(co, __exprinfo_expr=source_result)
except Exception: except Exception:
raise Failure(explanation) raise Failure(explanation)

View File

@ -355,6 +355,17 @@ class Getattr(Interpretable):
expr.eval(frame) expr.eval(frame)
source = '__exprinfo_expr.%s' % self.attrname source = '__exprinfo_expr.%s' % self.attrname
try: try:
try:
self.result = frame.eval(source, __exprinfo_expr=expr.result)
except AttributeError:
# Maybe the attribute name needs to be mangled?
if (not self.attrname.startswith("__") or
self.attrname.endswith("__")):
raise
source = "getattr(__exprinfo_expr.__class__, '__name__', '')"
class_name = frame.eval(source, __exprinfo_expr=expr.result)
mangled_attr = "_" + class_name + self.attrname
source = "__exprinfo_expr.%s" % (mangled_attr,)
self.result = frame.eval(source, __exprinfo_expr=expr.result) self.result = frame.eval(source, __exprinfo_expr=expr.result)
except passthroughex: except passthroughex:
raise raise

View File

@ -131,6 +131,18 @@ def test_assert_keyword_arg():
e = exvalue() e = exvalue()
assert "x=5" in e.msg assert "x=5" in e.msg
def test_private_class_variable():
class X:
def __init__(self):
self.__v = 41
def m(self):
assert self.__v == 42
try:
X().m()
except AssertionError:
e = exvalue()
assert "== 42" in e.msg
# These tests should both fail, but should fail nicely... # These tests should both fail, but should fail nicely...
class WeirdRepr: class WeirdRepr:
def __repr__(self): def __repr__(self):