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.

Title: inspect.getsourcelines ignores context and returns wrong line #
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.4
Status: closed Resolution: duplicate
Dependencies: Superseder: inspect.getsource returns incorrect source for classes when class definition is part of multiline strings
View: 35113
Assigned To: Nosy List: iritkatriel, jedwards, pitrou, rhettinger, siming85, xtreak, yselivanov
Priority: normal Keywords:

Created on 2015-04-29 23:04 by siming85, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (6)
msg242254 - (view) Author: Siming Yuan (siming85) * Date: 2015-04-29 23:04
if the same class name is used within a module, but defined in different contexts (either class in class or class in function), inspect.getsourcelines() on the class object ignores the object context and only returns the first matched name.

class A(object):
    class B(object):

class C(object):
    class B(object):

>>> import inspect
>>> import a
>>> inspect.getsourcelines(a.C.B)
(['    class B(object):\n', '        pass\n'], 2)
msg242255 - (view) Author: Siming Yuan (siming85) * Date: 2015-04-29 23:08
according to line 675 - this is only a best effort.

is this intended? @ 672
    if isclass(object):
        name = object.__name__
        pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
        # make some effort to find the best matching class definition:
        # use the one with the least indentation, which is the one
        # that's most probably not inside a function definition.
        candidates = []
        for i in range(len(lines)):
            match = pat.match(lines[i])
            if match:
                # if it's at toplevel, it's already the best one
                if lines[i][0] == 'c':
                    return lines, i
                # else add whitespace to candidate list
                candidates.append((, i))
        if candidates:
            # this will sort by whitespace, and by line number,
            # less whitespace first
            return lines, candidates[0][1]
            raise OSError('could not find class definition')
msg242335 - (view) Author: James Edwards (jedwards) * Date: 2015-05-01 17:14
Inspect could probably be updated to use 3.3's __qualname__ in the case of classes-in-classes; classes-in-functions or functions-in-functions would likely be harder, but I'm not sure it's impossible.
msg242337 - (view) Author: James Edwards (jedwards) * Date: 2015-05-01 17:18
Added Yury (inspect module) and Antoine (PEP 3155) to nosy -- apologies  if you're not interested.
msg377124 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2020-09-18 15:15
I think this was fixed under issue35113.
msg377150 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2020-09-19 05:18
Thanks iritkatriel for triaging. I can confirm it's fixed with the linked issue. Closing it as duplicate.

Python 3.10.0a0 (heads/master:2b05361bf7, Sep 19 2020, 04:38:05) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import inspect, a
>>> inspect.getsourcelines(a.C.B)
(['    class B(object):\n', '        pass\n'], 6)
Date User Action Args
2022-04-11 14:58:16adminsetgithub: 68266
2020-09-19 05:18:22xtreaksetstatus: open -> closed
superseder: inspect.getsource returns incorrect source for classes when class definition is part of multiline strings
messages: + msg377150

resolution: duplicate
stage: resolved
2020-09-18 15:15:10iritkatrielsetnosy: + iritkatriel, xtreak
messages: + msg377124
2015-05-08 20:49:16rhettingersetnosy: + rhettinger
2015-05-01 17:18:26jedwardssetmessages: + msg242337
2015-05-01 17:16:14jedwardssetnosy: + pitrou, yselivanov
2015-05-01 17:14:09jedwardssetnosy: + jedwards
messages: + msg242335
2015-04-29 23:08:48siming85setmessages: + msg242255
2015-04-29 23:04:32siming85create