53

PyCharm 2016.2.3, Mac OS X 10.11.1, Python 3.5 (Homebrew);

I have this folder structure

project
  /somepackage
    /subpackage
     __init__.py   
     bar.py
   __init__.py
   foo.py

foo.py:

import somepackage.subpackage.bar
print("foo")

bar.py:

print("bar")

So my expected output is

bar
foo

This works fine when run from PyCharm. However, when I run it from my terminal I get an ImportError:

$ pwd
$ /home/project (not the actual path; just omitting some personal stuff)
$ python3.5 somepackage/foo.py
File "foo.py", line 1, in <module>
import somepackage.subpackage.bar
ImportError: No module named 'somepackage'

I have found this question, which is about the same problem. However, none of the suggested solutions work for me, as I am indeed using the same Python interpreter as PyCharm does and I am currently in the folder that contains the /somepackage folder.

Does anyone have any other suggestions about how to solve this issue?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Pibborn
  • 640
  • 1
  • 5
  • 13

4 Answers4

60

You are running foo.py like a script, but you are really using it like a module. So the proper solution is to run it as a module:

python3 -m somepackage.foo

For the record, another alternative is to edit your path like:

export PYTHONPATH=.

(Or you could put the absolute directory in there, and of course you should append any other directories that are already in your PYTHONPATH.) This is closer to what PyCharm does, but is less philosophically correct.

Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49
  • Approach #1 worked for me. Where is this documented? – alex Sep 15 '17 at 13:41
  • 3
    @alex It's in the [Command Line and Environment docs](https://docs.python.org/3/using/cmdline.html), but it's not obvious to look there unless you already know the solution! It's a pity it's not mentioned in the [Modules section of the tutorial](https://docs.python.org/3/tutorial/modules.html), or even the highly technical [Import System reference docs](https://docs.python.org/3/reference/import.html). – Arthur Tacca Sep 15 '17 at 13:59
  • @ArthurTacca Yep, sure enough: `When called with -m module-name, the given module is located on the Python module path and executed as a script.`. Wish I could upvote this twice ;) – alex Sep 15 '17 at 15:10
  • This works! But how to execute somepackage/foo.py as a script using `python3 somepackage/foo.py`? – Kaushal28 Nov 24 '19 at 07:02
  • @Kaushal28 Edit your `PYTHONPATH`, as I said in the part of my answer that starts "For the record, another alternative ..." – Arthur Tacca Nov 25 '19 at 10:20
  • What does `export PYTHONPATH=.` do? – Rylan Schaeffer Dec 09 '21 at 18:45
  • @RylanSchaeffer First some background: By default, import statements look within the directory containing the python file you pass on the command line. For example: if you `cd mydir` and then run `python foo/bar.py` (so `mydir` contains a subdirectory `foo` which contains a file `bar.py`), then by default `import mymodule` will look for `mymodule.py` *in the `foo` subdirectory*. But `export PYTHONPATH=.` tells Python to also look in the current directory. In that example, it would also look for `mymodule.py` right there in `mydir`. – Arthur Tacca Dec 10 '21 at 09:27
  • @RylanSchaeffer Actually I realised maybe you're asking something simpler. Why the `.`? The answer is that `.` has a special meaning on file systems: it means the current directory. (And `..` means the parent directory.) – Arthur Tacca Dec 10 '21 at 09:28
8

Setting PYTHONPATH is what makes it work, as noted above. I use the following VSCODE .env content so that it works for any project:

PYTHONPATH=${PROJ_DIR}:${PYTHONPATH}

This is essentially what PyCharm does when you check "Add Content Roots to PYTHONPATH" in your run/debug configuration. It's a helpful setting, but it spoils you because your code fails outside PyCharm.

Or, if you run in terminal, first export:

export PYTHONPATH=...

Took me days to work all this out.

val
  • 139
  • 1
  • 6
6

i solved my problem by two steps on Linux:

  1. first step go to the root directory of your project and set:
export PYTHONPATH=$PATHONPATH:`pwd`
  1. second step run python3 -m somepackage.foo remember Without '.py' suffix
Oscar
  • 324
  • 1
  • 3
  • 11
0

I just had the same problem using scapy.layers.http Module, this problem occurred on my Kali (linux-Debian) but run fine on Win-10 (after few modifications.)

packet was installed (scapy-http) correctly and the program was running in PyCharm but not as script (from terminal)

I tried solving it with reinstalling in main root, and messing with the sys.path but None have worked.

Troubleshoot & Solution

  1. I found that it looks for the http module in:

    /usr/local/lib/python3.7/dist-packages/scapy/layers/init.py

and got the ImportError:

from scapy.layers import http --->
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'http' from 'scapy.layers' (/usr/local/lib/python3.7/dist-packages/scapy/layers/__init__.py)

  1. So then I checked where scapy-http is really installed, which is module called http.py, so I just copied it to:

     /usr/local/lib/python3.7/dist-packages/scapy/layers/   
    
      found the http.py file in :/usr/local/lib/python3.7/dist-packages/scapy_http/
    

And that did it :)!

I know its a bit glitchie but that worked!

Federico Baù
  • 6,013
  • 5
  • 30
  • 38