Do Pants plugin tests assume a specific python ver...
# plugins
w
Do Pants plugin tests assume a specific python version on run? I just got hit with
Copy code
E           Engine traceback:
E             in select
E             in experimental.pyoxidizer.rules.package_pyoxidizer_binary (src:test-bin)
E             in pants.backend.python.util_rules.pex.create_pex (pyoxidizer.pex)
E             in pants.backend.python.util_rules.pex.build_pex (pyoxidizer.pex)
E             in pants.backend.python.util_rules.pex.find_interpreter (CPython>=3.8)
E             in pants.engine.process.fallible_to_exec_result_or_raise
E             in pants.backend.python.util_rules.pex_cli.setup_pex_cli_process
E             in pants.backend.python.util_rules.pex_environment.find_pex_python
E             in pants.python._binaries_rules.find_python
E           Traceback (most recent call last):
E             File "/Users/sj/.cache/pants/named_caches/pex_root/venvs/de04010553f1713b72512ad07d1b20b66bf8f840/f5cef8ebdbaf03ed774d467ae52a457e8fe3774a/lib/python3.9/site-packages/pants/engine/internals/selectors.py", line 705, in native_engine_generator_send
E               res = func.send(arg)
E             File "/Users/sj/.cache/pants/named_caches/pex_root/venvs/de04010553f1713b72512ad07d1b20b66bf8f840/f5cef8ebdbaf03ed774d467ae52a457e8fe3774a/lib/python3.9/site-packages/pants/python/_binaries_rules.py", line 82, in find_python
E               raise BinaryNotFoundError(
E           pants.engine.process.BinaryNotFoundError: Was not able to locate a Python interpreter to execute rule code.
E           Please ensure that Python is available in one of the locations identified by `[python-bootstrap] search_path`, which currently expands to:
E             []
As far as I can tell, it's using the Python 3.9 venv,so it should be fine to run the rule
h
Does "it" in that sentence mean the Pants process that is running your tests?
w
"it" in that case is that which caused the error, which is the
./pants test ::
command
h
There are two different interpreters in play: 1) The one Pants itself runs on when you run
./pants test ::
, 2) The one that the pex-creation rule invokes
1) is chosen to be compatible with Pants's code, 2) is chosen to be compatible with your code
Let me take a look at your test code
w
This does beg the question about whether I should be using the ./pants test :: command or not - I'm assuming so, but 🤷
Noteworthy, I haven't added any interpreter_constraints to my test, nor am I running the utility which tests across all of them
h
Yes,
./pants test
is the right way to run your tests, even if they are testing a plugin
👍 1
OK, try calling
rule_runner.set_options([], env_inherit={"PATH"})
in your test before the call to
rule_runner.request
w
THere we go, that did it!
That's interesting, I thought it would have been okay to use the default env it ran in! wild
h
Everything is very hermetic and locked down by default
you can poke holes through, but you have to do it explicitly, like that
w
So, I was structuring my code around what's in the repo - but I guess that has runners setup to avoid all these problems
f
the pants.toml for Pants itself has:
Copy code
[test]
extra_env_vars = [
  # TODO: These are exposed to tests in order to allow for python interpreter discovery when
  # Pants-tests-Pants: in particular, the [python] subsystem consumes them.
  #   see <https://github.com/pantsbuild/pants/issues/11638>
  "PYENV_ROOT",
  "HOME",
  "PATH",
  # We'd always like complete backtraces in tests.
  "RUST_BACKTRACE=1",
]
👍 1
so Pants allows PATH (and the other listed env variables) into tests
w
Ah, okay, that's interesting - I'd never thought of them wrt python tests, as I'd never had issues with tests until writing this first plugin
c
So your previous tests probably didn’t invoke any Python interpreter from the test code, then.. 🙂
w
Seems that way - interestingly, I pulled down the pants repo in prep of doing a pull request for my plugin, and for the sake of it, ran ./pants test :: and a whole ton of those tests failed too. So, I'm not really sure what's going on. Very strange stuff. The experience of writing a plugin has been pretty seamless once I get that baseline knowledge I need, but it turns out that writing tests has ended up being more difficult 😅
c
yeah, tests can be a bit intimidating to get the hang of.. esp rule graph issues 😅
w
The rule graph was surprisingly the simplest - I still haven't gotten a successful "approach 3" or "approach 4" to work for the tests. What I'm doing right now is forking and merging my code, and I'll try running tests in the main pants repo - as I think that's a more reliable approach at the moment
👍 1
h
Hmm
./pants test ::
failed on your laptop? That's not ideal
What kind of failures?
w
Okay, so still not luck passing any RoleRunner or run_pants tests. As a sanity test, why would this give me a ModuleNotFoundError for "pants.backend.experimental.python.packaging.pyoxidizer"?
Copy code
pants_run = run_pants([
    "--backend-packages=['pants.backend.python', 'pants.backend.experimental.python.packaging.pyoxidizer']",
    "help",
    "pyoxidizer_binary"])
