__all__ defined inside a class

Hi folks, I've just noticed that a legacy piece of code I'm working with contains the following pattern:
class SomeClass(object): __all__ = ['add', 'delete']
def __init__(self): pass
def get(self): pass
def add(self, x): pass
def delete(self, x): pass
And the caller of this class actually uses the .get() method. I have this in at least 10 different places.
I wasn't able to find any information about __all__ having any special meaning when defined inside a class so this looks like a mistake.
Q1: Do we want pylint to warn about __all__ being detected not at module level ?
Q2: Do we want another check to warn about class attributes staring with single/double underscore ?
-- Alex

On Thu, Mar 22, 2018 at 4:23 PM, Alexander Todorov atodorov@mrsenko.com wrote:
Hi folks, I've just noticed that a legacy piece of code I'm working with contains the following pattern:
class SomeClass(object): __all__ = ['add', 'delete']
def __init__(self): pass def get(self): pass def add(self, x): pass def delete(self, x): pass
And the caller of this class actually uses the .get() method. I have this in at least 10 different places.
I wasn't able to find any information about __all__ having any special meaning when defined inside a class so this looks like a mistake.
Q1: Do we want pylint to warn about __all__ being detected not at module level ?
Q2: Do we want another check to warn about class attributes staring with single/double underscore ?
-- Alex
Hi Alex,
Regarding Q1: Maybe? It's not entirely clear based on your brief example what the original author though __all__ did here.
Regarding Q2: Why would you want to prohibit class attributes starting with single or double underscores? The former is useful for "private" class attributes. The latter performs name mangling which can be useful in situations (see: https://stackoverflow.com/a/1301369/1953283). I don't think pylint should be warning in this case.
Cheers, Ian

On 03/22/2018 06:30 PM, Ian Stapleton Cordasco wrote:
On Thu, Mar 22, 2018 at 4:23 PM, Alexander Todorov atodorov@mrsenko.com wrote:
Hi folks, I've just noticed that a legacy piece of code I'm working with contains the following pattern:
class SomeClass(object): __all__ = ['add', 'delete']
def __init__(self): pass def get(self): pass def add(self, x): pass def delete(self, x): pass
And the caller of this class actually uses the .get() method. I have this in at least 10 different places.
I wasn't able to find any information about __all__ having any special meaning when defined inside a class so this looks like a mistake.
Q1: Do we want pylint to warn about __all__ being detected not at module level ?
Q2: Do we want another check to warn about class attributes staring with single/double underscore ?
-- Alex
Hi Alex,
Regarding Q1: Maybe? It's not entirely clear based on your brief example what the original author though __all__ did here.
Regarding Q2: Why would you want to prohibit class attributes starting with single or double underscores? The former is useful for "private" class attributes. The latter performs name mangling which can be useful in situations (see: https://stackoverflow.com/a/1301369/1953283). I don't think pylint should be warning in this case.
And then, from http://xion.io/post/code/python-all-wild-imports.html, is this little gem of a note:
All in all (ahem), this hints at a cute little trick which is also very self-evident:
__all__ = ['DO_NOT_WILD_IMPORT']
Put this in a Python module, and no one will be able to import * from it! Much more effective than any lint warning ;-)

On Thu, Mar 22, 2018 at 08:30:44PM -0500, Ian Stapleton Cordasco wrote:
Regarding Q2: Why would you want to prohibit class attributes starting with single or double underscores? The former is useful for "private" class attributes. The latter performs name mangling which can be useful in situations (see: https://stackoverflow.com/a/1301369/1953283). I don't think pylint should be warning in this case.
But __all__ is a dunder name, and dunders are reserved for use by Python.
I don't know what the author of the class thought they were doing, but they shouldn't have been using __all__ for it, hence the idea of a warning. But it probably isn't practical to keep a white list of permitted dunders and warn about those that any others.

На 23.03.2018 в 07:00, Steven D'Aprano написа:
On Thu, Mar 22, 2018 at 08:30:44PM -0500, Ian Stapleton Cordasco wrote:
Regarding Q2: Why would you want to prohibit class attributes starting with single or double underscores? The former is useful for "private" class attributes. The latter performs name mangling which can be useful in situations (see: https://stackoverflow.com/a/1301369/1953283). I don't think pylint should be warning in this case.
But __all__ is a dunder name, and dunders are reserved for use by Python.
I don't know what the author of the class thought they were doing, but they shouldn't have been using __all__ for it, hence the idea of a warning. But it probably isn't practical to keep a white list of permitted dunders and warn about those that any others.
Thanks everyone for the replies and the useful links.
I also don't know what the original author was trying to do. In most cases in the original code this class attribute is not used and it looks like they were trying to control the list of exported class methods. I don't have other explanation about it.
I am with Steven on this one, __all__ is a dunder (plus it looks very confusing inside the class context) so warn about it.
I didn't express myself clearly on the second question. Instead of warning about class attributes that *start* with single or double underscore how about pylint warns about class attributes whose names are dunders (both start and end with double underscores) ?
-- Alex
participants (4)
-
Alexander Todorov
-
Ian Stapleton Cordasco
-
Stephen Satchell
-
Steven D'Aprano