@@ -639,6 +639,21 @@ def cleandoc(doc):
639
639
lines .pop (0 )
640
640
return '\n ' .join (lines )
641
641
642
+ def _get_code_object (obj ):
643
+ """Walk through a callable or frame to find the code object"""
644
+ if ismethod (obj ):
645
+ obj = obj .__func__
646
+ if isfunction (obj ):
647
+ obj = unwrap (obj )
648
+ obj = obj .__code__
649
+ if istraceback (obj ):
650
+ obj = obj .tb_frame
651
+ if isframe (obj ):
652
+ obj = obj .f_code
653
+ if iscode (obj ):
654
+ return obj
655
+ raise TypeError
656
+
642
657
def getfile (object ):
643
658
"""Work out which source or compiled file an object was defined in."""
644
659
if ismodule (object ):
@@ -651,19 +666,13 @@ def getfile(object):
651
666
if hasattr (object , '__file__' ):
652
667
return object .__file__
653
668
raise TypeError ('{!r} is a built-in class' .format (object ))
654
- if ismethod (object ):
655
- object = object .__func__
656
- if isfunction (object ):
657
- object = object .__code__
658
- if istraceback (object ):
659
- object = object .tb_frame
660
- if isframe (object ):
661
- object = object .f_code
662
- if iscode (object ):
663
- return object .co_filename
664
- raise TypeError ('module, class, method, function, traceback, frame, or '
665
- 'code object was expected, got {}' .format (
666
- type (object ).__name__ ))
669
+
670
+ try :
671
+ return _get_code_object (object ).co_filename
672
+ except TypeError :
673
+ raise TypeError ('module, class, method, function, traceback, frame, or '
674
+ 'code object was expected, got {}' .format (
675
+ type (object ).__name__ )) from None
667
676
668
677
def getmodulename (path ):
669
678
"""Return the module name for a given file, or None."""
@@ -811,24 +820,19 @@ def findsource(object):
811
820
else :
812
821
raise OSError ('could not find class definition' )
813
822
814
- if ismethod (object ):
815
- object = object .__func__
816
- if isfunction (object ):
817
- object = object .__code__
818
- if istraceback (object ):
819
- object = object .tb_frame
820
- if isframe (object ):
821
- object = object .f_code
822
- if iscode (object ):
823
- if not hasattr (object , 'co_firstlineno' ):
824
- raise OSError ('could not find function definition' )
825
- lnum = object .co_firstlineno - 1
826
- pat = re .compile (r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)' )
827
- while lnum > 0 :
828
- if pat .match (lines [lnum ]): break
829
- lnum = lnum - 1
830
- return lines , lnum
831
- raise OSError ('could not find code object' )
823
+ try :
824
+ object = _get_code_object (object )
825
+ except TypeError :
826
+ raise OSError ('could not find code object' ) from None
827
+
828
+ if not hasattr (object , 'co_firstlineno' ):
829
+ raise OSError ('could not find function definition' )
830
+ lnum = object .co_firstlineno - 1
831
+ pat = re .compile (r'^(\s*def\s)|(\s*async\s+def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)' )
832
+ while lnum > 0 :
833
+ if pat .match (lines [lnum ]): break
834
+ lnum = lnum - 1
835
+ return lines , lnum
832
836
833
837
def getcomments (object ):
834
838
"""Get lines of comments immediately preceding an object's source code.
@@ -951,7 +955,6 @@ def getsourcelines(object):
951
955
corresponding to the object and the line number indicates where in the
952
956
original source file the first line of code was found. An OSError is
953
957
raised if the source code cannot be retrieved."""
954
- object = unwrap (object )
955
958
lines , lnum = findsource (object )
956
959
957
960
if ismodule (object ):
0 commit comments