On 20May2015 16:20, Daniel Gonçalves <daniel.ba...@gmail.com> wrote:
When you decorate a function with contextmanager that didn't yield you got an 
AttributeError instead of a proper RuntimeError "generator didn't yield". For 
example:

@contextlib.contextmanager
def foo():
...     pass
...
with foo():
...     do_something()
...
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/usr/lib/python2.7/contextlib.py", line 17, in __enter__
   return self.gen.next()
AttributeError: 'NoneType' object has no attribute 'next'

The proper exception should be a RuntimerError with the "generator didn't 
yield" message. At least for Python version 2.7.6.

Unfortunately no.

Your function foo() is _not_ a generator because it does not have a yield statement. Therefore it is a normal funcion which returns None (because it also lacks a return statement).

contextlib.contextmanager works by _calling_ the inner foo(). It expected to get a generator back. But your foo() returns None, _not_ a generator.

hence the error message: contextlib.contextmanager tries to use the return value with next(), which of course fails with exactly the exception one might expect.

To get "generator didn't yield" you need to actually have a generator. Eg:

 @contextlib.contextmanager
 def foo():
   if false:
     yield

Untested, though.

Cheers,
Cameron Simpson <c...@zip.com.au>
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to