sphinx-autoapi/autoapi/mappers/python.py

145 lines
4.0 KiB
Python
Raw Normal View History

import os
2015-04-08 05:54:53 +00:00
from collections import defaultdict
import textwrap
2015-04-08 05:54:53 +00:00
from .base import PythonMapperBase, SphinxMapperBase
from ..utils import slugify
from pydocstyle import parse
2015-08-05 17:09:07 +00:00
2015-04-21 05:54:32 +00:00
2015-06-10 21:23:50 +00:00
class PythonSphinxMapper(SphinxMapperBase):
2015-04-21 05:54:32 +00:00
'''Auto API domain handler for Python
Parses directly from Python files.
:param app: Sphinx application passed in as part of the extension
'''
def read_file(self, path, **kwargs):
'''Read file input into memory, returning deserialized objects
:param path: Path of file to read
'''
try:
parsed_data = parse(open(path), path)
return parsed_data
except IOError:
self.app.warn('Error reading file: {0}'.format(path))
except TypeError:
self.app.warn('Error reading file: {0}'.format(path))
except ImportError:
self.app.warn('Error reading file: {0}'.format(path))
return None
2015-06-10 21:23:50 +00:00
def create_class(self, data, options=None, **kwargs):
'''
Create a class from the passed in data
2015-04-21 05:54:32 +00:00
:param data: dictionary data of pydocstyle output
2015-04-21 05:54:32 +00:00
'''
obj_map = dict((cls.type, cls) for cls
in [PythonClass, PythonFunction, PythonModule, PythonMethod, PythonPackage])
try:
cls = obj_map[data.kind]
except KeyError:
self.app.warn("Unknown Type: %s" % data.kind)
else:
path = kwargs.get('path')
obj = cls(data, jinja_env=self.jinja_env,
options=self.app.config.autoapi_options, path=path
)
for child_data in data.children:
for child_obj in self.create_class(child_data, options=options, path=path):
obj.children.append(child_obj)
self.add_object(child_obj)
yield obj
2015-04-21 05:54:32 +00:00
2015-04-08 05:54:53 +00:00
2015-06-10 21:23:50 +00:00
class PythonPythonMapper(PythonMapperBase):
2015-04-08 05:54:53 +00:00
language = 'python'
def __init__(self, obj, **kwargs):
2015-06-10 21:23:50 +00:00
super(PythonPythonMapper, self).__init__(obj, **kwargs)
# Properly name the object with dot notation
if self.top_level_object:
name = self.path.relative.split('.')[0].replace('/', '.')
else:
name = '.'.join([
os.path.dirname(self.path.relative).replace('/', '.'),
obj.name
])
self.id = slugify(name)
self.name = name
2015-04-08 05:54:53 +00:00
2015-04-21 05:54:32 +00:00
# Optional
self.children = []
try:
args = obj.source.split('\n')[0]
args = args.split('(')[1]
args = args.split(')')[0]
self.args = args.split(',')
except:
args = ''
self.docstring = obj.docstring or ''
self.docstring = textwrap.dedent(self.docstring)
self.docstring = self.docstring.replace("'''", '').replace('"""', '')
if getattr(obj, 'parent'):
self.inheritance = [obj.parent.name]
else:
self.inheritance = ''
2015-04-08 05:54:53 +00:00
2015-04-21 05:54:32 +00:00
# For later
self.item_map = defaultdict(list)
2015-04-08 05:54:53 +00:00
def __repr__(self):
return 'Python {type}: {name}'.format(name=self.name, type=self.type)
@property
def undoc_member(self):
return self.docstring == ''
@property
def private_member(self):
return self.short_name[0] == '_'
@property
def special_member(self):
return self.short_name[0:2] == '__'
@property
def display(self):
if self.undoc_member and 'undoc-members' not in self.options:
return False
if self.private_member and 'private-members' not in self.options:
return False
if self.special_member and 'special-members' not in self.options:
return False
return True
2015-04-08 05:54:53 +00:00
2015-06-10 21:23:50 +00:00
class PythonFunction(PythonPythonMapper):
2015-04-21 05:54:32 +00:00
type = 'function'
2015-04-08 05:54:53 +00:00
2015-04-21 05:54:32 +00:00
class PythonMethod(PythonPythonMapper):
type = 'method'
2015-06-10 21:23:50 +00:00
class PythonModule(PythonPythonMapper):
2015-04-21 05:54:32 +00:00
type = 'module'
top_level_object = True
2015-04-21 05:54:32 +00:00
class PythonPackage(PythonPythonMapper):
type = 'package'
top_level_object = True
2015-06-10 21:23:50 +00:00
class PythonClass(PythonPythonMapper):
2015-04-21 05:54:32 +00:00
type = 'class'