proud-dentist-22844
06/15/2021, 3:29 AM./pants dependencies ...
output looks correct, but pylint is complaining that it can't find some modules (modules that are listed in the ./pants dependencies
output). What's more, if I only include the targets in that directory, pylint has a different set of errors. And if I do a very narrow selection of files to lint (including files that had errors with a larger selection of targets) then I don't get any errors at all.
I thought maybe it was overlapping source roots, so I temporarily deleted //conftest.py
, the relevant target from //BUILD
, and the /
source root, but that didn't resolve it.
Here's a bunch of ./pants ...
output:
https://gist.github.com/cognifloyd/f428a423a07e1e859d4e2625c0cd66f1
And here's the code base I'm working with:
https://github.com/st2sandbox/st2/tree/pantshundreds-father-404
06/15/2021, 3:31 AM./pants dependencies
rather than ./pants dependencies --transitive
? Note that Pylint only looks at direct deps, not transitive
You could also try --no-process-execution-local-cleanup
to inspect the files you expect are thereproud-dentist-22844
06/15/2021, 3:35 AM./pants dependencies
and ./pants dependencies --transitive
.proud-dentist-22844
06/15/2021, 3:47 AM************* Module st2api.controllers.v1.keyvalue
st2api/st2api/controllers/v1/keyvalue.py:1:0: F0002: <class 'ModuleNotFoundError'>: No module named 'st2common.logging' (astroid-error)
If I look at ./pants dependencies st2api/st2api/controllers/v1/keyvalue.py
I do not see st2common/st2common/logging/__init__.py
though it is present in --transitive
. And when I look in the dir left by --no-process-execution-local-cleanup
, the st2common/st2common/logging
directory is not present.
The relevant import in keyvalue.py
is from st2common import log as logging
. st2common/st2common/log.py
in turn has:
from st2common.logging.filters import LoggerNameExclusionFilter
# Those are here for backward compatibility reasons
from st2common.logging.handlers import FormatNamedFileHandler
from st2common.logging.handlers import ConfigurableSyslogHandler
proud-dentist-22844
06/15/2021, 3:48 AMhundreds-father-404
06/15/2021, 3:51 AM__init__.py
changes that somehow? To test, you could try creating a dummy repo w/o Pants and with a similar layout to what you have. Delete the transitive dep file, and see if Pylint complainsproud-dentist-22844
06/15/2021, 4:16 AM,/pants lint st2api::
(with the weird potentially transitive-related errors) to ./pants lint ::
- that is more clear cut - all the files that pylint says are missing are definitely present.
Given the tmp directory /tmp/process-execution5xrkvP
there are directories /tmp/process-execution5xrkvP/st2api
and /tmp/process-execution5xrkvP/st2api/st2api
. Is /tmp/process-execution5xrkvP
, the directory that contains __run.sh
implicitly included in the PYTHONPATH somehow? Because then it might try looking in st2api/
instead of st2api/st2api/
which would not work.hundreds-father-404
06/15/2021, 4:18 AM__run.sh
should show PEX_EXTRA_SYS_PATH
, which is the Pex way of setting PYTHONPATH
proud-dentist-22844
06/15/2021, 4:19 AM$ ./pylint_runner.pex_bin_python_shim.sh
Python 3.6.13 (default, Jun 12 2021, 12:27:04)
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import st2api
>>> st2api.__path__
_NamespacePath(['/tmp/process-execution5xrkvP/st2api'])
>>> import sys
>>> sys.path
['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/tmp/process-execution5xrkvP/.cache/pex_root/venvs/6e8f51fbbffcacbdf7d21b92a25fe2057ac9e907/f0dd7252e78b9eef2b00bf88b4b41d699b14a04a/lib64/python3.6/site-packages']
proud-dentist-22844
06/15/2021, 4:21 AMproud-dentist-22844
06/15/2021, 4:22 AMexport PEX_EXTRA_SYS_PATH=$'contrib/chatops:contrib/core:contrib/examples:contrib/examples/lib:contrib/hello_st2:contrib/linux:contrib/packs:contrib/runners/action_chain_runner:contrib/runners/announcement_runner:contrib/runners/http_runner:contrib/runners/inquirer_runner:contrib/runners/local_runner:contrib/runners/noop_runner:contrib/runners/orquesta_runner:contrib/runners/python_runner:contrib/runners/remote_runner:contrib/runners/winrm_runner:pylint_plugins:scripts:st2actions:st2api:st2auth:st2client:st2common:st2common/benchmarks/micro:st2exporter:st2reactor:st2stream:st2tests:st2tests/testpacks/checks:tools:__plugins'
proud-dentist-22844
06/15/2021, 4:25 AMproud-dentist-22844
06/15/2021, 6:06 AM__run.sh
from ./pants lint ::
so that it tested just two files: st2api/bin/st2api st2api/st2api/app.py
, which failed, but st2api/st2api/app.py st2api/bin/st2api
passes, so pylint's module detection logic is getting confused by the binaries that match the module names.
From the pylint docs:
It is also possible to analyze Python files, with a few restrictions. The thing to keep in mind is that Pylint will try to convert the file name to a module name, and only be able to process the file if it succeeds.and pants is passing all of the filenames to pylint, instead of modules. So I wonder if it would be safer to pass modules instead, except for the files that aren't in modules? (like st2api/bin/st2api)? For now,
skip_pylint=True
in st2*/bin
allows ./pants lint ::
to pass (as much as I expect it to). selecting a smaller subset still fails, which is odd. but its better.proud-dentist-22844
06/15/2021, 6:06 AMproud-dentist-22844
06/15/2021, 6:06 AMhappy-kitchen-89482
06/15/2021, 6:14 AMhappy-kitchen-89482
06/15/2021, 6:15 AMhappy-kitchen-89482
06/15/2021, 6:16 AMhappy-kitchen-89482
06/15/2021, 6:19 AMhappy-kitchen-89482
06/15/2021, 6:20 AMhappy-kitchen-89482
06/15/2021, 6:21 AMhappy-kitchen-89482
06/15/2021, 11:49 AMst2api/
is a source root?happy-kitchen-89482
06/15/2021, 11:49 AMst2api/bin/st2api
you mean st2api/bin/st2api.py
?happy-kitchen-89482
06/15/2021, 12:10 PMhappy-kitchen-89482
06/15/2021, 12:27 PMproud-dentist-22844
06/15/2021, 4:21 PMst2api/
is a source root.
st2api/bin/st2api
is an executable without a .py
extension. I explicitly added it to a python_libraries
target sources.proud-dentist-22844
06/15/2021, 4:26 PMst2*/bin
should be considered a leaf (of sorts) - ie, nothing should be allowed to import from those files, but they should be able to import from everything else. Not sure how to inform pants (or pylint) about something like that. πproud-dentist-22844
06/15/2021, 4:30 PMisolated_source_roots
? ie a source root that never gets added to PYTHONPATH, but that counts as a root when calculating its "module"?proud-dentist-22844
06/15/2021, 4:31 PMisolated_source_root
would get passed to pylint last, which apparently doesn't confuse it.proud-dentist-22844
06/15/2021, 4:33 PMbin_root
?happy-kitchen-89482
06/15/2021, 8:19 PMst2api.bin.st2api
for exampleproud-dentist-22844
06/15/2021, 9:23 PMbin.st2api
since st2api/
is a source root, however, I think pylint inspects st2api/bin/st2api
and decides that it provides the st2api
module. It must be caching that because subsequent files that import something from st2api
fail. But if it loads the bin file last, it already processed the real st2api
module, so there is no ambiguity.proud-dentist-22844
06/15/2021, 9:27 PMastroid
stores a cache of parsed modules.
https://github.com/PyCQA/pylint/issues/158proud-dentist-22844
06/15/2021, 9:35 PMst2api/tests
and st2auth/tests
would both resolve to the module tests
proud-dentist-22844
06/15/2021, 9:39 PMproud-dentist-22844
06/15/2021, 9:41 PMst2api/bin/st2api
vs st2api/st2api
issue though.proud-dentist-22844
06/15/2021, 10:01 PMproud-dentist-22844
06/15/2021, 10:03 PMproud-dentist-22844
06/15/2021, 10:19 PM__init__.py
should be passed to pylint last.happy-kitchen-89482
06/16/2021, 4:33 PMst2api/bin/st2api
provides st2api
? It should only do that if st2api/bin
is in PYTHONPATH no?happy-kitchen-89482
06/16/2021, 4:33 PM___init___.py
happy-kitchen-89482
06/16/2021, 4:34 PMst2api/bin
does nothappy-kitchen-89482
06/16/2021, 4:40 PMhappy-kitchen-89482
06/16/2021, 4:40 PMhappy-kitchen-89482
06/16/2021, 4:40 PMhappy-kitchen-89482
06/16/2021, 4:40 PMhappy-kitchen-89482
06/16/2021, 4:41 PMhundreds-father-404
06/16/2021, 4:42 PMhappy-kitchen-89482
06/16/2021, 4:43 PMhappy-kitchen-89482
06/16/2021, 4:44 PMhappy-kitchen-89482
06/16/2021, 4:44 PMhappy-kitchen-89482
06/16/2021, 4:45 PMhappy-kitchen-89482
06/16/2021, 5:34 PMproud-dentist-22844
06/16/2021, 5:39 PMproud-dentist-22844
06/16/2021, 5:45 PMhappy-kitchen-89482
06/16/2021, 5:51 PMtests/
dir?happy-kitchen-89482
06/16/2021, 5:52 PMproud-dentist-22844
06/16/2021, 5:54 PMproud-dentist-22844
06/16/2021, 6:06 PMtests.unit.base
https://github.com/st2sandbox/st2/blob/pants/st2common/tests/unit/base.py
https://github.com/st2sandbox/st2/blob/pants/st2common/tests/unit/test_db_rbac.py#L27
from tests.unit.base import ...
and orquesta_runner also has tests.unit.base
https://github.com/st2sandbox/st2/blob/pants/contrib/runners/orquesta_runner/tests/unit/base.py
https://github.com/st2sandbox/st2/blob/pants/contrib/runners/orquesta_runner/tests/unit/test_basic.py#L32
from tests.unit import base
I had to disambiguate it manually for pants:
https://github.com/st2sandbox/st2/blob/pants/st2common/tests/unit/BUILD#L3
dependencies=["st2common/tests/unit/base.py"],
https://github.com/st2sandbox/st2/blob/pants/contrib/runners/orquesta_runner/tests/unit/BUILD#L3
dependencies=["contrib/runners/orquesta_runner/tests/unit/base.py"],
happy-kitchen-89482
06/16/2021, 6:43 PMhappy-kitchen-89482
06/16/2021, 6:43 PMproud-dentist-22844
06/16/2021, 6:49 PMproud-dentist-22844
06/16/2021, 6:50 PMpython setup.py develop
- scary I know), and then the makefile iterates through each of the package directories and runs nosetest
in them.proud-dentist-22844
06/16/2021, 6:53 PM./pants lint
and ./pants test
and fix any issues that come up.proud-dentist-22844
06/16/2021, 6:54 PMhappy-kitchen-89482
06/16/2021, 7:29 PMhappy-kitchen-89482
06/16/2021, 7:30 PMhappy-kitchen-89482
06/16/2021, 7:30 PM