Pylint E0202 False Positive? Or is this piece of code wrong? - python

I've been working on a class with properties but we ran into a nasty problem with pylint (0.25.1) In the code below we are defining a class with a property which were introduced in python 2.6
However, pylint whines about the fact that in the __init__ method self.aProperty will overwrite the defined method named aProperty. I've also pasted the output from the console and the output of the pylint messages.
Is this a case of 'please report to the pylint devs' or is this piece of (example) code wrong?
"""example module"""
class Example(object):
"""example class"""
#property
def aProperty(self):
"""get"""
print "using getter"
return self._myPropertyValue
#aProperty.setter
def aProperty(self, value):
"""set"""
print "using setter"
self._myPropertyValue = value
def secondPublicMethodToIgnorePylintWarning(self):
"""dummy"""
return self.aProperty
def __init__(self):
"""init"""
self._myPropertyValue = None
self.aProperty = "ThisStatementWillRaise E0202"
anExample = Example()
print anExample.aProperty
anExample.aProperty = "Second binding"
print anExample.aProperty
Console Output:
using setter
using getter
ThisStatementWillRaise E0202
using setter
using getter
Second binding
Pylint Output:
E0202: 7,4:Example.aProperty: An attribute affected in test1 line 26 hide this method
E0202: 13,4:Example.aProperty: An attribute affected in test1 line 26 hide this method

see http://www.logilab.org/ticket/89092, a patch will soon be integrated into pylint to fix this pb

Related

How to properly silence mypy when you have a setter with a decorator?

