flake8 fails in tox testing environment - python

Below is the failure message on running tox. I don't see this exact error reported on any forum.
Any guidance here would be of great help.
I'm invoking the tox in 3.8-slim-buster docker container & installed the required dependencies - pip install tox flake8 black pylint
Error:
File ".tox/lint/lib/python3.6/site-packages/hacking/core.py", line 185
except ImportError, exc:
^
SyntaxError: invalid syntax
During handling of the above exception, another exception occurred:
.tox/lint/lib/python3.6/site-packages/flake8/plugins/manager.py", line 168, in load_plugin
raise failed_to_load
flake8.exceptions.FailedToLoadPlugin: Flake8 failed to load plugin "H000" due to invalid syntax (core.py, line 185).
my tox.ini file.
[tox]
minversion = 1.8
envlist =
unit
lint
format-check
skipsdist = true
[testenv]
usedevelop = true
basepython = python3
passenv = *
setenv =
COVERAGE_FILE={toxworkdir}/.coverage
PIP_EXTRA_INDEX_URL=https://maven.com/artifactory/api/pypi/simple/
extras =
test
[testenv:unit]
commands =
python -m pytest {posargs}
[testenv:lint]
commands =
python -m flake8
[testenv:format]
commands =
python -m black {toxinidir}
[testenv:format-check]
commands =
python -m black --diff --check {toxinidir}
[testenv:build-dists-local]
usedevelop = false
skip_install = true
commands =
python -m pep517.build \
--source \
--binary \
--out-dir {toxinidir}/dist/ \
{toxinidir}
[testenv:build-dists]
commands =
rm -rfv {toxinidir}/dist/
{[testenv:build-dists-local]commands}
whitelist_externals =
rm
[testenv:publish-dists]
commands =
bash -c '\
twine upload {toxinidir}/dist/*.whl \
-u $TWINE_USERNAME \
-p $TWINE_PASSWORD \
--repository-url $TWINE_REPOSITORY \
'
whitelist_externals =
bash
[flake8]
max-line-length = 100
format = pylint
exclude =
.eggs/
.tox/,
.venv*,
build/,
dist/,
doc/,
#- [H106] Don't put vim configuration in source files.
#- [H203] Use assertIs(Not)None to check for None.
#- [H904] Delay string interpolations at logging calls.
enable-extensions = H106,H203,H904
ignore = E226,E302,E41
[pytest]
testpaths = test/
addopts = -v -rxXs --doctest-modules --cov metarelease --cov-report term-missing --showlocals
norecursedirs = dist doc build .tox .eggs
[coverage:run]
omit =
metarelease/cmd/*
metarelease/shell.py
[coverage:report]
fail_under =
100

This is neither a flake8 nor a tox bug, but a bug in hacking, which you will notice when you have a close look at the traceback.
The syntax
File ".tox/lint/lib/python3.6/site-packages/hacking/core.py", line 185
except ImportError, exc:
is only valid in Python 2, but you use Python 3.
I never heard of the hacking project before, but using a search engine revealed https://pypi.org/project/hacking/
You should report a bug a their bug tracker.

Related

How in tox run bash script and reuse returned value?

When I create a tox environment, some libraries are installed under different paths depending on the environment that I use to trigger tox:
# Tox triggered inside virtual env
.tox/lib/site-packages
Sometimes
# Tox triggered inside docker
.tox/lib/python3.8/site-packages
I need to reuse such path in further steps inside tox env. I decided to create a bash script to find the path for installed libraries to be able to reuse it and to run it inside tox env. I thought that I can pass found path to tox and reuse it in one of the next commands. Is it possible to do such thing?
I tried:
tox.ini
[tox]
envlist =
docs
min_version = 4
skipsdist = True
allowlist_externals = cd
passenv =
HOMEPATH
PROGRAMDATA
basepython = python3.8
[testenv:docs]
changedir = docs
deps =
-r some_path/library_name/requirements.txt
commands =
my_variable=$(bash ../docs/source/script.sh)
sphinx-apidoc -f -o $my_variable/source $my_variable
But apparently this doesn't work with tox:
docs: commands[0] docs> my_variable=$(bash ../docs/source/script.sh)
docs: exit 2 (0.03 seconds) docs>
my_variable=$(bash../docs/source/script.sh) docs: FAIL code 2
(0.20=setup[0.17]+cmd[0.03] seconds) evaluation failed :( (0.50
seconds)
Bash script
script.sh
#!/bin/bash
tox_env_path="../.tox/docs/"
conf_source="source"
tox_libs=$(find . $tox_env_path -type d -name "<name of library>")
sudo mkdir -p $tox_libs/docs/source
cp $conf_source/conf.py $conf_source/index.rst $tox_libs/docs/source
echo $tox_libs
Not a direct answer to your question, but maybe something like this can help you achieve the actual goal (XY problem):
[testenv:docs]
# ...
allowlist_externals =
bash
commands =
python -c 'print("The path is: {env_site_packages_dir}")'
bash ../docs/source/script.sh
sphinx-apidoc -f -o {env_site_packages_dir}/LibName/source {env_site_packages_dir}/LibName
Indeed, it seems to me like it is unnecessary to compute the path in the bash script and try to read this path in a variable.
1. As far as I know it is not possible to assign values to a variable like you suggest in your question, tox.ini does not allow it.
2. On the other hand, tox.ini allows subsitutions and in particular the {env_site_packages_dir} seems helpful for your use case.

Reuse environment on Tox 4

This is my tox.ini file:
# Tox (https://tox.readthedocs.io/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
#
# See also https://tox.readthedocs.io/en/latest/config.html for more
# configuration options.
[tox]
# Choose your Python versions. They have to be available
# on the system the tests are run on.
# skipsdist=True
ignore_basepython_conflict=false
[testenv:{setup,lint,codestyle,docstyle,tests,doc-linux,doc-darwin,doc-win32}]
basepython=python3.9
envdir = {toxworkdir}/py39
setenv =
PROJECT_NAME = project_name
passenv =
WINDIR
install_command=
pip install \
--find-links=pkg \
--trusted-host=pypi.python.org \
--trusted-host=pypi.org \
--trusted-host=files.pythonhosted.org \
{opts} {packages}
platform = doc-linux: linux
doc-darwin: darwin
doc-win32: win32
deps =
-r{toxinidir}/requirements-dev.txt
-r{toxinidir}/requirements.txt
commands =
setup: python -c "print('All SetUp')"
# Mind the gap, use a backslash :)
lint: pylint -f parseable -r n --disable duplicate-code \
lint: --extension-pkg-whitelist=PyQt5,numpy,torch,cv2,boto3 \
lint: --ignored-modules=PyQt5,numpy,torch,cv2,boto3 \
lint: --ignored-classes=PyQt5,numpy,torch,cv2,boto3 \
lint: project_name \
lint: {toxinidir}/script
lint: pylint -f parseable -r n --disable duplicate-code \
lint: demo/demo_file.py
codestyle: pycodestyle --max-line-length=100 \
codestyle: --exclude=project_name/third_party/* \
codestyle: project_name demo script
docstyle: pydocstyle \
docstyle: --match-dir='^((?!(third_party|deprecated)).)*' \
docstyle: project_name demo script
doc-linux: make -C {toxinidir}/doc html
doc-darwin: make -C {toxinidir}/doc html
doc-win32: {toxinidir}/doc/make.bat html
tests: python -m pytest -v -s --cov-report xml --durations=10 \
tests: --cov=project_name --cov=script \
tests: {toxinidir}/test
tests: coverage report -m --fail-under 100
On tox<4.0 it was very convinient to run tox -e lint to fix linting stuff or tox -e codestyle tox fix codestyle stuff, etc. But now, with version tox>4.0 each time I run one of these commands I get this message (for instance):
codestyle: recreate env because env type changed from {'name': 'lint', 'type': 'VirtualEnvRunner'} to {'name': 'codestyle', 'type': 'VirtualEnvRunner'}
codestyle: remove tox env folder .tox/py39
And it takes forever to run these commands since the evironments are recreated each time ...
I also use these structure for running tests on jenkins so I can map each of these commands to a jenkins stage.
How can I reuse the environment? I have read that it is possible to do it using plugins, but no idea how this can be done, or how to install/use plugins.
I have tried this:
tox multiple tests, re-using tox environment
But it does not work in my case.
I spect to reuse the environment for each of the environments defined in the tox file.
As an addition to N1ngu's excellent answer...
You could re-structure your tox.ini as following:
[tox]
...
[testenv]
<here goes all the common configuration>
[testenv:lint]
<here goes the lint specific configuration>
[testenv:codestyle]
...
And so on. This is a common setup.
While still the environments need to be created at least once, they won't get recreated on each invocation.
This all said, you could also have a look at https://pre-commit.com/ to run your linters, which is very common in the Python community.
Then you would have a tox.ini like the following...
[tox]
...
[testenv]
<here goes all the common configuration>
[testenv:lint]
deps = pre-commit
commands = pre-commit run --all-files
There is now a definite answer about re-use of environments in the faq:
https://tox.wiki/en/latest/upgrading.html#re-use-of-environments
I fear the generative names + factor-specific commands solution you linked relied on tox-3 not auto-recreating the environments by default, which is among the new features in tox 4. Now, environment recreation is something that can be forced (--recreate) but can't be opted-out.
Official answer on this https://github.com/tox-dev/tox/issues/425 boils down to
Officially we don't allow sharing tox environments at the moment [...] As of today, each tox environment has to have it's own virtualenv even if the Python version and dependencies are identical [...] We'll not plan to support this. However, tox 4 allows one to do this via a plugin, so we'd encourage people [...] to try it [...]. Once the project is stable and widely used we can revisit accepting it in core.
So that's it, write a plugin. No idea on how to do that either, so my apologies if this turns out as "not an answer"

How to run one specific test by using tox?

This is the path to the project
D:\QA\test-framework\python-client
This is a test frame work implemented by python
This is the python file that contains tests
This is the path to the test case that I need to run
D:\QA\test-framework\python-client\test_data\tests\curve.json
This is the beginning of the curve.json file.
{
"Sklearn - Sklearn - Regression - Curve M2" : [
{
"dataImport": {
"
"
"
]
}
This is the tox.ini file
[tox]
envlist = py38
[testenv]
deps =
pytest
pytest-html
pytest-sugar
pytest-logger
allure-pytest
pytest-xdist
pytest_steps
datetime
oauth2client
gspread
aiclub
commands =
pytest -s -v -k _workflow --html=test_report.html --alluredir=allure-
results/ -n auto --dist=loadfile
allure serve allure-results
pytest {posargs}
I need to run only this curve.json using tox command

Auto-chose platform (or other) condition in tox sections

I want to specifically run a certain tox section which then auto-decides on the specific platform.
The example code-snippet below works fine if I just ran tox -e ALL. Then the platform condition nicely sects out the correct platform.
However, I want to only adress and run a specific section like for instance something like tox -e other (not tox -e other-win, other-linux) and then have tox auto-chosing the corresponding platform (or any other) condition.
I don't know if this way of setting up conditions in tox is not possible, or if I'm missing something.
[tox]
skipsdist = true
[testenv:systest-{win, linux}]
platform =
linux: linux
win: win|msys
whitelist_externals =
win: cmd
linux: sh
commands =
win: cmd /r echo {env:OS}
linux: sh -c echo {env:OS}
[testenv:other-{win, linux}]
platform =
linux: linux
win: win|msys
whitelist_externals =
win: cmd
linux: sh
commands =
win: cmd /r echo {env:OS}
linux: sh -c echo {env:OS}
You could give the tox-factor plugin a try.
For example:
tox.ini
[tox]
envlist =
alpha-{redmond,tux}
bravo-{redmond,tux}
requires =
tox-factor
skipsdist = true
[testenv]
commands =
python -c 'import sys; print("platform", sys.platform)'
platform =
redmond: win32
tux: linux
This gives the following four environments:
$ tox --listenvs
alpha-redmond
alpha-tux
bravo-redmond
bravo-tux
That can be selected according to the factors:
$ tox --listenvs --factor tux
alpha-tux
bravo-tux
$ tox --listenvs --factor alpha
alpha-redmond
alpha-tux
And then run like this (for example on a Linux platform):
$ tox --factor bravo
bravo-tux run-test-pre: PYTHONHASHSEED='1770792708'
bravo-tux run-test: commands[0] | python -c 'import sys; print("platform", sys.platform)'
platform linux
________________________________________________ summary ________________________________________________
SKIPPED: bravo-redmond: platform mismatch ('linux' does not match 'win32')
bravo-tux: commands succeeded
congratulations :)
References:
https://github.com/tox-dev/tox/issues/1338
https://pypi.org/project/tox-factor/

Qt unable to connect to virtual framebuffer with tox

yml version works (both in CI and locally inputting script commands manually)
staging:
stage: test
image: foobar/python36-qt
script:
- pip install things...
- export PATH=/root/.local/bin:$PATH
- export DISPLAY=":$(( ( RANDOM % 250 ) + 1 ))"
- Xvfb $DISPLAY -screen 0 1920x1080x16 &
- pytest --ignore src/foobar/tests/gui/functional
tox version does not work (I run it locally with python3 -m tox -rc tox.ini -e foobar -v)
[testenv:foobar]
whitelist_externals =
Xvfb
sh
setenv =
PATH={env:PATH}:/root/.local/bin
DISPLAY=":3"
QT_DEBUG_PLUGINS=1
deps =
pytest
install_command = pip install --extra-index-url https://pypi-ext.foobar.com/simple {opts} {packages}
commands =
sh -c 'Xvfb ":3" -screen 0 1920x1080x16 &'
pytest -sv tests --ignore tests/gui/functional
initial error:
foobar run-test: commands[2] | sh -c 'Xvfb ":3" -screen 0 1920x1080x16 &'
[17538] /home/localadmin/Documents/foobar/src/foobar$ /bin/sh -c 'Xvfb ":3" -screen 0 1920x1080x16 &'
foobar run-test: commands[3] | pytest -sv tests --ignore tests/gui/functional
[17540] /home/localadmin/Documents/foobar/src/foobar$ /home/localadmin/Documents/foobar/src/foobar/.tox/foobar/bin/pytest -sv tests --ignore tests/gui/functional
_XSERVTransSocketUNIXCreateListener: ...SocketCreateListener() failed
_XSERVTransMakeAllCOTSServerListeners: server already running
(EE)
Fatal server error:
(EE) Cannot establish any listening sockets - Make sure an X server isn't already running(EE)
resulting error:
qt.qpa.xcb: could not connect to display ":3"
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
The first thing I need to solve is why I constantly get _XSERVTransMakeAllCOTSServerListeners: server already running. Before I select a number X in Display=":X", I check /tmp and /tmp/.X11-unix to make sure no X screen exists, and remove it if it does.
I thought maybe I need to run them in the same command (I figure the [17538] and [17540] are processes (?)). No dice

Categories