Back to index

moin  1.9.0~rc2
__init__.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 """
00003     werkzeug
00004     ~~~~~~~~
00005 
00006     Werkzeug is the Swiss Army knife of Python web development.
00007 
00008     It provides useful classes and functions for any WSGI application to make
00009     the life of a python web developer much easier.  All of the provided
00010     classes are independent from each other so you can mix it with any other
00011     library.
00012 
00013 
00014     :copyright: (c) 2009 by the Werkzeug Team, see AUTHORS for more details.
00015     :license: BSD, see LICENSE for more details.
00016 """
00017 from types import ModuleType
00018 import sys
00019 
00020 # This import magic raises concerns quite often which is why the implementation
00021 # and motiviation is explained here in detail now.
00022 #
00023 # The majority of the functions and classes provided by Werkzeug work on the
00024 # HTTP and WSGI layer.  There is no useful grouping for those which is why
00025 # they are all importable from "werkzeug" instead of the modules where they are
00026 # implemented.  The downside of that is, that now everything would be loaded at
00027 # once, even if unused.
00028 #
00029 # The implementation of a lazy-loading module in this file replaces the
00030 # werkzeug package when imported from within.  Attribute access to the werkzeug
00031 # module will then lazily import from the modules that implement the objects.
00032 
00033 
00034 # import mapping to objects in other modules
00035 all_by_module = {
00036     'werkzeug.debug':       ['DebuggedApplication'],
00037     'werkzeug.local':       ['Local', 'LocalManager', 'LocalProxy'],
00038     'werkzeug.templates':   ['Template'],
00039     'werkzeug.serving':     ['run_simple'],
00040     'werkzeug.test':        ['Client', 'EnvironBuilder', 'create_environ',
00041                              'run_wsgi_app'],
00042     'werkzeug.testapp':     ['test_app'],
00043     'werkzeug.exceptions':  ['abort', 'Aborter'],
00044     'werkzeug.utils':       ['escape', 'url_quote',
00045                              'environ_property', 'cookie_date', 'http_date',
00046                              'url_encode', 'url_quote_plus', 'url_fix',
00047                              'get_host', 'responder',
00048                              'SharedDataMiddleware', 'ClosingIterator',
00049                              'FileStorage', 'url_unquote_plus', 'url_decode',
00050                              'url_unquote', 'get_current_url', 'redirect',
00051                              'append_slash_redirect',
00052                              'cached_property', 'import_string',
00053                              'dump_cookie', 'parse_cookie', 'unescape',
00054                              'format_string', 'Href', 'DispatcherMiddleware',
00055                              'find_modules', 'header_property', 'html',
00056                              'xhtml', 'HTMLBuilder', 'parse_form_data',
00057                              'validate_arguments', 'ArgumentValidationError',
00058                              'bind_arguments', 'FileWrapper', 'wrap_file',
00059                              'pop_path_info', 'peek_path_info',
00060                              'LimitedStream', 'make_line_iter',
00061                              'secure_filename'],
00062     'werkzeug.datastructures': ['MultiDict', 'CombinedMultiDict', 'Headers',
00063                              'EnvironHeaders', 'ImmutableList',
00064                              'ImmutableDict', 'ImmutableMultiDict',
00065                              'TypeConversionDict', 'ImmutableTypeConversionDict',
00066                              'Accept', 'MIMEAccept', 'CharsetAccept',
00067                              'LanguageAccept', 'RequestCacheControl',
00068                              'ResponseCacheControl', 'ETags', 'HeaderSet',
00069                              'WWWAuthenticate', 'Authorization',
00070                              'CacheControl', 'FileMultiDict', 'CallbackDict'],
00071     'werkzeug.useragents':  ['UserAgent'],
00072     'werkzeug.http':        ['parse_etags', 'parse_date', 'parse_cache_control_header',
00073                              'is_resource_modified', 'parse_accept_header',
00074                              'parse_set_header', 'quote_etag', 'unquote_etag',
00075                              'generate_etag', 'dump_header',
00076                              'parse_list_header', 'parse_dict_header',
00077                              'parse_authorization_header',
00078                              'parse_www_authenticate_header',
00079                              'remove_entity_headers', 'is_entity_header',
00080                              'remove_hop_by_hop_headers', 'parse_options_header',
00081                              'dump_options_header', 'is_hop_by_hop_header',
00082                              'unquote_header_value',
00083                              'quote_header_value', 'HTTP_STATUS_CODES'],
00084     'werkzeug.wrappers':    ['BaseResponse', 'BaseRequest', 'Request',
00085                              'Response', 'AcceptMixin', 'ETagRequestMixin',
00086                              'ETagResponseMixin', 'ResponseStreamMixin',
00087                              'CommonResponseDescriptorsMixin',
00088                              'UserAgentMixin', 'AuthorizationMixin',
00089                              'WWWAuthenticateMixin',
00090                              'CommonRequestDescriptorsMixin'],
00091     # the undocumented easteregg ;-)
00092     'werkzeug._internal':   ['_easteregg']
00093 }
00094 
00095 # modules that should be imported when accessed as attributes of werkzeug
00096 attribute_modules = dict.fromkeys(['exceptions', 'routing', 'script'])
00097 
00098 
00099 object_origins = {}
00100 for module, items in all_by_module.iteritems():
00101     for item in items:
00102         object_origins[item] = module
00103 
00104 
00105 #: the cached version of the library.  We get the distribution from
00106 #: pkg_resources the first time this attribute is accessed.  Because
00107 #: this operation is quite slow it speeds up importing a lot.
00108 version = None
00109 
00110 class module(ModuleType):
00111     """Automatically import objects from the modules."""
00112 
00113     def __getattr__(self, name):
00114         if name in object_origins:
00115             module = __import__(object_origins[name], None, None, [name])
00116             for extra_name in all_by_module[module.__name__]:
00117                 setattr(self, extra_name, getattr(module, extra_name))
00118             return getattr(module, name)
00119         elif name in attribute_modules:
00120             __import__('werkzeug.' + name)
00121         return ModuleType.__getattribute__(self, name)
00122 
00123     def __dir__(self):
00124         """Just show what we want to show."""
00125         result = list(new_module.__all__)
00126         result.extend(('__file__', '__path__', '__doc__', '__all__',
00127                        '__docformat__', '__name__', '__path__',
00128                        '__package__', '__version__'))
00129         return result
00130 
00131     @property
00132     def __version__(self):
00133         global version
00134         if version is None:
00135             try:
00136                 version = __import__('pkg_resources') \
00137                           .get_distribution('Werkzeug').version
00138             except:
00139                 version = 'unknown'
00140         return version
00141 
00142 # keep a reference to this module so that it's not garbage collected
00143 old_module = sys.modules['werkzeug']
00144 
00145 
00146 # setup the new module and patch it into the dict of loaded modules
00147 new_module = sys.modules['werkzeug'] = module('werkzeug')
00148 new_module.__dict__.update({
00149     '__file__':         __file__,
00150     '__path__':         __path__,
00151     '__doc__':          __doc__,
00152     '__all__':          tuple(object_origins) + tuple(attribute_modules),
00153     '__docformat__':    'restructuredtext en'
00154 })