No moduled name... with pytest and pytest.ini - python

Hello I am trying to develop a few tests with python in order to do this I have the following folder structure:
.
├── Pipfile
├── Pipfile.lock
├── src
│ ├── adapters
│ │ ├── __init__.py
│ │ ├── orm.py
│ │ └── repository.py
│ ├── app.py
│ ├── bootstrap.py
│ ├── db.py
│ ├── domain
│ │ ├── __init__.py
│ └── settings.py
└── test
├── conftest.py
├── __init__.py
├── integration
│ ├── test_orm.py
│ └── test_repository.py
├── pytest.ini
└── unit
├── test_account.py
├── test_client.py
├── test_commerce.py
└── test_move.py
The pytest.ini contains:
[pytest]
pythonpath = src
The tests are launched with the following command:
python -m pytest -s -v test/
The problem is about import, in the conftest.py I have the following code:
import pytest
from sqlalchemy.orm import clear_mappers
from adapters.orm import start_mappers
#pytest.fixture
def mappers():
start_mappers()
yield
clear_mappers()
The line from adapters.orm import start_mappers fails if I doesn't set src before like this from src.adapters.orm import start_mappers
but if do that, the file inside orm module fails, because it has the relative import:
from domain import Move, Account, Client, Commerce
instead of
from src.domain import Move, Account, Client, Commerce
but if I use this, of course, another thing fails, and the idea is not to use src. suffix in the src code.
So how can I solve this, in order to avoid installing src as a python package, or fill all folders with init.py or put src. in all places?
Thanks.

Related

Problem importing nested package in Python

Based from a project with the following structure:
.
└── src/
├── main.py
├── PackageA/
│ ├── __init__.py
│ ├── logic.py
│ ├── SubPackageA1/
│ │ ├── __init__.py
│ │ └── util.py
│ └── SubPackageA2/
│ ├── __init__.py
│ └── otherUtil.py
└── PackageB/
├── __init__.py
└── helpers.py
Project structure
It would be possible to import in the file helpers.py the package otherutil.py?
All the combinations I tried until now fail.
If your program is executed from main.py the import in helpers.py should work like this:
from PackageA.SubPackageA2 import otherUtil
Yes, I checked it, main.py:
from PackageB import helpers
print(helpers.HELPERS_UTIL)
otherUtil.py:
OTHER_UTIL = 'test'
helpers.py
from PackageA.SubPackageA2 import otherUtil
HELPERS_UTIL = otherUtil.OTHER_UTIL

Python project structure many main.py endpoints

I currently have the following project structure in python:
| project
├── module_1
│ ├── __init__.py
│ ├── class_1.py
├── module_2
│ ├── __init__.py
│ ├── class_2.py
├── main_1.py
├── main_2.py
├── ..
├── main_n.py
├── set_up.py
Because of the vast amount of main files we use to run our scripts, I would like to organise these in different modules within the project (different module based on different usage of the endpoint). I have tried something like below:
| project
├── module_1
│ ├── __init__.py
│ ├── class_1.py
├── module_2
│ ├── __init__.py
│ ├── class_2.py
├── endpoints_1
│ ├── __init__.py
│ ├── main_1.py
│ ├── set_up.py
├── endpoints_2
│ ├── __init__.py
│ ├── main_2.py
│ ├── set_up.py
The problem that arises however is that I would have to make a different 'set_up.py' file for each of the endpoint modules. In this set_up file I would add the project path to the sys.paths so that all imports work as expected.
So to conclude I have the following two questions:
Is there any way I can have this project structure without having to mess to much with the sys paths and having a custom 'set_up.py' for each module which contains endpoints?
Should I, to begin with, even use this kind of project structure or should I just keep the original structure and not bundle the endpoints in a module ?

Sphinx: unable to import internal modules

My project (written in python 2.7) has a complex structure and most modules are interlinked. There is no direct entry or link to this project to execute. It works as toolbox for other project.
When I tried to use sphinx to create the documentation it is giving error related to "unable to import module.
sample structure:
<workspace>
└── toolbox (main folder)
├── __init__.py
│
├── sub
│ ├── __init__.py
│ ├── sub1.py
│ └── sub2.py
│
├── subpackageA
│ ├── __init__.py
│ ├── submoduleA1.py
│ └── submoduleA2.py
│
└── subpackageB
├── __init__.py
├── submoduleB1.py
└── submoduleB2.py code[from sub import sub1
from subpackageA import submoduleA2 and so on]
Is there a way to configure the index.rst or the config.rst to ignore the import module error and give a output document directory like below:
└── toolbox
│
├── sub
│ ├── index
│ ├── sub1.m
│ └── sub2.m
│
├── subpackageA
│ ├── index
│ ├── submoduleA1.m
│ └── submoduleA2.m
│
└── subpackageB
├── index
├── submoduleB1.m
└── submoduleB2.m
I tried adding system path in config.rst
import os
import sys
sys.path.insert(0, os.path.abspath('../'))
tried ('../..') or ('..')
even hardcoded the project path.
even tried to use the sphinx.ext.autodoc but getting the same import error.
commands used:
sphinx-apidoc -o doc project/toolbox
make html

