cold-soccer-63228
05/02/2022, 4:02 PMgoogleapiclient
Python package when running ./pants test ...
. It seems to be an issue with the underlying pyparsing
module.
I was wondering if anyone has seen anything like this before.
The error I'm getting is as follows.
AttributeError: module 'pyparsing' has no attribute 'downcaseTokens'
Here's the part of the stack trace that seems relevant.
front_porch/modules/common/google_drive/google_drive.py:11: in <module>
from googleapiclient.discovery import build
/Users/hughhan/.cache/pants/named_caches/pex_root/venvs/8dccf2108884fe3898a8bc04279cb74a330a1bbd/e83365d7bd577d2fac6d4ec70eb77f4d4607d634/lib/python3.9/site-packages/googleapiclient/discovery.py:48: in <module>
import httplib2
/Users/hughhan/.cache/pants/named_caches/pex_root/venvs/8dccf2108884fe3898a8bc04279cb74a330a1bbd/e83365d7bd577d2fac6d4ec70eb77f4d4607d634/lib/python3.9/site-packages/httplib2/__init__.py:52: in <module>
from . import auth
/Users/hughhan/.cache/pants/named_caches/pex_root/venvs/8dccf2108884fe3898a8bc04279cb74a330a1bbd/e83365d7bd577d2fac6d4ec70eb77f4d4607d634/lib/python3.9/site-packages/httplib2/auth.py:20: in <module>
auth_param_name = token.copy().setName("auth-param-name").addParseAction(pp.downcaseTokens)
E AttributeError: module 'pyparsing' has no attribute 'downcaseTokens'
hundreds-father-404
05/02/2022, 4:04 PMgoogleapiclient
is not correctly setting its metadata for the version of pyparsing
it needs
What pants version are you on? Are you using lock files?cold-soccer-63228
05/02/2022, 4:06 PM➜ ./pants --version
2.10.0
I am using a Pipfile.lock
, which is generated from a Pipfile
that I define.
Here is what my root-level BUILD
file looks like.
python_sources(name = "root")
pipenv_requirements(
name = "requirements",
module_mapping = {
"analytics-python": ["analytics"],
"factory-boy": ["factory"],
"google-api-python-client": ["google"],
"graphql-core": ["graphql"],
"iso-639": ["iso639"],
"launchdarkly-server-sdk": ["ldclient"],
"plaid-python": ["plaid"],
"pytest-xdist": ["xdist"],
"python-dateutil": ["dateutil"],
},
overrides = {
"google-cloud-pubsub": { "dependencies": [":requirements#setuptools"] },
"iso-639": { "dependencies": [":requirements#setuptools"] },
},
source = "Pipfile.lock",
type_stubs_module_mapping = {
"types-Flask": ["flask"],
"types-PyMySQL": ["pymysql"],
"types-python-dateutil": ["python-dateutil"],
"types-pytz": ["pytz"],
"types-PyYAML": ["pyyaml"],
"types-requests": ["requests"],
"types-simplejson": ["simplejson"],
"types-Werkzeug": ["werkzeug"],
},
)
cold-soccer-63228
05/02/2022, 4:09 PMoverrides
, specifically to tell googleapiclient
that it needs a specific version of pyparsing
?
I'm not sure how automatic module mapping works, but alternatively would I have to add googleapiclient
to the values list for google-api-python-client
?
For example:
"google-api-python-client": ["google", "googleapiclient"]
cold-soccer-63228
05/02/2022, 4:09 PMModuleNotFoundError
in the cases that I need to explicitly define the module mapping.hundreds-father-404
05/02/2022, 4:18 PMI am using a Pipfile.lockSo that won't be consued by Pants. See https://www.pantsbuild.org/docs/python-third-party-dependencies#lockfiles for how you can use a lockfile with Pants. It might shed some light on this problem by telling us which version of pyparsing is being used -- Even if you do not use a lock file for now, I suspect that the fix might be the same. Find the version of pyparser that is being used in your poetry lock file, as it sounds like that one is working. Then, add this to your BUILD file:
python_requirement(
name="pyparsing",
requirements=["pyparsing==<insert version>"]
)
Finally add to your overrrides
that google-api-python-client
depends on :pyparsing
, similar to what you do w/ setuptoolshundreds-father-404
05/02/2022, 4:18 PMI wouldn't think that I need to do the latter because normally I would have expected a ModuleNotFoundError in the cases that I need to explicitly define the module mapping.I agree
cold-soccer-63228
05/02/2022, 4:26 PMSo that won't be consumed by Pants.I followed the reference at https://www.pantsbuild.org/docs/reference-pipenv_requirements. Are
Pipfile.lock
files not consumed by Pants? It seems that the corresponding dependencies are properly installed when running other tests that do not need pyparsing
?hundreds-father-404
05/02/2022, 4:29 PMAre Pipfile.lock files not consumed by Pants?They are not. You must set up a lock file as instructed at https://www.pantsbuild.org/docs/python-third-party-dependencies#lockfiles if you want the benefits of lockfiles like reproducibility
It seems that the corresponding dependencies are properly installed when running other tests that do not need pyparsing?Based on the stack trace, it looks like pyparsing is a transitive dependency of google api client, right? do you ever directly use
pyparsing
?cold-soccer-63228
05/02/2022, 4:36 PMBased on the stack trace, it looks like pyparsing is a transitive dependency of google api client, right? do you ever directly useYup, that's correct?pyparsing
cold-soccer-63228
05/02/2022, 5:06 PM./pants generate-lockfiles
,
2. add a pyparsing
requirement to the root-level BUILD
file,
3. add pyparsing
as a dependency to the overrides of google-api-python-client
.
Afterwards, I re-ran ./pants test ...
, and still am getting the same error. Here is what my BUILD
looks like now.
python_sources(name = "root")
python_requirement(
name = "pyparsing",
requirements = ["pyparsing==2.4.7"]
)
pipenv_requirements(
name = "requirements",
module_mapping = {
"analytics-python": ["analytics"],
"factory-boy": ["factory"],
"google-api-python-client": ["google"],
"graphql-core": ["graphql"],
"iso-639": ["iso639"],
"launchdarkly-server-sdk": ["ldclient"],
"plaid-python": ["plaid"],
"pytest-xdist": ["xdist"],
"python-dateutil": ["dateutil"],
},
overrides = {
"google-api-python-client": { "dependencies": [":pyparsing#pyparsing"] },
"google-cloud-pubsub": { "dependencies": [":requirements#setuptools"] },
"iso-639": { "dependencies": [":requirements#setuptools"] },
},
source = "Pipfile.lock",
type_stubs_module_mapping = {
"types-Flask": ["flask"],
"types-PyMySQL": ["pymysql"],
"types-python-dateutil": ["python-dateutil"],
"types-pytz": ["pytz"],
"types-PyYAML": ["pyyaml"],
"types-requests": ["requests"],
"types-simplejson": ["simplejson"],
"types-Werkzeug": ["werkzeug"],
},
)
Am I misinterpreting something?hundreds-father-404
05/02/2022, 5:07 PMcold-soccer-63228
05/02/2022, 5:08 PMpyparsing
is the same as far as I can tell.
➜ pipenv graph
...
- pyparsing [required: >=2.0.2,!=3.0.5, installed: 2.4.7]
...
hundreds-father-404
05/02/2022, 5:10 PMcold-soccer-63228
05/02/2022, 5:11 PMhundreds-father-404
05/02/2022, 5:13 PMtrue
to test that hypothesis: https://www.pantsbuild.org/docs/reference-python#section-run-against-entire-lockfilecold-soccer-63228
05/02/2022, 5:16 PMpants.toml
, and then reran ./pants test ...
, and am still seeing the same error.
[python]
...
run_against_entire_lockfile = true
hundreds-father-404
05/02/2022, 5:35 PMcold-soccer-63228
05/02/2022, 5:39 PMcold-soccer-63228
05/02/2022, 6:02 PMhttplib2
to 0.2+
because of another dependency. And downgrading pyparsing
to 2.4.2
didn't fix it for me 😞cold-soccer-63228
05/03/2022, 2:32 PM./pants test
causes this issue to be encountered, whereas running something like pipenv run pytest
directly doesn't encounter this error?hundreds-father-404
05/03/2022, 2:56 PMhttplib2
is relevant.
It would be helpful to see where the differences arecold-soccer-63228
05/03/2022, 4:29 PMhttplib2==0.19.1 \
--hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
--hash=sha256:0b12617eeca7433d4c396a100eaecfa4b08ee99aa881e6df6e257a7aad5d533d
From `Pipfile.lock`:
"httplib2": {
"hashes": [
"sha256:0b12617eeca7433d4c396a100eaecfa4b08ee99aa881e6df6e257a7aad5d533d",
"sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4"
],
"version": "==0.19.1"
},
cold-soccer-63228
05/03/2022, 4:29 PMhundreds-father-404
05/03/2022, 4:30 PMcold-soccer-63228
05/03/2022, 4:31 PM3rdparty/python/default.lock
and Pipfile.lock
files are quite large...hundreds-father-404
05/03/2022, 4:33 PMcold-soccer-63228
05/03/2022, 4:34 PM2.4.7
in my Pipfile.lock
...
"pyparsing": {
"hashes": [
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.7"
},
cold-soccer-63228
05/03/2022, 4:34 PMdefault.lock
file just to sanity check...hundreds-father-404
05/03/2022, 4:35 PMcold-soccer-63228
05/03/2022, 4:40 PMpython_sources(name = "root")
python_requirement(
name = "pyparsing",
requirements = ["pyparsing==2.4.7"]
)
pipenv_requirements(
name = "requirements",
overrides = {
"google-api-python-client": { "dependencies": [":pyparsing#pyparsing"] },
...
},
source = "Pipfile.lock",
...
)
cold-soccer-63228
05/03/2022, 4:40 PMhttplib2
for where we had google-api-python-client
previously)?
python_sources(name = "root")
python_requirement(
name = "pyparsing",
requirements = ["pyparsing==2.4.7"]
)
pipenv_requirements(
name = "requirements",
overrides = {
"httplib2": { "dependencies": [":pyparsing#pyparsing"] },
...
},
source = "Pipfile.lock",
...
)
hundreds-father-404
05/03/2022, 4:41 PMcold-soccer-63228
05/03/2022, 4:44 PMhttplib2
is not in my Pipfile as a direct dependency.cold-soccer-63228
05/03/2022, 4:46 PMOld pip dependency resolver allowed installation of conflicting requirements. Installing httplib2 (with requirements pyparsing<3) would not downgrade existing pyparsing>=3.
pypa/pip#6969
pypa/pip#988
> pip 20.3 has been released, and it has the new resolver by default!
So upgrade pip might also help.
pip install 'pip>=20.3'
cold-soccer-63228
05/03/2022, 4:47 PMhundreds-father-404
05/03/2022, 4:51 PMcold-soccer-63228
05/03/2022, 4:51 PMcold-soccer-63228
05/03/2022, 4:51 PMcold-soccer-63228
05/03/2022, 4:52 PM