sds
sds

Reputation: 60054

pylint: Class 'message' has no 'startswith' member

For some reason, pylint 1.6.4 (astroid 1.4.9) does not like this:

try:
    some_package.their_function()
except Exception as ex:
    if ex.message.startswith(...):
        ...

It complains:

error (E1101, no-member, feed_sentiment) Class 'message' has no 'startswith' member

I find this surprising because:

>>> type(Exception("foo").message)
<type 'str'>
>>> Exception("foo").message.startswith
<built-in method startswith of str object at 0x10520d360>

I think this is a bug in pylint.

However, am I doing something wrong? What is the "pythonic" way here?

PS. Yes, I know that the right way is to define my own exception subclass, but I have no control over some_package.

PPS. Yes, I know I can annotate the code with pylint: disable=no-member.

Upvotes: 5

Views: 487

Answers (2)

MSeifert
MSeifert

Reputation: 152775

The pythonic way would be to convert the ex to a str explicitly because that also converts the message to a string:

try:
    some_package.their_function()
except Exception as ex:
    if str(ex).startswith(...):  # or "if something in str(ex)":

The problem with Exception.message is that it may not be a str:

>>> try:
...     raise ValueError(1.2)
... except Exception as ex:
...     print ex
...     print type(ex.message)
...     print repr(str(ex))  # force it to be a string
...     print hasattr(ex.message, 'startswith')
ValueError(1.2,)
<type 'float'>
'1.2'
False

It's good style and highly advisable that you use strs as message but that is by no means guaranteed!

Upvotes: 0

Łukasz Rogalski
Łukasz Rogalski

Reputation: 23243

This is indeed a bug in astroid - a pylint's internal library used for building abstract syntax trees and value inference.

import astroid

node = astroid.builder.parse("""
    ex = Exception()
    msg = ex.message
""")
print list(node.locals['msg'][0].infer())

Output from this code snippet is:

[<ClassDef(message) l.0 [exceptions] at 0x34aadd0>, <ClassDef(message) l.0 [exceptions] at 0x3482cb0>]

Output means that message attribute on exception instance is inferred as custom class definition, and not string instance.

Thanks for submitting a bug!

Upvotes: 1

Related Questions