-
Notifications
You must be signed in to change notification settings - Fork 60
add pylint
to test suite
#1860
Comments
Here's a text file with the full output of
|
I propose we do the following. General comments / notes
Dispositions (what to do)I went through the 1,641 messages in the text file above and ended up boiling it down to 75 groups with the same disposition. (Note: I would call these “warnings”, but Pylint calls them “messages”, with “warning” being a specific category of message.) These dispositions fell into the six classes below. I’d like the initial PR for this to yield no messages. We’ll do that by fixing the easy stuff in that PR and deferring the rest. NowEach of these is described in an individual comment below. These should all be fixed in this issue’s PR.
LaterEach of these has its own issue, linked below.
I wonder if a good approach is to disable all the messages we get (I have a spreadsheet that can give a list), e.g. with |
Class names (C0103 invalid-name)
charliecloud/lib/build_cache.py Line 202 in d679373
We just use a different naming convention. Pylint doesn’t have a pre-configured style name but it should be easy to configure via regex. |
Log function names (C0103 invalid-name)
charliecloud/lib/charliecloud.py Lines 467 to 469 in d679373
These functions just have special names. Probably just add ignore comments to each |
Bad None comparison (C0121 singleton-comparison)
charliecloud/lib/build_cache.py Line 785 in d679373
Should be |
Bad type check? (C0123 unidiomatic-typecheck)
Lines 88 to 89 in d679373
I think this is OK because this class has a weird notion of equality, but needs a little more though. |
Bad
|
args = list(self.tree.child_terminals("copy_list", "STRING_QUOTED")) | |
for i in range(len(args)): | |
args[i] = args[i][1:-1] # strip quotes |
These can be easily refactored to not use indexes.
Non-idiomatic class argument (C0202 bad-classmethod-argument)
charliecloud/lib/build_cache.py Lines 287 to 288 in d679373
We use |
Bad
|
These should all be fixed.
Unnecessary splitting (C0207 use-maxsplit-arg)
Line 411 in d679373
This appears to be a performance thing and we don’t use this in places where it matters. I think what we have is more readable, so let’s global ignore. |
Modules too long (C0302 too-many-lines)This probably right, but I don’t see this changing in the foreseeable future and I don’t think Pylint is the right place to enforce it. If the warnings are all solved, then the most likely way it would re-appear is that a small change pushes a module over the threshold, which is the wrong time to demand a refactor. Global ignore. |
Multiple statements per line (C0321 multiple-statements)
I don’t mind this and we use it a lot: Line 50 in d679373
but: Lines 633 to 635 in d679373
or: Lines 839 to 842 in d679373
seem confusion-prone. Let’s just stop using multiple statements per line. |
Bad import position (C0413 wrong-import-position)
charliecloud/lib/charliecloud.py Lines 26 to 33 in d679373
We have a good reason for this, but probably better to disable on a case-by-case basis. |
Inappropriate dunder call (C2801 unnecessary-dunder-call)
charliecloud/lib/filesystem.py Line 393 in 5ceefa7
False positive; we’re implementing |
Bad
|
except lark.exceptions.UnexpectedInput as x: | |
if (x.column == -1): | |
ch.FATAL("image ref syntax, at end: %s" % s, hint); | |
else: | |
ch.FATAL("image ref syntax, char %d: %s" % (x.column, s), hint) | |
except lark.exceptions.UnexpectedEOF as x: | |
# We get UnexpectedEOF because of Lark issue #237. This exception | |
# doesn’t have a column location. | |
ch.FATAL("image ref syntax, at end: %s" % s, hint) |
This is a real bug that should be fixed.
Nonexistent instance member access in external classes (E1101 no-member)
This happens twice: charliecloud/lib/build_cache.py Lines 384 to 385 in d679373
Genuinely wrong and will crash the error message. charliecloud/lib/charliecloud.py Line 737 in d679373
This one seems like if it’s not present it shouldn't work at all? Investigate. |
Non-iterable iterated (E1133 not-an-iterable)
Line 118 in d679373
The specific error is a false positive, but it’s a property that need |
Bad
|
ch.FATAL("can’t copy metadata: %s -> %s" % (self, dst, x.strerror)) |
Yep, that's wrong.
Merge
|
if (not (isinstance(inst, Directive_G) | |
or isinstance(inst, From__G) | |
or isinstance(inst, Instruction_No_Image))): |
Should probably fix.
FP complaints about
|
try: | |
return d.split(":", maxsplit=1)[1] | |
except AttributeError: | |
FATAL("not a string: %s" % repr(d)) | |
except IndexError: | |
FATAL("no algorithm tag: %s" % d) |
This is a FP because ch.FATAL
doesn’t return (it goes into an exception procedure that kills the program). Can we teach Pylint that it doesn’t return?
Useless return complaints (R1711 useless-return)
charliecloud/lib/build_cache.py Lines 1387 to 1389 in d679373
The |
Built-in
|
if (len(depfails) > 0): | |
exit(1) |
charliecloud/lib/charliecloud.py
Lines 661 to 664 in d679373
def exit(code): | |
profile_stop() | |
profile_dump() | |
sys.exit(code) |
This is the same problem. Rename our exit()
, and see if we are calling sys.exit()
anywhere we should be using our own exit()
.
Use error-checking
|
fp = open(pid_path, "rt", encoding="UTF-8") |
with
isn’t a good match for Charliecloud because the key operations are wrapped so they can’t fail. That is, I don’t think we should take the advice, but the flagged code should probably be using fs.Path.open()
instead and the warning should be left enabled.
Bad keyword argument defaults (W0102 dangerous-default-value)
charliecloud/lib/charliecloud.py Lines 528 to 529 in d679373
I agree. Fix. |
Needless
|
def execute(self): | |
"""Do what the instruction says. At this point, the unpack directory is | |
all ready to go. Thus, the method is cache-ignorant.""" | |
pass |
IMO clearer this way. Ignore globally.
FP on
|
self.__class__._gzip_set() |
Technically this a false positive — we’re accessing a private class (not instance) member — but going though self.__class__
seems weird. Why not just self
?
Superclass
|
class Disabled_Cache(Rebuild_Cache): | |
def __init__(self, *args): | |
pass |
This is on purpose b/c the inheritance is a bit strange. I’d like to leave it enabled and justify exceptions on a case-by-base basis.
Superclass argument renamed (W0237 arguments-renamed)
charliecloud/lib/charliecloud.py Line 286 in d679373
Personally I think |
Method that only delegates back to parent (W0246 useless-parent-delegation)
Lines 928 to 929 in d679373
Indeed this method seems to be doing nothing. Solution is probably delete it regardless, but I really wonder why. |
Bad indentation (W0311 bad-indentation)
charliecloud/lib/build_cache.py Lines 827 to 829 in d679373
This whole method is indented too much, probably due to being moved at some point. |
Needless semicolons (W0301 unnecessary-semicolon)
charliecloud/lib/build_cache.py Lines 639 to 640 in d679373
Somebody forgot they were writing Python instead of C. Fix. |
Global variable introduced secretly (W0601 global-variable-undefined)
charliecloud/lib/charliecloud.py Lines 666 to 668 in d679373
This is where |
Remove unused imports (W0611 unused-import)
Line 5 in d679373
I think unused imports might have been the original motivation for this entire issue. |
Remove unused variables (W0612 unused-variable)
charliecloud/lib/charliecloud.py Line 753 in d679373
The idiom in this particular case is IIRC |
Undefined loop variables? (W0631 unused-loop-variable)
Line 373 in 5ceefa7
Here it is defined. Should we simplify the control flow? I don’t know. Probably analyze on a case-by-case basis. |
Catch-all
|
def git(self, argv, cwd=None, quiet=True, *args, **kwargs): |
This can cause duplicate argument exceptions. Fix.
Non-string default in
|
self.port = int(os.getenv("CH_REGY_DEFAULT_PORT", 443)) |
In this particular case it’s harmless because we immediately convert to int anyway, but probably an antipattern. Fix.
|
cp = subprocess.run(argv, **kwargs) |
Sure, fix.
Since I started using VSCode, I've noticed that it's easy to add unused imports to our Python code without noticing. Adding a Python linter (e.g.
pylint
) to our test suite could help catch those instances and other potentially bad coding practices.One thing worth noting is that
pylint
really doesn't like our code, e.g.Here our code is given a rating of☹️
5.38/10
pylint
messages have a naming convention based on the following categories (seemingly in descending order of severity): Fatal, Error, Warning, Convention, Refactor, Information. The breakdown of the messages we get is as follows:So the vast majority of complaints
pylint
gives us fall under the "Convention" category. Some common messages that show up for us are:__init__
, mostly inbuild.py
)This is just a sample, there are obviously many more. I think step 1 for whoever takes this on is to go through the list of messages and figure out what we want to ignore and what we don't.
The text was updated successfully, but these errors were encountered: