473,325 Members | 2,870 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

relative imports improve program organization... suggestions?

DG
Alright, I have searched and searched and read many conversations on
the topic of relative and absolute imports and am still not getting
the whole thing through my skull.

Highlights of what I've read:
http://mail.python.org/pipermail/pyt...ry/422973.html
http://groups.google.com/group/comp....51c82cfe1ca3f2
http://www.python.org/dev/peps/pep-0328/
http://docs.python.org/whatsnew/pep-328.html

So my problem and argument:
I want to create a package organized as the following:
pckg/
__init__.py
main.py
moduleA/
__init__.py
A_base.py
A1/
__init__.py
A_inherit1.py
other_A1_files...
A2/
__init__.py
A_inherit2.py
other_A2_files...
moduleB/
...
Explanation:
The main program is located in main.py and it implements the different
modules (A, B). Within the modules the basic organization is; the
base class for all different types of A is directly within the moduleA
directory. All of the different inherited classes of A are within
their own subdirectory with a mess of their own files. This is done
so that a new subclass of A can be added/removed by just adding/
removing the subdirectory and each of these subclasses may have their
own maintainer, but they should all inherit from A_base.py

If I am developing the A1 directory, I want to be able to test
A_inherit1.py by using 'if __name__ == "__main__"' within the
A_inherit1.py file and by typing 'python A_inherit1.py' on the command
line. I prefer this simply to keep all unit tests within the same
directory and same file as the inherited class.

My Problem:
A_inherit1.py has the line:
'from ..A_base import A_Base_Class'
so that I can later declare the inherited class as such:
'A1_Inherited_Class(A_Base_Class):'

*BUT* I get the 'attempted relative import in non-package' error even
when I try the
'from __future__ import absolute_import' command.
I would prefer to be able to test the file without adding anything to
the PYTHONPATH, like I said by using the name == main trick.

So could someone explain to me what the rationale behind not allowing
parent directory relative imports is? And possibly what I can do to
get around it? (I really don't like messing with the sys.path for
something like this)

Thanks,
Danny G
Aug 8 '08 #1
4 1797
DG
http://www.velocityreviews.com/forum...rt-broken.html
also gets a bit into this issue, and explains it a bit more
thoroughly.

Still though, I don't why there isn't a 'clean' way to be able to
inherit from a file in the parent directory but still be able to test
the derived class in its own directory without modifying the
PYTHONPATH.
Aug 8 '08 #2
On Aug 8, 1:37*pm, DG <dang...@gmail.comwrote:
My Problem:
A_inherit1.py has the line:
* * *'from ..A_base import A_Base_Class'
so that I can later declare the inherited class as such:
* * *'A1_Inherited_Class(A_Base_Class):'

*BUT* I get the 'attempted relative import in non-package' error even
when I try the
'from __future__ import absolute_import' command.
I would prefer to be able to test the file without adding anything to
the PYTHONPATH, like I said by using the name == main trick.

So could someone explain to me what the rationale behind not allowing
parent directory relative imports is? *And possibly what I can do to
get around it? *(I really don't like messing with the sys.path for
something like this)

The problem you are seeing is because when you invoke the script via
the command line it is considered an isolated module called __main__.
In fact if another module were to reimport it it would actually create
a new module with the module's intended name. Not one of the nicer
aspects of Python.

The rationale for doing it this way is mostly historical reasons:
before packages existed it wasn't so confusing. Python 3 (and, I
think, 2.6) has some features to help cope with it better.

Until then, I would say the most straightforward way to workaround
this is to have a helper script. Instead of running "python
A_inherit1.py", you'd run "unittest A_inherit1.py", where unittest is
a Python script that adds the project root to the sys.path, constructs
the actual module name, imports it, and runs a function called
test(). You would have to define test() and use it in lieu of the if
__name__ == '__main__' thing.

Very simple, unchecked, bug-filled example of what the unittest script
would look like:

---------------------
#!/usr/bin/python

import os
import sys

# Get module name

filename = sys.argv[1]
modname = os.path.splitext(filename)[0]

# Starting from cwd, find the project root

pathname = os.getcwd()
pkgpath = []
while True:
dirname,basename = os.path.split(pathname)
if dirname == 'pckg':
break
pkgpath.append(basename)
pathname = dirname

# Insert the project root into sys.path

sys.path.insert(0,pathname)

# Determine the package

pkgpath.reverse()
pkgname = ".".join(pkgpath)

# Import the module

mod = __import__(modpath,None,None,modname)

# Run the unit tests

mod.test()
---------------------