Consider the following code, that is also basically the example given at https://pyro5.readthedocs.io/en/latest/servercode.html :
import Pyro5.server
class PyroService(object):
value = 42 # not exposed
def __dunder__(self): # exposed
pass
def _private(self): # not exposed
pass
def __private(self): # not exposed
pass
#Pyro5.server.expose
def get_value(self): # exposed
return self.value
#Pyro5.server.expose #type: ignore
#property
def attr(self): # exposed as 'proxy.attr' remote attribute
return self.value
#Pyro5.server.expose #type: ignore
#attr.setter
def attr(self, value): # exposed as 'proxy.attr' writable
self.value = value
a = PyroService()
a.attr = 5
When using mypy, there are several problems with this code.
We need to ignore the import Pyro5.server
Decorators on top of property are not supported. We need to include the #type: ignore (https://github.com/python/mypy/issues/1362)
Mypy has issues with setters (https://github.com/python/mypy/issues/1465).
This issue also appears in this case, even if the setter comes right after the getter.
So when using mypy ignoring the import, I still get the following error:
error: Property "attr" defined in "PyroService" is read-only [misc].
How do I properly fix this?

mypy reports errors on custom defined builtins

I'm using the gettext package to perform translations in the Python application. There's a custom Translation class which serves as a wrapper around strings and also defines a custom built-in function
class Wrapper:
def __init__(self, message: str):
self.message = message
#classmethod
def install(cls):
import builtins
builtins._ = cls
test = _('translate me')
When running mypy over this code I'm receiving the error
test.py: error: Name "_" is not defined
Is there a way to tell mypy abou the custom created built-in function?
In flake8 I was able to set a config with
[flake8]
builtins = _
If I understand well, you need something as:
_: Type[Wrapper]
test = _('translate me')

python Cmd module autocompletion error in nested interpreters

I'm trying to create a debug console for the main console I'm writing using Cmd module.
The debug console should have all the main console attributes and ontop some more extentions used for debug and advanced users.
The best answer to fir my needs was the second answer of the following post:
object inheritance and nested cmd
My implementation currently looks like this:
class MainConsole(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
def do_something(self, line):
print "do something!"
return
def do_something2(self, line):
print "do something2!"
return
class SubConsole1(cmd.Cmd):
def __init__(self, maincon):
cmd.Cmd.__init__(self)
self.maincon = maincon
self.register_main_console_methods()
def register_main_console_methods(self):
main_names = self.maincon.get_names()
for name in main_names:
if (name[:3] == 'do_') or (name[:5] == 'help_') or (name[:9] == 'complete_'):
self.__dict__[name] = getattr(self.maincon, name)
Observation:
When I hit "help", I indeed see all the upper console methods and I'm able to invoke them.
Problem:
The autocompletion of the actual commands is not available.
The expected behaviour of the shell when hitting "some" and tab would be to autocomplete it to "something". This doesn't happen.
When I tried to debug the issue, I found out that self.get_names() method which is used by the self.completenames() function returns the list of methods before the registration.
So what's actually happening is that the newly added methods are "removed" from the nested console, although I can invoke them.
I'd love some insights on that.
Thanks!
You can solve your problem by extending get_names method
import cmd
class MainConsole(cmd.Cmd):
def __init__(self,console_id):
cmd.Cmd.__init__(self)
self.console_id = console_id
def do_something(self, line):
print "do something!",self.console_id
return
def do_something2(self, line):
print "do something2!",self.console_id
return
class SubConsole1(cmd.Cmd):
def __init__(self, maincon):
cmd.Cmd.__init__(self)
self.maincon = maincon
self.register_main_console_methods()
def do_super_commands(self,line):
print "do supercommand",self.maincon
def register_main_console_methods(self):
main_names = dir(self.maincon)
for name in main_names:
for prefix in 'do_','help_','complete_', :
if name.startswith(prefix) and name not in dir(self):
self.__dict__[name] = getattr(self.maincon, name)
def get_names(self):
result = cmd.Cmd.get_names(self)
result+=self.maincon.get_names()
return result
SubConsole1(MainConsole("mainconsole")).cmdloop()
it is not guaranteed to work on subsequence version of python as it is undocumented behavior of python 2.7
EDIT: replacing the subclassing method by mainconsole as a member as required in comment
EDIT 2: don't replace the existing methods in SubConsole to keep method as do_help

python 2.6 exceptions.TypeError: unbound method _init_() ESMTP client instance

I am a completely new user to Python and BuildBot. Currently I am using an e-mail alert
when the BuildBot build status changes (moves from success to fail, or vice versa), and failing will e-mail every time there is a failed build. I am encountering the following Python error when sending an email is attempted.
--- <exception caught here> ---
**ESMTPClient.__init__(self, secret, contextFactory, *args, **kw)
exceptions.TypeError?: unbound method init() must be called with ESMTPClient
instance as first argument (got ESMTPSender instance instead)**
I have found some examples of this error online when searching for an answer, including
You just need to pass 'self' as an argument to 'Thread.init' and
calling the super class
but I am still unsure why there is an error. I would appreciate any guidance/help on why this error has occurred and how to go about resolving the issue. I am not the author of this code so I am unsure of what to be looking for to solve the problem.
The email was working before the following code was changed from gmail account to company account.
c['status'].append(mail.MailNotifier(
fromaddr="load.builder#company.co.uk",
extraRecipients=["example#company.com",
],
sendToInterestedUsers=False,
mode=('change', 'failing'),
relayhost="smtp.company.lan",
useTls=True,
smtpUser="lbuilder",
smtpPassword="password"))
Here's the block of code producing the exception:
class ESMTPSender(SenderMixin, ESMTPClient):
requireAuthentication = True
requireTransportSecurity = True
def __init__(self, username, secret, contextFactory=None, *args, **kw):
self.heloFallback = 0
self.username = username
if contextFactory is None:
contextFactory = self._getContextFactory()
ESMTPClient.__init__(self, secret, contextFactory, *args, **kw)
self._registerAuthenticators()
SSA
This seems like it would be a difficult exception to come by -- Generally you don't call __init__ explicitly unless you're inheriting from some other class. Here's one situation where you could get that error:
class Foo(object):
def __init__(self,*args):
print("In Foo, args:",args,type(self))
class Bar(object):
def __init__(self,*args):
Foo.__init__(self,*args) #Doesn't work. Complains that the object isn't the right type.
To fix this, we can make Bar inherit from Foo:
class Bar(Foo):
#^ Bar now inherits from Foo
def __init__(self,*args):
Foo.__init__(self,*args) #This will work now since a Bar instance is a Foo instance
If it doesn't make sense to have Bar subclassed from Foo, you can factor the common code out into a separate function:
def common_code(instance,*args):
print("Common code: args",args,type(instance))
class Foo(object):
def __init__(self,*args):
common_code(self,*args)
class Bar(object):
def __init__(self,*args):
common_code(self,*args)
Although this kind of problem can be difficult to diagnose without actually seeing the code which produces the error.

I have a Python code that is given below, when I run this global name PDBAttributes is not defined

#!/usr/bin/env python2.7
##-*- mode:python;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t;python-indent:2 -*-'
import noesy
import argparse
import library
parser =argparse.ArgumentParser(description="read pdb file",
add_help=True)
parser.add_argument("file",help="protein pdb file")
library.add_standard_args( parser )
args = parser.parse_args()
def read_structure(pdbfile):
struct=[]
for line in pdbfile:
if len(line):
struct.append(PDBAttributes.read_from_line(line))
return struct
pdb=read_structure(open(args.file,'r'))
class PDBAttributes:
def __init__(self, atomindex=1, atom=noesy.Atom(), atomx=1, atomy=1, atomz=1):
self._atomindex=atomindex
self._atom=atom
self._atomx=atomx
self._atomy=atomy
self._atomz=atomz
def __str__(self):
s='ATOM %(_atomindex)d %(_atom)s at %(_atomx)8.3f %(_atomy)8.3f %(_atomz)8.3f'%self.__dict__
return s
def atom(self):
return self._atom
def atomindex(self):
return self._atomindex
def atomx(self):
return self._atomx
def atomy(self):
return self._atomy
def atomz(self):
return self._atomz
#classmethod
def read_from_line(obj,line):
tags=line.split()
atomindex=int(tags[1])
atom=noesy.Atom(tags[2],int(tags[5]))
atomx=float(tags[6])
atomy=float(tags[7])
atomz=float(tags[8])
obj=PDBAttributes(atomindex, atom, atomx, atomy, atomz)
print obj
class AtomDistance(PDBAttributes):
def distance(self, atom1,atom2):
pass
The NameError you are getting is due to the order you have placed the code in your file.
When you call read_structure to create a value for the pdb variable, it tries to look for PDBAttributes, but it has not been defined yet. If you move that line lower down in the file (below the class definition) you'll avoid that error. Note that it is OK to have the declaration of read_structure above the PDBAttributes class definition, though you might want to move it lower too to make the code easier to understand.
Here's a very simple bit of code that demonstrates the same error:
def foo():
print(foo_text)
foo() # raises a NameError
foo_text = "foo"
Here's a fixed version:
def foo():
print(foo_text)
foo_text = "foo"
foo() # no error, prints "foo"
Move your call of read_structure to follow the definition of the PDBAttributes class.
Also, in the process of reformatting your post, I see that you have mixed tabs and spaces for your indentation. Try reformatting your code to use all spaces for indentation, the recommended form is 4-space indents.
Your definition of all those getter functions looks like Java written in Python - this is a lot of extra code that is often unnecessary in Python. The recommended approach is to omit these all-they-do-is-assign-a-value-to-an-attribute-with-the-same-name-but-with-a-leading-underscore methods and just use attributes with the public names. See Python is Not Java.

Categories