[Python-modules-commits] [python-werkzeug] 01/15: Import python-werkzeug_0.11.9+dfsg1.orig.tar.gz

Ondřej Nový onovy-guest at moszumanska.debian.org
Sun May 1 13:31:21 UTC 2016


This is an automated email from the git hooks/post-receive script.

onovy-guest pushed a commit to branch master
in repository python-werkzeug.

commit f888071666bddf458ff403c23cb41a508d74b44d
Author: Ondřej Nový <novy at ondrej.org>
Date:   Sun May 1 12:32:12 2016 +0200

    Import python-werkzeug_0.11.9+dfsg1.orig.tar.gz
---
 .gitignore                              |  17 ++
 .travis.yml                             |  42 +++
 CHANGES                                 | 139 ++++++++++
 CONTRIBUTING.rst                        |  62 +++++
 Makefile                                |   3 +
 PKG-INFO                                |  72 -----
 README.rst                              |  17 +-
 bench/wzbench.py                        | 461 ++++++++++++++++++++++++++++++++
 docs/_themes/werkzeug_theme_support.pyc | Bin 2468 -> 0 bytes
 docs/contents.rst.inc                   |   1 +
 docs/debug.rst                          |  28 +-
 docs/exceptions.rst                     |  10 +-
 docs/filesystem.rst                     |  11 +
 docs/local.rst                          |  23 +-
 docs/middlewares.rst                    |   2 +-
 docs/python3.rst                        |   5 +-
 docs/request_data.rst                   |   2 +-
 docs/unicode.rst                        |  22 ++
 examples/cupoftee/pages.py              |   2 +-
 scripts/make-release.py                 | 153 +++++++++++
 setup.cfg                               |  11 +-
 setup.py                                |  18 +-
 tests/__init__.py                       |   2 -
 tests/contrib/test_atom.py              |   1 +
 tests/contrib/test_cache.py             |  45 +++-
 tests/contrib/test_fixers.py            |  27 +-
 tests/contrib/test_iterio.py            |   2 +-
 tests/contrib/test_securecookie.py      |   1 +
 tests/contrib/test_sessions.py          |   5 +-
 tests/contrib/test_wrappers.py          |   4 +-
 tests/test_compat.py                    |  11 +-
 tests/test_datastructures.py            |  19 +-
 tests/test_debug.py                     |  13 +-
 tests/test_exceptions.py                |   1 +
 tests/test_formparser.py                |  41 ++-
 tests/test_http.py                      |  76 ++++--
 tests/test_internal.py                  |   2 +
 tests/test_local.py                     |  35 ++-
 tests/test_routing.py                   | 224 ++++++++++++----
 tests/test_security.py                  |  10 +-
 tests/test_serving.py                   |  53 ++++
 tests/test_test.py                      |  68 ++++-
 tests/test_urls.py                      |  48 ++--
 tests/test_utils.py                     |  64 ++++-
 tests/test_wrappers.py                  | 115 ++++++--
 tests/test_wsgi.py                      |  31 ++-
 tox.ini                                 |  31 +++
 werkzeug-import-rewrite.py              | 230 ++++++++++++++++
 werkzeug/__init__.py                    | 114 ++++----
 werkzeug/_compat.py                     |  36 +--
 werkzeug/_internal.py                   |  18 +-
 werkzeug/_reloader.py                   |  37 ++-
 werkzeug/contrib/atom.py                |  14 +-
 werkzeug/contrib/cache.py               | 165 +++++++++---
 werkzeug/contrib/fixers.py              |  10 +-
 werkzeug/contrib/iterio.py              |   3 +
 werkzeug/contrib/limiter.py             |   1 +
 werkzeug/contrib/lint.py                |  19 +-
 werkzeug/contrib/profiler.py            |  19 +-
 werkzeug/contrib/securecookie.py        |   4 +-
 werkzeug/contrib/sessions.py            |  18 +-
 werkzeug/contrib/testtools.py           |   4 +-
 werkzeug/contrib/wrappers.py            |   6 +
 werkzeug/datastructures.py              |  98 +++++--
 werkzeug/debug/__init__.py              | 322 ++++++++++++++++++++--
 werkzeug/debug/console.py               |   6 +-
 werkzeug/debug/repr.py                  |   7 +-
 werkzeug/debug/shared/debugger.js       | 110 ++++----
 werkzeug/debug/shared/style.css         |  59 ++--
 werkzeug/debug/tbtools.py               |  90 +++++--
 werkzeug/exceptions.py                  |  43 ++-
 werkzeug/filesystem.py                  |  66 +++++
 werkzeug/formparser.py                  |  10 +-
 werkzeug/http.py                        | 102 ++++---
 werkzeug/local.py                       |  13 +-
 werkzeug/posixemulation.py              |  10 +-
 werkzeug/routing.py                     | 139 ++++++++--
 werkzeug/script.py                      |   3 +-
 werkzeug/security.py                    |   3 +-
 werkzeug/serving.py                     | 145 +++++++---
 werkzeug/test.py                        |  26 +-
 werkzeug/testapp.py                     |   6 +-
 werkzeug/urls.py                        |  27 +-
 werkzeug/useragents.py                  |   8 +-
 werkzeug/utils.py                       |  46 ++--
 werkzeug/wrappers.py                    |  97 ++++---
 werkzeug/wsgi.py                        |  32 ++-
 87 files changed, 3373 insertions(+), 823 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1ae242a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+MANIFEST