Yes, this does manipulate sys.path. It won't kill you. At least this
way the magic behavior is kept out of the files themselves. As an
added bonus, it allows the unit tests to be run from an interactive
prompt.
Carl Banks
Aug 8 '08 #3
On Aug 8, 12:37*pm, DG <dang...@gmail.comwrote:
Alright, I have searched and searched and read many conversations on
the topic of relative and absolute imports and am still not getting
the whole thing through my skull.

Highlights of what I've read:http://mail.python.org/pipermail/pyt...w/pep-328.html

So my problem and argument:
I want to create a package organized as the following:
pckg/
* * *__init__.py
* * *main.py
* * *moduleA/
* * * * * __init__.py
* * * * * A_base.py
* * * * * A1/
* * * * * * * *__init__.py
* * * * * * * *A_inherit1.py
* * * * * * * *other_A1_files...
* * * * * A2/
* * * * * * * *__init__.py
* * * * * * * *A_inherit2.py
* * * * * * * *other_A2_files...
* * *moduleB/
* * * * * ...
Explanation:
The main program is located in main.py and it implements the different
modules (A, B). *Within the modules the basic organization is; the
base class for all different types of A is directly within the moduleA
directory. *All of the different inherited classes of A are within
their own subdirectory with a mess of their own files. *This is done
so that a new subclass of A can be added/removed by just adding/
removing the subdirectory and each of these subclasses may have their
own maintainer, but they should all inherit from A_base.py

If I am developing the A1 directory, I want to be able to test
A_inherit1.py by using 'if __name__ == "__main__"' within the
A_inherit1.py file and by typing 'python A_inherit1.py' on the command
line. *I prefer this simply to keep all unit tests within the same
directory and same file as the inherited class.

My Problem:
A_inherit1.py has the line:
* * *'from ..A_base import A_Base_Class'
so that I can later declare the inherited class as such:
* * *'A1_Inherited_Class(A_Base_Class):'

*BUT* I get the 'attempted relative import in non-package' error even
when I try the
'from __future__ import absolute_import' command.
I would prefer to be able to test the file without adding anything to
the PYTHONPATH, like I said by using the name == main trick.

So could someone explain to me what the rationale behind not allowing
parent directory relative imports is? *And possibly what I can do to
get around it? *(I really don't like messing with the sys.path for
something like this)

Thanks,
Danny G
Didn't read the whole thing, but would imp.load_source( name,
relative_path ) help you at all?
Aug 9 '08 #4
DG
Carl: Your solution is kind of what I was leaning towards after a bit
of thinking. Since I have to have the modules each have their own
detect() method, then it wouldn't be too hard to have their own test()
method to put them through their paces.

Catrironpi: I will look into this as it might help just get around the
problem, but in my eyes it's still not 'clean'. Simply because people
(including me) would expect the regular 'import' statement over the
method I would think.

Thanks to all who responded.
Aug 13 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Rutger Claes | last post by:
In the directory /var/www/dynamo/xsl is the basic xsl file for xhtml documents /var/www/dynamo/xsl/xhtml.xsl. In this file there is an import statement: <xsl:import href="xhtml/basic.xhtml.xsl"...
0
by: Randall Smith | last post by:
I've noticed the push by Guido and others to use absolute imports instead of relative imports. I've always enjoyed the ease of relative imports, but am starting to understand that "explicit is...
18
by: Nak | last post by:
Hi there, Does anyone know what path the AssemblyKeyFile attribute is relative to? For example I currently have mine set to <Assembly: AssemblyKeyFile("..\NicksKey.snk")> Sometimes this...
0
by: Anders J. Munch | last post by:
Now 2.5 is out, and we have a syntax for explicit relative imports (PEP 328, http://www.python.org/dev/peps/pep-0328/, in case anyone wasn't paying attention). The long-term plan is that the...
1
by: Alexey Borzenkov | last post by:
After reading PEP-0328 I wanted to give relative imports a try: # somepkg/__init__.py <empty> # somepkg/test1.py from __future__ import absolute_import from . import test2 if __name__ ==...
12
by: Alan Isaac | last post by:
Are relative imports broken in 2.5? Directory ``temp`` contains:: __init__.py test1.py test2.py File contents: __init__.py and test2.py are empty test1.py contains a single line::
9
by: rbygscrsepda | last post by:
Hi, I'm a newbie at Python. :) Right now it's not letting me import * from any relative package name--i.e., a name that starts with a dot. For instance, none of the following work: from . import...
0
by: Kay Schluehr | last post by:
Since their introduction in Python 2.5 I only reviewed the new "relative import" notation briefly by reading the "What's new in Python 2.5" article. Now I wanted checkout if I get comfortable with...
0
by: Gabriel Genellina | last post by:
En Sat, 18 Oct 2008 05:52:04 -0300, Stef Mientki <stef.mientki@gmail.com> escribió: Why don't you let the caller tell you its own location, using __file__? The above code is too much magic for...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.