<#19625 Failure to run pytests against a distribut...
# github-notifications
c
#19625 Failure to run pytests against a distribution with a native extension and a third party dependency Issue created by gauthamnair Describe the bug Using pants to create a
python_distribution
containing a native extension (and therefore using manual setup.py). The distribution also depends on a third party package. Packaging works fine. When trying to run tests set up to consume the distribution, pants fails with an error about Failure to resolve the third party dependency requirements from the PEX Environment when
'Building pytest_runner.pex'
. Detailed reproduction steps and preliminary investigation below. Ran into this issue while trying to port the simple example distribution from https://www.manning.com/books/publishing-python-packages into pants. Pants version 2.16.0 OS MacOS Ventura 13.0 Additional info Reproduction A repo to reproduce the situation is here: https://github.com/gauthamnair/pants-example-local-dist/tree/main Run
pants package ::
and it will work fine, producing a wheel that can be installed in a clean virtualenv elsewhere and it pulls in the extra dep automatically. But
pants test ::
fails with:
Copy code
$ pants --no-local-cache test ::
15:35:20.56 [INFO] Initialization options changed: reinitializing scheduler...
15:35:24.66 [INFO] Scheduler initialized.
15:35:26.45 [INFO] Canceled: Building pytest.pex from <resource://pants.backend.python.subsystems/pytest.lock>
15:35:27.05 [INFO] Completed: Building 1 requirement for requirements.pex from the main_resolve.lock resolve: tabulate
15:35:27.28 [INFO] Completed: Building pytest.pex from <resource://pants.backend.python.subsystems/pytest.lock>
15:35:28.45 [INFO] Completed: Building 3 requirements for build_backend.pex from the setuptools.lock resolve: cython, setuptools, wheel
15:35:30.14 [INFO] Completed: List contents of artifacts produced by //:foodist
15:35:32.04 [INFO] Completed: Building local_dists.pex with 1 requirement: foo-0.0.1-cp39-cp39-macosx_10_9_universal2.whl
15:35:32.66 [INFO] Completed: Building pytest_runner.pex
15:35:32.66 [ERROR] 1 Exception encountered:

Engine traceback:
  in `test` goal

ProcessExecutionFailure: Process 'Building pytest_runner.pex' failed with exit code 1.
stdout:

stderr:
Failed to resolve requirements from PEX environment @ /Users/gauthamnair/.cache/pants/named_caches/pex_root/unzipped_pexes/4e96679a2dc078756a2200d65211ed056ad32e7e.
Needed cp39-cp39-macosx_13_0_arm64 compatible dependencies for:
 1: tabulate
    Required by:
      foo 0.0.1
    But this pex had no ProjectName(raw='tabulate', normalized='tabulate') distributions.
Description of setup
Copy code
.
├── BUILD    # defines the python_distribution, generate_setup = False
├── LICENSE
├── README.md
├── dist   # these generated packages install fine
│   ├── foo-0.0.1-cp39-cp39-macosx_10_9_universal2.whl
│   └── foo-0.0.1.tar.gz
├── main_resolve.lock   # contains the third party dep
├── pants.toml
├── requirements.txt    # contains the third-party dep
├── setup.py    # contains the third-party dep in the install_requires
├── setuptools-requirements.txt    # custom setuptools lockfile to include Cython in the setuptools ExternalTool
├── setuptools.lock
├── src
│   └── foo
│       ├── BUILD
│       ├── __init__.py
│       ├── bar.pyx   # trivial cython module
│       └── main.py    # consumes bar and the thirdparty dep
└── test
    ├── BUILD  # instructs the tests here to depend on the python_distribution
    ├── test_foo.py
    └── test_main.py
This project defines a distribution package "foo". foo contains a native extension (built with Cython). foo also depends on a third party library (
tabulate
). The tests depend on the distribution as a matter of necessity, but also to simulate the behavior seen by a user who installs the package. It uses the capability introduced in #12573 to depend on a distribution via the
local_dists
mechanism. Preliminary debugging Failure happens when building the pytest_runner pex. The sandbox looks like this at the moment of failure:
Copy code
/private/var/folders/z4/dvm2try15dg7gl1vcc_6pv140000gn/T/pants-sandbox-Xlkblq
├── .cache
│   └── pex_root -> /Users/gauthamnair/.cache/pants/named_caches/pex_root
├── .python-build-standalone -> /private/var/folders/z4/dvm2try15dg7gl1vcc_6pv140000gn/T/immutable_inputsMuvD08/.tmpRwZekH/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
├── .tmp
├── __run.sh
├── local_dists.pex
│   ├── .bootstrap
│   ├── .deps
│   │   └── foo-0.0.1-cp39-cp39-macosx_10_9_universal2.whl
│   ├── PEX-INFO
│   ├── __main__.py
│   └── __pex__
│       └── __init__.py
├── pex
├── pytest.pex
│   ├── .bootstrap
│   ├── .deps
│   │   ├── attrs-22.2.0-py3-none-any.whl
...
│   │   ├── pytest_xdist-2.5.0-py3-none-any.whl
│   │   └── tomli-2.0.1-py3-none-any.whl
│   ├── PEX-INFO
│   ├── __main__.py
│   └── __pex__
│       └── __init__.py
├── requirements.pex
│   ├── .bootstrap
│   ├── .deps
│   │   └── tabulate-0.9.0-py3-none-any.whl
│   ├── PEX-INFO
│   ├── __main__.py
│   └── __pex__
│       └── __init__.py
└── source_files
foo is in the
local_dists.pex
, alone, and the third party dep
tabulate
is in the
requirements.pex
. modifying the
__run.sh
to have
PEX_VERBOSE=1
and running in the sandbox
Copy code
...
pex: Failed to resolve a requirement: tabulate                            
pex: Unresolved requirements:
pex:   - tabulate
pex: Distributions contained within this pex:
pex:   - foo-0.0.1-cp39-cp39-macosx_10_9_universal2.whl
Traceback (most recent call last):
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/result.py", line 105, in catch
    return func(*args, **kwargs)
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/bin/pex.py", line 856, in do_main
    pex_builder = build_pex(
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/bin/pex.py", line 767, in build_pex
    pex_builder.set_script(options.script)
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/pex_builder.py", line 360, in set_script
    distributions.update(PEX(pex, interpreter=self._interpreter).resolve())
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/orderedset.py", line 45, in update
    for key in iterable:
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/pex.py", line 215, in resolve
    for dist in env.resolve():
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/environment.py", line 502, in resolve
    for fingerprinted_distribution in self.resolve_dists(all_reqs)
  File "/<some_long_path>/pex-2.1.134-py2.py3-none-any.whl/pex/environment.py", line 589, in resolve_dists
    raise ResolveError(
pex.environment.ResolveError: Failed to resolve requirements from PEX environment @ /Users/gauthamnair/.cache/pants/named_caches/pex_root/unzipped_pexes/b87e8afec3011a2eb8ceb0ef15f6c0abc9097f6c.
Needed cp39-cp39-macosx_13_0_arm64 compatible dependencies for:
 1: tabulate
    Required by:
      foo 0.0.1
    But this pex had no ProjectName(raw='tabulate', normalized='tabulate') distributions.
It appears the builder is trying to "resolve" the local_dists pex while trying to determine what the script should be for the pytest runner pex. The resolve is expecting that the third-party dep is within the local_dists pex, but it isn't - its in the requirements.pex only. pantsbuild/pants