+build
+dist
+*.egg-info
+*.pyc
+*.pyo
+env
+.DS_Store
+.tox
+docs/_build
+bench/a
+bench/b
+.coverage
+coverage_out
+.cache
+.xprocess
+htmlcov
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..06fe761
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,42 @@
+language: python
+python:
+    - "2.6"
+    - "2.7"
+    - "pypy"
+    - "3.3"
+    - "3.4"
+    - "3.5"
+
+install:
+    # Travis uses an outdated PyPy, this installs the most recent one.
+    # We need it because apparently cryptography isn't compatible with PyPy versions < 2.6
+    # This makes the tests run on Travis' legacy infrastructure, but so be it.
+    # temporary pyenv installation to get pypy-2.6 before container infra upgrade
+    - if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then
+        git clone https://github.com/yyuu/pyenv.git ~/.pyenv;
+        PYENV_ROOT="$HOME/.pyenv";
+        PATH="$PYENV_ROOT/bin:$PATH";
+        eval "$(pyenv init -)";
+        pyenv install pypy-2.6.1;
+        pyenv global pypy-2.6.1;
+      fi
+    - python --version
+    - pip install tox flake8
+
+script:
+    - tox -e py
+    - make stylecheck
+
+branches:
+  except:
+    - website
+
+notifications:
+  email: false
+  irc:
+    channels:
+      - "chat.freenode.net#pocoo"
+    on_success: change
+    on_failure: always
+    use_notice: true
+    skip_join: true
diff --git a/CHANGES b/CHANGES
index 241b68e..de99d6e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,140 @@
 Werkzeug Changelog
 ==================
 
