core

Create a list of symbols in a python package

Format Symbols

Once you collect symbols, you want to format it as a markdown list


source

format_symbol

def format_symbol(
    name, signature, doc, decorators:NoneType=None, is_method:bool=False
):

format the information in markdown

Parse Symbols In The Module

Next we parse symbols in the module that we want to list.


source

log_error

def log_error(
    name, error
):

Call self as a function.


source

get_decorators

def get_decorators(
    obj
):

Call self as a function.


source

is_valid_method

def is_valid_method(
    method, method_name
):

Call self as a function.


source

is_public_symbol

def is_public_symbol(
    name
):

Call self as a function.


source

get_params

def get_params(
    func
):

Call self as a function.


source

process_function

def process_function(
    func, name, include_no_docstring
):

Parse functions


source

process_class

def process_class(
    cls, name, include_no_docstring
):

Parse classes.

For example, this is how a Class will be parsed:

mock_class = extract_node('''
@decorator
class TestClass:
    """
    Class docstring
    with multiple lines
    """
    @staticmethod
    def method1(arg1):
        """
        Method1 docstring
        with multiple lines
        """
        pass
    def method2(self):
        """Single line docstring"""
        pass
    
    @property
    def myprop(self):
        "My docstring"
        return 'isaac'
''')

# Process the class
result = process_class(mock_class, "TestClass", True)

# # Test equality
# test_eq(result, (
#     'class',
#     'TestClass',
#     '\n    Class docstring\n    with multiple lines\n    ',
#     ['decorator'],
#     [
#         ('method1', 'method1(arg1)', '\n        Method1 docstring\n        with multiple lines\n        ', ['staticmethod']),
#         ('method2', 'method2(self)', 'Single line docstring', [])
#     ]
# ))
result
('class',
 'TestClass',
 '\n    Class docstring\n    with multiple lines\n    ',
 ['decorator'],
 [('method1',
   'method1(arg1)',
   '\n        Method1 docstring\n        with multiple lines\n        ',
   ['staticmethod']),
  ('method2', 'method2(self)', 'Single line docstring', []),
  ('myprop', 'myprop', 'My docstring', ['property'])])

source

process_enum

def process_enum(
    cls, name, include_no_docstring
):

Parse Enum classes


source

is_enum_builtin

def is_enum_builtin(
    name
):

Check if a name is a built-in enum property

code1 = """
class Color(Enum):
    "A enum for selecting colors"
    RED='red'
    BLUE='blue'
    GREEN='green'
    
    def get_color(self): 
        "Color method for testing"
        return self.value
    
    @property
    def get_name(self): 
        "name property for testing"
        return self.value
"""
code2 = """
class VEnum(Enum):
    def __str__(self): pass

class Size(VEnum):
    "A size picker"
    small='small'
    medium='medium'
    large='large'
"""

result1 = process_enum(extract_node(code1), "Color", True)
result2 = process_enum(extract_node(code2), "Size", True)
print(result1)
print(result2)
('enum', 'Color', (['RED', 'BLUE', 'GREEN'], [('get_color', 'get_color(self)', 'Color method for testing', []), ('get_name', 'get_name', 'name property for testing', ['property'])]), 'A enum for selecting colors', [])
('enum', 'Size', (['small', 'medium', 'large'], []), 'A size picker', [])

source

get_public_symbols

def get_public_symbols(
    module, include_no_docstring
):

Extract all public symbols


source

get_public_symbols

def get_public_symbols(
    module, include_no_docstring
):

Extract all public symbols


source

format_enum

def format_enum(
    name, members_and_methods, doc, decorators:NoneType=None
):

Format an enum class in markdown

_sym = get_public_symbols(parse(code1), False)[0]
print(format_enum(_sym[1], _sym[2], _sym[3]))
- `class Color(Enum)`
    A enum for selecting colors
    Members: RED, BLUE, GREEN

    - `get_color(self)`
        Color method for testing

    - `@property get_name`
        name property for testing



source

generate_markdown

def generate_markdown(
    package_name, include_no_docstring, verbose:bool=False
):

Call self as a function.

Here is a preview of the fastcore library, for instance:

_md = generate_markdown('fastcore', False)
_lns = _md.splitlines()
print('\n'.join([x for x in _lns][:20]))
# fastcore Module Documentation

## fastcore.aio

> Bridging async and sync code: `run_sync`, `iter_sync`, `ctx_sync`, `maybe_await`, and `then`
> 
> Docs: https://fastcore.fast.ai/aio.html.md

- `def run_sync(coro)`
    Run coroutine `coro` to completion from sync code and return its result

- `def iter_sync(agen)`
    Iterate async generator `agen` from sync code

- `@contextmanager def ctx_sync(acm)`
    Use async context manager `acm` in a plain `with` block

- `def maybe_await(o)`
    Await `o` if needed, and return it

Write markdown to file

We can generate our list of symbols as a markdown file like so:


source

pysym2md

def pysym2md(
    package_name:str, # Name of the Python package
    include_no_docstring:store_true=False, # Include symbols without docstrings?
    verbose:store_true=False, # Turn on verbose logging?
    output_file:str='filelist.md', # The output file
):

Generate a list of symbols corresponding to a python package in a markdown format.

pysym2md('fastcore')