```from pants.testutil.rule_runner import RuleRunn...
# general
c
Copy code
from pants.testutil.rule_runner import RuleRunner
Is there any way I can use this? I want to write some tests for my plugins. I'm getting the following error.
Copy code
Import "pants.testutil.rule_runner" could not be resolved
1
b
Pants' testutil is a separate package. Recommend following https://www.pantsbuild.org/docs/plugins-overview#building-in-repo-plugins-with-pants
♥️ 1
(Specifically having a separate resolve for Pants plugins)
c
I've done the following in `pants.toml`:
Copy code
[GLOBAL]
pants_version = "2.11.0"
pythonpath = ["%(buildroot)s/front_porch/modules/peach/internals/pants"]

backend_packages = [
  ...
  "pants.backend.plugin_development",
]

[source]
root_patterns = [
  "/",
  "/front_porch/modules/peach/internals/pants",
]
I've also added
front_porch/modules/peach/internals/pants/BUILD
with the following body:
Copy code
pants_requirements(name="pants")
However, I still can't import
pants.testutil.rule_runner
. Do I need to run some codegen command or anything?
b
Check out the Pants docs on multiple resolves. You want a "default" resolve for your repo's requirements. And then a secondary resolve for Pants' reqs. All your plugins will opt-into the latter resolve.
And you'll need to have those resolves be consuming lockfiles/requirements files, which you'll want to generate and check into the repo
c
I see. Let me try. Thanks!
❤️ 1
w
after adding:
pants_requirements(name="pants")
…did you get a recommendation to regenerate your lockfile? do you see
pants
in your lockfile?
assuming so, the next question is just whether inference is working (i.e.: do you see the pants dependency in
./pants dependencies $file-importing-rulerunner
?)
because while you can use a separate resolve for your plugins, you don’t need to
🥴 1
c
Forgot to follow up here, but when I tried
./pants generate-lockfiles
earlier, I actually just saw some warnings about some targets being used in different directories (no errors though), and then no lockfiles being generated. Didn't have time to look too much into it yet though
I have to sign off for the night now, but I'll come back to this tomorrow and keep you posted 🙂
👋 1
w
sounds good. would also check that
./pants list $directory-containing-the-pants_requirements-definition:
shows them
c
Okay, following up here. Regarding the warnings I'm seeing: after adding
"/front_porch/modules/peach/internals/pants"
to the
source_roots
, it turns out that imports from
ariadne
are ambiguous because I have an
ariadne
plugin located in
/front_porch/modules/peach/internals/pants
, and
ariadne
is also the name of a third party library that I'm using. Is there any way to get around this? I would like for my plugin name to be the same as the third party library that I'm using. The warning looks like this:
Copy code
[WARN] The target front_porch/modules/companies/graphql/company_module_config.py imports `ariadne.convert_kwargs_to_snake_case`, but Pants cannot safely infer a dependency because more than one target owns this module, so it is ambiguous which to use: ['//:requirements#ariadne', 'front_porch/modules/peach/internals/pants/ariadne/__init__.py'].
Okay, so now I see that after the
./pants generate-lockfiles
command finishes, I'm left with an error (pasted below). This error is a bit weird for me, because if I run
pipenv graph
, it shows the
timezonefinder==5.2.0
was able to be installed fine in my virtual environment.
Copy code
23:30:51.80 [ERROR] 1 Exception encountered:

  ProcessExecutionFailure: Process 'Generate lockfile for python-default' failed with exit code 1.
stdout:

stderr:
WARNING: Discarding <https://files.pythonhosted.org/packages/f6/f7/f37bb8c8d93e6126d845c381798a8331a7bb282895343e324dac02d40fef/timezonefinder-5.2.0.tar.gz#sha256=a374570295a8dbd923630ce85f754e52578e288cb0a9cf575834415e84758352> (from <https://pypi.org/simple/timezonefinder/>) (requires-python:>=3.6). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
ERROR: Could not find a version that satisfies the requirement timezonefinder==5.2.0
ERROR: No matching distribution found for timezonefinder==5.2.0
pid 74569 -> /Users/hughhan/.cache/pants/named_caches/pex_root/venvs/4a4903f4a53b18a8968a4b2bac7896c88ae1b1da/0d6095b3aac42347ff31a51b62aeb720eb57f7ab/pex --disable-pip-version-check --no-python-version-warning --exists-action a --isolated -q --cache-dir /Users/hughhan/.cache/pants/named_caches/pex_root --log /private/tmp/pex-pip-log49fyya2t/pip.log download --dest /private/tmp/tmpbymn6u22/Users.hughhan..pyenv.versions.3.9.11.bin.python3.9 aenum==2.2.3 alembic==1.6.5 analytics-python==1.4.0 ansicolors==1.1.8 apache-beam==2.36.0 appnope==0.1.3; sys_platform == "darwin" ariadne==0.11.0 astroid==2.5; python_version >= "3.6" asttokens==2.0.5 attrs==21.4.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" autoflake==1.3.1 backcall==0.2.0 backoff==1.10.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" bcrypt==3.2.2; python_version >= "3.6" black==22.3.0 cachecontrol==0.12.11; python_version >= "3.6" cached-property==1.5.2 cachetools==4.2.4; python_version ~= "3.5" cairocffi==1.3.0; python_version >= "3.7" cairosvg==2.5.2; python_version >= "3.5" cattrs==22.1.0; python_version >= "3.7" and python_version < "4" cdktf==0.9.4 certifi==2021.10.8 cffi==1.15.0 charset-normalizer==2.0.12; python_version >= "3" click==8.1.3; python_version >= "3.7" cloudpickle==2.0.0; python_version >= "3.6" constructs==10.1.9; python_version ~= "3.7" coverage[toml]==6.3.3; python_version >= "3.7" crcmod==1.7 cryptography==36.0.1 cssselect2==0.6.0; python_version >= "3.7" datadog==0.41.0 ddtrace==0.57.3 decorator==5.1.1; python_version >= "3.5" defusedxml==0.7.1; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" dill==0.3.1.1; python_version >= "2.6" and python_version != "3.0" dnspython==2.2.1; python_version >= "3.6" and python_version < "4" docopt==0.6.2 eight==1.0.1 email-validator==1.1.3 et-xmlfile==1.1.0; python_version >= "3.6" exceptiongroup==1.0.0rc5; python_version < "3.11" execnet==1.9.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" executing==0.8.3 expiringdict==1.1.4 factory-boy==2.12.0 faker==13.11.1; python_version >= "3.6" fastavro==1.4.11; python_version >= "3.7" fasteners==0.17.3; python_version >= "3.6" firebase-admin==5.2.0 flask-cors==3.0.8 flask-saml2==0.3.0 flask==2.0.3 fpdf==1.7.2 future==0.18.2; python_version >= "2.6" and python_version not in "3.0, 3.1, 3.2, 3.3" google-api-core==1.31.5; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4, 3.5" google-api-python-client==1.12.3 google-apitools==0.5.32 google-auth-httplib2==0.1.0 google-auth-oauthlib==0.5.1; python_version >= "3.6" google-auth==1.35.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4, 3.5" google-cloud-bigquery-storage==2.11.0 google-cloud-bigquery[bqstorage,pandas]==2.34.2 google-cloud-core==1.7.2; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4, 3.5" google-cloud-firestore==2.4.0; platform_python_implementation != "PyPy" google-cloud-monitoring==0.36.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" google-cloud-pubsub==2.8.0 google-cloud-secret-manager==2.10.0 google-cloud-storage==1.38.0 google-cloud-trace==0.24.1; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" google-crc32c==1.3.0; python_version >= "3.5" google-resumable-media==1.3.3; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4, 3.5" googleapis-common-protos==1.56.1; python_version >= "3.6" graphql-core==3.0.6; python_version >= "3.6" and python_version < "4" grpc-google-iam-v1==0.12.4; python_version >= "3.6" grpcio==1.46.1; python_version >= "3.6" gspread==3.7.0 gunicorn==20.0.4 hdfs==2.7.0 html5lib==1.1; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" httplib2==0.19.1 humbug==0.2.7 idna==3.3; python_version >= "3.5" ijson==3.1.4 img2pdf==0.4.3 importlib-metadata==2.1.1 iniconfig==1.1.1 ipdb==0.13.4 ipython==8.3.0; python_version >= "3.4" iso-639==0.4.5 iso8601==0.1.16 isodate==0.6.1 isort==4.3.21; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" itsdangerous==2.0.1 jdcal==1.4.1 jedi==0.18.1; python_version >= "3.6" jellyfish==0.7.2; python_version >= "3.5" jinja2==3.0.3 jsii==1.59.0; python_version ~= "3.7" json-log-formatter==0.4.0 launchdarkly-server-sdk==7.2.0 lazy-object-proxy==1.7.1; python_version >= "3.6" libcst==0.4.3; python_version >= "3.7" lob==4.5.4 lxml==4.8.0 mako==1.2.0; python_version >= "3.7" markupsafe==2.1.1; python_version >= "3.7" marshmallow-dataclass==8.2.0 marshmallow-enum==1.5.1 marshmallow==3.15.0; python_version >= "3.7" matplotlib-inline==0.1.3; python_version >= "3.5" mccabe==0.6.1 monotonic==1.6 more-itertools==8.12.0 msgpack==0.6.2 mypy-extensions==0.4.3 mypy==0.942 nameparser==1.1.1 numpy==1.21.5 oauth2client==4.1.3 oauthlib==3.2.0; python_version >= "3.6" opencensus-context==0.1.1 opencensus-ext-stackdriver==0.7.2 opencensus==0.7.7 openpyxl==3.0.5 orjson==3.6.8; python_version >= "3.7" packaging==21.3; python_version >= "3.6" pandas==1.3.5 pantsbuild.pants.testutil<2.12,>=2.11.0rc0 pantsbuild.pants<2.12,>=2.11.0rc0 pantsbuild.pants==2.11.0 paramiko==2.11.0 parso==0.8.3; python_version >= "3.6" pathspec==0.9.0 pex==2.1.84; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" and python_full_version < "3.11.0" pexpect==4.8.0; sys_platform != "win32" pgpy==0.5.4 pickleshare==0.7.5 pikepdf==5.1.3; python_version >= "3.7" pillow==9.1.0; python_version >= "3.7" plaid-python==4.0.0 platformdirs==2.4.0 pluggy==1.0.0; python_version >= "3.6" probableparsing==0.0.1 prompt-toolkit==3.0.29; python_full_version >= "3.6.2" proto-plus==1.19.6 protobuf==3.20.1; python_version >= "3.7" psutil==5.9.0 ptyprocess==0.7.0 publication==0.0.3 pure-eval==0.2.2 py==1.11.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3, 3.4" pyarrow==6.0.1; python_version >= "3.6" pyasn1-modules==0.2.8 pyasn1==0.4.8 pycparser==2.21 pydantic==1.9.0 pydot==1.4.2; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" pyflakes==2.4.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" pygments==2.12.0; python_version >= "3.6" pyjwt==2.4.0; python_version >= "3.6" pylint==2.5.2 pymongo==3.12.3 pymysql==0.9.3 pynacl==1.5.0; python_version >= "3.6" pyopenssl==17.5.0 pyparsing==2.4.7; python_version >= "2.6" and python_version not in "3.0, 3.1, 3.2, 3.3" pypdf2==1.26.0 pypdftk==0.4 pyphen==0.12.0; python_version >= "3.7" pyrfc3339==1.1 pysftp==0.2.9 pytest-cov==3.0.0 pytest-forked==1.4.0; python_version >= "3.6" pytest-json-report==1.4.1 pytest-metadata==2.0.1; python_version >= "3.7" and python_full_version < "3.11.0" pytest-rerunfailures==10.2.0 pytest-xdist==2.5.0 pytest==7.1.1 python-crfsuite==0.9.8 python-dateutil==2.8.1 python-editor==1.0.4 python-http-client==3.3.7; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" python-lsp-jsonrpc==1.0.0 pytz==2020.1 pyyaml==6.0 pyzipcode==3.0.1 ratelimiter==1.2.0 requests-file==1.5.1 requests-oauthlib==1.3.1; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" requests-toolbelt==0.9.1 requests==2.27.1 rsa==4.8; python_version >= "3.6" and python_version < "4" semver==2.13.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" sendgrid==6.3.1 setproctitle==1.1.10 setuptools==62.3.1; python_version >= "3.7" signxml==2.9.0 simplejson==3.17.2 six==1.16.0; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" sqlalchemy-bigquery==1.4.3 sqlalchemy-stubs==0.4 sqlalchemy==1.4.27 stack-data==0.2.0 starlette==0.13.8; python_version >= "3.6" tenacity==8.0.1; python_version >= "3.6" timezonefinder==5.2.0 tinycss2==1.1.1; python_version >= "3.6" toml==0.10.2; python_version >= "2.6" and python_version not in "3.0, 3.1, 3.2, 3.3" tomli==2.0.1; python_version >= "3.7" traitlets==5.2.1.post0; python_version >= "3.7" twilio==6.41.0 types-click==7.1.8 types-cryptography==3.3.21 types-flask==1.1.1 types-jinja2==2.11.9 types-markupsafe==1.1.10 types-paramiko==2.8.16 types-pymysql==1.0.7 types-python-dateutil==0.1.4 types-pytz==2021.1.0 types-pyyaml==6.0.3 types-requests==2.27.25 types-setuptools==57.4.7 types-simplejson==0.1.4 types-toml==0.10.3 types-urllib3==1.26.14 types-werkzeug==1.0.9 typing-extensions==4.2.0; python_version >= "3.7" typing-inspect==0.7.1 ujson==5.2.0; python_version >= "3.7" uritemplate==3.0.1; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3" urllib3==1.26.9 us==2.0.0 usaddress==0.5.10 vulture==2.3 wcwidth==0.2.5 weasyprint==52.1 webencodings==0.5.1 werkzeug==2.0.3 wrapt==1.12.1 xlrd==2.0.1 xmlsec==1.3.12 zeep==4.1.0 zipp==3.8.0; python_version >= "3.7" --index-url <https://pypi.org/simple/> --retries 5 --timeout 15 exited with 1 and STDERR:
None
b
I can't see the whole thing because I'm on mobile. But AFAIK PEX follows the package metadata declarations very literally, whereas pip is looser. So I'm not surprised when they don't agree (it's just frustrating)
So what's probably happening is you have conflicting metadata. Two packages can't agree on a version. Pip is like "I picked a version, hope it works lol". PEX is refusing to leave you high and dry
Oh actually checking the error message, I'm wrong. Running
setup.py
seemingly failed
c
Is this a problem on timezonefinder’s end?
b
It depends 🤷‍♂️ Try with
--no-process-cleanup
, find the leaked sandbox, and then splash around. Not quite sure what incantation will give you the relevant output
setup.py
can run any arbitrary code, so it's a poopshoot what goes wrong
😭 1