summaryrefslogtreecommitdiff
path: root/paste
diff options
context:
space:
mode:
Diffstat (limited to 'paste')
-rw-r--r--paste/docsupport/__init__.py1
-rw-r--r--paste/docsupport/extract.py355
-rw-r--r--paste/docsupport/findmodules.py33
-rwxr-xr-xpaste/docsupport/gensite.py146
-rw-r--r--paste/docsupport/metadata.py19
-rw-r--r--paste/docsupport/metadata_real.py118
6 files changed, 0 insertions, 672 deletions
diff --git a/paste/docsupport/__init__.py b/paste/docsupport/__init__.py
deleted file mode 100644
index 792d600..0000000
--- a/paste/docsupport/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-#
diff --git a/paste/docsupport/extract.py b/paste/docsupport/extract.py
deleted file mode 100644
index 3837863..0000000
--- a/paste/docsupport/extract.py
+++ /dev/null
@@ -1,355 +0,0 @@
-# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-
-if __name__ == '__main__':
- # This has to be done very early on, to make the real module
- # replace the stubby version
- from paste.docsupport import metadata_real
- metadata_real.install()
-
-import types
-import inspect
-from cStringIO import StringIO
-import textwrap
-import re
-import findmodules
-
-from paste.docsupport import metadata
-from paste.util.classinit import ClassInitMeta
-from paste.httpexceptions import HTTPException
-
-extractors = []
-
-class Extractor(object):
-
- __metaclass__ = ClassInitMeta
- match_type = None
- match_level = None
-
- def __classinit__(cls, new_attrs):
- if cls.__bases__ != (object,):
- if cls.match_level is None:
- extractors.append(cls)
- else:
- extractors.insert(cls.match_level, cls)
-
- def __init__(self, obj, context):
- self.obj = obj
- self.context = context
-
- def extract(self):
- raise NotImplementedError
-
- def applies(cls, obj, context):
- return isinstance(obj, cls.match_type)
- applies = classmethod(applies)
-
-class ModuleExtractor(Extractor):
-
- match_type = types.ModuleType
-
- def extract(self):
- objs = getattr(self.obj, '__all__', [])
- if not objs:
- return
- self.context.writeheader(self.obj.__name__, type='Module')
- self.context.writedoc(self.obj.__doc__)
- for name in objs:
- self.context.push_name(name)
- self.context.extract(getattr(self.obj, name))
- self.context.pop_name(name)
- self.context.endheader()
-
-class ClassExtractor(Extractor):
-
- match_type = (type, types.ClassType)
-
- def extract(self):
- self.context.writeheader(self.context.last_name, type='Class')
- self.context.writedoc(self.obj.__doc__)
- attrs = self.getattrs(self.obj)
- for name, value in attrs:
- self.context.push_name(name)
- self.context.extract(value)
- self.context.pop_name(name)
- methods = self.getmethods(self.obj)
- for name, value in methods:
- self.context.push_name(name)
- self.context.extract(value)
- self.context.pop_name(name)
- self.context.endheader()
-
- def getattrs(self, cls):
- bases = inspect.getmro(cls)
- attrs = {}
- for i, base in enumerate(bases):
- for name, value in base.__dict__.items():
- if not isinstance(value, metadata.DocItem):
- continue
- if name in attrs:
- continue
- attrs[name] = (i, value.__creationorder__, value)
- attrs = attrs.items()
- attrs.sort(lambda a, b: cmp(a[1], b[1]))
- return [
- (m[0], m[1][2]) for m in attrs]
-
- def getmethods(self, cls):
- bases = inspect.getmro(cls)
- methods = {}
- for i, base in enumerate(bases):
- if base.__dict__.has_key('__all__'):
- all = base.__all__ or []
- else:
- all = None
- for name, value in base.__dict__.items():
- if all is not None and name not in all:
- continue
- if not isinstance(value, types.FunctionType):
- continue
- if name in methods:
- continue
- methods[name] = (i, value.func_code.co_firstlineno, value)
- methods = methods.items()
- methods.sort(lambda a, b: cmp(a[1], b[1]))
- return [
- (m[0], m[1][2]) for m in methods]
-
-class DetectedExtractor(Extractor):
-
- def applies(cls, obj, context):
- return isinstance(obj, metadata.DocItem)
- applies = classmethod(applies)
-
- def extract(self):
- self.obj.writeto(self.context)
-
-class MethodExtractor(Extractor):
-
- match_type = types.FunctionType
-
- def extract(self):
- if not self.obj.__doc__:
- return
- sig = self.make_sig()
- self.context.writekey('def %s(%s)' % (self.obj.func_name, sig),
- monospace=True)
- self.context.writedoc(self.obj.__doc__)
- if self.get_attr('proxy'):
- self.context.writedoc(self.get_attr('proxy').__doc__)
- if getattr(self.obj, 'returns', None):
- returns = self.obj.returns
- if isinstance(returns, str):
- returns = self.obj.func_globals[returns]
- self.context.extract(self.obj.returns)
- self.context.endkey()
-
- def make_sig(self):
- proxy = self.get_attr('proxy')
- args, varargs, varkw, defaults = inspect.getargspec(
- proxy or self.obj)
- sig = []
- args.reverse()
- for arg in args:
- if defaults:
- sig.append('%s=%r' % (arg, defaults[-1]))
- defaults = defaults[:-1]
- else:
- sig.append(arg)
- sig.reverse()
- if varargs:
- sig.append('*%s' % varargs)
- if varkw:
- sig.append('**%s' % varkw)
- return ', '.join(sig)
-
- def get_attr(self, attr):
- if not getattr(self.obj, attr, None):
- return None
- value = getattr(self.obj, attr)
- if isinstance(value, str):
- value = self.obj.func_globals[value]
- return value
-
-class HTTPExtractor(Extractor):
-
- match_level = 0
-
- def extract(self):
- self.context.writekey(self.obj.__name__)
- self.context.write('%s %s\n' % (self.obj.code, self.obj.title))
- self.context.endkey()
-
- def applies(cls, obj, context):
- return (isinstance(obj, types.ClassType)
- and issubclass(obj, HTTPException))
- applies = classmethod(applies)
-
-############################################################
-## Context
-############################################################
-
-class DocContext(object):
-
- headerchars = '+=-~.\'_`'
-
- def __init__(self):
- self.out = StringIO()
- self.header_level = 0
- self.indent_level = 0
- self.names = []
- self.need_break = False
- self.indexes = {}
-
- def push_name(self, name):
- self.names.append(name)
-
- def pop_name(self, name=None):
- if name is not None:
- assert self.names[-1] == name, (
- "Out of order pop (popping %r; expected %r)"
- % (self.names[-1], name))
- self.names.pop()
-
- def last_name__get(self):
- return self.names[-1]
- last_name = property(last_name__get)
-
- def writeheader(self, name, type=None):
- self.need_break = False
- if self.indent_level:
- self.writekey(name, type=type, monospace=False)
- return
- if type:
- name = '%s: %s' % (type, name)
- self.write(name + '\n')
- self.write(self.headerchars[self.header_level]
- * len(name))
- self.write('\n\n')
- self.header_level += 1
-
- def endheader(self):
- if self.indent_level:
- self.endkey()
- return
- self.header_level -= 1
- assert self.header_level >= 0, (
- "Too many endheader() calls.")
- self.need_break = True
-
- def writedoc(self, doc):
- if doc is None:
- return
- doc = self.clean(doc)
- if not doc:
- return
- self.write(doc)
- self.write('\n\n')
-
- def writelist(self, seq, header=None, with_titles=False):
- seq = list(seq)
- if not seq:
- return
- if header:
- self.writeheader(header)
- for name, value in seq:
- if with_titles:
- self.writeheader(name)
- value.write(self)
- if with_titles:
- self.endheader()
- if header:
- self.endheader()
-
- def writekey(self, key, type=None, monospace=True):
- if monospace:
- key = '``%s``' % key
- if type:
- key = '%s: %s' % (type, key)
- self.write('%s:\n' % key)
- self.indent_level += 2
-
- def endkey(self):
- self.indent_level -= 2
- assert self.indent_level >= 0, (
- "Too many endkeys or dedents (indent %s)" % self.indent_level)
-
- def addindex(self, index_type, name, description=None):
- full_name = '%s.%s' % (index_type, name)
- self.write('.. _%s:\n\n' % full_name)
- self.indexes.setdefault(index_type, []).append(
- (name, description))
-
- def write(self, s):
- if self.need_break:
- self.out.write('\n\n%s\n\n' % ('-'*40))
- self.need_break = False
- if self.indent_level:
- self.out.write(self.indent(s, self.indent_level))
- else:
- self.out.write(s)
-
- def clean(self, s):
- return textwrap.dedent(s).rstrip().lstrip('\n')
-
- def indent(self, s, indent=2):
- new = '\n'.join([' '*indent + l for l in s.splitlines()])
- if s.endswith('\n'):
- new += '\n'
- return new
-
- def capture(self, obj):
- old_out = self.out
- self.out = StringIO()
- obj.write(self)
- result = self.out.getvalue()
- self.out = old_out
- return result
-
- def extract(self, obj):
- for extractor in extractors:
- if extractor.applies(obj, self):
- ext = extractor(obj, self)
- ext.extract()
- break
- else:
- print >> sys.stderr, 'No extractor applies to %r\n' % obj
-
- def close(self):
- self.writeindexes()
-
- def writeindexes(self):
- index_types = self.indexes.keys()
- index_types.sort()
- for index_type in index_types:
- self.writeindex(index_type, self.indexes[index_type])
-
- def writeindex(self, index_type, indexes):
- indexes.sort()
- self.writeheader('Index: %s' % index_type)
- for n, (name, description) in enumerate(indexes):
- self.write('* `%s <#%s>`_\n'
- % (description or name,
- self.munge_link(index_type + '.' + name)))
- self.write('\n')
- self.endheader()
-
- def munge_link(self, link):
- link = link.lower()
- link = re.sub(r'[ ._-]+', '-', link)
- link = re.sub(r'[^a-z0-9-]', '', link)
- return link
-
-def build_doc(package):
- context = DocContext()
- for module in findmodules.find_modules(package):
- context.extract(module)
- context.close()
- return context.out.getvalue()
-
-if __name__ == '__main__':
- import sys
- from paste.util.import_string import import_module
- base = import_module(sys.argv[1])
- print build_doc(base)
-
diff --git a/paste/docsupport/findmodules.py b/paste/docsupport/findmodules.py
deleted file mode 100644
index d917291..0000000
--- a/paste/docsupport/findmodules.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-
-"""
-Finds all modules in a packages, loads them, and returns them.
-"""
-
-import os
-import re
-from paste.util.import_string import import_module
-
-module_name = re.compile(r'^[a-zA-Z][a-zA-Z0-9_]*$')
-
-def find_modules(package):
- pkg_name = package.__name__
- modules = []
- base = os.path.abspath(package.__file__)
- if os.path.basename(os.path.splitext(base)[0]) == '__init__':
- base = os.path.dirname(base)
- if os.path.isdir(base):
- for module_fn in os.listdir(base):
- base, ext = os.path.splitext(module_fn)
- full = os.path.join(base, module_fn)
- if not module_name.search(base):
- continue
- if (os.path.isdir(full)
- and os.path.exists(os.path.join(full, '__ini__.py'))):
- modules.extend(import_module(pkg_name + '.' + base))
- elif ext == '.py':
- modules.append(import_module(pkg_name + '.' + base))
- else:
- modules.append(package)
- return modules
diff --git a/paste/docsupport/gensite.py b/paste/docsupport/gensite.py
deleted file mode 100755
index a5f4459..0000000
--- a/paste/docsupport/gensite.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-
-#!/usr/bin/env python
-"""
-This is a very basic script to generate a site from a set of ReST
-documents.
-"""
-
-import os
-import re
-import shutil
-import optparse
-from Cheetah.Template import Template
-from paste import pyconfig
-
-__version__ = '0.1'
-
-parser = optparse.OptionParser(
- version=__version__,
- usage="%prog [OPTIONS]")
-
-parser.add_option(
- '-f', '--config-file',
- dest='config_file',
- metavar='FILENAME',
- default='doc.conf',
- help="The configuration file to load (default doc.conf)")
-
-def main():
- options, args = parser.parse_args()
- assert not args, (
- "No arguments are allowed")
- conf = pyconfig.Config(with_default=True)
- conf.load_dict({'dirs': {},
- 'dest_base': os.getcwd()})
- conf.load(options.config_file)
- dirs = conf['dirs']
- base = conf['dest_base']
- for source, dest in dirs.items():
- dirs[source] = os.path.join(base, dest)
- gen_site(conf)
-
-def gen_site(conf):
- template = make_template(conf)
- files = find_files(conf)
- for source, dest in files.items():
- if not source.endswith('.html'):
- shutil.copyfile(source, dest)
- continue
- f = RestFile(source)
- template.ns.clear()
- f.update_ns(template.ns)
- content = str(template)
- print 'Writing %s (%i bytes)' % (os.path.basename(source), len(content))
- dest_dir = os.path.dirname(dest)
- if not os.path.exists(dest_dir):
- print 'Creating %s' % dest_dir
- os.makedirs(dest_dir)
- f = open(dest, 'w')
- f.write(content)
- f.close()
-
-def find_files(conf):
- files = {}
- for source, dest in conf['dirs'].items():
- find_files_dir(source, dest, conf, files)
- return files
-
-def find_files_dir(source, dest, conf, files):
- for name in os.listdir(source):
- source_fn = os.path.join(source, name)
- if os.path.isdir(source_fn):
- continue
- files[source_fn] = os.path.join(os.path.join(dest, name))
-
-def make_template(conf):
- template_fn = os.path.join(os.getcwd(), conf['template'])
- ns = {}
- template = Template(
- file=template_fn, searchList=[ns])
- template.ns = ns
- return template
-
-class RestFile(object):
-
- def __init__(self, fn):
- self.filename = fn
- f = open(fn)
- self.html = f.read()
- f.close()
- self.read_properties()
- self.read_content()
-
- def update_ns(self, ns):
- ns['file'] = self
- ns['content'] = self.content
- ns.update(self.properties)
-
- _title_re = re.compile(r'<title>(.*?)</title>')
- def read_properties(self):
- props = self.properties = {}
- m = self._title_re.search(self.html)
- if m:
- props['title'] = m.group(1)
- else:
- print 'No title in %s' % self.filename
- props['title'] = ''
-
- #_start_re = re.compile(r'<div class=".*?" id="contents">')
- _start_re = re.compile(r'<body>[ \n]*(?:<div.*?>[ \n]*)?<h1.*?>.*?</h1>')
- _end_re = re.compile(r'(?:</div>[ \n]*)?</div>[ \n]*</body>[\n\r ]*</html>[\n\r ]*$')
- _bad_res = [
- (re.compile(r'<link rel="stylesheet".*?>'), ''),
- (re.compile(r'<h1 class="title">.*?</h1>'), ''),
- (re.compile(r'(<p class=".*?"><a name="contents">.*?</p>)[ \n]*'
- r'(<ul class="simple">)'),
- '<div><ul class="simple contents">\n'
- '<li class="header">Contents</li>\n'),
- (re.compile(r'(<th class="docinfo-name">Date:</th>[ \n]*)'
- r'(<td>).*?\((.*?)\)'),
- r'\1\2\3'),
- ]
-
- def read_content(self):
- c = self.html
- m = self._start_re.search(c)
- if m:
- c = c[m.end():]
- else:
- print 'Bad beginning in %s' % self.filename
- m = self._end_re.search(c)
- if m:
- c = c[:m.start()]
- else:
- print 'Bad ending in %s' % self.filename
- for regex, sub in self._bad_res:
- c = regex.sub(sub, c)
- self.content = c
-
- def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, self.filename)
-
-if __name__ == '__main__':
- main()
-
diff --git a/paste/docsupport/metadata.py b/paste/docsupport/metadata.py
deleted file mode 100644
index a0e71c4..0000000
--- a/paste/docsupport/metadata.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""
-This module provides the basic metadata_real classes, but without any
-functionality. This way the import is fast and low-overhead. But
-when running docsupport.extract it will replace this module with the
-real (more functional) thing.
-
-Everything here is stubs.
-"""
-
-class DocItem(object):
-
- def __init__(self, *args, **kw):
- pass
-
-WSGIKey = DocItem
-Config = DocItem
-Attribute = DocItem
-
-
diff --git a/paste/docsupport/metadata_real.py b/paste/docsupport/metadata_real.py
deleted file mode 100644
index bea51f9..0000000
--- a/paste/docsupport/metadata_real.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-
-import sys
-import inspect
-from itertools import count
-from paste.util import import_string
-from paste.util.classinit import ClassInitMeta
-
-doc_count = count()
-
-class DocItem(object):
-
- __metaclass__ = ClassInitMeta
-
- def __classinit__(cls, new_attrs):
- cls.__creationorder__ = doc_count.next()
-
- def __init__(self):
- self.__creationorder__ = doc_count.next()
- stack = inspect.stack()
- try:
- while 1:
- name = stack[0][0].f_globals['__name__']
- if name != __name__:
- break
- stack.pop(0)
- self.call_module_name = name
- finally:
- # Break reference to frames
- stack = None
-
- def get_object(self, name):
- if '.' in name:
- return import_string.eval_import(name)
- else:
- return getattr(sys.modules[self.call_module_name], name)
-
- def writeto(self, context):
- raise NotImplementedError
-
- def writeobj(self, name, context):
- """
- Write the named object to the context
- """
- if name is None:
- return
- obj = self.get_object(name)
- context.push_name(name)
- context.extract(obj)
- context.pop_name(name)
-
-
-class WSGIKey(DocItem):
-
- def __init__(self, name, doc=None, interface=None):
- self.name = name
- self.doc = doc
- self.interface = interface
- super(WSGIKey, self).__init__()
-
- def writeto(self, context):
- context.addindex('wsgikey', self.name)
- context.writekey(self.name, type='WSGI Environment Key')
- context.writedoc(self.doc)
- self.writeobj(self.interface, context)
- context.endkey()
-
-class NoDefault: pass
-
-class Config(DocItem):
-
- def __init__(self, doc, name=None, default=NoDefault):
- self.doc = doc
- self.name = name
- self.default = default
-
- def writeto(self, context):
- name = self.name
- if not self.name:
- name = context.last_name
- if name.startswith('_config_'):
- name = name[len('_config_'):]
- context.addindex('config', name)
- name = "``%s``" % name
- if self.default is not NoDefault:
- name += ' (default: ``%r``)' % self.default
- context.writekey(name, type='Paste Configuration',
- monospace=False)
- context.writedoc(self.doc)
- context.endkey()
-
-class Attribute(DocItem):
-
- def __init__(self, doc, name=None, interface=None):
- self.doc = doc
- self.name = name
- self.interface = interface
- super(Attribute, self).__init__()
-
- def writeto(self, context):
- name = self.name or context.last_name
- context.writekey(self.name, type='Attribute')
- context.writedoc(self.doc)
- if self.interface:
- context.write(self.interface)
- context.endkey()
-
-def install():
- """
- Puts this module in place of the normal paste.docsupport.metadata
- module, which is all stubby because this functional module takes
- longer to import.
- """
- from paste.docsupport import metadata
- for name, value in globals().items():
- setattr(metadata, name, value)
-