+Version 0.11.9
+--------------
+
+Released on April 24th 2016.
+
+- Corrected an issue that caused the debugger not to use the
+  machine GUID on POSIX systems.
+- Corrected an Unicode error on Python 3 for the debugger's
+  PIN usage.
+- Corrected the timestamp verification in the pin debug code.
+  Without this fix the pin was remebered until too long.
+
+Version 0.11.8
+--------------
+
+Released on April 15th 2016.
+
+- fixed a problem with the machine GUID detection code on OS X
+  on Python 3.
+
+Version 0.11.7
+--------------
+
+Released on April 14th 2016.
+
+- fixed a regression on Python 3 for the debugger.
+
+Version 0.11.6
+--------------
+
+Released on April 14th 2016.
+
+- werkzeug.serving: Still show the client address on bad requests.
+- improved the PIN based protection for the debugger to make it harder to
+  brute force via trying cookies.  Please keep in mind that the debugger
+  *is not intended for running on production environments*
+- increased the pin timeout to a week to make it less annoying for people
+  which should decrease the change that users disable the pin check
+  entirely.
+- werkzeug.serving: Fix broken HTTP_HOST when path starts with double slash.
+
+Version 0.11.5
+--------------
+
+Released on March 22nd 2016.
+
+- werkzeug.serving: Fix crash when attempting SSL connection to HTTP server.
+
+Version 0.11.4
+--------------
+
+Released on February 14th 2016.
+
+- Fixed werkzeug.serving not working from -m flag.
+- Fixed incorrect weak etag handling.
+
+Version 0.11.3
+--------------
+
+Released on December 20th 2015.
+
+- Fixed an issue with copy operations not working against
+  proxies.
+- Changed the logging operations of the development server to
+  correctly log where the server is running in all situations
+  again.
+- Fixed another regression with SSL wrapping similar to the
+  fix in 0.11.2 but for a different code path.
+
+Version 0.11.2
+--------------
+
+Released on November 12th 2015.
+
+- Fix inheritable sockets on Windows on Python 3.
+- Fixed an issue with the forking server not starting any longer.
+- Fixed SSL wrapping on platforms that supported opening sockets
+  by file descriptor.
+- No longer log from the watchdog reloader.
+- Unicode errors in hosts are now better catched or converted into
+  bad request errors.
+
+Version 0.11.1
+--------------
+
+Released on November 10th 2015.
+
+- Fixed a regression on Python 3 in the debugger.
+
+Version 0.11
+------------
+
+Released on November 8th 2015, codename Gleisbaumaschine.
+
+- Added ``reloader_paths`` option to ``run_simple`` and other functions in
+  ``werkzeug.serving``. This allows the user to completely override the Python
+  module watching of Werkzeug with custom paths.
+- Many custom cached properties of Werkzeug's classes are now subclasses of
+  Python's ``property`` type (issue ``#616``).
+- ``bind_to_environ`` now doesn't differentiate between implicit and explicit
+  default port numbers in ``HTTP_HOST`` (pull request ``#204``).
+- ``BuildErrors`` are now more informative. They come with a complete sentence
+  as error message, and also provide suggestions (pull request ``#691``).
+- Fix a bug in the user agent parser where Safari's build number instead of
+  version would be extracted (pull request ``#703``).
+- Fixed issue where RedisCache set_many was broken for twemproxy, which doesn't
+  support the default MULTI command (pull request ``#702``).
+- ``mimetype`` parameters on request and response classes are now always
+  converted to lowercase.
+- Changed cache so that cache never expires if timeout is 0. This also fixes
+  an issue with redis setex (issue ``#550``)
+- Werkzeug now assumes ``UTF-8`` as filesystem encoding on Unix if Python
+  detected it as ASCII.
+- New optional `has` method on caches.
+- Fixed various bugs in `parse_options_header` (pull request ``#643``).
+- If the reloader is enabled the server will now open the socket in the parent
+  process if this is possible.  This means that when the reloader kicks in
+  the connection from client will wait instead of tearing down.  This does
+  not work on all Python versions.
+- Implemented PIN based authentication for the debugger.  This can optionally
+  be disabled but is discouraged.  This change was necessary as it has been
+  discovered that too many people run the debugger in production.
+- Devserver no longer requires SSL module to be installed.
+
+Version 0.10.5
+--------------
+
+(bugfix release, release date yet to be decided)
+
+- Reloader: Correctly detect file changes made by moving temporary files over
+  the original, which is e.g. the case with PyCharm (pull request ``#722``).
+- Fix bool behavior of ``werkzeug.datastructures.ETags`` under Python 3 (issue
+  ``#744``).
+
 Version 0.10.4
 --------------
 
@@ -146,6 +280,11 @@ Version 0.9.6
   internally to work around issues with spec violations for
   protocols such as ``itms-service``.
 
+Version 0.9.7
+-------------
+
+- Fixed uri_to_iri() not re-encoding hashes in query string parameters.
+
 Version 0.9.5
 -------------
 
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 0000000..2febd5e
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,62 @@
+=============================
+How to contribute to Werkzeug
+=============================
+
+Thanks for considering contributing to Werkzeug.
+
+Support questions
+=================
+
+Please, don't use the issue tracker for this. Check whether the `Pocoo IRC
+channel <http://www.pocoo.org/irc/>`_ can help with your issue. If your problem
+is not strictly Werkzeug- or Flask-specific, ``#python`` on Freenode is
+generally more active.  `StackOverflow <https://stackoverflow.com/>`_ is also
+worth considering.
+
+Reporting issues
+================
+
+- Under which versions of Python does this happen? This is even more important
+  if your issue is encoding related.
+
+- Under which versions of Werkzeug does this happen? Check if this issue is
+  fixed in the repository.
+
+Submitting patches
+==================
+
+- Include tests if your patch is supposed to solve a bug, and explain
+  clearly under which circumstances the bug happens. Make sure the test fails
+  without your patch.
+
+- Try to follow `PEP8 <http://legacy.python.org/dev/peps/pep-0008/>`_, but you
+  may ignore the line-length-limit if following it would make the code uglier.
+
+
+Running the testsuite
+---------------------
+
+You probably want to set up a `virtualenv
+<http://virtualenv.readthedocs.org/en/latest/index.html>`_.
+
+The minimal requirement for running the testsuite is ``py.test``.  You can
+install it with::
+
+    pip install pytest
+
+Then you can run the testsuite with::
+
+    py.test
+
+With only py.test installed, a large part of the testsuite will get skipped
+though.  Whether this is relevant depends on which part of Werkzeug you're
+working on.  Travis is set up to run the full testsuite when you submit your
+pull request anyways.
+
+If you really want to test everything, you will have to install ``tox`` instead
+of ``pytest``. You can install it with::
+
+    pip install tox
+
+The ``tox`` command will then run all tests against multiple combinations
+Python versions and dependency versions.
diff --git a/Makefile b/Makefile
index b5e3c98..9c933d0 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,9 @@ release:
 test:
 	py.test --tb=native
 
+stylecheck:
+	flake8
+
 tox-test:
 	tox
 
diff --git a/PKG-INFO b/PKG-INFO
deleted file mode 100644
index a1c3338..0000000
--- a/PKG-INFO
+++ /dev/null
@@ -1,72 +0,0 @@
-Metadata-Version: 1.1
-Name: Werkzeug
-Version: 0.10.4
-Summary: The Swiss Army knife of Python web development
-Home-page: http://werkzeug.pocoo.org/
-Author: Armin Ronacher
-Author-email: armin.ronacher at active-4.com
-License: BSD
-Description: 
-        Werkzeug
-        ========
-        
-        Werkzeug started as simple collection of various utilities for WSGI
-        applications and has become one of the most advanced WSGI utility
-        modules.  It includes a powerful debugger, full featured request and
-        response objects, HTTP utilities to handle entity tags, cache control
-        headers, HTTP dates, cookie handling, file uploads, a powerful URL
-        routing system and a bunch of community contributed addon modules.
-        
-        Werkzeug is unicode aware and doesn't enforce a specific template
-        engine, database adapter or anything else.  It doesn't even enforce
-        a specific way of handling requests and leaves all that up to the
-        developer. It's most useful for end user applications which should work
-        on as many server environments as possible (such as blogs, wikis,
-        bulletin boards, etc.).
-        
-        Details and example applications are available on the
-        `Werkzeug website <http://werkzeug.pocoo.org/>`_.
-        
-        
-        Features
-        --------
-        
-        -   unicode awareness
-        
-        -   request and response objects
-        
-        -   various utility functions for dealing with HTTP headers such as
-            `Accept` and `Cache-Control` headers.
-        
-        -   thread local objects with proper cleanup at request end
-        
-        -   an interactive debugger
-        
-        -   A simple WSGI server with support for threading and forking
-            with an automatic reloader.
-        
-        -   a flexible URL routing system with REST support.
-        
-        -   fully WSGI compatible
-        
-        
-        Development Version
-        -------------------
-        
-        The Werkzeug development version can be installed by cloning the git
-        repository from `github`_::
-        
-            git clone git at github.com:mitsuhiko/werkzeug.git
-        
-        .. _github: http://github.com/mitsuhiko/werkzeug
-        
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/README.rst b/README.rst
index e8d2aa3..1764419 100644
--- a/README.rst
+++ b/README.rst
@@ -22,10 +22,13 @@ Details and example applications are available on the
 Branches
 --------
 
-+---------------------+--------------------------------------------------------------------------------+
-| ``master``          | .. image:: https://travis-ci.org/mitsuhiko/werkzeug.svg?branch=master          |
-|                     |     :target: https://travis-ci.org/mitsuhiko/werkzeug                          |
-+---------------------+--------------------------------------------------------------------------------+
-| ``0.9-maintenance`` | .. image:: https://travis-ci.org/mitsuhiko/werkzeug.svg?branch=0.9-maintenance |
-|                     |     :target: https://travis-ci.org/mitsuhiko/werkzeug                          |
-+---------------------+--------------------------------------------------------------------------------+
++----------------------+---------------------------------------------------------------------------------+
+| ``master``           | .. image:: https://travis-ci.org/mitsuhiko/werkzeug.svg?branch=master           |
+|                      |     :target: https://travis-ci.org/mitsuhiko/werkzeug                           |
++----------------------+---------------------------------------------------------------------------------+
+| ``0.9-maintenance``  | .. image:: https://travis-ci.org/mitsuhiko/werkzeug.svg?branch=0.9-maintenance  |
+|                      |     :target: https://travis-ci.org/mitsuhiko/werkzeug                           |
++----------------------+---------------------------------------------------------------------------------+
+| ``0.10-maintenance`` | .. image:: https://travis-ci.org/mitsuhiko/werkzeug.svg?branch=0.10-maintenance |
+|                      |     :target: https://travis-ci.org/mitsuhiko/werkzeug                           |
++----------------------+---------------------------------------------------------------------------------+
diff --git a/bench/wzbench.py b/bench/wzbench.py
new file mode 100755
index 0000000..10d4fa4
--- /dev/null
+++ b/bench/wzbench.py
@@ -0,0 +1,461 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    wzbench
+    ~~~~~~~
+
+    A werkzeug internal benchmark module.  It's used in combination with
+    hg bisect to find out how the Werkzeug performance of some internal
+    core parts changes over time.
+
+    :copyright: 2014 by the Werkzeug Team, see AUTHORS for more details.
+    :license: BSD, see LICENSE for more details.
+"""
+from __future__ import division
+import os
+import gc
+import sys
+import subprocess
+from cStringIO import StringIO
+from timeit import default_timer as timer
+from types import FunctionType
+
+PY2 = sys.version_info[0] == 2
+
+if not PY2:
+    xrange = range
+
+
+# create a new module where we later store all the werkzeug attributes.
+wz = type(sys)('werkzeug_nonlazy')
+sys.path.insert(0, '<DUMMY>')
+null_out = open(os.devnull, 'w')
+
+
+# ±4% are ignored
+TOLERANCE = 0.04
+MIN_RESOLUTION = 0.002
+
+# we run each test 5 times
+TEST_RUNS = 5
+
+
+def find_hg_tag(path):
+    """Returns the current node or tag for the given path."""
+    tags = {}
+    try:
+        client = subprocess.Popen(['hg', 'cat', '-r', 'tip', '.hgtags'],
+                                  stdout=subprocess.PIPE, cwd=path)
+        for line in client.communicate()[0].splitlines():
+            line = line.strip()
+            if not line:
+                continue
+            hash, tag = line.split()
+            tags[hash] = tag
+    except OSError:
+        return
+
+    client = subprocess.Popen(['hg', 'parent', '--template', '#node#'],
+                              stdout=subprocess.PIPE, cwd=path)
+
+    tip = client.communicate()[0].strip()
+    tag = tags.get(tip)
+    if tag is not None:
+        return tag
+    return tip
+
+
+def load_werkzeug(path):
+    """Load werkzeug."""
+    sys.path[0] = path
+
+    # get rid of already imported stuff
+    wz.__dict__.clear()
+    for key in sys.modules.keys():
+        if key.startswith('werkzeug.') or key == 'werkzeug':
+            sys.modules.pop(key, None)
+
+    # import werkzeug again.
+    import werkzeug
+    for key in werkzeug.__all__:
+        setattr(wz, key, getattr(werkzeug, key))
+
+    # get the hg tag
+    hg_tag = find_hg_tag(path)
+
+    # get the real version from the setup file
+    try:
+        f = open(os.path.join(path, 'setup.py'))
+    except IOError:
+        pass
+    else:
+        try:
+            for line in f:
+                line = line.strip()
+                if line.startswith('version='):
+                    return line[8:].strip(' \t,')[1:-1], hg_tag
+        finally:
+            f.close()
+    print >> sys.stderr, 'Unknown werkzeug version loaded'
+    sys.exit(2)
+
+
+def median(seq):
+    seq = sorted(seq)
+    if not seq:
+        return 0.0
+    return seq[len(seq) // 2]
+
+
+def format_func(func):
+    if type(func) is FunctionType:
+        name = func.__name__
+    else:
+        name = func
+    if name.startswith('time_'):
+        name = name[5:]
+    return name.replace('_', ' ').title()
+
+
+def bench(func):
+    """Times a single function."""
+    sys.stdout.write('%44s   ' % format_func(func))
+    sys.stdout.flush()
+
+    # figure out how many times we have to run the function to
+    # get reliable timings.
+    for i in xrange(3, 10):
+        rounds = 1 << i
+        t = timer()
+        for x in xrange(rounds):
+            func()
+        if timer() - t >= 0.2:
+            break
+
+    # now run the tests without gc TEST_RUNS times and use the median
+    # value of these runs.
+    def _run():
+        gc.collect()
+        gc.disable()
+        try:
+            t = timer()
+            for x in xrange(rounds):
+                func()
+            return (timer() - t) / rounds * 1000
+        finally:
+            gc.enable()
+
+    delta = median(_run() for x in xrange(TEST_RUNS))
+    sys.stdout.write('%.4f\n' % delta)
+    sys.stdout.flush()
+
+    return delta
+
+
+def main():
+    """The main entrypoint."""
+    from optparse import OptionParser
+    parser = OptionParser(usage='%prog [options]')
+    parser.add_option('--werkzeug-path', '-p', dest='path', default='..',
+                      help='the path to the werkzeug package. defaults to cwd')
+    parser.add_option('--compare', '-c', dest='compare', nargs=2,
+                      default=False, help='compare two hg nodes of Werkzeug')
+    parser.add_option('--init-compare', dest='init_compare',
+                      action='store_true', default=False,
+                      help='Initializes the comparison feature')
+    options, args = parser.parse_args()
+    if args:
+        parser.error('Script takes no arguments')
+    if options.compare:
+        compare(*options.compare)
+    elif options.init_compare:
+        init_compare()
+    else:
+        run(options.path)
+
+
+def init_compare():
+    """Initializes the comparison feature."""
+    print('Initializing comparison feature')
+    subprocess.Popen(['hg', 'clone', '..', 'a']).wait()
+    subprocess.Popen(['hg', 'clone', '..', 'b']).wait()
+
+
+def compare(node1, node2):
+    """Compares two Werkzeug hg versions."""
+    if not os.path.isdir('a'):
+        print >> sys.stderr, 'error: comparison feature not initialized'
+        sys.exit(4)
+
+    print('=' * 80)
+    print('WERKZEUG INTERNAL BENCHMARK -- COMPARE MODE'.center(80))
+    print('-' * 80)
+
+    def _error(msg):
+        print >> sys.stderr, 'error:', msg
+        sys.exit(1)
+
+    def _hg_update(repo, node):
+        hg = lambda *x: subprocess.call(['hg'] + list(x), cwd=repo,
+                                        stdout=null_out, stderr=null_out)
+        hg('revert', '-a', '--no-backup')
+        client = subprocess.Popen(['hg', 'status', '--unknown', '-n', '-0'],
+                                  stdout=subprocess.PIPE, cwd=repo)
+        unknown = client.communicate()[0]
+        if unknown:
+            client = subprocess.Popen(['xargs', '-0', 'rm', '-f'], cwd=repo,
+                                      stdout=null_out, stdin=subprocess.PIPE)
+            client.communicate(unknown)
+        hg('pull', '../..')
+        hg('update', node)
+        if node == 'tip':
+            diff = subprocess.Popen(['hg', 'diff'], cwd='..',
+                                    stdout=subprocess.PIPE).communicate()[0]
+            if diff:
+                client = subprocess.Popen(['hg', 'import', '--no-commit', '-'],
+                                          cwd=repo, stdout=null_out,
+                                          stdin=subprocess.PIPE)
+                client.communicate(diff)
+
+    _hg_update('a', node1)
+    _hg_update('b', node2)
+    d1 = run('a', no_header=True)
+    d2 = run('b', no_header=True)
+
+    print('DIRECT COMPARISON'.center(80))
+    print('-' * 80)
+    for key in sorted(d1):
+        delta = d1[key] - d2[key]
+        if abs(1 - d1[key] / d2[key]) < TOLERANCE or \
+           abs(delta) < MIN_RESOLUTION:
+            delta = '=='
+        else:
+            delta = '%+.4f (%+d%%)' % \
+                (delta, round(d2[key] / d1[key] * 100 - 100))
+        print('%36s   %.4f    %.4f    %s' %
+              (format_func(key), d1[key], d2[key], delta))
+    print('-' * 80)
+
+
+def run(path, no_header=False):
+    path = os.path.abspath(path)
+    wz_version, hg_tag = load_werkzeug(path)
+    result = {}
+    if not no_header:
+        print('=' * 80)
+        print('WERKZEUG INTERNAL BENCHMARK'.center(80))
+        print('-' * 80)
+    print('Path:    %s' % path)
+    print('Version: %s' % wz_version)
+    if hg_tag is not None:
+        print('HG Tag:  %s' % hg_tag)
+    print('-' * 80)
+    for key, value in sorted(globals().items()):
+        if key.startswith('time_'):
+            before = globals().get('before_' + key[5:])
+            if before:
+                before()
+            result[key] = bench(value)
+            after = globals().get('after_' + key[5:])
+            if after:
+                after()
+    print('-' * 80)
+    return result
+
+
+URL_DECODED_DATA = dict((str(x), str(x)) for x in xrange(100))
+URL_ENCODED_DATA = '&'.join('%s=%s' % x for x in URL_DECODED_DATA.items())
+MULTIPART_ENCODED_DATA = '\n'.join((
+    '--foo',
+    'Content-Disposition: form-data; name=foo',
+    '',
+    'this is just bar',
+    '--foo',
+    'Content-Disposition: form-data; name=bar',
+    '',
+    'blafasel',
+    '--foo',
+    'Content-Disposition: form-data; name=foo; filename=wzbench.py',
+    'Content-Type: text/plain',
+    '',
+    open(__file__.rstrip('c')).read(),
+    '--foo--'
+))
+MULTIDICT = None
+REQUEST = None
+TEST_ENV = None
+LOCAL = None
+LOCAL_MANAGER = None
+
+
+def time_url_decode():
+    wz.url_decode(URL_ENCODED_DATA)
+
+
+def time_url_encode():
+    wz.url_encode(URL_DECODED_DATA)
+
+
+def time_parse_form_data_multipart():
+    # use a hand written env creator so that we don't bench
+    # from_values which is known to be slowish in 0.5.1 and higher.
+    # we don't want to bench two things at once.
+    environ = {
+        'REQUEST_METHOD':   'POST',
+        'CONTENT_TYPE':     'multipart/form-data; boundary=foo',
+        'wsgi.input':       StringIO(MULTIPART_ENCODED_DATA),
+        'CONTENT_LENGTH':   str(len(MULTIPART_ENCODED_DATA))
+    }
+    request = wz.Request(environ)
+    request.form
+
+
+def before_multidict_lookup_hit():
+    global MULTIDICT
+    MULTIDICT = wz.MultiDict({'foo': 'bar'})
+
+
+def time_multidict_lookup_hit():
+    MULTIDICT['foo']
+
+
+def after_multidict_lookup_hit():
+    global MULTIDICT
+    MULTIDICT = None
+
+
+def before_multidict_lookup_miss():
+    global MULTIDICT
+    MULTIDICT = wz.MultiDict()
+
+
+def time_multidict_lookup_miss():
+    try:
+        MULTIDICT['foo']
+    except KeyError:
+        pass
+
+
+def after_multidict_lookup_miss():
+    global MULTIDICT
+    MULTIDICT = None
+
+
+def time_cached_property():
+    class Foo(object):
+        @wz.cached_property
+        def x(self):
+            return 42
+
+    f = Foo()
+    for x in xrange(60):
+        f.x
+
+
+def before_request_form_access():
+    global REQUEST
+    data = 'foo=bar&blah=blub'
+    REQUEST = wz.Request({
+        'CONTENT_LENGTH':        str(len(data)),
+        'wsgi.input':            StringIO(data),
+        'REQUEST_METHOD':        'POST',
+        'wsgi.version':          (1, 0),
+        'QUERY_STRING':          data,
+        'CONTENT_TYPE':          'application/x-www-form-urlencoded',
+        'PATH_INFO':             '/',
+        'SCRIPT_NAME':           ''
+    })
+
+
+def time_request_form_access():
+    for x in xrange(30):
+        REQUEST.path
+        REQUEST.script_root
+        REQUEST.args['foo']
+        REQUEST.form['foo']
+
+
+def after_request_form_access():
+    global REQUEST
+    REQUEST = None
+
+
+def time_request_from_values():
+    wz.Request.from_values(base_url='http://www.google.com/',
+                           query_string='foo=bar&blah=blaz',
+                           input_stream=StringIO(MULTIPART_ENCODED_DATA),
+                           content_length=len(MULTIPART_ENCODED_DATA),
+                           content_type='multipart/form-data; '
+                                        'boundary=foo', method='POST')
+
+
+def before_request_shallow_init():
+    global TEST_ENV
+    TEST_ENV = wz.create_environ()
+
+
+def time_request_shallow_init():
+    wz.Request(TEST_ENV, shallow=True)
+
+
+def after_request_shallow_init():
+    global TEST_ENV
+    TEST_ENV = None
+
+
+def time_response_iter_performance():
+    resp = wz.Response(u'Hällo Wörld ' * 1000,
+                       mimetype='text/html')
+    for item in resp({'REQUEST_METHOD': 'GET'}, lambda *s: None):
+        pass
+
+
+def time_response_iter_head_performance():
+    resp = wz.Response(u'Hällo Wörld ' * 1000,
+                       mimetype='text/html')
+    for item in resp({'REQUEST_METHOD': 'HEAD'}, lambda *s: None):
+        pass
+
+
+def before_local_manager_dispatch():
+    global LOCAL_MANAGER, LOCAL
+    LOCAL = wz.Local()
+    LOCAL_MANAGER = wz.LocalManager([LOCAL])
+
+
+def time_local_manager_dispatch():
+    for x in xrange(10):
+        LOCAL.x = 42
+    for x in xrange(10):
+        LOCAL.x
+
+
+def after_local_manager_dispatch():
+    global LOCAL_MANAGER, LOCAL
+    LOCAL = LOCAL_MANAGER = None
+
+
+def before_html_builder():
+    global TABLE
+    TABLE = [['col 1', 'col 2', 'col 3', '4', '5', '6'] for x in range(10)]
+
+
+def time_html_builder():
+    html_rows = []
+    for row in TABLE:  # noqa
+        html_cols = [wz.html.td(col, class_='col') for col in row]
+        html_rows.append(wz.html.tr(class_='row', *html_cols))
+    wz.html.table(*html_rows)
+
+
+def after_html_builder():
+    global TABLE
+    TABLE = None
+
+
+if __name__ == '__main__':
+    os.chdir(os.path.dirname(__file__) or os.path.curdir)
+    try:
+        main()
+    except KeyboardInterrupt:
+        print >> sys.stderr, 'interrupted!'
diff --git a/docs/_themes/werkzeug_theme_support.pyc b/docs/_themes/werkzeug_theme_support.pyc
deleted file mode 100644
index 97bb328..0000000
Binary files a/docs/_themes/werkzeug_theme_support.pyc and /dev/null differ
diff --git a/docs/contents.rst.inc b/docs/contents.rst.inc
index 7615eae..d5d29a8 100644
--- a/docs/contents.rst.inc
+++ b/docs/contents.rst.inc
@@ -36,6 +36,7 @@ Reference
    wrappers
    routing
    wsgi
+   filesystem
    http
    datastructures
    utils
diff --git a/docs/debug.rst b/docs/debug.rst
index a8ae084..0ccc186 100644
--- a/docs/debug.rst
+++ b/docs/debug.rst
@@ -16,7 +16,8 @@ The interactive debugger however does not work in forking environments
 which makes it nearly impossible to use on production servers.  Also the
 debugger allows the execution of arbitrary code which makes it a major
 security risk and **must never be used on production machines** because of
-that.
... 8827 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-werkzeug.git



More information about the Python-modules-commits mailing list