Py3: Import relative path module

G

Gnarlodious

I am loathe to duplicate programming in files that should just load a
copy from a module. I tried all kinds of tricks to import a module
from one level up. What's the secret?

It works if I say:

from Data import DumpHT

but ONLY if the search path in sys.path. I want a relative path import
independent from sys.path.

How to? This is Python 3.1.1

-- Gnarlie
 
Ð

Дамјан ГеоргиевÑки

I am loathe to duplicate programming in files that should just load a
copy from a module. I tried all kinds of tricks to import a module
from one level up. What's the secret?

It works if I say:

from Data import DumpHT

but ONLY if the search path in sys.path. I want a relative path import
independent from sys.path.

How to? This is Python 3.1.1

from .. import Data.DumpHT as DumpHT
 
S

Steven D'Aprano

That doesn't work. Any more ideas?

Define "doesn't work". Does it?


Print a warning message but continue execution?
Import the wrong module?
Abort Python without warning?
Dump core?
Reboot the operating system without warning?
Lock up the computer?
Something else?
 
G

Gnarlodious

Define "doesn't work".

LOL.
I get error:

from .. import Data.DumpHT as DumpHT
^
SyntaxError: invalid syntax

Rewording gets me closer:

from ..Data import DumpHT
ValueError: Attempted relative import in non-package

I do have the empty __init__.py file in the Data folder. What is
wrong?

-- Gnarlie
 
P

Peter Otten

Gnarlodious said:
LOL.
I get error:

from .. import Data.DumpHT as DumpHT
^
SyntaxError: invalid syntax

Rewording gets me closer:

from ..Data import DumpHT
ValueError: Attempted relative import in non-package

I do have the empty __init__.py file in the Data folder. What is
wrong?

Remove the directory containing the importing file from your sys.path.
E. g. if you have

$ tree
..
`-- alpha
|-- __init__.py
|-- beta
| |-- __init__.py
| `-- one.py
`-- gamma
|-- __init__.py
`-- two.py

only the parent of alpha should be in your sys.path. Then to import
alpha/gamma/two.py from alpha/beta/one.py use

from ..gamma import two

Peter
 
G

Gnarlodious

Remove the directory containing the importing file from your sys.path.
I removed all sys.path customizations and rebooted.

In the following scenario, I am programming in one.py attempting to
import Data.py which is in the alpha folder:
$ tree
.
`-- alpha
    |-- __init__.py
    |-- beta
    |   |-- __init__.py
    |   `-- one.py
    `-- gamma
        |-- __init__.py
        `-- two.py

However, all I can get is error:

from .. import Data
ValueError: Attempted relative import in non-package

Why is the parent folder not recognized as a package? Because right
now I am liberally using sys.path, which works but is a little too
messy.

-- Gnarlie
 
P

Peter Otten

Gnarlodious said:
I removed all sys.path customizations and rebooted.

In the following scenario, I am programming in one.py attempting to
import Data.py which is in the alpha folder:

However, all I can get is error:

from .. import Data
ValueError: Attempted relative import in non-package

Why is the parent folder not recognized as a package? Because right
now I am liberally using sys.path, which works but is a little too
messy.

If you didn't add '/path/to/alpha' to your path explicitly then you may be
starting one.py as a script with

$ python /path/to/alpha/beta/one.py

one.py then becomes the __main__ module instead of alpha.beta.one.
Or your working directory is /path/to/alpha and you import one.py with

import beta.one

which makes beta instead of alpha the toplevel package.

Peter
 
T

Terry Reedy

LOL.
I get error:

from .. import Data.DumpHT as DumpHT
^
SyntaxError: invalid syntax

Rewording gets me closer:

from ..Data import DumpHT
ValueError: Attempted relative import in non-package

I do have the empty __init__.py file in the Data folder. What is
wrong?

What about the folder above it?

As far as I know, the main reason to use relative imports is if you have
a subpackage that you expect to use within more then one package.
Otherwise, it is usually a lot easier to use absolute imports starting
with the top-level package.
 
G

Gnarlodious

I admit I don't understand any of what was said here. Or why it is so
hard what I am trying to do. I searched Google for a few hours looking
for a way to import a module from an absolute path, but that was a
waste of time too.

To reiterate, I am trying to import a Def function from a file one
level up. Let's say relative import is unreasonable to expect from
Python. If it is possible using an absolute path, please let me know
how, in plain language. Otherwise I can continue to copy and paste my
programming into several files.

Thank you for any help.

