I have a project with directory structure like below
.
├── Pipfile
├── Pipfile.lock
├── module
│ ├── __init__.py
│ ├── helpers
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ │ └── __init__.cpython-36.pyc
│ │ ├── dynamo.py
│ │ └── logger.py
│ └── test.py
Relavant code
logger.py
import click
import sys
from tabulate import tabulate
def formatter(string, *rest):
return string.format(*rest)
def info(*rest):
"""Write text in blue color
"""
click.echo(click.style('☵ ' + formatter(*rest), fg='blue'))
test.py
import helpers
helpers.logger.info('Trying')
When I try to run using the command
python3 module/test.py
I get this error
Traceback (most recent call last):
File "module/test.py", line 4, in <module>
helpers.logger.info('Trying')
AttributeError: module 'helpers' has no attribute 'logger'
I have tried restructuring the code. Putting the helpers directory outside, in level with module directory. But still it didn't work, which it should not have, from what I have read. I tried researching a bit about __init__.py and python module system. The more I read, the more confusing it gets. But from whatever I learned, I created another sample project. With the following structure,
.
└── test
├── __init__.py
├── helpers
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ └── quote.cpython-36.pyc
│ └── quote.py
├── index.py
├── logger
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ └── info.cpython-36.pyc
│ └── info.py
Code is same as first project.
Here when I do,
python3 test/index.py
It works as expected. The only difference between the two projects:
In the first project, I used pipenv to install deps and create virtual environment.
Using your initial layout (with loggers as a submodule of the helpers package), you'd need to explicitely import loggers in helpers/__init__.py to expose it as an attribute of the helpers package:
# helpers/__init__.py
from . import logger
logger is module and not attribute and helpers.logger evalutes logger as attribute. Actually you should do as follow:
from helpers import logger
print(logger.info('Trying'))
Related
Before I say something, let me show the current project hierarchy. The app name is api.
── api
│ ├──
│ ├── admin.py
│ ├── apps.py
│ ├── init.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_wallet_customer_id.py
│ │ ├── 0003_auto_20201201_1103.py
│ │ ├── 0004_auto_20201203_0703.py
│ │ ├── 0005_auto_20201207_1355.py
│ │ ├── __init__.py
│ │
│ ├── models.py
│ ├── permissions.py
│ ├── serializers.py
│ ├── stellar.py
│ ├── te_s_ts_bk.py
│ ├── te_sts_2.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── debug.log
├── manage.py
└── myapp
├── __init__.py
├── asgi.py
├── settings-local.py
├── settings-remote.py
├── settings.py
├── urls.py
└── wsgi.py
As it was suggested here, I even removed __init__.py file from the api app folder, yet having the issue.
My TestCase Class look like below:
class CreateWalletTestCase(APITestCase):
app_id = 0
app = None
def test_create_wallet(self):
response = self.client.post(
'/wallets/',
data={'app_id': self.app_id, 'customer_id': 'A-001'},
**{'HTTP_api_key': 'test-api', 'HTTP_api_secret': 'test-api-password'}
)
data = json.loads(response.content)
self.assertEqual(data['status'], 'OK
When I run as python manage.py test api.CreateWalletTestCase.test_create_wallet or even python manage.py test CreateWalletTestCase.test_create_wallet, it generates the error:
ImportError: Failed to import test module: CreateWalletTestCase
Traceback (most recent call last):
File "/usr/local/lib/python3.9/unittest/loader.py", line 154, in loadTestsFromName
module = __import__(module_name)
ModuleNotFoundError: No module named 'api.CreateWalletTestCase'
The way to call the tests in python is very similar to the way you import things in that language. For example, if you want to import that TestCase in your file and assuming it is in the tests.py file, you should write import CreateWalletTestCase from api.tests in the elegant way. You can also write import api.tests.CreateWalletTestCase, to import it.
So, to call that specific test, you should write the command in the following way:
python manage.py test api.tests.CreateWalletTestCase.test_create_wallet
You can check the Django Documentation here about running tests.
It is not necessary to delete the __init__.py file.
What am I doing wrong? I'm trying to use relative imports in subfolder crawler to import utility from common?
Of note, if I move the script into the root folder it works – but I need to call common.utils from scripts , how can I fix this?
├── crawler
│ ├── common
│ │ ├── __init__.py
│ │ └── utils.py
│ ├── collector.py
│ ├── __init__.py
│ ├── scripts
│ │ ├── __init__.py
│ │ ├── test_imports.py # ImportError: attempted relative import with no known parent package
│ │ └── update_importer.py
test_imports.py
from .common.utils import fimct1 # error or from crawler.common.utils import fimct1 the same
print(fimct1)
You're doing it wrong. test_scripts.py is under scripts, so your import would expect that tree:
crawler -> scripts -> common -> utils
Use crawler.common.utils instead. Or, if you still want to go with relative imports, try ..common.utils. But, to be honest, relative imports aren't a good idea.
Directory structure:
.
├── classification
│ ├── lstm_repres.py
│ ├── lstm_test.py
│ ├── lstm_train.py
│ ├── lstm_utils.py
│ ├── lstm_utils.pyc
│ └── svm_run.py
├── utils
│ ├── data_splits.py
│ ├── evaluation.py
│ ├── load_data.py
│ ├── NLTKPreprocessor.py
│ ├── resources.py
│ ├── TfIdf.py
│ └── vector_utils.py
at lstm_train.py:
from classification.lstm_utils import *
when i try to run with both python2 lstm_train.py or python3 lstm_train.py, i get:
Traceback (most recent call last):
File "classification/lstm_train.py", line 7, in <module>
from classification.lstm_utils import *
ModuleNotFoundError: No module named 'classification'
The same happens at the line
from utils.data_splits import get_train, get_val
What is the issue here? Why does the format from <dir>.<script> import * doesn't seem to be working here?
EDIT
As suggested by #deathangel908, I've added __init__.py empty files to both directories, but the error persists.
In order to mark directory as a package you want to import, it needs to have least empty __init__.py within that directory. So add __init__.py files to classification and utils directories.
In order to import absolute path package you need to run python interpreter from the root package as a module: python3 -m "classification.lstm_train"
I wrote a small tool (package) that reuses an existing namespace, pki.server. I named my package as pki.server.healthcheck. The old namespace did not use setuptools to install the package, while my package uses it.
Contents of setup.py
from setuptools import setup
setup(
name='pkihealthcheck',
version='0.1',
packages=[
'pki.server.healthcheck.core',
'pki.server.healthcheck.meta',
],
entry_points={
# creates bin/pki-healthcheck
'console_scripts': [
'pki-healthcheck = pki.server.healthcheck.core.main:main'
]
},
classifiers=[
'Programming Language :: Python :: 3.6',
],
python_requires='!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*',
setup_requires=['pytest-runner',],
tests_require=['pytest',],
)
The installation tree (from scenario 1 below) looks like:
# tree /usr/lib/python3.8/site-packages/pki/
├── __init__.py <---- Has methods and classes
├── cli
│ ├── __init__.py <---- Has methods and classes
│ ├── <some files>
├── server
│ ├── cli
│ │ ├── __init__.py <---- Has methods and classes
│ │ ├── <Some files>
│ ├── deployment
│ │ ├── __init__.py <---- Has methods and classes
│ │ ├── <some files>
│ │ └── scriptlets
│ │ ├── __init__.py <---- Has methods and classes
│ │ ├── <some files>
│ ├── healthcheck
│ │ ├── core
│ │ │ ├── __init__.py <---- EMPTY
│ │ │ └── main.py
│ │ └── pki
│ │ ├── __init__.py <---- EMPTY
│ │ ├── certs.py
│ │ └── plugin.py
│ └── instance.py <---- Has class PKIInstance
└── <snip>
# tree /usr/lib/python3.8/site-packages/pkihealthcheck-0.1-py3.8.egg-info/
├── PKG-INFO
├── SOURCES.txt
├── dependency_links.txt
├── entry_points.txt
└── top_level.txt
I read the official documentation and experimented with all 3 suggested methods. I saw the following results:
Scenario 1: Native namespace packages
At first, everything seemed smooth. But:
# This used to work before my package gets installed
>>> import pki.server
>>> instance = pki.server.instance.PKIInstance("pki-tomcat")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'pki.server' has no attribute 'instance'
Now, only this works
>>> import pki.server.instance
>>> instance = pki.server.instance.PKIInstance("pki-tomcat")
>>> instance
pki-tomcat
Scenario 2: pkgutil-style namespace packages
I am restricted from using this method as my other __init__.py contain classes and functions
Scenario 3: pkg_resources-style namespace packages
Though this method was not-recommended, I went ahead and experimented with it by adding namespace=pki.server.healthcheck to my setup.py. This made all pki.* modules invisible
So I am convinced that Scenario 1 seems to be the closest to what I'm trying to achieve. I was reading an old post to understand more on how import in python works.
My question is: Why does a perfectly working snippet break after I install my package?
Your __init__.py files need to import the files. You have two options--absolute and relative imports:
Relative Imports
pki/__init__.py:
from . import server
pki/server/__init__.py:
from . import instance
Absolute Imports
pki/__init__.py:
import pki.server
pki/server/__init__.py:
import pki.server.instance
I'm trying to test out an example from a book and I'm getting an ImportError.
The example starts out like:
from tkinter import *
from PP4E.Gui.Tools.widgets import frame, button, entry
And if I put an import sys; print(sys.path) at the beginning of the code, the output is
['/Users/aaa/Documents/workspace/programming-python/PP4E/Lang/Calculator',
'/usr/local/lib/python3.4/site-packages/setuptools-12.2-py3.4.egg',
'/usr/local/lib/python3.4/site-packages/pip-6.0.8-py3.4.egg',
'/User/aaa/Documents/workspace/programming-python',... ]
This is what a truncated version of my programming-python directory looks like:
❯ tree
.
├── PP4E
│ ├── __init__.py
│ ├── Gui
│ │ ├── Tools
│ │ │ ├── __init__.py
│ │ │ └── widgets.py
│ │ └── __init__.py
│ ├── Lang
│ │ └── Calculator
│ │ ├── __init__.py
│ │ └── calc0.py
└── site-packages
└── PP4E.pth
The error message I'm getting is:
❯ python3 calc0.py
Traceback (most recent call last):
File "calc0.py", line 2, in <module>
from PP4E.Gui.Tools.widgets import frame, button, entry
ImportError: No module named 'PP4E'
Does anybody know what I have to do to get Python to find the PP4E module? Thanks.
I had my PYTHONPATH wrong -- the root directory is /Users, not /User. Thanks.