Hello. I'm trying to get `flake8` and `yapf` runni...
# general
a
Hello. I'm trying to get
flake8
and
yapf
running with Pants on our code but I'm having some questions & wondering what the best approach is.
flake8
is handling configuration well, but
yapf
is giving me some trouble. In particular, we have some autogenerated files that we want to not run
yapf
on. If I use a
.yapfignore
, however,
yapf
will return
Copy code
input filenames did not match any python files
and an exit code of 1 when called against a set of files that are all excluded in the
.yapfignore
. This makes
./pants lint
fail when run against a set of files of files. I did find a fairly reasonable workaround here, using either a
python_sources(skip_yapf=True)
or a
Copy code
python_sources(overrides={
        "*_pattern_common_to_generated_files.py": {
            "skip_yapf": True
        },
    }
)
I'm wondering if this is the best way to handle this?
./pants tailor ::
won't know to include this line, so developers will probably have some confusion when they write something that will produce a new folder of generated files. I could mitigate that with a unit test that inspects the
BUILD
files, but that also seems a little gross. Is there a way to make that
*_pattern_common_to_generated_files.py
override implicit in each
python_sources
?
b
You may be able to do something with
__defaults__
: https://www.pantsbuild.org/docs/targets#field-default-values
a
Very interesting! This took care of one folder tree we have that is all generated files, but I'm having difficult with the
overrides
I used for places were generated files are mixed in with regular code.
Copy code
__defaults__(
    {
        (python_sources, ): dict(overrides={
            "*_generated.py": {
                "skip_yapf": True
            },
        })
    },
    extend=True,
)
Yields
Copy code
TypeError: Even though you are using a `FrozenDict`, the underlying values are not hashable. Please use hashable (and preferably immutable) types for the underlying values, e.g. use tuples instead of lists and use FrozenOrderedSet instead of set().

Original error message: unhashable type: 'dict'

Value: FrozenDict({'overrides': {('*_generated.py',): {'skip_yapf': True}}})
b
huh, maybe that's a bug with
__defaults__
not supporting nested dicts. Could you file an issue? https://github.com/pantsbuild/pants/issues/new?assignees=&labels=bug&template=bug_report.md&title= In the short term, I wonder if it will coerce sequences of pairs to a dict:
overides=(("*_generated.py", (("skip_yapf", True),)),)
🤔
a
Will do, thanks. It looks like the field type validation won't budge:
Copy code
InvalidFieldTypeException: The 'overrides' field in target my/path#__defaults__ must be dict[str | tuple[str, ...], dict[str, Any]], but was `(('*_generated.py',), (('skip_yapf', True),))` with type `tuple`.
👍 1
Defaults for the generated file tree is definitely a huge help though, thanks much. The mixed-file case should be more straight-forward for developers to figure out
👍 1
h
I think the nested dict value can be a string representation of a dict?
a
Do you have an example? I wasn't able to come up with something valid that uses a string
c
Thanks for the bug report. I’m on it.
a
Wow, thanks for the quick turnaround on that! Out of curiosity, do you think the above example will work on folders that don't have
*_generated.py
files? What I had intended to test after the
TypeError
was to see how unmatched globs would be handled
c
Oh, that’s an excellent question. I’m not that familiar with how overrides work. i.e. what happens if you provide overrides for unknown files/globs. Coming from
__defaults__
feels like it should be able to ignore any errors the same way unknown fields may be ignored if needed.