tox拒绝在py38中使用deps设置以及各种pip问题

tox refuses to use deps setting in py38 and various pip problems

我有一个 Django 项目,我正在尝试使用 tox in 设置单元测试。
这是目录结构:

+ djangoProject
|
+-.github
+-.pytest
+-.tox
+- api
+- blog
+- djangoProject
+- templates
|
+ .gitignore
+ manage.py
+ pyproject.toml
+ requirements.txt
+ requirements_dev.txt
+ setup.cfg
+ tox.ini

这是各种配置文件
tox.ini:

[tox]
minversion = 3.8.0
envlist = py38, py39, py310, flake8
isolated_build = true

[testenv]
setenv =
    PYTHONPATH = {toxinidir}
deps =
    -r{toxinidir}/requirements_dev.txt
commands =
    pytest --basetemp={envtmpdir}

[testenv:flake8]
basepython = python3.8
deps = flake8
commands = flake8

pyproject.toml:

[build-system]
requires = ["setuptools>=42.0", "wheel"]
build-backend = "setuptools.build_meta"

[tool.pytest.ini_options]
testpaths = [
    "api",
    "blog",
    "djangoProject"
]
DJANGO_SETTINGS_MODULE = "djangoProject.settings"
python_files = "tests.py test_*.py *_tests.py"

setup.cfg:

[options]
packages =
    api
    blog
    djangoProject
    templates

[flake8]
max-line-length = 210
exclude =
    .git,
    .github,
    .pytest_cache,
    __pycache__,
    docs/source/conf.py,
    old,
    build,
    dist,
    venv,
    migrations

requirements_dev.txt:

Django~=4.0.3
djangorestframework~=3.13.1
django-gravatar2~=1.4.4
psycopg2~=2.9.3
beautifulsoup4~=4.10.0
pytest-django~=4.5.2
tox~=3.24.5
flake8~=4.0.1

我正在 Pycharm 和 Linux Mint 20.3(在 HyperV VM 中)开发

这是我尝试 运行 tox 时的输出:

(venv) dafrandle@linux-mint-VM:\~/PycharmProjects/djangoProject$ tox
py38 inst-nodeps: /home/dafrandle/PycharmProjects/djangoProject/.tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz
ERROR: invocation failed (exit code 1), logfile: /home/dafrandle/PycharmProjects/djangoProject/.tox/py38/log/py38-10.log
=============================================================================================================== log start ===============================================================================================================
Processing ./.tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz
Installing build dependencies: started
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'error'
error: subprocess-exited-with-error
 
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─\> \[6 lines of output\]
No parent package detected, impossible to derive `name`
running egg_info
writing UNKNOWN.egg-info/PKG-INFO
writing dependency_links to UNKNOWN.egg-info/dependency_links.txt
writing top-level names to UNKNOWN.egg-info/top_level.txt
error: package directory 'templates' does not exist
\[end of output\]
 
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
 
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─\> See above for output.
 
note: This error originates from a subprocess, and is likely not a problem with pip.
 
