diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..7604382 --- /dev/null +++ b/.flake8 @@ -0,0 +1,15 @@ +[flake8] +# flake8 added error class "I" that we need to ignore in this project +# as they contradict import grouping as suggested by Google Python Style Guide, +# https://github.com/google/styleguide/blob/gh-pages/pyguide.md#313-imports-formatting +# +# I100: Your import statements are in the wrong order. +# I101: The names in your from import are in the wrong order. +# I201: Missing newline between import groups. +# I202: Additional newline in a group of imports. +# W503: line break before binary operator - see updated PEP8 (01-Aug-2013) +# DEFAULTS: E121, E123, E126, E133, E226, E241, E242, E704, W503, W504 and W505 +# are ignored because they are not rules unanimously accepted +# +# ATTENTION: Replaces all default ignores: +ignore = I100,I101,I201,I202,E121,E123,E126,E133,E226,E241,E242,E704,W503,W505 diff --git a/requirements-dev-gaesdk.txt b/requirements-dev-gaesdk.txt index f2bfad1..2ed95ad 100644 --- a/requirements-dev-gaesdk.txt +++ b/requirements-dev-gaesdk.txt @@ -11,4 +11,4 @@ gaepytz==2011h pytest==2.9.1 pytest-cov==2.2.1 mock==2.0.0 -gcp-devrel-py-tools==0.0.8 +gcp-devrel-py-tools==0.0.15 diff --git a/requirements-dev.txt b/requirements-dev.txt index 648d555..d9acb7d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,4 +9,4 @@ pytest==2.9.1 pytest-cov==2.2.1 mock==2.0.0 six==1.10.0 -gcp-devrel-py-tools==0.0.8 +gcp-devrel-py-tools==0.0.15 diff --git a/tests/extras_routes_test.py b/tests/extras_routes_test.py index 8f35c22..a9810a0 100644 --- a/tests/extras_routes_test.py +++ b/tests/extras_routes_test.py @@ -225,7 +225,7 @@ def test_simple(self): def test_with_variables_name_and_handler(self): router = webapp2.Router([ - PathPrefixRoute('/user/', [ + PathPrefixRoute(r'/user/', [ HandlerPrefixRoute('apps.users.', [ NamePrefixRoute('user-', [ webapp2.Route('/', 'UserOverviewHandler', 'overview'), @@ -301,7 +301,7 @@ def test_simple(self): def test_with_variables_name_and_handler(self): router = webapp2.Router([ DomainRoute('.<:.*>', [ - PathPrefixRoute('/user/', [ + PathPrefixRoute(r'/user/', [ HandlerPrefixRoute('apps.users.', [ NamePrefixRoute('user-', [ webapp2.Route( diff --git a/tests/gae/webapp1_test.py b/tests/gae/webapp2_test.py similarity index 73% rename from tests/gae/webapp1_test.py rename to tests/gae/webapp2_test.py index 3de8f0e..50d1a98 100644 --- a/tests/gae/webapp1_test.py +++ b/tests/gae/webapp2_test.py @@ -13,35 +13,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -from google.appengine.ext import webapp - import test_base import webapp2 -# Old WSGIApplication, new RequestHandler. +# WSGIApplication and RequestHandler of webapp2 +# webapp1 is not supported anymore class NewStyleHandler(webapp2.RequestHandler): def get(self, text): self.response.out.write(text) -app = webapp.WSGIApplication([ - (r'/test/(.*)', NewStyleHandler), -]) - - -# New WSGIApplication, old RequestHandler. -class OldStyleHandler(webapp.RequestHandler): - def get(self, text): - self.response.out.write(text) - - -class OldStyleHandler2(webapp.RequestHandler): - def get(self, text=None): - self.response.out.write(text) - - -class OldStyleHandlerWithError(webapp.RequestHandler): +class NewStyleHandlerWithError(webapp2.RequestHandler): def get(self, text): raise ValueError() @@ -51,27 +34,27 @@ def handle_exception(self, e, debug): app2 = webapp2.WSGIApplication([ - (r'/test/error', OldStyleHandlerWithError), - (r'/test/(.*)', OldStyleHandler), - webapp2.Route(r'/test2/', OldStyleHandler2), + (r'/test/error', NewStyleHandlerWithError), + (r'/test/(.*)', NewStyleHandler), + webapp2.Route(r'/test2/', NewStyleHandler), ]) -class TestWebapp1(test_base.BaseTestCase): - def test_old_app_new_handler(self): +class TestWebapp2(test_base.BaseTestCase): + def test_app_handler(self): req = webapp2.Request.blank('/test/foo') - rsp = req.get_response(app) + rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 200) self.assertEqual(rsp.body, 'foo') req = webapp2.Request.blank('/test/bar') - rsp = req.get_response(app) + rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 200) self.assertEqual(rsp.body, 'bar') - self.assertTrue(issubclass(OldStyleHandler, webapp.RequestHandler)) + self.assertTrue(issubclass(NewStyleHandler, webapp2.RequestHandler)) - def test_new_app_old_handler(self): + def test_handler_200(self): req = webapp2.Request.blank('/test/foo') rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 200) @@ -82,33 +65,33 @@ def test_new_app_old_handler(self): self.assertEqual(rsp.status_int, 200) self.assertEqual(rsp.body, 'bar') - def test_new_app_old_handler_405(self): + def test_handler_405(self): req = webapp2.Request.blank('/test/foo') req.method = 'POST' rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 405) - self.assertEqual(rsp.headers.get('Allow'), None) + self.assertEqual(rsp.headers.get('Allow'), 'GET') - def test_new_app_old_handler_501(self): + def test_handler_405_new_method(self): app2.allowed_methods = list(app2.allowed_methods) + ['NEW_METHOD'] req = webapp2.Request.blank('/test/foo') req.method = 'NEW_METHOD' rsp = req.get_response(app2) - self.assertEqual(rsp.status_int, 501) + self.assertEqual(rsp.status_int, 405) - def test_new_app_old_handler_501_2(self): + def test_handler_501(self): req = webapp2.Request.blank('/test/foo') req.method = 'WHATMETHODISTHIS' rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 501) - def test_new_app_old_handler_with_error(self): + def test_handler_with_error(self): req = webapp2.Request.blank('/test/error') rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 500) self.assertEqual(rsp.body, 'ValueError!') - def test_new_app_old_kwargs(self): + def test_kwargs(self): req = webapp2.Request.blank('/test2/foo') rsp = req.get_response(app2) self.assertEqual(rsp.status_int, 200) @@ -126,11 +109,11 @@ def test_unicode_cookie(self): # So we have to do it. quoted_value = urllib.quote(initial_value.encode('utf-8')) - rsp = webapp.Response() + rsp = webapp2.Response() rsp.headers['Set-Cookie'] = 'app=%s; Path=/' % quoted_value cookie = rsp.headers.get('Set-Cookie') - req = webapp.Request.blank('/', headers=[('Cookie', cookie)]) + req = webapp2.Request.blank('/', headers=[('Cookie', cookie)]) # The stored value is the same quoted value from before. stored_value = req.cookies.get('app') diff --git a/tests/handler_test.py b/tests/handler_test.py index ffb2c3c..45624b3 100644 --- a/tests/handler_test.py +++ b/tests/handler_test.py @@ -163,9 +163,9 @@ def get_redirect_url(handler, **kwargs): webapp2.Route('/methods', MethodsHandler, name='methods'), webapp2.Route('/broken', BrokenHandler), webapp2.Route('/broken-but-fixed', BrokenButFixedHandler), - webapp2.Route('///', None, + webapp2.Route(r'///', None, name='route-test'), - webapp2.Route('/<:\d\d>/<:\d{2}>/<:\w+>', PositionalHandler, + webapp2.Route(r'/<:\d\d>/<:\d{2}>/<:\w+>', PositionalHandler, name='positional'), webapp2.Route('/redirect-me', webapp2.RedirectHandler, defaults={'_uri': '/broken'}), diff --git a/tests/routing_test.py b/tests/routing_test.py index 463d114..fde7bf2 100644 --- a/tests/routing_test.py +++ b/tests/routing_test.py @@ -209,7 +209,7 @@ def test_build_int_variable(self): def test_router_build_error(self): router = Router(None) - router.add(Route('/', None, name='year-page')) + router.add(Route(r'/', None, name='year-page')) url = router.build( Request.blank('/'), 'year-page', (), dict(year='2010')) @@ -233,7 +233,7 @@ def test_reverse_template(self): # Access route.regex just to set the lazy properties. self.assertEqual(route.reverse_template, '/foo/%(bar)s') - route = Route('/foo//', None) + route = Route(r'/foo//', None) route.regex # Access route.regex just to set the lazy properties. self.assertEqual(route.reverse_template, '/foo/%(bar)s/%(baz)s') @@ -259,7 +259,7 @@ def test_build_full_without_request(self): ) def test_positions(self): - template = '/<:\d+>' * 98 + template = r'/<:\d+>' * 98 args = tuple(str(i) for i in range(98)) url_res = '/' + '/'.join(args) diff --git a/webapp2.py b/webapp2.py index e48e7bf..9812a2a 100755 --- a/webapp2.py +++ b/webapp2.py @@ -514,8 +514,8 @@ def wsgi_write(self, start_response): :param start_response: The WSGI-compatible start_response function. """ - if (self.headers.get('Cache-Control') == 'no-cache' and - not self.headers.get('Expires')): + if (self.headers.get('Cache-Control') == 'no-cache' + and not self.headers.get('Expires')): self.headers['Expires'] = 'Fri, 01 Jan 1990 00:00:00 GMT' self.headers['Content-Length'] = str(len(self.body)) @@ -924,7 +924,7 @@ class Route(BaseRoute): def __init__(self, template, handler=None, name=None, defaults=None, build_only=False, handler_method=None, methods=None, schemes=None): - """Initializes this route. + r"""Initializes this route. :param template: A route template to match against the request path. A template @@ -935,8 +935,8 @@ def __init__(self, template, handler=None, name=None, defaults=None, Format Example ================= ================================== ```` ``'/blog//'`` - ``<:regex>`` ``'/blog/<:\d{4}>/<:\d{2}>'`` - ```` ``'/blog//'`` + ``<:regex>`` ``r'/blog/<:\d{4}>/<:\d{2}>'`` + ```` ``r'/blog//'`` ================= ================================== The same template can mix parts with name, regular expression or @@ -951,7 +951,7 @@ def __init__(self, template, handler=None, name=None, defaults=None, Route('//settings', handler=SettingsHandler, name='user-settings') - Route('//settings', handler=SettingsHandler, + Route(r'//settings', handler=SettingsHandler, name='user-settings') .. note:: diff --git a/webapp2_extras/auth.py b/webapp2_extras/auth.py index 30490d0..5b44b6f 100644 --- a/webapp2_extras/auth.py +++ b/webapp2_extras/auth.py @@ -61,11 +61,11 @@ # The user object must provide all of them as attributes. #: Default is an empty list. default_config = { - 'user_model': 'webapp2_extras.appengine.auth.models.User', + 'user_model': 'webapp2_extras.appengine.auth.models.User', 'session_backend': 'securecookie', - 'cookie_name': 'auth', - 'token_max_age': 86400 * 7 * 3, - 'token_new_age': 86400, + 'cookie_name': 'auth', + 'token_max_age': 86400 * 7 * 3, + 'token_new_age': 86400, 'token_cache_age': 3600, 'user_attributes': [], } @@ -418,9 +418,9 @@ def get_user_by_token(self, user_id, token, token_ts=None, cache=None, A user dict or None. """ if self._user is not None: - assert (self._user is not _anon and - self._user['user_id'] == user_id and - self._user['token'] == token) + assert (self._user is not _anon + and self._user['user_id'] == user_id + and self._user['token'] == token) return self._user_or_none() if cache and cache_ts: @@ -518,7 +518,7 @@ def set_session(self, user, token=None, token_ts=None, cache_ts=None, # the session metadata (token, timestamps etc). This is easier to test. # But we could store only user_id and custom user attributes instead. user.update({ - 'token': token, + 'token': token, 'token_ts': token_ts, 'cache_ts': cache_ts, 'remember': int(remember), diff --git a/webapp2_extras/i18n.py b/webapp2_extras/i18n.py index 37f17e4..e55bb1f 100644 --- a/webapp2_extras/i18n.py +++ b/webapp2_extras/i18n.py @@ -66,31 +66,31 @@ #: date_formats #: Default date formats for datetime, date and time. default_config = { - 'translations_path': 'locale', - 'domains': ['messages'], - 'default_locale': 'en_US', - 'default_timezone': 'UTC', - 'locale_selector': None, - 'timezone_selector': None, + 'translations_path': 'locale', + 'domains': ['messages'], + 'default_locale': 'en_US', + 'default_timezone': 'UTC', + 'locale_selector': None, + 'timezone_selector': None, 'date_formats': { - 'time': 'medium', - 'date': 'medium', - 'datetime': 'medium', - 'time.short': None, - 'time.medium': None, - 'time.full': None, - 'time.long': None, - 'time.iso': "HH':'mm':'ss", - 'date.short': None, - 'date.medium': None, - 'date.full': None, - 'date.long': None, - 'date.iso': "yyyy'-'MM'-'dd", - 'datetime.short': None, + 'time': 'medium', + 'date': 'medium', + 'datetime': 'medium', + 'time.short': None, + 'time.medium': None, + 'time.full': None, + 'time.long': None, + 'time.iso': "HH':'mm':'ss", + 'date.short': None, + 'date.medium': None, + 'date.full': None, + 'date.long': None, + 'date.iso': "yyyy'-'MM'-'dd", + 'datetime.short': None, 'datetime.medium': None, - 'datetime.full': None, - 'datetime.long': None, - 'datetime.iso': "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ", + 'datetime.full': None, + 'datetime.long': None, + 'datetime.iso': "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ", }, } diff --git a/webapp2_extras/jinja2.py b/webapp2_extras/jinja2.py index 7f88b75..c4753db 100644 --- a/webapp2_extras/jinja2.py +++ b/webapp2_extras/jinja2.py @@ -151,9 +151,9 @@ def __init__(self, app, config=None): lambda s, p, n: i18n.ngettext(s, p, n), newstyle=True) env.filters.update({ - 'format_date': i18n.format_date, - 'format_time': i18n.format_time, - 'format_datetime': i18n.format_datetime, + 'format_date': i18n.format_date, + 'format_time': i18n.format_time, + 'format_datetime': i18n.format_datetime, 'format_timedelta': i18n.format_timedelta, }) diff --git a/webapp2_extras/local.py b/webapp2_extras/local.py index 9270078..91c63af 100644 --- a/webapp2_extras/local.py +++ b/webapp2_extras/local.py @@ -31,7 +31,7 @@ get_current_greenlet = greenlet.getcurrent del greenlet - except: + except: # noqa: E722 # catch all, py.* fails with so many different errors. get_current_greenlet = int try: diff --git a/webapp2_extras/routes.py b/webapp2_extras/routes.py index 24b5bfc..39fd76b 100644 --- a/webapp2_extras/routes.py +++ b/webapp2_extras/routes.py @@ -121,19 +121,19 @@ def match(self, request): def regex(self): regex, reverse_template, args_count, kwargs_count, variables = \ webapp2._parse_route_template(self.template, - default_sufix='[^\.]+') + default_sufix=r'[^\.]+') return regex class NamePrefixRoute(MultiRoute): - """The idea of this route is to set a base name for other routes:: + r"""The idea of this route is to set a base name for other routes:: app = WSGIApplication([ NamePrefixRoute('user-', [ - Route('/users//', UserOverviewHandler, 'overview'), - Route('/users//profile', UserProfileHandler, + Route(r'/users//', UserOverviewHandler, 'overview'), + Route(r'/users//profile', UserProfileHandler, 'profile'), - Route('/users//projects', UserProjectsHandler, + Route(r'/users//projects', UserProjectsHandler, 'projects'), ]), ]) @@ -142,10 +142,10 @@ class NamePrefixRoute(MultiRoute): convenient as you can reuse the name prefix:: app = WSGIApplication([ - Route('/users//', UserOverviewHandler, 'user-overview'), - Route('/users//profile', UserProfileHandler, + Route(r'/users//', UserOverviewHandler, 'user-overview'), + Route(r'/users//profile', UserProfileHandler, 'user-profile'), - Route('/users//projects', UserProjectsHandler, + Route(r'/users//projects', UserProjectsHandler, 'user-projects'), ]) """ @@ -174,23 +174,23 @@ class HandlerPrefixRoute(NamePrefixRoute): class PathPrefixRoute(NamePrefixRoute): - """Same as :class:`NamePrefixRoute`, but prefixes the route path. + r"""Same as :class:`NamePrefixRoute`, but prefixes the route path. For example, imagine we have these routes:: app = WSGIApplication([ - Route('/users//', UserOverviewHandler, + Route(r'/users//', UserOverviewHandler, 'user-overview'), - Route('/users//profile', UserProfileHandler, + Route(r'/users//profile', UserProfileHandler, 'user-profile'), - Route('/users//projects', UserProjectsHandler, + Route(r'/users//projects', UserProjectsHandler, 'user-projects'), ]) We could refactor them to reuse the common path prefix:: app = WSGIApplication([ - PathPrefixRoute('/users/', [ + PathPrefixRoute(r'/users/', [ Route('/', UserOverviewHandler, 'user-overview'), Route('/profile', UserProfileHandler, 'user-profile'), Route('/projects', UserProjectsHandler, 'user-projects'), diff --git a/webapp2_extras/sessions.py b/webapp2_extras/sessions.py index 7a0ec2e..7391561 100644 --- a/webapp2_extras/sessions.py +++ b/webapp2_extras/sessions.py @@ -67,22 +67,22 @@ #: A dictionary of available session backend classes used by #: :meth:`SessionStore.get_session`. default_config = { - 'secret_key': None, - 'cookie_name': 'session', + 'secret_key': None, + 'cookie_name': 'session', 'session_max_age': None, 'cookie_args': { - 'max_age': None, - 'domain': None, - 'path': '/', - 'secure': None, - 'httponly': False, + 'max_age': None, + 'domain': None, + 'path': '/', + 'secure': None, + 'httponly': False, }, 'backends': { 'securecookie': 'webapp2_extras.sessions.SecureCookieSessionFactory', - 'datastore': 'webapp2_extras.appengine.sessions_ndb.' - 'DatastoreSessionFactory', - 'memcache': 'webapp2_extras.appengine.sessions_memcache.' - 'MemcacheSessionFactory', + 'datastore': 'webapp2_extras.appengine.sessions_ndb.' + 'DatastoreSessionFactory', + 'memcache': 'webapp2_extras.appengine.sessions_memcache.' + 'MemcacheSessionFactory', }, }