33

I'm trying to catch a Queue.Empty exception that is raised if a multiprocessing.Queue is empty. The following does not work:

import multiprocessing
f = multiprocessing.Queue()
try:
      f.get(True,0.1)
except Queue.Empty:
      print 'foo'

This gives me a name error: NameError: name 'Queue' is not defined

replacing Queue.Empty with multiprocessing.Queue.Empty does not help either. In this case it gives me a "AttributeError: 'function' object has no attribute 'Empty'" exception.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
Alexander
  • 1,673
  • 4
  • 19
  • 25

2 Answers2

61

The Empty exception you're looking for isn't available directly in the multiprocessing module, because multiprocessing borrows it from the queue module (which used to be named Queue in Python 2). To make your code work, just do an import queue at the top:

Try this:

import multiprocessing
import queue # or Queue in Python 2

f = multiprocessing.Queue()
try:
    f.get(True,0.1)
except queue.Empty: # queue here refers to the module, not a class
    print('foo')
Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • 3
    [`multiprocessing` should (and does) use `isinstance(exception, Queue.Empty)`](http://ideone.com/iHpNoJ) (Queue is a module) because multiprocessing emulates threading api that often used with Queue.Queue and exceptions are part of the api. – jfs Dec 18 '12 at 22:30
  • 2
    Oh, I see. `multiprocessing.queues.Empty` is `Queue.Empty` (just imported there for `multiprocessing.queues.Queue` to use). I'll update the answer. – Blckknght Dec 18 '12 at 22:34
  • 1
    @Blckknght @J.F. Sebastian Thanks this works, but I'm not sure why. By importing multiprocessing have I not imported all the modules that multiprocessing imports? So why do I need the line `import Queue` ? Also how do you figure that out? There was nothing about needing to import Queue from the documentation of multiprocessing. – Alexander Dec 20 '12 at 15:06
  • @Alexander: a module (e.g., `multiprocessing`) can use objects (e.g., raise exceptions) that are defined in other modules (in this case `Empty` name is defined in `Queue` module). The docs say that `multiprocessing.Queue` is a near clone of `Queue.Queue`. It means you should expect the same api: available methods, their arguments, exceptions raised are the same unless specified otherwise. And `Queue.Queue` documents when it raises `Queue.Empty`. – jfs Dec 20 '12 at 15:27
21

Blckknght's answer from back in 2012 is still correct, however using Python 3.7.1 I discovered that you have to use queue.Empty as the name of the exception to catch (Note the lowercase 'q' in 'queue'.)

So, to recap:

import queue

# Create a queue
queuevarname = queue.Queue(5) # size of queue is unimportant

while some_condition_is_true:
    try:
        # attempt to read queue in a way that the exception could be thrown
        queuedObject = queuevarname.get(False)

        ...
    except queue.Empty:
        # Do whatever you want here, e.g. pass so
        # your loop can continue, or exit the program, or...
ggariepy
  • 1,027
  • 8
  • 8