def parse_dynamic_calldefs(modpath=None):
from xdoctest import static_analysis as static<EOL>from xdoctest import utils  <EOL>module = utils.import_module_from_path(modpath)<EOL>calldefs = {}<EOL>if getattr(module, '<STR_LIT>'):<EOL><INDENT>calldefs['<STR_LIT>'] = static.CallDefNode(<EOL>callname='<STR_LIT>',<EOL>docstr=module.__doc__,<EOL>lineno=<NUM_LIT:0>,<EOL>doclineno=<NUM_LIT:1>,<EOL>doclineno_end=<NUM_LIT:1>,<EOL>args=None<EOL>)<EOL><DEDENT>for key, val in iter_module_doctestables(module):<EOL><INDENT>if hasattr(val, '<STR_LIT>') and hasattr(val, '<STR_LIT>'):<EOL><INDENT>calldefs[key] = static.CallDefNode(<EOL>callname=val.__name__,<EOL>docstr=val.__doc__,<EOL>lineno=<NUM_LIT:0>,<EOL>doclineno=<NUM_LIT:1>,<EOL>doclineno_end=<NUM_LIT:1>,<EOL>args=None<EOL>)<EOL><DEDENT><DEDENT>return calldefs<EOL>
Dynamic parsing of module doctestable items.

While this does execute module code it is needed for testing extension
libraries.

CommandLine:
    python -m xdoctest.dynamic_analysis parse_dynamic_calldefs

Example:
    >>> from xdoctest import dynamic_analysis
    >>> module = dynamic_analysis
    >>> calldefs = parse_dynamic_calldefs(module.__file__)
    >>> for key, calldef in sorted(calldefs.items()):
    ...     print('key = {!r}'.format(key))
    ...     print(' * calldef.callname = {}'.format(calldef.callname))
    ...     if calldef.docstr is None:
    ...         print(' * len(calldef.docstr) = {}'.format(calldef.docstr))
    ...     else:
    ...         print(' * len(calldef.docstr) = {}'.format(len(calldef.docstr)))