234 lines
6.6 KiB
Python
234 lines
6.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
werkzeug
|
|
~~~~~~~~
|
|
|
|
Werkzeug is the Swiss Army knife of Python web development.
|
|
|
|
It provides useful classes and functions for any WSGI application to make
|
|
the life of a python web developer much easier. All of the provided
|
|
classes are independent from each other so you can mix it with any other
|
|
library.
|
|
|
|
|
|
:copyright: 2007 Pallets
|
|
:license: BSD-3-Clause
|
|
"""
|
|
import sys
|
|
from types import ModuleType
|
|
|
|
__version__ = "0.15.4"
|
|
|
|
# This import magic raises concerns quite often which is why the implementation
|
|
# and motivation is explained here in detail now.
|
|
#
|
|
# The majority of the functions and classes provided by Werkzeug work on the
|
|
# HTTP and WSGI layer. There is no useful grouping for those which is why
|
|
# they are all importable from "werkzeug" instead of the modules where they are
|
|
# implemented. The downside of that is, that now everything would be loaded at
|
|
# once, even if unused.
|
|
#
|
|
# The implementation of a lazy-loading module in this file replaces the
|
|
# werkzeug package when imported from within. Attribute access to the werkzeug
|
|
# module will then lazily import from the modules that implement the objects.
|
|
|
|
# import mapping to objects in other modules
|
|
all_by_module = {
|
|
"werkzeug.debug": ["DebuggedApplication"],
|
|
"werkzeug.local": [
|
|
"Local",
|
|
"LocalManager",
|
|
"LocalProxy",
|
|
"LocalStack",
|
|
"release_local",
|
|
],
|
|
"werkzeug.serving": ["run_simple"],
|
|
"werkzeug.test": ["Client", "EnvironBuilder", "create_environ", "run_wsgi_app"],
|
|
"werkzeug.testapp": ["test_app"],
|
|
"werkzeug.exceptions": ["abort", "Aborter"],
|
|
"werkzeug.urls": [
|
|
"url_decode",
|
|
"url_encode",
|
|
"url_quote",
|
|
"url_quote_plus",
|
|
"url_unquote",
|
|
"url_unquote_plus",
|
|
"url_fix",
|
|
"Href",
|
|
"iri_to_uri",
|
|
"uri_to_iri",
|
|
],
|
|
"werkzeug.formparser": ["parse_form_data"],
|
|
"werkzeug.utils": [
|
|
"escape",
|
|
"environ_property",
|
|
"append_slash_redirect",
|
|
"redirect",
|
|
"cached_property",
|
|
"import_string",
|
|
"dump_cookie",
|
|
"parse_cookie",
|
|
"unescape",
|
|
"format_string",
|
|
"find_modules",
|
|
"header_property",
|
|
"html",
|
|
"xhtml",
|
|
"HTMLBuilder",
|
|
"validate_arguments",
|
|
"ArgumentValidationError",
|
|
"bind_arguments",
|
|
"secure_filename",
|
|
],
|
|
"werkzeug.wsgi": [
|
|
"get_current_url",
|
|
"get_host",
|
|
"pop_path_info",
|
|
"peek_path_info",
|
|
"ClosingIterator",
|
|
"FileWrapper",
|
|
"make_line_iter",
|
|
"LimitedStream",
|
|
"responder",
|
|
"wrap_file",
|
|
"extract_path_info",
|
|
],
|
|
"werkzeug.datastructures": [
|
|
"MultiDict",
|
|
"CombinedMultiDict",
|
|
"Headers",
|
|
"EnvironHeaders",
|
|
"ImmutableList",
|
|
"ImmutableDict",
|
|
"ImmutableMultiDict",
|
|
"TypeConversionDict",
|
|
"ImmutableTypeConversionDict",
|
|
"Accept",
|
|
"MIMEAccept",
|
|
"CharsetAccept",
|
|
"LanguageAccept",
|
|
"RequestCacheControl",
|
|
"ResponseCacheControl",
|
|
"ETags",
|
|
"HeaderSet",
|
|
"WWWAuthenticate",
|
|
"Authorization",
|
|
"FileMultiDict",
|
|
"CallbackDict",
|
|
"FileStorage",
|
|
"OrderedMultiDict",
|
|
"ImmutableOrderedMultiDict",
|
|
],
|
|
"werkzeug.useragents": ["UserAgent"],
|
|
"werkzeug.http": [
|
|
"parse_etags",
|
|
"parse_date",
|
|
"http_date",
|
|
"cookie_date",
|
|
"parse_cache_control_header",
|
|
"is_resource_modified",
|
|
"parse_accept_header",
|
|
"parse_set_header",
|
|
"quote_etag",
|
|
"unquote_etag",
|
|
"generate_etag",
|
|
"dump_header",
|
|
"parse_list_header",
|
|
"parse_dict_header",
|
|
"parse_authorization_header",
|
|
"parse_www_authenticate_header",
|
|
"remove_entity_headers",
|
|
"is_entity_header",
|
|
"remove_hop_by_hop_headers",
|
|
"parse_options_header",
|
|
"dump_options_header",
|
|
"is_hop_by_hop_header",
|
|
"unquote_header_value",
|
|
"quote_header_value",
|
|
"HTTP_STATUS_CODES",
|
|
],
|
|
"werkzeug.wrappers": [
|
|
"BaseResponse",
|
|
"BaseRequest",
|
|
"Request",
|
|
"Response",
|
|
"AcceptMixin",
|
|
"ETagRequestMixin",
|
|
"ETagResponseMixin",
|
|
"ResponseStreamMixin",
|
|
"CommonResponseDescriptorsMixin",
|
|
"UserAgentMixin",
|
|
"AuthorizationMixin",
|
|
"WWWAuthenticateMixin",
|
|
"CommonRequestDescriptorsMixin",
|
|
],
|
|
"werkzeug.middleware.dispatcher": ["DispatcherMiddleware"],
|
|
"werkzeug.middleware.shared_data": ["SharedDataMiddleware"],
|
|
"werkzeug.security": ["generate_password_hash", "check_password_hash"],
|
|
# the undocumented easteregg ;-)
|
|
"werkzeug._internal": ["_easteregg"],
|
|
}
|
|
|
|
# modules that should be imported when accessed as attributes of werkzeug
|
|
attribute_modules = frozenset(["exceptions", "routing"])
|
|
|
|
object_origins = {}
|
|
for module, items in all_by_module.items():
|
|
for item in items:
|
|
object_origins[item] = module
|
|
|
|
|
|
class module(ModuleType):
|
|
"""Automatically import objects from the modules."""
|
|
|
|
def __getattr__(self, name):
|
|
if name in object_origins:
|
|
module = __import__(object_origins[name], None, None, [name])
|
|
for extra_name in all_by_module[module.__name__]:
|
|
setattr(self, extra_name, getattr(module, extra_name))
|
|
return getattr(module, name)
|
|
elif name in attribute_modules:
|
|
__import__("werkzeug." + name)
|
|
return ModuleType.__getattribute__(self, name)
|
|
|
|
def __dir__(self):
|
|
"""Just show what we want to show."""
|
|
result = list(new_module.__all__)
|
|
result.extend(
|
|
(
|
|
"__file__",
|
|
"__doc__",
|
|
"__all__",
|
|
"__docformat__",
|
|
"__name__",
|
|
"__path__",
|
|
"__package__",
|
|
"__version__",
|
|
)
|
|
)
|
|
return result
|
|
|
|
|
|
# keep a reference to this module so that it's not garbage collected
|
|
old_module = sys.modules["werkzeug"]
|
|
|
|
|
|
# setup the new module and patch it into the dict of loaded modules
|
|
new_module = sys.modules["werkzeug"] = module("werkzeug")
|
|
new_module.__dict__.update(
|
|
{
|
|
"__file__": __file__,
|
|
"__package__": "werkzeug",
|
|
"__path__": __path__,
|
|
"__doc__": __doc__,
|
|
"__version__": __version__,
|
|
"__all__": tuple(object_origins) + tuple(attribute_modules),
|
|
"__docformat__": "restructuredtext en",
|
|
}
|
|
)
|
|
|
|
|
|
# Due to bootstrapping issues we need to import exceptions here.
|
|
# Don't ask :-(
|
|
__import__("werkzeug.exceptions")
|