Pylint false positives

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Aug 15 03:09:57 EDT 2018


On Tue, 14 Aug 2018 15:18:13 +0000, Jon Ribbens wrote:

> On 2018-08-14, Steven D'Aprano <steve+comp.lang.python at pearwood.info>
> wrote:
>> If there really are a lot of such missing methods, I'd consider writing
>> something like this:
>>
>> class A:
>>     def __init__(self, ...):
>>         ...
>>
>>     # === process abstract methods en masse === 
>>     for name in "method_a method_b method_c method_d".split():
>>         @abstractmethod
>>         def inner(self):
>>             raise NotImplementedError
>>         inner.__name__ = name
>>         # This is okay, writing to locals works inside the class body.
>>         locals()[name] = inner
>>
>>     del inner, name  # Clean up the class namespace.
> 
> You have a peculiar idea of "good style"...

Yes, very peculiar. It's called "factor out common operations" and "Don't 
Repeat Yourself" :-)

In a world full of people who write:

    d[1] = None
    d[2] = None
    d[3] = None
    d[4] = None

I prefer to write:

    for i in range(1, 5):
       d[i] = None

Shocking, I know.

Literally my first professional programming job was working on a 
Hypercard project written by a professional programmer. (He was paid for 
it, so he was professional.) The first time I looked at his code, as a 
fresh-out-of-uni naive coder, I was surprised to read his GUI set-up 
code. By memory, it was something like this:

    set the name of button 1 to "Wibble 1"
    set the name of button 2 to "Wibble 2"
    set the name of button 3 to "Wibble 3"
    set the name of button 4 to "Wibble 4"
    # and so on...
    set the name of button 100 to "Wibble 100"

(using "Wibble" as a placeholder for the actual name, which I don't 
recall). The first thing I did was replace that with a loop:

    for i = 1 to 100 do
        set the name of button 100 to ("Wibble " & i)
    end for


Hypertalk uses & for string concatenation. That one change cut startup 
time from something like 90 seconds to about 30, and a few more equally 
trivial changes got it down to about 15 seconds.

Hypertalk in 1988 was not the fastest language in the world, but it was 
fun to work with.



>> although to be honest I'm not sure if that would be enough to stop
>> PyLint from complaining.
> 
> No - if you think about it, there's no way Pylint could possibly know
> that the above class has methods method_a, method_b, etc. 

Well, if a human reader can do it, a sufficiently advanced source-code 
analyser could do it too... *wink*

Yes, of course you are right, in practical terms I think it is extremely 
unlikely that PyLint or any other linter is smart enough to recognise 
that locals()[name] = inner is equivalent to setting attributes method_a 
etc. I actually knew that... "although to be honest I'm not sure" is an 
understated way of saying "It isn't" :-)

https://en.wikipedia.org/wiki/Litotes


> It also
> doesn't like the `del inner, name` because theoretically neither of
> those names might be defined, if the loop executed zero times.

That's a limitation of the linter. Don't blame me if it is too stupid to 
recognise that looping over a non-empty string literal cannot possibly 
loop zero times :-)



-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson




More information about the Python-list mailing list