How to import a folder with absolute path as package? - python

The path is app/base/admin/crud/__init__.py.
I want to import an entire folder as a package like this:
import app.base.admin.crud as cx
But it doesn't work and gives this error:
AttributeError: module 'app.base' has no attribute 'admin'
But when I import it's function like this from app.base.admin.crud import crud, it works.
What's going on here?

See the documentation about packages.
More specifically that part:
[...] when using syntax like import item.subitem.subsubitem, each item except for the last must be a package; the last item can be a module or a package but can’t be a class or function or variable defined in the previous item.
When using the import x.y.z statement alone (without from), you're actually importing a package for usage in your code as x.y.z.something(). Each part of that path must be a proper package (in other words, contain a __init__.py file)

Related

Change python import name without changing code and file structure

I currently have a package A from someone else that uses an import syntax like import A in its code, e.g. A/B/C/xx.py.
What I want to do is to reference package A in my project X, forming a package structure X/A like this. However, I need to meet the following two requirements:
not modify a single line of code in A
import A is not valid anywhere else unless it is in package X.
I spent a few days looking for a workaround, but none of it worked. All methods that do not throw an error result in import A being available everywhere else.
You could create a my_requirements.py file that does all imports leaving out module_name or again deleing module_name under the conditions that you demand. You would then just have to:
import my_requirements

Toggle between relative and absolute Import of built in module

So I have the script that imports the standard module checkmarc.
import checkdmarc
I want to implement some mock checkmarc that will seat at the same directory as the script.
Now sometime it will be there and I want the script to pull that local module and if it's not there it should take the standard checkmarc.
I know I can do something like if the file in the path exists it'll take that, else do that, but I want to keep the import line just import checkmarc.
From reading: https://docs.python.org/3/whatsnew/2.5.html#pep-328-absolute-and-relative-imports
there's a section of exactly what I need but only for Python 2.4 and lower:
In Python 2.4 and earlier, it will first
look in the package’s directory to perform a relative import, finds
pkg/string.py, imports the contents of that file as the pkg.string
module, and that module is bound to the name string in the pkg.main
module’s namespace.
If there's an elegant way to do it, I'd love to hear.
I don't think you can do this if your custom module has the same name. You can however do something like this:
try:
import customcheckdmarc as checkdmarc
except ImportError:
import checkdmarc as checkdmarc
this will load your customecheckedmarc.py if it's there and will load default checkdmarc otherwise.

Change main package name in python

In my project I want to change the main package name.
I've a dir structure like this:
hallo/sub
hallo/foo
hallo/bar
And I want to change the main name for example to 'goodbye':
goodbye/sub
goodbye/foo
goodbye/bar
But as result the new name is always rejected! for example if I import
import goodbye.sub.utils as utils
It return the error
ImportError: No module named sub.utils
And clearly the old name don't works.
The file __init__.py is written in all subdirectories!
I've tried to remove all *.pyc files and cache directory, I've tried to re-clone the project in another directory, but nothing, the new name is always rejected!
I'm using python2 under *nix and I'm never moved under windows.
Some idea?
Edit:
The old name works perfectly:
import hallo.sub.utils as utils
Has always worked without any errors, the problem is the name change.
For imports from the outside, check the contents of __init__.py for variables that can throw things off -- like __all__.
Also, the typical idiom is:
from hallo.sub import utils #tyically this
import hallo.sub.utils as utils #instead of this
I can't imagine why that would make a difference, but python occasionally has silly bugs.
For imports from within the package, you can instead use relative imports. Within your hallo package you can change this:
import hallo.sub as sub
import hallo.sub.utils as utils
to this
from . import sub
from .sub import utils
Then it doesn't matter what the outer package is called.

Package Import woes in Python

My structure is thus:
companynamespace/
__init__.py
projectpackage/
__init__.py
somemodule.py
companynamespace/__init__.py is empty
projectpackage/__init__.py has this line:
import companynamespace.projectpackage.somemodule as module_shortname
When I open up a python console and type import companynamespace.projectpackage (PYTHONPATH is set correctly for this), I get AttributeError: 'module' object has no attribute 'projectpackage' on the import companynamespace.projectpackage.somemodule as module_shortname line. If I remove the as module_shortname part (and make all the requisite substitutions in the rest of the file), everything imports correctly.
Can anyone tell me why this is? My Google-Fu fails me.
There is no need for absolute import in projectpackage/__init__.py, do relative one
import somemodule as module_shortname
The way you're doing it (with absolute import), would lead to circular import, which don't work very well in Python. When you're importing module, you're also calling __init__.py of parent modules. In your case, with absolute import you're also calling projectpackage/__init__.py in projectpackage/__init__.py.
Well, according to the PEP 221 your code seems to be legitimate. It could be a bug. The following workaround, which is equivalent of that expression, works for me (Python 2.6.6):
from companynamespace.projectpackage import somemodule as module_shortname
Hope it helps.

Trying to import module with the same name as a built-in module causes an import error

I have a module that conflicts with a built-in module. For example, a myapp.email module defined in myapp/email.py.
I can reference myapp.email anywhere in my code without issue. However, I need to reference the built-in email module from my email module.
# myapp/email.py
from email import message_from_string
It only finds itself, and therefore raises an ImportError, since myapp.email doesn't have a message_from_string method. import email causes the same issue when I try email.message_from_string.
Is there any native support to do this in Python, or am I stuck with renaming my "email" module to something more specific?
You will want to read about Absolute and Relative Imports which addresses this very problem. Use:
from __future__ import absolute_import
Using that, any unadorned package name will always refer to the top level package. You will then need to use relative imports (from .email import ...) to access your own package.
NOTE: The above from ... line needs to be put into any 2.x Python .py files above the import ... lines you're using. In Python 3.x this is the default behavior and so is no longer needed.

Categories