-- Gnarlie
 
M

MRAB

I admit I don't understand any of what was said here. Or why it is so
hard what I am trying to do. I searched Google for a few hours looking
for a way to import a module from an absolute path, but that was a
waste of time too.

To reiterate, I am trying to import a Def function from a file one
level up. Let's say relative import is unreasonable to expect from
Python. If it is possible using an absolute path, please let me know
how, in plain language. Otherwise I can continue to copy and paste my
programming into several files.

Thank you for any help.
After some experimentation (and Googling!) I think the problem is that
a module can do your relative import but a main script can't.

Or, to put it another way, if __name__ is "__main__" then it won't work.
 
P

Peter Otten

MRAB said:
After some experimentation (and Googling!) I think the problem is that
a module can do your relative import but a main script can't.

Or, to put it another way, if __name__ is "__main__" then it won't work.

Slightly generalized: have the importing module print its __name__. There
has to be at least one dot in the name for

from .. import whatever

to succeed.
 
G

Gnarlodious

Slightly generalized: have the importing module print its __name__. There
has to be at least one dot in the name for

from .. import whatever

to succeed.

Just spent about 3 hours trying every permutation I could think of,
and searching Google for exactly how to do it, but all I get is:

ValueError: Attempted relative import in non-package

How do I import a module so that a dot will appear in its name?

-- Gnarlie
 
P

Peter Otten

Gnarlodious said:
Just spent about 3 hours trying every permutation I could think of,
and searching Google for exactly how to do it, but all I get is:

ValueError: Attempted relative import in non-package

How do I import a module so that a dot will appear in its name?

Make sure the no path in sys.path leads into a directory that contains an
__init__.py. In particular, ensure that you aren't invoking the python
interpreter from a working directory that contains an __init__.py and that
the main script is in a directory that doesn't contain an __init__.py.

Peter
 
P

Peter Otten

Peter said:
Make sure the no path in sys.path leads into a directory that contains an
__init__.py. In particular, ensure that you aren't invoking the python
interpreter from a working directory that contains an __init__.py and that
the main script is in a directory that doesn't contain an __init__.py.

Peter

Here's a working example that you can use as a starting point:

$ tree
..
|-- alpha
| |-- __init__.py
| |-- beta
| | |-- __init__.py
| | `-- one.py
| `-- two.py
`-- main.py

2 directories, 5 files
$ cat main.py
import alpha.beta.one
$ cat alpha/beta/one.py
from ..alpha import two
$ cat alpha/two.py
print "success!"
$ python main.py
success!

Peter
 
P

Peter Otten

Peter said:
Here's a working example that you can use as a starting point:

$ tree
.
|-- alpha
| |-- __init__.py
| |-- beta
| | |-- __init__.py
| | `-- one.py
| `-- two.py
`-- main.py

2 directories, 5 files
$ cat main.py
import alpha.beta.one
$ cat alpha/beta/one.py
from ..alpha import two
$ cat alpha/two.py
print "success!"
$ python main.py
success!

Hmm, now I'm puzzled myself.
$ cat alpha/beta/one.py
from ..alpha import two

That line should have been

from .. import two

For some reason (bug?) it seems to work with and without the extra alpha.

Peter
 
G

Gnarlodious

Peter said:
|-- alpha
|   |-- __init__.py
|   |-- beta
|   |   |-- __init__.py
|   |   `-- one.py
|   `-- two.py
`-- main.py

2 directories, 5 files
$ cat main.py
import alpha.beta.one
$ cat alpha/beta/one.py
from ..alpha import two
$ cat alpha/two.py
print "success!"
$ python main.py
success!

Thank you for that example, it works for me. However, what I want to
do is go UP one folder to import the module(s) in some library:

python main.py
import ..alpha.beta.one
^
SyntaxError: invalid syntax

python main.py
from .. import alpha.beta.one
^
SyntaxError: invalid syntax

So how to specify a relative path?

-- Gnarlie
 
G

Gnarlodious

OK I've had a modicum of success! However I was forced to add the path
to my application folder to sys.path, which I suppose is the closest I
can get to what I want. The example given then works in the shell.

Apache is another problem. I added the same path to the script then
Apache finds the application folder and does the importing. Not an
ideal solution, but workable. I hope Apache3 in the future has more
smarts about importing relative filepaths.

Thank you Peter for your patience on this!

-- Rachel
http://google.com/profiles/Gnarlodious
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,734
Latest member
manin

Latest Threads

Top