Python: automatically prints a representation of each component in an expression

I find myself writing the following statements:

if f(x, y) != z:
  print(repr(x))
  print(repr(y))
  print(repr(z))
  raise MyException('Expected: f(x, y) == z')

I was wondering if there is a way to write a function that will take a valid Python expression and an exception class as input, evaluate the expression, and if it considers it false, print out the representation of each of the younger members in the expression and raise this exception?

# validate is the mystery function
validate('f(x, y) == z', MyException)
+5
source share
6 answers

Here's the implementation:

import inspect, keyword, pprint, sys, tokenize

def value_in_frame(name, frame):
    try:
        return frame.f_locals[name]
    except KeyError:
        try:
            return frame.f_globals[name]
        except KeyError:
            raise ValueError("Couldn't find value for %s" % name)

def validate(expr, exc_class=AssertionError):
    """Evaluate `expr` in the caller frame, raise `exc_class` if false."""
    frame = inspect.stack()[1][0]
    val = eval(expr, frame.f_globals, frame.f_locals)
    if not val:
        rl = iter([expr]).next
        for typ, tok, _, _, _ in tokenize.generate_tokens(rl):
            if typ == tokenize.NAME and not keyword.iskeyword(tok):
                try:
                    val = value_in_frame(tok, frame)
                except ValueError:
                    val = '???'
                else:
                    val = repr(val)
                print "  %s: %s" % (tok, val)
        raise exc_class("Failed to validate: %s" % expr)

if __name__ == '__main__':
    a = b = 3
    validate("a + b == 5")
+2
source

What about statements?

assert  f(x, y) != z, 'Expected: f(%r, %r) == %r'%(x,y,z)

Edit

to add% r to print. Thanks for the comment.

+2
source

. Python ( , ) AST. AST ( eval , ). , , AST, , . , AST.

+1

, -, , , , , :

  • , , . , , , , , , , . , , .

    if f(x, y) != z:
      raise MyException("Unexpected: the foobar is glowing; " +
                        "f(%r, %r) != %r" % (x, y, z))
    

    , , x y, ( ) f (x, y), , . .

  • pdb , , , ( ), "" . ; , -.

    if f(x, y) != z:
      import pdb
      pdb.set_trace()
      raise MyException("Unexpected: ...")
    
  • .

+1

nose , " ", : http://somethingaboutorange.com/mrl/projects/nose/0.11.1/plugins/failuredetail.html. , , , , , , .

:

, :

def test_integers():
    a = 2
    assert a == 4, "assert 2 is 4"

, :

File "/path/to/file.py", line XX, in test_integers:
      assert a == 4, "assert 2 is 4" 
AssertionError: assert 2 is 4
  >>  assert 2 == 4, "assert 2 is 4"
+1

:

expr = 'f(%r, %r) != %r' % (x,y,z)

if eval(expr):
    raise MyException(expr)

:

def validate(expr,myexception):
    if eval(expr):
        raise myexception(expr)

, :)

+1

All Articles