@@ -40,6 +40,18 @@ def filepath(self, filepath: Union[str, Path]):
4040 filepath = Path (filepath )
4141 self ._filepath = filepath
4242
43+ @staticmethod
44+ def is_docstring (content :str )-> bool :
45+ if not content :
46+ return False
47+
48+ stripped = content .strip ()
49+ if stripped .startswith ('"""' ) and stripped .endswith ('"""' ):
50+ return True
51+ elif stripped .startswith ("'''" ) and stripped .endswith ("'''" ):
52+ return True
53+ return False
54+
4355 @staticmethod
4456 def import_statement_template (importSatement :ImportStatement )-> str :
4557 statement = f"import { importSatement .source or importSatement .name } "
@@ -312,19 +324,29 @@ def _process_decorated_definition(cls, node: Node, code: bytes, codeFile: CodeFi
312324 decorators .append (cls ._get_content (code , child ))
313325 elif child .type == "function_definition" :
314326 cls ._process_function_definition (child , code , codeFile , is_class_method = is_class_method , decorators = decorators , raw = raw )
327+
328+ @classmethod
329+ def _get_docstring_from_block (cls , node : Node , code : bytes )-> Optional [str ]:
330+ for child in node .children :
331+ if child .type == "expression_statement" :
332+ candidate = cls ._get_content (code , child , preserve_indentation = True )
333+ if cls .is_docstring (candidate ):
334+ return candidate
335+ return None
336+
315337
316338 @classmethod
317339 def _process_function_definition (cls , node : Node , code : bytes , codeFile : CodeFileModel , is_class_method :bool = False , decorators :Optional [List [str ]]= None , raw :Optional [str ]= None ):
318340 # print(node.type, cls._get_content(code, node))
319341 definition = None
342+ docstring = None
320343 signature = FunctionSignature ()
321344 modifiers = []
322345
323346
324347 if decorators is None :
325348 decorators = []
326349
327- ### TODO add logic to extract modifiers i.e. async
328350 for child in node .children :
329351 if child .type == "identifier" :
330352 definition = cls ._get_content (code , child )
@@ -335,6 +357,8 @@ def _process_function_definition(cls, node: Node, code: bytes, codeFile: CodeFil
335357 signature .parameters = cls ._process_parameters (child , code )
336358 elif child .type == "type" :
337359 signature .return_type = cls ._get_content (code , child )
360+ elif child .type == "block" :
361+ docstring = cls ._get_docstring_from_block (child , code )
338362
339363 if is_class_method :
340364 if raw is None :
@@ -345,6 +369,7 @@ def _process_function_definition(cls, node: Node, code: bytes, codeFile: CodeFil
345369 signature = signature ,
346370 decorators = decorators ,
347371 modifiers = modifiers ,
372+ docstring = docstring ,
348373 raw = raw
349374 )
350375 )
@@ -361,6 +386,7 @@ def _process_function_definition(cls, node: Node, code: bytes, codeFile: CodeFil
361386 signature = signature ,
362387 decorators = decorators ,
363388 modifiers = modifiers ,
389+ docstring = docstring ,
364390 raw = raw
365391 )
366392 )
0 commit comments