Benjamin Peterson avatar Benjamin Peterson committed e09cf85

display the repr of some global names (fixes #171)

Comments (0)

Files changed (3)

 Changes between 2.3.4 and 2.3.5dev
 -----------------------------------
 
+- fix issue171 - in assertion rewriting, show the repr of some
+  global variables
+
 - fix option help for "-k"
 
 - move long description of distribution into README.rst
 
 - fix issue202 - better automatic names for parametrized test functions
 - fix issue139 - introduce @pytest.fixture which allows direct scoping
-  and parametrization of funcarg factories. 
+  and parametrization of funcarg factories.
 - fix issue198 - conftest fixtures were not found on windows32 in some
   circumstances with nested directory structures due to path manipulation issues
 - fix issue193 skip test functions with were parametrized with empty

_pytest/assertion/rewrite.py

 _saferepr = py.io.saferepr
 from _pytest.assertion.util import format_explanation as _format_explanation
 
+def _should_repr_global_name(obj):
+    return not hasattr(obj, "__name__") and not py.builtin.callable(obj)
+
 def _format_boolop(explanations, is_or):
     return "(" + (is_or and " or " or " and ").join(explanations) + ")"
 
         return self.statements
 
     def visit_Name(self, name):
-        # Check if the name is local or not.
+        # Display the repr of the name if it's a local variable or
+        # _should_repr_global_name() thinks it's acceptable.
         locs = ast.Call(self.builtin("locals"), [], [], None, None)
-        globs = ast.Call(self.builtin("globals"), [], [], None, None)
-        ops = [ast.In(), ast.IsNot()]
-        test = ast.Compare(ast.Str(name.id), ops, [locs, globs])
+        inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
+        dorepr = self.helper("should_repr_global_name", name)
+        test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
         expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
         return name, self.explanation_param(expr)
 

testing/test_assertrewrite.py

         assert getmsg(f) == "assert False"
         def f():
             assert a_global
-        assert getmsg(f, {"a_global" : False}) == "assert a_global"
+        assert getmsg(f, {"a_global" : False}) == "assert False"
+        def f():
+            assert sys == 42
+        assert getmsg(f, {"sys" : sys}) == "assert sys == 42"
+        def f():
+            assert cls == 42
+        class X(object):
+            pass
+        assert getmsg(f, {"cls" : X}) == "assert cls == 42"
 
     def test_assert_already_has_message(self):
         def f():
     def test_attribute(self):
         class X(object):
             g = 3
-        ns = {"X" : X, "x" : X()}
+        ns = {"x" : X}
         def f():
             assert not x.g
         assert getmsg(f, ns) == """assert not 3
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.