pants_run.assert_success()
For this, I'm running
./pants test src/..../pyoxidizer:rules_integration_test
@happy-kitchen-89482 I wiped everything and am re-building rust, will give you more deets shortly
Oh, I remember what they were failing with...
ImportError while importing test module
and then something about symbol not found in flat namespace
_PyObject_VectorCallMethod
I think the issue here was the version of Python - I remember that I forced my BUILD to use interpreter_constraints for >= 3.9 and that error went away when testing my own rules
Oh yeah, even weirder, it's using some python3.8 version sitting inside of XCode that I didn't even know existed - it's ignoring my path's python3 alias, and jumping to this other "thing"
I'm testing using PY=python3 to see if that fixes these. I had no idea there was any python3.8 anywhere on my system, I was sure I evicted that. Don't even know how pants found it
h
Oh yeah, MacOS pythons are broken in all sorts of weird ways
We are planning to switch to shipping Pants as a standalone binary with an embedded interpreter, to avoid this sort of nonsense
w
Yeah, looks like it was never using my Brew installed python in the first place, so that's one problem. I just wiped the .pids and .pants.d and set PY=python3.9, and it's now modifying the Rust build - which is nice. I'll report back if there are any test suite failures still. However, none of this affects my sanity test I don't think - can't seem to find the experimental package registration.
And still no luck with running tests - it still tries to grab my python3.8 installation, even after setting the env variable and re-building Rust
h
Is it running Pants itself on 3.8, or running your tests on 3.8?
What are the interpreter constraints, if any, in your pants.toml?
w
This whole thing is blowing my mind right now. I don't know by which mechanism this Xcode python3 was even discovered - even after I manually sourced the pants_venv file. I pulled pants main branch today, so I should be inline with that, other than my PR. In there, we have
Copy code
[python]
experimental_lockfile = "3rdparty/python/lockfiles/user_reqs.txt"
interpreter_constraints = [">=3.7,<3.10"]
macos_big_sur_compatibility = true
This is for going to the root folder and typing
./pants test ::
I built this project with
PY=python3.9 ./pants test ::
Sample error:
Copy code
___________ ERROR collecting src/python/pants/option/options_test.py ___________
ImportError while importing test module '/private/var/folders/11/60kkmmxx08q79t_pf28zlbm80000gp/T/process-executionqmeXQq/src/python/pants/option/options_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
src/python/pants/option/options_test.py:22: in <module>
    from pants.engine.fs import FileContent
src/python/pants/engine/fs.py:13: in <module>
    from pants.engine.engine_aware import SideEffecting
src/python/pants/engine/engine_aware.py:9: in <module>
    from pants.engine.internals import native_engine
E   ImportError: dlopen(/private/var/folders/11/60kkmmxx08q79t_pf28zlbm80000gp/T/process-executionqmeXQq/src/python/pants/engine/internals/native_engine.so, 0x0002): symbol not found in flat namespace '_PyObject_VectorcallMethod'
- generated xml file: /private/var/folders/11/60kkmmxx08q79t_pf28zlbm80000gp/T/process-executionqmeXQq/src.python.pants.option.options_test.py.tests.xml -
h
So PY= affects the interpreter Pants runs itself on, not the interpreter it selects to run your code on
so it is finding that shoddy interpreter, and it matches the constraints, so it uses it
Probably you want to lock down where Pants looks for interpreters with...
<rushes off to look at docs>
w
Yeah, that's what it looks like when I dig in the logs - the very first thing that it asks for is the "correct" constraints and grabs my 3.9, but then I see it looking for other constraints later. However, I forced the constraints to be >=3.9, and its looking better
I've only seen 2 failures so far, instead of 50 by changing that inside of pants.toml
So
search_path
option in the
[python-bootstrap]
config section
If you set this to
["<PYENV>"]
it will only find pyenv-installed interpreters at runtime
for example
w
According to the docs, it looks in my path, and pyenv. I don't have pyenv installed, and using any Python3.8 command, I can't find that Python on my path.
Changing the constraints in the pants.toml definitely solved that problem for now though, so I can go back to my original problem and see if maybe my experimental tool is registered now in the tests
Okay, figured it out - through some perpetual grepping. There is a file called
/src/python/pants/init/BUILD
and in that file are a list of manually included dependencies. Mine wasn't in that list (as I guess I missed the documentation about adding it here), so when I ran my tests, it couldn't find my register.py... However, when I used pants at the command line, it was using the pants.toml file, which correctly registered it...
👍 1