This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author xtreak
Recipients xtreak
Date 2018-10-30.12:32:56
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1540902777.26.0.788709270274.issue35113@psf.upfronthosting.co.za>
In-reply-to
Content
inspect.getsource uses inspect.findsource that uses a regex to check for class declaration and starts matching against the regex from the start of the program. When there is a match it checks for the first character to be 'c' to return the line number from which getblock is used to get the class definition. If there are multiple matches and there is no line with 'c' as the first character in the line then they are sorted based on the number of whitespaces preceding class keyword. This poses the following problem :

1. When a class definition like string occurs as part of a multiline string before the actual definition then this causes the function to return the multiline string instead of actual definition. This occurs both while using the multiline string also as comment and also using them in variable definition in other places.

2. When the class is defined inside another class and there is a similar multiline string inside another class which is indented along the same indentation level of the class then they are sorted by whitespace where they are equal and then followed by line number. Since the class definition occurs after the multiline string it causes the multiline string to be taken up as the source of the class.

This was last changed in 89f507fe8c4 (Dec 2006) which is also a merge commit. I searched for issues and relevant test cases but I couldn't find any in the test suite or issue tracker regarding the same. Hence I am filing a new issue.

# backups/bpo35101.py

import inspect

class Bar:
    a = """
class MultilineStringVariable:
    ...
"""

class MultilineStringVariable:

    def foo(self):
        pass

'''
class MultilineStringComment:
    pass
'''

class MultilineStringComment:

    def foo(self):
        pass

class NestedClass:
    a = '''
    class Spam:
        ...
    '''

class Nested:

    class Spam:
        pass

print(inspect.getsource(MultilineStringVariable))
print(inspect.getsource(MultilineStringComment))
print(inspect.getsource(Nested.Spam))

# Incorrect results

$ ./python.exe ../backups/bpo35101.py
class MultilineStringVariable:
    ...

class MultilineStringComment:
    pass

    class Spam:
        ...
History
Date User Action Args
2018-10-30 12:32:57xtreaksetrecipients: + xtreak
2018-10-30 12:32:57xtreaksetmessageid: <1540902777.26.0.788709270274.issue35113@psf.upfronthosting.co.za>
2018-10-30 12:32:57xtreaklinkissue35113 messages
2018-10-30 12:32:56xtreakcreate