summaryrefslogtreecommitdiff
path: root/paste/docsupport/metadata_real.py
blob: e5777e9dbe8dd248a968b12c76eeddda4a70a638 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# @@: There are too many imports here; this shouldn't have much
# overhead except during extraction, but everything in this
# module has to be imported regardless.
import sys
import copy
import types
import inspect
import new
from itertools import count
from paste.util import import_string
from paste.util.classinit import ClassInitMeta
from paste.util.classinstance import classinstancemethod

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)