relative import from __init__.py file throws error
Question: So I'm using a template set by a co-worker and as a newbie to python I may be
missing something very obvious.

The main directory has the init file which has a module I need for the main
python file that generates the error.

Co-worker used:

    
    
    from . import X
    

Where X was the module, but when copying this (and a populated init file) to
my own directory it generates this error:

> ValueError: Attempted relative import in non-package

From google and SO I gather that this is perfectly fine and logical so I'm
wondering, as a newbie, what I've missed.


Answer: You have to understand how Python handles modules.

When you start the interpreter with a script, this script becomes the main
module, with the matching name `__main__`.

When using `import`, other modules are searched in the search path, that you
can also access (and change) using `sys.path`. The first entry of `sys.path`
is usually empty and stands for the current directory.

A directory within the search path is a package if it contains a `__init__.py`
file.

Now, when you execute a script within a directory that contains an
`__init__.py` file, this script will become `__main__` and the directory is
not regarded as a package, as it is not in `sys.path`!

For example, consider the following directory layout:

    
    
    root/
        pkg/
            __init__.py
            b.py
            c.py
        a.py
    

When you run `python a.py` from the `root/` directory, you can import `pkg/`
and use relative imports within this package (e.g., `from . import c` in
`b.py` or `__init__.py`).

When you run `python b.py` from the `pkg` directory, you cannot use relative
imports since Python does not recognize `pkg` as a package: it is not in
`sys.path`. For Python, `pkg` is an ordinary directory, no matter if it
contains a `__init__.py`. The fully qualified name of `c.py` is just `c`, not
`pkg.c`, so a relative `from . import c` won't work.

