Home | History | Annotate | Download | only in webapp2
      1 Version 2.5.1 - February 07, 2012
      2 ---------------------------------
      3 - Bug fix release related to request charset in old versions of
      4 	WebOb.
      5 
      6 Version 2.5 - February 01, 2012
      7 -------------------------------
      8 
      9 Version 2.4 - January 23, 2012
     10 ------------------------------
     11 - Maintenance release. Fixed outstanding bugs related to App Engine.
     12 - Removed webapp2_extras/protorpc, broken since webapp2 was added
     13 	to App Engine.
     14 
     15 
     16 Version 2.3 - August 24, 2011
     17 -----------------------------
     18 - webapp2.Response.out creates a reference loop that impedes garbage
     19 	collection. Changing it to a property fixed this (Issue #15).
     20 - webapp2_extras.i18n:
     21 	- When in debug mode, translations are not cached, so compiling new
     22 		translations make them readily available (Issue #13).
     23 - webapp2_extras.auth:
     24 	- ATTENTION: auth_id is no longer converted to lower case to retrieve
     25 		a key or save a new user in webapp2_extras.appengine.auth.models.User.
     26 		This is a more general approach, as not all systems use case-insensitive
     27 		user ids. If you want case-insensitive auth ids, convert them to lower
     28 		case before passing auth ids to the auth module (Issue #14).
     29 	- If user data is missing attributes, don't raise AssertionError.
     30 		Simply don't save or return a valid session, instead.
     31 	- call user_model.get_id() instead of the ndb-specific user.key.id().
     32 	- removed set_password_validator() and set_token_validator().
     33 		They add complexity to the API without a use case to justify.
     34 		Extend AuthStore to achieve the same thing.
     35 
     36 
     37 Version 2.2.3 - August 6, 2011
     38 ------------------------------
     39 - Version 2.2.2 missed the webapp2_extras.appengine package.
     40 
     41 - get_app() and get_request() now test that app and request are set, to avoid
     42 	hard to debug stack traces when they are not and the local proxy is used.
     43 
     44 
     45 Version 2.2.2 - August 5, 2011 (more 2's than ever!)
     46 ----------------------------------------------------
     47 - A default charset is always set in the Request object: if it is not defined
     48 	in the constructor, environ['CONTENT_TYPE'] is checked; and if it is still
     49 	not defined 'utf-8' is used.
     50 
     51 - Added token_model as an attribute of the User model; it is used instead of
     52 	the hardcoded class.
     53 
     54 
     55 Version 2.2.1 - August 1st, 2011
     56 --------------------------------
     57 - Fixed a bug in WSGIApplication.run() when running outside of App Engine:
     58 	CGIHandler().run(app) -> CGIHandler().run(self). (issue 9)
     59 
     60 
     61 Version 2.2 - July 30, 2011
     62 ===========================
     63 - Revised webapp2_extras.auth and simplified User model, by Kyle Finley.
     64 	Thanks!
     65 
     66 
     67 Version 2.1 - July 29, 2011
     68 ===========================
     69 - Added webapp2_extras.auth: high-level utilities for authentication and
     70 	authorization.
     71 
     72 - Added webapp2_extras.appengine.auth.models: default model implementations
     73 	for webapp2_extras.auth (can be overridden).
     74 
     75 - Added webapp2_extras.appengine.ndb.unique_model: a model to store unique
     76 	values. This was added mainly so that the default user model can have
     77 	multiple unique properties.
     78 
     79 - import_string() now displays useful debug information when it fails.
     80 
     81 - To make things clearly separated specially for those using webapp2
     82 	outside of App Engine, from now on all App Engine-specific modules will
     83 	be placed in webapp2_extras.appengine. Also three modules were moved to
     84 	the new package:
     85 
     86 	- webapp2_extras.sessions_memcache
     87 	- webapp2_extras.sessions_ndb
     88 	- webapp2_extras.users
     89 
     90 	The original modules were not removed, though: they will be kept in the same
     91 	place for compatibility purposes, just importing their stuff from the new
     92 	locations.
     93 
     94 - Config.load_config() now makes a copy of the configuration when user_values
     95 	are passed. That keyword is meant to override app configuration, so the
     96 	previous behavior was actually wrong. This is a side feature not used inside
     97 	webapp2 or even well documented so the change should not affect existing
     98 	apps.
     99 
    100 
    101 Version 2.0.2 - July 18, 2011
    102 =============================
    103 - cached_property now uses threading.RLock for thread-safety.
    104 
    105 
    106 Version 2.0.1 - July 17, 2011
    107 =============================
    108 - Little fix: use google.appengine.ext.webapp.util if available, like before.
    109 
    110 
    111 Version 2.0 - July 17, 2011
    112 ===========================
    113 - Added support for the (not yet released) App Engine Python 2.7 SDK.
    114 
    115 - Deprecated webapp2_extras.local_app. WSGIApplication is now thread-safe
    116 	by default when webapp2_extras.local is available.
    117 	webapp2_extras.local_app.WSGIApplication can still be imported, but it is
    118 	just an alias to webapp2.WSGIApplication (and a deprecation warning is
    119 	emitted when it is imported).
    120 
    121 - Like DomainRoute, PathPrefixRoute now only tests the nested routes if the
    122 	prefix matches. So now it is not only convenient but matches smartly and
    123 	faster. ;)
    124 
    125 - Added webapp2_extras.security, with security related helpers such as secure
    126 	password hashing tools.
    127 
    128 - webapp2_extras.sessions:
    129 	- Now uses webapp2_extras.security.create_token() to generate session IDs
    130 		instead of uuid.
    131 	- Added 'backends' configuration: get_session() can now be called passing
    132 		a more convenient 'backend' key. Default ones are 'securecookie',
    133 		'datastore' and 'memcache'.
    134 
    135 - get_build_routes() now yields (name, route) instead of simply route. This
    136 	will allow routes with nested routes to act as a proxy to build URIs.
    137 
    138 - webapp2.urlunsplit() was removed from the public API.
    139 
    140 - Variables names in routes must now look like python identifiers -
    141 	this means that they can no longer start with a number, like before.
    142 
    143 - Removed support for _anchor in uri_for() -- the documented keyword is
    144 	_fragment.
    145 
    146 - Removed support for handler functions receiving (request, response). The
    147 	correct arguments for function handlers are (request, *args, **kwargs).
    148 
    149 - webapp2_extras.json:
    150 	- Fixed an issue with importing json on non-GAE environments (missing
    151 		absolute import).
    152 	- Now imports simplejson directly instead of using the one from Django,
    153 		since it is now included in the App Engine SDK (since version 1.4.2).
    154 
    155 - Added WSGIApplication.clear_globals(). Instead of
    156 	app.set_globals(app=None, request=None), use app.clear_globals().
    157 
    158 
    159 Version 1.8.1 - June 29, 2011
    160 =============================
    161 - Implemented an adapter mechanism to dispatch different kind of handlers:
    162 	webapp.RequestHandler, webapp2.RequestHandler and "view functions".
    163 	Instead of monkeypatching handlers (adding a 'factory' attribute),
    164 	handlers are wrapped by adapters that do the appropriate dispatch.
    165 	How handlers are adapted can be overridden using the convenience method
    166 	``set_adapter()`` from the Router class, but the common cases are covered.
    167 
    168 - Function views now conveniently receive (request, *args, **kwargs), like
    169 	in Django. The previous arguments will work, but they are now deprecated
    170 	and will not be supported in the future. This is a major incompatibility
    171 	with previous versions but it feels a lot better than the previous
    172 	(request, response) behavior, as adapters make it easy to have custom
    173 	dispatch arguments using a unified API.
    174 	The webapp2.RequestHandler class remain unchanged and is instantiated with
    175 	(request, response).
    176 
    177 
    178 Version 1.8 - June 26, 2011
    179 ===========================
    180 - webap2_extras.i18n: the functions passed to I18nStore.set_locale_selector()
    181 	and I18nStore.set_timezone_selector() now receive (store, request) instead of
    182 	(request, store), for consistency with the router custom callables.
    183 
    184 - webap2_extras.json:
    185 	- json is imported first trying direct simplejson, then built-in json
    186 		(for Python >= 2.6), then the one from django.utils (for App Engine).
    187 	- All convenience functions now receive *args, **kwargs to be passed to
    188 		encode()/decode().
    189 
    190 - Added webapp2_extras.mako.
    191 
    192 - Added webapp2.redirect_to.
    193 
    194 - Added Request.blank() parameters compatible with WebOb >= 1.0: POST and
    195 	**kwargs.
    196 
    197 - Increased compatibility with wsgiref.headers.Headers, used by
    198 	webapp.Response.
    199 
    200 
    201 Version 1.7.5 - June 20, 2011
    202 =============================
    203 - Implemented methods from ``wsgiref.headers.Headers``, used by
    204 	webapp.Response.headers.
    205 
    206 
    207 Version 1.7.4 - June 19, 2011
    208 =============================
    209 - Fixed bug in response.status_message.
    210 
    211 
    212 Version 1.7.3 - June 17, 2011
    213 =============================
    214 - Routes can now only match specific schemes, e.g., 'http' or 'https'.
    215 
    216 - Added a tutorial to use webapp2 outside of App Engine.
    217 
    218 
    219 Version 1.7.2 - June 16, 2011
    220 =============================
    221 - Response is now compatible with latest WebOb.
    222 
    223 - Increased Response compatibility with webapp, implementing wsgi_write() and
    224 	has_error().
    225 
    226 - Changed some status messages to be the same as webapp:
    227 	- 203: 'Non-Authoritative Information'
    228 	- 302: 'Moved Temporarily'
    229 	- 306: 'Unused'
    230 	- 408: 'Request Time-out'
    231 	- 414: 'Request-URI Too Large'
    232 	- 504: 'Gateway Time-out'
    233 	- 505: 'HTTP Version not supported'
    234 
    235 - Copied Request from webapp, so that when using webapp2 outside of the SDK
    236 	they are the same.
    237 
    238 - Routes now match the Request path unquoted. See App Engine issue #2636
    239 	for an explanation.
    240 
    241 
    242 Version 1.7.1 - June 14, 2011
    243 =============================
    244 - Added standalone redirect() function.
    245 
    246 - RequestHandler.redirect and redirect_to now return a response object.
    247 
    248 - Fixed: multiple routes that define methods are tried before MethodNotAllowed
    249 	is raised.
    250 
    251 - Updated webapp2_extras.protorpc to work with latest ProtoRPC.
    252 
    253 
    254 Version 1.7 - June 4, 2011
    255 ==========================
    256 - Added a simple configuration object for WSGIapplication, available in the
    257 	config attribute. Extras modules that use configuration (i18n, jinja2,
    258 	sessions) don't require app.config to be set manually anymore. Still, the
    259 	`secret_key` key config for sessions, if not defined, will result in an
    260 	exception.
    261 
    262 - Deprecated webapp2_extras.config, replaced by the simpler app dict.
    263 
    264 - Router no longer receives app on construction, for consistency with the
    265 	config object. App is set as global before router is initialized.
    266 
    267 - Fixed a bug in webapp2_extras.sessions that made it not save the session
    268 	when it was empty (like when flashes are popped).
    269 
    270 - Added standalone uri_for function, to be used in templates.
    271 
    272 
    273 Version 1.6.3 - June 3, 2011
    274 ============================
    275 - Added webap2_extras.local_app, with the WSGIApplication previously in
    276 	webap2_extras.local. This allows using LocalProxy on App Engine, without
    277 	actually monkeypatching the WSGI app for threaded environments.
    278 
    279 - Route now raises exc.HTTPMethodNotAllowed if methods are set and the request
    280 	method doesn't match.
    281 
    282 - Router.default_matcher() now raises exc.HTTPNotFound if no route matches.
    283 
    284 
    285 Version 1.6.2 - May 30, 2011
    286 ============================
    287 - WSGIApplication.__call__ checks if the dispatcher didn't return None to
    288 	accept the returned value as a response. Previously it checked if it was an
    289 	instance of Response.
    290 
    291 - To support returned response, RequestHandler.dispatch() returns the result of
    292 	the dispatched method.
    293 
    294 Version 1.6.1 - May 30, 2011
    295 ============================
    296 - Fixed an indentation bug in webapp2_extras.users.
    297 
    298 - Added back _to_utf8() to convert values for import_string() and urlunsplit().
    299 
    300 - Added WSGIApplication.get_response(), a convenience for unit tests.
    301 
    302 
    303 Version 1.6 - May 29, 2011
    304 ==========================
    305 - Handlers registered in WSGIApplication.error_handlers can now also be a
    306 	string to be lazily imported.
    307 
    308 - The request object now has the active response available as an attribute:
    309 	request.response.
    310 
    311 - Added a factory method to RequestHandler, to better deal with libraries that
    312 	use a custom webapp.RequestHandler constructors (like ProtoRPC).
    313 
    314 - Added set_dispatcher() to Router, to set extended dispatching.
    315 
    316 - Handlers and error handlers can now return a response object, which will be
    317 	used instead of the default response created by the WSGI app. This allows
    318 	webapp2 to be used following the common pattern of handlers that return a
    319 	response, instead of the webapp way of a handler that writes to an existing
    320 	response.
    321 
    322 - Request.Handler.redirect() now can receive a `code` parameter, to set the
    323 	status code. This is preferable than the `permanent` parameter, kept for
    324 	compatibility with webapp.
    325 
    326 - webapp2 is now a file webapp2.py, instead of a package with a __init__.py
    327 	file.
    328 
    329 - API cleanup:
    330 	- Removed WSGIApplication.url_for(), to_unicode(), to_utf8().
    331 	- RequestHandler.url_for was renamed to uri_for, with url_for kept
    332 		as an alias.
    333 	- Renamed webapp2_extras.routes.ImprovedRoute to RedirectRoute, as it
    334 		basically adds redirect conveniences.
    335 	- For consistency with uri building parameters, RedirectHandler parameters
    336 		are now prefixed with a underscore: `url` becomes `_uri` and `permanent`
    337 		becomes `_permanent`. A parameter `_code` was added to set status code.
    338 	- Router.do_match and do_build renamed to default_matcher and
    339 		default_dispatcher.
    340 	- URI building accepts a _fragment argument, with _anchor as fallback.
    341 
    342 
    343 Version 1.5 - May 16, 2011
    344 ==========================
    345 - Added webapp2_extras.local, with an extended WSGIApplication that uses
    346 	thread-local for globals and so can be used outside of App Engine.
    347 
    348 - Added webapp2_extras.protorpc, with support for Google ProtoRPC.
    349 
    350 - Added set_matcher() and set_builder() to Router, to set extended matcher and
    351 	builder.
    352 
    353 - Routes now return the route on match() or routes with nested routes cannot
    354 	work. So instead of returning (args, kwargs) they return
    355 	(route, args, kwargs).
    356 
    357 - Now handlers only receive **args if no named variables are set. Otherwise,
    358 	they only receive **kwargs. This allows users to use regexes that are not
    359 	intended to be captured, mixing named and unnamed variables.
    360 
    361 - DomainRoute now uses the same syntax used by webapp2.Route, instead of a
    362 	regex. The resulting keywords are added to the mathed route **kwargs.
    363 	This gives control of what is passed to the handler if a domain/subdomain
    364 	matches, and allows to not pass anything if no regex groups are defined.
    365 
    366 - Several small bugs fixed and increased test coverage in webapp2_extras.
    367 
    368 
    369 Version 1.3 - May 9, 2011
    370 =========================
    371 - Added webapp2_extras modules:
    372 	- webapp2_extras.i18n: internationalization support.
    373 	- webapp2_extras.sessions_memcache: memcache based sessions.
    374 	- webapp2_extras.sessions_ndb: datastore based sessions.
    375 - Several api improvements in webapp2_extras.
    376 
    377 
    378 Version 1.2 - May 6, 2011
    379 =========================
    380 - Removed Config from webapp2 core. It is now part of the new "webapp2_extras"
    381 	package.
    382 - Added the package webapp2_extras. These are all optional modules that
    383 	complement webapp2 with common functionalities. Currently they include:
    384 	- webapp2_extras.config: Configuration object.
    385 	- webapp2_extras.jinja2: Support for Jinja2 templating.
    386 	- webapp2_extras.json: JSON utilities.
    387 	- webapp2_extras.routes: Extended route classes.
    388 	- webapp2_extras.securecookie: Signed cookie serializer.
    389 	- webapp2_extras.sessions: Sessions support.
    390 
    391 
    392 Version 1.1 - May 5, 2011
    393 =========================
    394 - Simplified routing with an unified dispatch method for classes and functions.
    395 
    396 
    397 Version 1.0 - May 1st, 2011
    398 ===========================
    399 This is a major refactoring with some incompatible changes, mostly internal
    400 stuff that won't be noticed in common usage.
    401 
    402 - Changed signature of RequestHandler's constructor: it now receives only
    403 	(request, response) instead of (app, request, response).
    404 
    405 - Added RequestContext class, which should help testing.
    406 
    407 - Added .app attribute to Request, a reference to the active app.
    408 
    409 - Refactored routing scheme:
    410 	- Now also supports function views besides classes.
    411 	- Now also supports normal functions as exception handlers, and exception
    412 		handlers don't need to be a subclass RequestHandler (but still can).
    413 	- Now also supports custom handler methods besides using the request method.
    414 
    415 - Removed Request.context: was redundant with Request.registry.
    416 
    417 - Renamed WSGIApplication.wsgi_app to WSGIApplication.dispatch.
    418 
    419 - Moved ALLOWED_METHODS to WSGIApplication.allowed_methods.
    420 
    421 - Moved get_valid_methods() to RequestHandler.get_valid_methods().
    422 
    423 
    424 Version 0.7 - September 26, 2010
    425 ================================
    426 - Added WSGIApplication.app and WSGIApplication.request, class attributes set
    427 	on each request to reference currently active app and request.
    428 	WSGIApplication.app is an alias to WSGIApplication.active_instance.
    429 
    430 - Fixed double escaping of + in urlunsplit(). Thanks, alkis.
    431 
    432 - IMPROVED: configuration now behaves exactly like a dictionary, still
    433 	auto-loading configuration values when needed and honoring required configs.
    434 	For example, we always used this::
    435 
    436 			bar = self.app.get_config('foo', 'bar')
    437 
    438 	Now it is also possible to use direct access and dict methods::
    439 
    440 			bar = self.app.config['foo']['bar']
    441 			# or...
    442 			bar = self.app.config['foo'].get('bar')
    443 			# or...
    444 			bar = self.app.config.get('foo').get('bar')
    445 
    446 	The previous get_config() method works as always.
    447 
    448 
    449 Version 0.6 - August 31, 2010
    450 =============================
    451 - Fix: Anchors in generated URLs are quoted using urlib.quote, instead of
    452 	urlib.quote_plus.
    453 
    454 - In Router.dispatch(), if an exception occurs while handling an exception,
    455 	raise it instead of trying to handle it again.
    456 
    457 - Fixed bug when writing a unicode string to Response and charset is not set.
    458 	Thanks to martinc for the patch.
    459 
    460 - Changed: the app won't fallback anymore to the exception handler set for
    461 	status 500 if handlers for other status are not set.
    462 
    463 - Changed: exceptions are only logged when unhandled. It is up to exception
    464 	handlers to log them when appropriate.
    465 
    466 
    467 Version 0.5.1 - August 17, 2010
    468 ===============================
    469 - When a URL matches, some attributes are set in the request object:
    470 	- request.route: the matched route
    471 	- request.route_args: the matched positional arguments, a tuple
    472 	- request.route_kwargs: the matched keyword arguments, a dict
    473 
    474 - WSGIApplication.handle_exception() doesn't automatically raises the exception
    475 	when in debug mode: it is up to the error handler to raise it if in dev; it
    476 	will be raised if no error handler is defined to handle it anyway.
    477 
    478 - Added attributes, WSGIApplication.registry, Request.registry and
    479 	Request.context, dictionaries for objects in use during the app or request
    480 	lifetimes.
    481 
    482 - Before passing the request method to the RequestHandler, '-' is replaced
    483 	by '_', so that a method like WebDav's 'VERSION-CONTROL' can be supported.
    484 
    485 - Config.get() now only returns the passed default value when key is defined.
    486 	This is the intended, more predictable behavior: default is a default for
    487 	the key, not the module. For example::
    488 
    489 			# If config['foo']['bar'] is not set, return 'baz'.
    490 			config.get('foo', 'bar', default='baz')
    491 
    492 			# If config['foo'] is not set, return None. Default is ignored here.
    493 			config.get('foo', default='baz')
    494 
    495 - Router initialization now receives the app as parameter, so that extended
    496 	routes can access app's config.
    497 
    498 
    499 Version 0.5 - August 13, 2010
    500 =============================
    501 - Better compatibility with webapp:
    502 	- webapp2.WSGIapplication can be used with webapp.RequestHandler.
    503 	- webapp.WSGIapplication can be used with webapp2.RequestHandler.
    504 
    505 	Although the functionality becomes limited in both cases, this should help
    506 	migration.
    507 
    508 - Review of Response based on observations from
    509 	http://pythonpaste.org/webob/differences.html#webapp-response:
    510 
    511 	- Response.out is now a reference to self, to use webob.Response's neat
    512 		.write() method which can handle both string and unicode.
    513 	- Response.clear() now sets .body = '' instead of .app_iter = [].
    514 
    515 - Added Response.write(), for compatibility with StringIO behavior in webapp
    516 	when calling write() passing non-basestring values (issue 2).
    517 
    518 - Removed url_escape() and url_unescape(). Unused or almost unused.
    519 
    520 - ErrorHandlers can now be defined as strings to be lazily loaded, as they
    521 	now use the same dispatch mechanism of other handlers.
    522 
    523 Backwards compatibility warning
    524 -------------------------------
    525 - The method handle_exception() is called from app-wide error handlers.
    526 	Previously, get() was called.
    527 
    528 
    529 Version 0.4.1 - August 08, 2010
    530 ===============================
    531 - Removed router parameter from get_routes(), get_match_routes(),
    532 	get_build_routes(). This simplifies multi-routes quite a bit.
    533 
    534 
    535 Version 0.4 - August 07, 2010
    536 =============================
    537 - redirect() and redirect_to() now accept a keyword argument 'abort' to raise
    538 	an exception to do the redirect.
    539 
    540 - '_netloc' can be passed to url_for() build URLs for a given domain or
    541 	subdomain.
    542 
    543 - Added BaseRoute, an interface for custom routes. Several improvements make
    544 	the routing system more extensible, while the default Route class sticks to
    545 	the basics.
    546 
    547 - Nested routes are now possible. As an example, `extras/routes.py` has several
    548 	classes that accept nested routes or extend routing in other ways:
    549 
    550 	- PathPrefixRoute: the idea of this route is to set a base path for other
    551 		routes::
    552 
    553 				app = WSGIApplication([
    554 						PathPrefixRoute('/users/<user:\w+>', [
    555 								Route('/', UserOverviewHandler, 'user-overview'),
    556 								Route('/profile', UserProfileHandler, 'user-profile'),
    557 								Route('/projects', UserProjectsHandler, 'user-projects'),
    558 						]),
    559 				])
    560 
    561 		The example above is the same as setting the following routes, just more
    562 		convenient as you can reuse the path prefix::
    563 
    564 				app = WSGIApplication([
    565 						Route('/users/<user:\w+>/', UserOverviewHandler, 'user-overview'),
    566 						Route('/users/<user:\w+>/profile', UserProfileHandler, 'user-profile'),
    567 						Route('/users/<user:\w+>/projects', UserProjectsHandler, 'user-projects'),
    568 				])
    569 
    570 	- NamePrefixRoute: Same as PathPrefixRoute, but prefixes the names of routes.
    571 
    572 	- HandlerPrefixRoute: Same as PathPrefixRoute, but prefixes the handlers of
    573 		routes.
    574 
    575 	- DomainRoute: a route used to restrict route matches to a given domain or
    576 		subdomain.
    577 
    578 		For example, to restrict routes to a subdomain of the appspot domain::
    579 
    580 				SUBDOMAIN_RE = '^([^.]+)\.app-id\.appspot\.com$'
    581 
    582 				app = WSGIApplication([
    583 						DomainRoute(SUBDOMAIN_RE, [
    584 								Route('/foo', 'FooHandler', 'subdomain-thing'),
    585 						]),
    586 						Route('/bar', 'BarHandler', 'normal-thing'),
    587 				])
    588 
    589 	- ImprovedRoute: a route with redirect_to and strict_slash.
    590 
    591 		- `redirect_to`: if set, the route is used to redirect to a URL. The value
    592 			 can be a URL string or a callable that returns a URL. These two are
    593 			 equivalent::
    594 
    595 					route = Route('/foo', RedirectHandler, defaults={'url': '/bar'})
    596 					route = Route('/foo', redirect_to='/bar')
    597 
    598 		- `strict_slash`: if True, redirects access to the same URL with different
    599 			trailing slash to the strict path defined in the rule. For example, take
    600 			these rules::
    601 
    602 					route = Route('/foo', FooHandler, strict_slash=True)
    603 					route = Route('/bar/', BarHandler, strict_slash=True)
    604 
    605 			Because **strict_slash** is True, this is what will happen:
    606 
    607 			- Access to ``/foo`` will execute ``FooHandler`` normally.
    608 			- Access to ``/bar/`` will execute ``BarHandler`` normally.
    609 			- Access to ``/foo/`` will redirect to ``/foo``.
    610 			- Access to ``/bar`` will redirect to ``/bar/``.
    611 
    612 
    613 Version 0.3 - August 05, 2010
    614 =============================
    615 - Routes store the handler, as we had in 0.1. This allows custom routes to
    616 	have nested routes.
    617 - Much improved URL building, now delegated to routes.
    618 - added urlunsplit() helper.
    619 
    620 
    621 Version 0.2 - August 04, 2010
    622 =============================
    623 - Fixed a bug in Route.match() that would make it return positional arguments
    624 	with wrong order. Dictionary is correctly sorted now.
    625 - Added build_only option for routes: routes that are only used for url_for()
    626 	and never match.
    627 
    628 
    629 Version 0.1 - August 03, 2010
    630 =============================
    631 - Initial release.
    632