Fix pylance import error by shifting working directory one level up to cover the imported code

I have this structure for my project:
├── Dockerfile
├── app
│ ├── __init__.py
│ ├── __pycache__
│ ├── config
│ ├── database
│ ├── logging.py
│ ├── main.py
│ ├── routers
│ ├── services
│ ├── static
│ ├── templates
│ ├── utils
│ └── worker
├── k6.js
├── poetry.lock
├── prestart.sh
├── pyproject.toml
├── pytest.ini
└── run.py
Inside app, I have this worker folder that I also open as a kind of separate project.
├── __init__.py
├── database
│ ├── __init__.py
│ └── conn.py
├── engine
│ ├── __init__.py
│ ├── core
│ ├── data
│ ├── main.py
│ └── utils
├── main.py
├── poetry.lock
├── pyproject.toml
└── run.sh
The issue that I have when I open worker project which uses code from upper directory, pylance gives me an error of an import that could not be resolved. However, this code runs fine and perfect.
I created .vscode/settings.json for the worker project and add these options:
"python.analysis.extraPaths": ["../../app"],
"python.autoComplete.extraPaths": ["../../app"]
But I am still getting these errors! How can I fix this?
These paths fixed my issue:
"python.analysis.extraPaths": ["${workspaceFolder}\\..\\.."],
"python.autoComplete.extraPaths": ["${workspaceFolder}\\..\\.."]

Run Django tests with nosetests

My python apps testing is performed on the remote server with command nosetests. I cannot modify the way tests are started nor can I add options to it. I have Django app with tests, but tests are not working properly.
My project structure:
project
├── README.md
├── setup.py
├── mysite
│   ├── blog
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── tests.py
| | ├── ...
│   ├── db.sqlite3
│   ├── manage.py
│   ├── mysite
│   │   ├── __init__.py
│   │   ├── settings.py
| | ├── ...
Command nosetests is executed in project directory. I want it to properly run tests.py which has 2 Django testcases. I tried creating tests directory in project root and invoke tests with DiscoverRunner):
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
test_dir = os.path.dirname(os.path.dirname(__file__)) # one level up
sys.path.insert(0, os.path.join(test_dir, 'mysite'))
class ServerTest(unittest.TestCase):
def test_runtests(self):
django.setup()
self.test_runner = DiscoverRunner(verbosity=1, interactive=True, failfast=False)
failures = self.test_runner.run_tests(['mysite'])
self.assertEqual(failures, 0)
It works but the problem is all the tests are considered as a single test and wrong reports are produced by the server.
Another solution: if I add empty __init__.py to project/mysite nose discovers tests.py but the tests fail because 'Apps are not loaded yet' which probably means I have to invoke django.setup() earlier but I don't know how to do it. I found a plugin for the nose which does it but I cannot install plugins or alter options on the remote machine.
Any ideas how to make any of my approaches solve the problem?
Firsts things first, you should install and configure django-nose if you haven't done so already:
pip install django-nose
Then add it on your INSTALLED_APPS:
INSTALLED_APPS = (
...
'django_nose'
)
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
Now for the nosetests command to run correctly, you can create a folder named tests with the following structure:
project
├── mysite
│ ├── blog
│ │ ├── __init__.py
│ │ ├── models.py
| | ├── ...
│ ├── mysite
│ │ ├── __init__.py
│ │ ├── settings.py
| | ├── ...
│ ├── tests
│ │ ├── __init__.py
│ │ ├── test_a_whole_class_of_methods.py
│ │ ├── test_a_whole_view.py
│ │ ├── test_one_of_my_methods.py
│ │ ├── test_another_one_of_my_methods.py
| | ├── ...
│ ├── db.sqlite3
│ ├── manage.py
├── README.md
├── setup.py
DON'T FORGET THE __init__.py FILE INSIDE THE tests FOLDER!!!
Now when you run nosetests from the root of your project, it will run every test in the tests folder:
~ $ cd path/to/project
path/to/project $ nosetests
Since you can add files to the root of your project, you could try adding a setup.cfg file there that nose will look for when executing, and in it specify where to look for tests:
# setup.cfg
[nosetests]
where=mysite/blog/
(See the documentation for what parameters you can put here).
I'm not sure that this will work (it is possible that the command that starts nose has already specified a different configuration file to use), but it seems worth a shot.

Categories