================================================================================================================ log end ================================================================================================================
py39 create: /home/dafrandle/PycharmProjects/djangoProject/.tox/py39
py39 installdeps: -r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt
ERROR: invocation failed (exit code 1), logfile: /home/dafrandle/PycharmProjects/djangoProject/.tox/py39/log/py39-1.log
=============================================================================================================== log start ===============================================================================================================
Collecting Django\~=4.0.3
Using cached Django-4.0.3-py3-none-any.whl (8.0 MB)
Collecting djangorestframework\~=3.13.1
Using cached djangorestframework-3.13.1-py3-none-any.whl (958 kB)
Collecting django-gravatar2\~=1.4.4
Using cached django_gravatar2-1.4.4-py2.py3-none-any.whl (7.9 kB)
Collecting psycopg2\~=2.9.3
Using cached psycopg2-2.9.3.tar.gz (380 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting beautifulsoup4\~=4.10.0
Using cached beautifulsoup4-4.10.0-py3-none-any.whl (97 kB)
Collecting pytest-django\~=4.5.2
Using cached pytest_django-4.5.2-py3-none-any.whl (20 kB)
Collecting tox\~=3.24.5
Using cached tox-3.24.5-py2.py3-none-any.whl (85 kB)
Collecting flake8\~=4.0.1
Using cached flake8-4.0.1-py2.py3-none-any.whl (64 kB)
Collecting asgiref\<4,\>=3.4.1
Using cached asgiref-3.5.0-py3-none-any.whl (22 kB)
Collecting sqlparse\>=0.2.2
Using cached sqlparse-0.4.2-py3-none-any.whl (42 kB)
Collecting pytz
Using cached pytz-2022.1-py2.py3-none-any.whl (503 kB)
Collecting soupsieve\>1.2
Using cached soupsieve-2.3.1-py3-none-any.whl (37 kB)
Collecting pytest\>=5.4.0
Using cached pytest-7.1.1-py3-none-any.whl (297 kB)
Collecting virtualenv!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,\>=16.0.0
Using cached virtualenv-20.14.0-py2.py3-none-any.whl (8.8 MB)
Collecting six\>=1.14.0
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting toml\>=0.9.4
Using cached toml-0.10.2-py2.py3-none-any.whl (16 kB)
Collecting packaging\>=14
Using cached packaging-21.3-py3-none-any.whl (40 kB)
Collecting py\>=1.4.17
Using cached py-1.11.0-py2.py3-none-any.whl (98 kB)
Collecting filelock\>=3.0.0
Using cached filelock-3.6.0-py3-none-any.whl (10.0 kB)
Collecting pluggy\>=0.12.0
Using cached pluggy-1.0.0-py2.py3-none-any.whl (13 kB)
Collecting pycodestyle\<2.9.0,\>=2.8.0
Using cached pycodestyle-2.8.0-py2.py3-none-any.whl (42 kB)
Collecting mccabe\<0.7.0,\>=0.6.0
Using cached mccabe-0.6.1-py2.py3-none-any.whl (8.6 kB)
Collecting pyflakes\<2.5.0,\>=2.4.0
Using cached pyflakes-2.4.0-py2.py3-none-any.whl (69 kB)
Collecting pyparsing!=3.0.5,\>=2.0.2
Using cached pyparsing-3.0.7-py3-none-any.whl (98 kB)
Collecting tomli\>=1.0.0
Using cached tomli-2.0.1-py3-none-any.whl (12 kB)
Collecting iniconfig
Using cached iniconfig-1.1.1-py2.py3-none-any.whl (5.0 kB)
Collecting attrs\>=19.2.0
Using cached attrs-21.4.0-py2.py3-none-any.whl (60 kB)
Collecting distlib\<1,\>=0.3.1
Using cached distlib-0.3.4-py2.py3-none-any.whl (461 kB)
Collecting platformdirs\<3,\>=2
Using cached platformdirs-2.5.1-py3-none-any.whl (14 kB)
Building wheels for collected packages: psycopg2
Building wheel for psycopg2 (setup.py): started
Building wheel for psycopg2 (setup.py): finished with status 'error'
error: subprocess-exited-with-error
 
× python setup.py bdist_wheel did not run successfully.
│ exit code: 1
╰─\> \[38 lines of output\]
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.9
creating build/lib.linux-x86_64-3.9/psycopg2
copying lib/\_json.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/\_range.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/errors.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/\_ipaddress.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/extras.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/pool.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/__init__.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/errorcodes.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/tz.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/extensions.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/sql.py -\> build/lib.linux-x86_64-3.9/psycopg2
running build_ext
building 'psycopg2.\_psycopg' extension
creating build/temp.linux-x86_64-3.9
creating build/temp.linux-x86_64-3.9/psycopg
x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC "-DPSYCOPG_VERSION=2.9.3 (dt dec pq3 ext lo64)" -DPSYCOPG_DEBUG=1 -DPG_VERSION_NUM=120009 -DHAVE_LO64=1 -DPSYCOPG_DEBUG=1 -I/home/dafrandle/PycharmProjects/djangoProject/.tox/py39/include -I/usr/include/python3.9 -I. -I/usr/include/postgresql -I/usr/include/postgresql/12/server -I/usr/include/libxml2 -I/usr/include/mit-krb5 -c psycopg/adapter_asis.c -o build/temp.linux-x86_64-3.9/psycopg/adapter_asis.o -Wdeclaration-after-statement
In file included from psycopg/adapter_asis.c:28:
./psycopg/psycopg.h:35:10: fatal error: Python.h: No such file or directory
35 | #include \<Python.h\>
|          ^\~\~\~\~\~\~\~\~\~
compilation terminated.
 
      It appears you are missing some prerequisite to build the package from source.
      
      You may install a binary package by installing 'psycopg2-binary' from PyPI.
      If you want to install psycopg2 from source, please install the packages
      required for the build and try again.
      
      For further information please check the 'doc/src/install.rst' file (also at
      <https://www.psycopg.org/docs/install.html>).
      
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
      [end of output]
 
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for psycopg2
Running setup.py clean for psycopg2
Failed to build psycopg2
Installing collected packages: pytz, mccabe, iniconfig, django-gravatar2, distlib, tomli, toml, sqlparse, soupsieve, six, pyparsing, pyflakes, pycodestyle, py, psycopg2, pluggy, platformdirs, filelock, attrs, asgiref, virtualenv, packaging, flake8, Django, beautifulsoup4, tox, pytest, djangorestframework, pytest-django
Running setup.py install for psycopg2: started
Running setup.py install for psycopg2: finished with status 'error'
error: subprocess-exited-with-error
 
× Running setup.py install for psycopg2 did not run successfully.
│ exit code: 1
╰─\> \[40 lines of output\]
running install
/home/dafrandle/PycharmProjects/djangoProject/.tox/py39/lib/python3.9/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_py
creating build
creating build/lib.linux-x86_64-3.9
creating build/lib.linux-x86_64-3.9/psycopg2
copying lib/\_json.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/\_range.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/errors.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/\_ipaddress.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/extras.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/pool.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/__init__.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/errorcodes.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/tz.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/extensions.py -\> build/lib.linux-x86_64-3.9/psycopg2
copying lib/sql.py -\> build/lib.linux-x86_64-3.9/psycopg2
running build_ext
building 'psycopg2.\_psycopg' extension
creating build/temp.linux-x86_64-3.9
creating build/temp.linux-x86_64-3.9/psycopg
x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC "-DPSYCOPG_VERSION=2.9.3 (dt dec pq3 ext lo64)" -DPSYCOPG_DEBUG=1 -DPG_VERSION_NUM=120009 -DHAVE_LO64=1 -DPSYCOPG_DEBUG=1 -I/home/dafrandle/PycharmProjects/djangoProject/.tox/py39/include -I/usr/include/python3.9 -I. -I/usr/include/postgresql -I/usr/include/postgresql/12/server -I/usr/include/libxml2 -I/usr/include/mit-krb5 -c psycopg/adapter_asis.c -o build/temp.linux-x86_64-3.9/psycopg/adapter_asis.o -Wdeclaration-after-statement
In file included from psycopg/adapter_asis.c:28:
./psycopg/psycopg.h:35:10: fatal error: Python.h: No such file or directory
35 | #include \<Python.h\>
|          ^\~\~\~\~\~\~\~\~\~
compilation terminated.
 
      It appears you are missing some prerequisite to build the package from source.
      
      You may install a binary package by installing 'psycopg2-binary' from PyPI.
      If you want to install psycopg2 from source, please install the packages
      required for the build and try again.
      
      For further information please check the 'doc/src/install.rst' file (also at
      <https://www.psycopg.org/docs/install.html>).
      
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
      [end of output]
 
note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure
 
× Encountered error while trying to install package.
╰─\> psycopg2
 
note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.
 
================================================================================================================ log end ================================================================================================================
ERROR: could not install deps \[-r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt\]; v = InvocationError('/home/dafrandle/PycharmProjects/djangoProject/.tox/py39/bin/python -m pip install -r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt', 1)
py310 create: /home/dafrandle/PycharmProjects/djangoProject/.tox/py310
py310 installdeps: -r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt
ERROR: invocation failed (exit code 1), logfile: /home/dafrandle/PycharmProjects/djangoProject/.tox/py310/log/py310-1.log
=============================================================================================================== log start ===============================================================================================================
Traceback (most recent call last):
File "/usr/lib/python3.10/runpy.py", line 196, in \_run_module_as_main
return \_run_code(code, main_globals, None,
File "/usr/lib/python3.10/runpy.py", line 86, in \_run_code
exec(code, run_globals)
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/__main__.py", line 29, in \<module\>
from pip.\_internal.cli.main import main as \_main
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/cli/main.py", line 9, in \<module\>
from pip.\_internal.cli.autocompletion import autocomplete
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/cli/autocompletion.py", line 10, in \<module\>
from pip.\_internal.cli.main_parser import create_main_parser
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/cli/main_parser.py", line 8, in \<module\>
from pip.\_internal.cli import cmdoptions
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/cli/cmdoptions.py", line 23, in \<module\>
from pip.\_internal.cli.parser import ConfigOptionParser
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/cli/parser.py", line 12, in \<module\>
from pip.\_internal.configuration import Configuration, ConfigurationError
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/configuration.py", line 26, in \<module\>
from pip.\_internal.utils.logging import getLogger
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/utils/logging.py", line 27, in \<module\>
from pip.\_internal.utils.misc import ensure_dir
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/utils/misc.py", line 39, in \<module\>
from pip.\_internal.locations import get_major_minor_version
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/locations/__init__.py", line 14, in \<module\>
from . import \_distutils, \_sysconfig
File "/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/lib/python3.10/site-packages/pip/\_internal/locations/\_distutils.py", line 9, in \<module\>
from distutils.cmd import Command as DistutilsCommand
ModuleNotFoundError: No module named 'distutils.cmd'
 
================================================================================================================ log end ================================================================================================================
ERROR: could not install deps \[-r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt\]; v = InvocationError('/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/bin/python -m pip install -r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt', 1)
flake8 inst-nodeps: /home/dafrandle/PycharmProjects/djangoProject/.tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz
ERROR: invocation failed (exit code 1), logfile: /home/dafrandle/PycharmProjects/djangoProject/.tox/flake8/log/flake8-7.log
=============================================================================================================== log start ===============================================================================================================
Processing ./.tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz
Installing build dependencies: started
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'error'
error: subprocess-exited-with-error
 
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─\> \[6 lines of output\]
No parent package detected, impossible to derive `name`
running egg_info
writing UNKNOWN.egg-info/PKG-INFO
writing dependency_links to UNKNOWN.egg-info/dependency_links.txt
writing top-level names to UNKNOWN.egg-info/top_level.txt
error: package directory 'templates' does not exist
\[end of output\]
 
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
 
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─\> See above for output.
 
note: This error originates from a subprocess, and is likely not a problem with pip.
 
================================================================================================================ log end ================================================================================================================
\___\_ summary \___\_
ERROR:   py38: InvocationError for command /home/dafrandle/PycharmProjects/djangoProject/.tox/py38/bin/python -m pip install --no-deps -U .tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz (exited with code 1)
ERROR:   py39: could not install deps \[-r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt\]; v = InvocationError('/home/dafrandle/PycharmProjects/djangoProject/.tox/py39/bin/python -m pip install -r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt', 1)
ERROR:   py310: could not install deps \[-r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt\]; v = InvocationError('/home/dafrandle/PycharmProjects/djangoProject/.tox/py310/bin/python -m pip install -r/home/dafrandle/PycharmProjects/djangoProject/requirements_dev.txt', 1)
ERROR:   flake8: InvocationError for command /home/dafrandle/PycharmProjects/djangoProject/.tox/flake8/bin/python -m pip install --no-deps -U .tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz (exited with code 1)

他们这里有多个问题

1: 两个 py38 envs 都不使用我的要求,而是 运行 pip with --no-deps 并追踪一些不存在的文件
2:在 py38 envs 中,轮子无法构建 - 这可能是因为 #1 但我不确定。
3:在所有其他环境中,psycopg2 的轮子无法构建,也无法使用 setup.py

安装

我已经尝试从 tox.ini 中删除行以获得不同的输出以尝试定位问题(如果它在 ini 文件中但什么也没找到)。

当我手动使用 pip 或使用 PyCharm 的包管理器 inclduing psycopg2 将东西添加到我的项目时,一切正常所以我不知道为什么不会在 tox

中工作

我不知道我做错了什么

我正在处理这个教程视频: https://www.youtube.com/watch?v=DhUpxWjOhME

它不是针对 Django 项目的,而是在 tox 部分之前的所有内容我都能得到 运行ning fine

问题在错误日志中有详细描述:

building 'psycopg2.\_psycopg' extension
creating build/temp.linux-x86_64-3.9
creating build/temp.linux-x86_64-3.9/psycopg
x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC "-DPSYCOPG_VERSION=2.9.3 (dt dec pq3 ext lo64)" -DPSYCOPG_DEBUG=1 -DPG_VERSION_NUM=120009 -DHAVE_LO64=1 -DPSYCOPG_DEBUG=1 -I/home/dafrandle/PycharmProjects/djangoProject/.tox/py39/include -I/usr/include/python3.9 -I. -I/usr/include/postgresql -I/usr/include/postgresql/12/server -I/usr/include/libxml2 -I/usr/include/mit-krb5 -c psycopg/adapter_asis.c -o build/temp.linux-x86_64-3.9/psycopg/adapter_asis.o -Wdeclaration-after-statement
In file included from psycopg/adapter_asis.c:28:
./psycopg/psycopg.h:35:10: fatal error: Python.h: No such file or directory
35 | #include \<Python.h\>
|          ^\~\~\~\~\~\~\~\~\~
compilation terminated.
 
      It appears you are missing some prerequisite to build the package from source.
      
      You may install a binary package by installing 'psycopg2-binary' from PyPI.
      If you want to install psycopg2 from source, please install the packages
      required for the build and try again.
      
      For further information please check the 'doc/src/install.rst' file (also at
      <https://www.psycopg.org/docs/install.html>).
      
      error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
      [end of output]
 
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for psycopg2
Running setup.py clean for psycopg2
Failed to build psycopg2
Installing collected packages: pytz, mccabe, iniconfig, django-gravatar2, distlib, tomli, toml, sqlparse, soupsieve, six, pyparsing, pyflakes, pycodestyle, py, psycopg2, pluggy, platformdirs, filelock, attrs, asgiref, virtualenv, packaging, flake8, Django, beautifulsoup4, tox, pytest, djangorestframework, pytest-django
Running setup.py install for psycopg2: started
Running setup.py install for psycopg2: finished with status 'error'
error: subprocess-exited-with-error
 
× Running setup.py install for psycopg2 did not run successfully.
│ exit code: 1
╰─\> \[40 lines of output\]

所以你未能构建 psycopg2 包,因为...

In file included from psycopg/adapter_asis.c:28:
./psycopg/psycopg.h:35:10: fatal error: Python.h: No such file or directory
35 | #include \<Python.h\>

...pip 尝试安装源包,为此需要一些编译步骤,缺少提到的头文件。

当我尝试重现问题时...

pip install psycopg2
Collecting psycopg2
  Downloading psycopg2-2.9.3.tar.gz (380 kB)
...

你清楚地看到,psycopg2 是作为源而不是 wheel 下载的。

所以这不是 tox 问题,而是该项目没有提供 pre-compiled 轮子,并且您的环境缺少必要的要求。

还有一个问题是为什么这会在您的 PyCharm 环境中起作用。这不是我可以肯定地说的,但一个可能的问题可能是您的 PyCharm 在与 tox 不同的环境中是 运行 - 正如您提到的您在 VM 环境中工作。所以这是你需要自己弄清楚的事情。

此回答是 Jürgen 回答的补充:

原因

py38 inst-nodeps: /home/dafrandle/PycharmProjects/djangoProject/.tox/.tmp/package/1/UNKNOWN-0.0.0.tar.gz

发生这种情况是因为 setuptools 将我的 Django 应用程序(api、博客)视为包

我不知道它到底做了什么 - 如果它把它们传递给 pip,或者添加其他东西,但它们没有设置为包,所以它最终会执行上述操作。

我找到了另一个问题的答案:

描述了我的项目的情况并应用了设置
skipsdist = True 在我的 tox.ini 中解决了我的问题