10

My import of Python modules

import Queue
from threading import Thread
import time

But when I run code

File "b1.py", line 3, in <module>
    import Queue
ModuleNotFoundError: No module named 'Queue'

I have seen similar threads on SO,but nothings works for me

/usr/bin/python3 --version
Python 3.5.2
milenko@milenko-System-Product-Name:~$ python --version
Python 3.6.0 :: Anaconda custom (64-bit)

If I change to

from multiprocessing import Queue

there is no import problem.But than I have this

AttributeError: 'Queue' object has no attribute 'join'

What should I try next?

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
MishaVacic
  • 1,812
  • 8
  • 25
  • 29
  • 3
    you can try `import queue` – Jean-François Fabre Sep 22 '17 at 11:39
  • 2
    To explain: On Python 2, the module is named `Queue`, on Python 3, it was renamed to follow PEP8 guidelines (all lowercase for module names), making it `queue`. The *class* remains `Queue` on all versions (following PEP8). – ShadowRanger Sep 22 '17 at 11:40
  • 1
    @Jean-FrançoisFabre: Unfortunately, the problem described there is best answered by the accepted answer. The `requests` module already tries importing from `queue`, then falling back to `Queue` if that fails. Their problem wasn't about Python version at all. The suggestion to use `multiprocessing.Queue` is a truly terrible answer (you'd have to monkey-patch `requests`, and it would involve slowing down everything, and breaking if unpicklable stuff was involved); every answer to that question *except* the accepted one was posted by people not paying attention to the OP's actual problem. – ShadowRanger Sep 22 '17 at 11:50
  • 1
    @ShadowRanger so you're suggesting reopening? that would fly by me since this particular question is clearer. your comment (with the PEP8 stuff) would make a nice answer. – Jean-François Fabre Sep 22 '17 at 11:53
  • 1
    @Jean-FrançoisFabre: I guess? That question is kind of a terrible duplicate target; most of the questions targeting it as a duplicate are like this one, not issues with naming personally written modules `queue.py` (the ultimate problem there), but trying `import Queue` on Python 3 (the problem here). – ShadowRanger Sep 22 '17 at 11:56
  • @ShadowRanger [this](https://stackoverflow.com/questions/41150948/how-to-convert-from-queue-import-queue-empty-from-python-2-to-python-3/41151032#41151032) is an appropriate duplicate target. Though, since I believe your answer here is better, I'll close it as a dupe of this one. – Dimitris Fasarakis Hilliard Sep 22 '17 at 12:53

2 Answers2

19

On Python 2, the module is named Queue, on Python 3, it was renamed to follow PEP8 guidelines (all lowercase for module names), making it queue. The class remains Queue on all versions (following PEP8).

Typically, the way you'd write version portable imports would be to do:

try:
    import queue           # Python 3 import
except ImportError:
    import Queue as queue  # If queue missing, we're on Py2, import Py2 as Py3 name
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • This doesnt work for Python 3.6, since it now throws a `ModuleNotFoundError` instead of the `ImportError`. Changing to `except ModuleNotFoundError` would then again not work for older versions, since this exception type did not exist there. Checkmate :D – Jeronimo Sep 22 '17 at 12:22
  • 1
    @Jeronimo: It works fine. [`ModuleNotFoundError` is a subclass of `ImportError`](https://docs.python.org/3/library/exceptions.html#ModuleNotFoundError), so catching `ImportError` also catches `ModuleNotFoundError`. `ImportError` isn't as fine-grained (e.g. it can't tell you the problem is a name-shadowing module, rather than a lack of a module), but it will work. Also, since I prioritized the Py3 name, the only place `ImportError` would be raised is Py2, so it's doubly fine. – ShadowRanger Sep 22 '17 at 12:28
  • Ah ok, you're right. I thought to remember this causing an error in my code recently, but I can't find it right now, so something else must have been the source then... – Jeronimo Sep 22 '17 at 12:42
  • File "main.py", line 36, in __init__ self.queue = queue() TypeError: 'module' object is not callable – John Jun 04 '20 at 06:46
  • @John: Reread the first paragraph of my answer. The module `queue` (which is the name the code above uses regardless of Python version, as we alias the Python 2 name to the Python 3 name) contains the class `Queue` (which is the same on all versions). You want `self.queue = queue.Queue()`. – ShadowRanger Jun 04 '20 at 11:23
0

In my case, I had the following for Python 2.7

from Queue import Queue, Empty

I changed only the module name to lower case, and it worked fine with Python 3 like

from queue import Queue, Empty
hyong
  • 340
  • 5
  • 8