From 6d37c8632b713af56c366c3ebeca55a89b30b57a Mon Sep 17 00:00:00 2001 From: John Kraal Date: Fri, 25 Apr 2014 10:00:31 +0200 Subject: added line numbers to generic log formatter --- pyramid/scaffolds/alchemy/production.ini_tmpl | 2 +- pyramid/scaffolds/starter/production.ini_tmpl | 2 +- pyramid/scaffolds/zodb/production.ini_tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index b316ec9ca..022bc0b7b 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -59,4 +59,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/pyramid/scaffolds/starter/production.ini_tmpl b/pyramid/scaffolds/starter/production.ini_tmpl index 6a123abf5..b2681c71d 100644 --- a/pyramid/scaffolds/starter/production.ini_tmpl +++ b/pyramid/scaffolds/starter/production.ini_tmpl @@ -51,4 +51,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index c231e159d..522ff7651 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -57,4 +57,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s -- cgit v1.2.3 From 36d5a438308dbd2a89d4da82eafbd5b368389348 Mon Sep 17 00:00:00 2001 From: Harz-FEAR Date: Tue, 8 Jul 2014 04:40:52 +0200 Subject: RFC 6585 HTTP Exceptions --- pyramid/httpexceptions.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index ebee39ada..7cf802139 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -52,6 +52,9 @@ Exception * 422 - HTTPUnprocessableEntity * 423 - HTTPLocked * 424 - HTTPFailedDependency + * 428 - HTTPPreconditionRequired + * 429 - HTTPTooManyRequests + * 431 - HTTPRequestHeaderFieldsTooLarge HTTPServerError * 500 - HTTPInternalServerError * 501 - HTTPNotImplemented @@ -60,6 +63,7 @@ Exception * 504 - HTTPGatewayTimeout * 505 - HTTPVersionNotSupported * 507 - HTTPInsufficientStorage + * 511 - HTTPNetworkAuthenticationRequired HTTP exceptions are also :term:`response` objects, thus they accept most of the same parameters that can be passed to a regular @@ -907,6 +911,62 @@ class HTTPFailedDependency(HTTPClientError): 'The method could not be performed because the requested ' 'action dependended on another action and that action failed') +class HTTPPreconditionRequired(HTTPClientError): + """ + subclass of :class:`~HTTPClientError` + + This indicates that the origin server requires the + request to be conditional. + + Its typical use is to avoid the "lost update" problem, where a client + GETs a resource's state, modifies it, and PUTs it back to the server, + when meanwhile a third party has modified the state on the server, + leading to a conflict. By requiring requests to be conditional, the + server can assure that clients are working with the correct copies. + + RFC 6585.3 + + code: 428, title: Precondition Required + """ + code = 428 + title = 'Precondition Required' + explanation = ( + 'The origin server requires the request to be conditional.') + +class HTTPTooManyRequests(HTTPClientError): + """ + subclass of :class:`~HTTPClientError` + + This indicates that the user has sent too many + requests in a given amount of time ("rate limiting"). + + RFC 6585.4 + + code: 429, title: Too Many Requests + """ + code = 429 + title = 'Too Many Requests' + explanation = ( + 'The action could not be performed because there were too ' + 'many requests by the client.') + +class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): + """ + subclass of :class:`~HTTPClientError` + + This indicates that the server is unwilling to process + the request because its header fields are too large. The request MAY + be resubmitted after reducing the size of the request header fields. + + RFC 6585.5 + + code: 431, title: Request Header Fields Too Large + """ + code = 431 + title = 'Request Header Fields Too Large' + explanation = ( + 'The requests header fields were too large.') + ############################################################ ## 5xx Server Error ############################################################ -- cgit v1.2.3 From 5ef159eb1a86046da4c53ca9530fff0eb3b3432f Mon Sep 17 00:00:00 2001 From: Harz-FEAR Date: Tue, 8 Jul 2014 04:44:32 +0200 Subject: did not include code 511 because it is for use by intercepting proxies --- pyramid/httpexceptions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index 7cf802139..ea40a99af 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -63,7 +63,6 @@ Exception * 504 - HTTPGatewayTimeout * 505 - HTTPVersionNotSupported * 507 - HTTPInsufficientStorage - * 511 - HTTPNetworkAuthenticationRequired HTTP exceptions are also :term:`response` objects, thus they accept most of the same parameters that can be passed to a regular -- cgit v1.2.3 From eae99acbf9eed71967ff12961e495f27708d1f39 Mon Sep 17 00:00:00 2001 From: dobesv Date: Wed, 9 Jul 2014 15:15:08 -0700 Subject: Allow the last callback called to add a callback This fixes a bug in the finished and response callbacks where if the last/only callback adds another callback, the newly added callback won't be called afterwards. This is because when it tries to add the callback, it is added to a new list instance because the callbacks list is empty at that time; the check for whether the callbacks list was created didn't previously distinguish between an empty list and not a list. However, if it is not the last callback in the list, the callbacks list will not be empty and the new callback will be added to the same list and the newly added callback *will* be called. Because the code as written appears to be trying to support callbacks adding callbacks, this push request modifies the code so that a callback may add another callback whether it is the last one or not. An alternative approach would be to modify the code so that callbacks cannot add new callbacks, which also would be reasonable. But I think it's a bug that the behavior depends currently on whether you are in the last/only callback when you try to add another one. --- pyramid/request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/request.py b/pyramid/request.py index 6318049ee..7e8b8c07d 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -72,7 +72,7 @@ class CallbackMethodsMixin(object): """ callbacks = self.response_callbacks - if not callbacks: + if callbacks == (): callbacks = [] callbacks.append(callback) self.response_callbacks = callbacks @@ -132,7 +132,7 @@ class CallbackMethodsMixin(object): """ callbacks = self.finished_callbacks - if not callbacks: + if callbacks == (): callbacks = [] callbacks.append(callback) self.finished_callbacks = callbacks -- cgit v1.2.3 From cd299ae7a21a95c1023c2b7c38624234ead1d464 Mon Sep 17 00:00:00 2001 From: Roy Hyunjin Han Date: Thu, 10 Jul 2014 14:08:47 -0700 Subject: Allow hyphens in project name Convert hyphens in project_name to underscores in pkg_name --- pyramid/scripts/pcreate.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 4c1f432fb..edf2c39f7 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -81,7 +81,8 @@ class PCreateCommand(object): args = self.args output_dir = os.path.abspath(os.path.normpath(args[0])) project_name = os.path.basename(os.path.split(output_dir)[1]) - pkg_name = _bad_chars_re.sub('', project_name.lower()) + pkg_name = _bad_chars_re.sub( + '', project_name.lower().replace('-', '_')) safe_name = pkg_resources.safe_name(project_name) egg_name = pkg_resources.to_filename(safe_name) -- cgit v1.2.3 From 63e6e14a83a10331635bdced1ff6258e4c18989c Mon Sep 17 00:00:00 2001 From: Dobes Vandermeer Date: Wed, 23 Jul 2014 09:49:44 -0700 Subject: Add a test case for a response callback adding a response callback when it is the only callback. --- pyramid/tests/test_request.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index ed41b62ff..ec206dad3 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -144,6 +144,29 @@ class TestRequest(unittest.TestCase): self.assertEqual(response.called2, True) self.assertEqual(inst.response_callbacks, []) + def test__process_response_callback_adding_response_callback(self): + """ + When a response callback adds another callback, that new callback should still be called. + + See https://github.com/Pylons/pyramid/pull/1373 + """ + inst = self._makeOne() + def callback1(request, response): + request.called1 = True + response.called1 = True + request.add_response_callback(callback2) + def callback2(request, response): + request.called2 = True + response.called2 = True + inst.add_response_callback(callback1) + response = DummyResponse() + inst._process_response_callbacks(response) + self.assertEqual(inst.called1, True) + self.assertEqual(inst.called2, True) + self.assertEqual(response.called1, True) + self.assertEqual(response.called2, True) + self.assertEqual(inst.response_callbacks, []) + def test_add_finished_callback(self): inst = self._makeOne() self.assertEqual(inst.finished_callbacks, ()) -- cgit v1.2.3 From d47b360cde1d98a67874f88adea69c57ee708dad Mon Sep 17 00:00:00 2001 From: Roy Hyunjin Han Date: Mon, 28 Jul 2014 11:31:45 -0400 Subject: Add test_scaffold_with_hyphen_in_project_name --- pyramid/tests/test_scripts/test_pcreate.py | 87 +++++++++++++++--------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py index 2488e9595..d2eef2ae9 100644 --- a/pyramid/tests/test_scripts/test_pcreate.py +++ b/pyramid/tests/test_scripts/test_pcreate.py @@ -1,4 +1,6 @@ import unittest +from os import getcwd +from os.path import abspath, join, normpath class TestPCreateCommand(unittest.TestCase): def setUp(self): @@ -50,153 +52,150 @@ class TestPCreateCommand(unittest.TestCase): self.assertTrue(out.startswith('You must provide a project name')) def test_unknown_scaffold_name(self): - cmd = self._makeOne('-s', 'dummyXX', 'distro') + cmd = self._makeOne('-s', 'dummyXX', 'Distro') result = cmd.run() self.assertEqual(result, 2) out = self.out_.getvalue() self.assertTrue(out.startswith('Unavailable scaffolds')) def test_known_scaffold_single_rendered(self): - import os cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") + cmd.pyramid_dist = DummyDist('0.1') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) + scaffold.output_dir, normpath(join(getcwd(), 'Distro'))) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + + def test_scaffold_with_hyphen_in_project_name(self): + cmd = self._makeOne('-s', 'dummy', 'Distro-') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist('0.1') + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.output_dir, normpath(join(getcwd(), 'Distro-'))) + self.assertEqual( + scaffold.vars, + {'project': 'Distro-', 'egg': 'Distro_', 'package': 'distro_', + 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) def test_known_scaffold_absolute_path(self): - import os - path = os.path.abspath('Distro') + path = abspath('Distro') cmd = self._makeOne('-s', 'dummy', path) - cmd.pyramid_dist = DummyDist("0.1") + cmd.pyramid_dist = DummyDist('0.1') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") + cmd.pyramid_dist = DummyDist('0.1') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) + scaffold.output_dir, normpath(join(getcwd(), 'Distro'))) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) def test_known_scaffold_multiple_rendered(self): - import os cmd = self._makeOne('-s', 'dummy1', '-s', 'dummy2', 'Distro') scaffold1 = DummyScaffold('dummy1') scaffold2 = DummyScaffold('dummy2') cmd.scaffolds = [scaffold1, scaffold2] - cmd.pyramid_dist = DummyDist("0.1") + cmd.pyramid_dist = DummyDist('0.1') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold1.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) + scaffold1.output_dir, normpath(join(getcwd(), 'Distro'))) self.assertEqual( scaffold1.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) self.assertEqual( - scaffold2.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) + scaffold2.output_dir, normpath(join(getcwd(), 'Distro'))) self.assertEqual( scaffold2.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) def test_known_scaffold_with_path_as_project_target_rendered(self): - import os cmd = self._makeOne('-s', 'dummy', '/tmp/foo/Distro/') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") + cmd.pyramid_dist = DummyDist('0.1') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), '/tmp/foo/Distro')) - ) + scaffold.output_dir, normpath(join(getcwd(), '/tmp/foo/Distro'))) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - + 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) def test_scaffold_with_prod_pyramid_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.2") + cmd.pyramid_dist = DummyDist('0.2') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.2', 'pyramid_docs_branch':'0.2-branch'}) + 'pyramid_version': '0.2', 'pyramid_docs_branch': '0.2-branch'}) def test_scaffold_with_prod_pyramid_long_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.2.1") + cmd.pyramid_dist = DummyDist('0.2.1') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.2.1', 'pyramid_docs_branch':'0.2-branch'}) + 'pyramid_version': '0.2.1', 'pyramid_docs_branch': '0.2-branch'}) def test_scaffold_with_prod_pyramid_unparsable_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("abc") + cmd.pyramid_dist = DummyDist('abc') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': 'abc', 'pyramid_docs_branch':'latest'}) + 'pyramid_version': 'abc', 'pyramid_docs_branch': 'latest'}) def test_scaffold_with_dev_pyramid_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.12dev") + cmd.pyramid_dist = DummyDist('0.12dev') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.12dev', - 'pyramid_docs_branch': 'master'}) + 'pyramid_version': '0.12dev', 'pyramid_docs_branch': 'master'}) def test_scaffold_with_dev_pyramid_long_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.10.1dev") + cmd.pyramid_dist = DummyDist('0.10.1dev') result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.10.1dev', - 'pyramid_docs_branch': 'master'}) + 'pyramid_version': '0.10.1dev', 'pyramid_docs_branch': 'master'}) class Test_main(unittest.TestCase): -- cgit v1.2.3 From 05ceab495c4390c0e3af5ae6458d4c808eb08e67 Mon Sep 17 00:00:00 2001 From: Dobes Vandermeer Date: Tue, 29 Jul 2014 17:54:23 -0700 Subject: Use None for the default value of the callbacks list. --- pyramid/request.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/request.py b/pyramid/request.py index 7e8b8c07d..fa35dc5f4 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -32,8 +32,8 @@ class TemplateContext(object): pass class CallbackMethodsMixin(object): - response_callbacks = () - finished_callbacks = () + response_callbacks = None + finished_callbacks = None def add_response_callback(self, callback): """ Add a callback to the set of callbacks to be called by the @@ -72,7 +72,7 @@ class CallbackMethodsMixin(object): """ callbacks = self.response_callbacks - if callbacks == (): + if callbacks is None: callbacks = [] callbacks.append(callback) self.response_callbacks = callbacks @@ -132,7 +132,7 @@ class CallbackMethodsMixin(object): """ callbacks = self.finished_callbacks - if callbacks == (): + if callbacks is None: callbacks = [] callbacks.append(callback) self.finished_callbacks = callbacks -- cgit v1.2.3 From c73eb9be17a17c6e0b19ce6b08a579a6d524c584 Mon Sep 17 00:00:00 2001 From: Dobes Vandermeer Date: Tue, 29 Jul 2014 18:05:27 -0700 Subject: Use a deque for the request finished / response callbacks. --- pyramid/request.py | 9 +++++---- pyramid/tests/test_request.py | 25 ++++++++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/pyramid/request.py b/pyramid/request.py index fa35dc5f4..bc2889310 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -1,3 +1,4 @@ +from collections import deque import json from zope.interface import implementer @@ -73,14 +74,14 @@ class CallbackMethodsMixin(object): callbacks = self.response_callbacks if callbacks is None: - callbacks = [] + callbacks = deque() callbacks.append(callback) self.response_callbacks = callbacks def _process_response_callbacks(self, response): callbacks = self.response_callbacks while callbacks: - callback = callbacks.pop(0) + callback = callbacks.popleft() callback(self, response) def add_finished_callback(self, callback): @@ -133,14 +134,14 @@ class CallbackMethodsMixin(object): callbacks = self.finished_callbacks if callbacks is None: - callbacks = [] + callbacks = deque() callbacks.append(callback) self.finished_callbacks = callbacks def _process_finished_callbacks(self): callbacks = self.finished_callbacks while callbacks: - callback = callbacks.pop(0) + callback = callbacks.popleft() callback(self) @implementer(IRequest) diff --git a/pyramid/tests/test_request.py b/pyramid/tests/test_request.py index ec206dad3..48af98f59 100644 --- a/pyramid/tests/test_request.py +++ b/pyramid/tests/test_request.py @@ -1,3 +1,4 @@ +from collections import deque import unittest from pyramid import testing @@ -119,13 +120,13 @@ class TestRequest(unittest.TestCase): def test_add_response_callback(self): inst = self._makeOne() - self.assertEqual(inst.response_callbacks, ()) + self.assertEqual(inst.response_callbacks, None) def callback(request, response): """ """ inst.add_response_callback(callback) - self.assertEqual(inst.response_callbacks, [callback]) + self.assertEqual(list(inst.response_callbacks), [callback]) inst.add_response_callback(callback) - self.assertEqual(inst.response_callbacks, [callback, callback]) + self.assertEqual(list(inst.response_callbacks), [callback, callback]) def test__process_response_callbacks(self): inst = self._makeOne() @@ -135,14 +136,15 @@ class TestRequest(unittest.TestCase): def callback2(request, response): request.called2 = True response.called2 = True - inst.response_callbacks = [callback1, callback2] + inst.add_response_callback(callback1) + inst.add_response_callback(callback2) response = DummyResponse() inst._process_response_callbacks(response) self.assertEqual(inst.called1, True) self.assertEqual(inst.called2, True) self.assertEqual(response.called1, True) self.assertEqual(response.called2, True) - self.assertEqual(inst.response_callbacks, []) + self.assertEqual(len(inst.response_callbacks), 0) def test__process_response_callback_adding_response_callback(self): """ @@ -165,17 +167,17 @@ class TestRequest(unittest.TestCase): self.assertEqual(inst.called2, True) self.assertEqual(response.called1, True) self.assertEqual(response.called2, True) - self.assertEqual(inst.response_callbacks, []) + self.assertEqual(len(inst.response_callbacks), 0) def test_add_finished_callback(self): inst = self._makeOne() - self.assertEqual(inst.finished_callbacks, ()) + self.assertEqual(inst.finished_callbacks, None) def callback(request): """ """ inst.add_finished_callback(callback) - self.assertEqual(inst.finished_callbacks, [callback]) + self.assertEqual(list(inst.finished_callbacks), [callback]) inst.add_finished_callback(callback) - self.assertEqual(inst.finished_callbacks, [callback, callback]) + self.assertEqual(list(inst.finished_callbacks), [callback, callback]) def test__process_finished_callbacks(self): inst = self._makeOne() @@ -183,11 +185,12 @@ class TestRequest(unittest.TestCase): request.called1 = True def callback2(request): request.called2 = True - inst.finished_callbacks = [callback1, callback2] + inst.add_finished_callback(callback1) + inst.add_finished_callback(callback2) inst._process_finished_callbacks() self.assertEqual(inst.called1, True) self.assertEqual(inst.called2, True) - self.assertEqual(inst.finished_callbacks, []) + self.assertEqual(len(inst.finished_callbacks), 0) def test_resource_url(self): self._registerResourceURL() -- cgit v1.2.3 From 39a03eef73b14bd05540af70e705d9f02d77f850 Mon Sep 17 00:00:00 2001 From: Dobes Vandermeer Date: Wed, 30 Jul 2014 09:42:28 -0700 Subject: Fix a few tests that assume response_callbacks was a list --- pyramid/tests/test_router.py | 6 +++--- pyramid/tests/test_session.py | 2 +- pyramid/tests/test_testing.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyramid/tests/test_router.py b/pyramid/tests/test_router.py index 838e52db0..c6c6eea1c 100644 --- a/pyramid/tests/test_router.py +++ b/pyramid/tests/test_router.py @@ -522,7 +522,7 @@ class TestRouter(unittest.TestCase): def view(context, request): def callback(request, response): response.called_back = True - request.response_callbacks = [callback] + request.add_response_callback(callback) return response environ = self._makeEnviron() self._registerView(view, '', IViewClassifier, IRequest, IContext) @@ -545,7 +545,7 @@ class TestRouter(unittest.TestCase): def view(context, request): def callback(request): request.environ['called_back'] = True - request.finished_callbacks = [callback] + request.add_finished_callback(callback) return response environ = self._makeEnviron() self._registerView(view, '', IViewClassifier, IRequest, IContext) @@ -567,7 +567,7 @@ class TestRouter(unittest.TestCase): def view(context, request): def callback(request): request.environ['called_back'] = True - request.finished_callbacks = [callback] + request.add_finished_callback(callback) raise NotImplementedError environ = self._makeEnviron() self._registerView(view, '', IViewClassifier, IRequest, IContext) diff --git a/pyramid/tests/test_session.py b/pyramid/tests/test_session.py index 35c234e99..b013ffa66 100644 --- a/pyramid/tests/test_session.py +++ b/pyramid/tests/test_session.py @@ -521,7 +521,7 @@ class Test_manage_accessed(unittest.TestCase): result = wrapper(session, 'a') self.assertEqual(result, 1) callbacks = request.response_callbacks - self.assertEqual(len(callbacks), 0) + if callbacks is not None: self.assertEqual(len(callbacks), 0) class Test_manage_changed(unittest.TestCase): def _makeOne(self, wrapped): diff --git a/pyramid/tests/test_testing.py b/pyramid/tests/test_testing.py index 2d0548b33..dfcad2a0c 100644 --- a/pyramid/tests/test_testing.py +++ b/pyramid/tests/test_testing.py @@ -217,7 +217,7 @@ class TestDummyRequest(unittest.TestCase): def test_add_response_callback(self): request = self._makeOne() request.add_response_callback(1) - self.assertEqual(request.response_callbacks, [1]) + self.assertEqual(list(request.response_callbacks), [1]) def test_registry_is_config_registry_when_setup_is_called_after_ctor(self): # see https://github.com/Pylons/pyramid/issues/165 -- cgit v1.2.3 From c1ef71cec60b0bfeac0445c3c30ae46a976f2b31 Mon Sep 17 00:00:00 2001 From: Roy Hyunjin Han Date: Thu, 31 Jul 2014 19:37:49 -0400 Subject: Minimize changes to increase merge likelihood --- pyramid/tests/test_scripts/test_pcreate.py | 82 ++++++++++++++++++------------ 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py index d2eef2ae9..020721ca7 100644 --- a/pyramid/tests/test_scripts/test_pcreate.py +++ b/pyramid/tests/test_scripts/test_pcreate.py @@ -1,6 +1,4 @@ import unittest -from os import getcwd -from os.path import abspath, join, normpath class TestPCreateCommand(unittest.TestCase): def setUp(self): @@ -52,150 +50,170 @@ class TestPCreateCommand(unittest.TestCase): self.assertTrue(out.startswith('You must provide a project name')) def test_unknown_scaffold_name(self): - cmd = self._makeOne('-s', 'dummyXX', 'Distro') + cmd = self._makeOne('-s', 'dummyXX', 'distro') result = cmd.run() self.assertEqual(result, 2) out = self.out_.getvalue() self.assertTrue(out.startswith('Unavailable scaffolds')) def test_known_scaffold_single_rendered(self): + import os cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.1') + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, normpath(join(getcwd(), 'Distro'))) + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_scaffold_with_hyphen_in_project_name(self): + import os cmd = self._makeOne('-s', 'dummy', 'Distro-') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.1') + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, normpath(join(getcwd(), 'Distro-'))) + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro-')) + ) self.assertEqual( scaffold.vars, {'project': 'Distro-', 'egg': 'Distro_', 'package': 'distro_', - 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_known_scaffold_absolute_path(self): - path = abspath('Distro') + import os + path = os.path.abspath('Distro') cmd = self._makeOne('-s', 'dummy', path) - cmd.pyramid_dist = DummyDist('0.1') + cmd.pyramid_dist = DummyDist("0.1") scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.1') + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, normpath(join(getcwd(), 'Distro'))) + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_known_scaffold_multiple_rendered(self): + import os cmd = self._makeOne('-s', 'dummy1', '-s', 'dummy2', 'Distro') scaffold1 = DummyScaffold('dummy1') scaffold2 = DummyScaffold('dummy2') cmd.scaffolds = [scaffold1, scaffold2] - cmd.pyramid_dist = DummyDist('0.1') + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold1.output_dir, normpath(join(getcwd(), 'Distro'))) + scaffold1.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) self.assertEqual( scaffold1.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) self.assertEqual( - scaffold2.output_dir, normpath(join(getcwd(), 'Distro'))) + scaffold2.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) self.assertEqual( scaffold2.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_known_scaffold_with_path_as_project_target_rendered(self): + import os cmd = self._makeOne('-s', 'dummy', '/tmp/foo/Distro/') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.1') + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( - scaffold.output_dir, normpath(join(getcwd(), '/tmp/foo/Distro'))) + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), '/tmp/foo/Distro')) + ) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch': '0.1-branch'}) + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + def test_scaffold_with_prod_pyramid_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.2') + cmd.pyramid_dist = DummyDist("0.2") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.2', 'pyramid_docs_branch': '0.2-branch'}) + 'pyramid_version': '0.2', 'pyramid_docs_branch':'0.2-branch'}) def test_scaffold_with_prod_pyramid_long_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.2.1') + cmd.pyramid_dist = DummyDist("0.2.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.2.1', 'pyramid_docs_branch': '0.2-branch'}) + 'pyramid_version': '0.2.1', 'pyramid_docs_branch':'0.2-branch'}) def test_scaffold_with_prod_pyramid_unparsable_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('abc') + cmd.pyramid_dist = DummyDist("abc") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': 'abc', 'pyramid_docs_branch': 'latest'}) + 'pyramid_version': 'abc', 'pyramid_docs_branch':'latest'}) def test_scaffold_with_dev_pyramid_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.12dev') + cmd.pyramid_dist = DummyDist("0.12dev") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.12dev', 'pyramid_docs_branch': 'master'}) + 'pyramid_version': '0.12dev', + 'pyramid_docs_branch': 'master'}) def test_scaffold_with_dev_pyramid_long_version(self): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist('0.10.1dev') + cmd.pyramid_dist = DummyDist("0.10.1dev") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( scaffold.vars, {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.10.1dev', 'pyramid_docs_branch': 'master'}) + 'pyramid_version': '0.10.1dev', + 'pyramid_docs_branch': 'master'}) class Test_main(unittest.TestCase): -- cgit v1.2.3 From ee2313a6842d12ae0db91c14da3855e3f7dd0632 Mon Sep 17 00:00:00 2001 From: Jay Martin Date: Tue, 14 Oct 2014 09:09:36 -0400 Subject: typo fix --- docs/quick_tutorial/forms.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tutorial/forms.rst b/docs/quick_tutorial/forms.rst index e8bc0c8b4..b08167edc 100644 --- a/docs/quick_tutorial/forms.rst +++ b/docs/quick_tutorial/forms.rst @@ -104,7 +104,7 @@ assets which need to be published. We don't have to know where on disk it is located. We point at the package, then the path inside the package. We just need to include a call to ``add_static_view`` to make that -directory available at a URL. For Pyramid-specific pages, +directory available at a URL. For Pyramid-specific packages, Pyramid provides a facility (``config.include()``) which even makes that unnecessary for consumers of a package. (Deform is not specific to Pyramid.) -- cgit v1.2.3 From 6aa96d5d40f8c420f020ae187d6842e01e6c668c Mon Sep 17 00:00:00 2001 From: Jay Martin Date: Tue, 14 Oct 2014 09:19:47 -0400 Subject: fix route name in comments --- docs/quick_tutorial/more_view_classes/tutorial/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quick_tutorial/more_view_classes/tutorial/views.py b/docs/quick_tutorial/more_view_classes/tutorial/views.py index 635de0520..fc0ccc37f 100644 --- a/docs/quick_tutorial/more_view_classes/tutorial/views.py +++ b/docs/quick_tutorial/more_view_classes/tutorial/views.py @@ -25,13 +25,13 @@ class TutorialViews: def hello(self): return {'page_title': 'Hello View'} - # Posting to /home via the "Edit" submit button + # Posting to /hello via the "Edit" submit button @view_config(request_method='POST', renderer='edit.pt') def edit(self): new_name = self.request.params['new_name'] return {'page_title': 'Edit View', 'new_name': new_name} - # Posting to /home via the "Delete" submit button + # Posting to /hello via the "Delete" submit button @view_config(request_method='POST', request_param='form.delete', renderer='delete.pt') def delete(self): -- cgit v1.2.3 From ac1bc3cb042fce04696bd799e095722be0d63fb9 Mon Sep 17 00:00:00 2001 From: Jay Martin Date: Tue, 14 Oct 2014 09:09:36 -0400 Subject: typo fix --- docs/quick_tutorial/forms.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tutorial/forms.rst b/docs/quick_tutorial/forms.rst index e8bc0c8b4..b08167edc 100644 --- a/docs/quick_tutorial/forms.rst +++ b/docs/quick_tutorial/forms.rst @@ -104,7 +104,7 @@ assets which need to be published. We don't have to know where on disk it is located. We point at the package, then the path inside the package. We just need to include a call to ``add_static_view`` to make that -directory available at a URL. For Pyramid-specific pages, +directory available at a URL. For Pyramid-specific packages, Pyramid provides a facility (``config.include()``) which even makes that unnecessary for consumers of a package. (Deform is not specific to Pyramid.) -- cgit v1.2.3 From 2c3ed01554f0fdceeff425b44f7f80c55b9a3545 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 14 Oct 2014 10:03:28 -0500 Subject: fix comment on hello view --- docs/quick_tutorial/more_view_classes/tutorial/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/quick_tutorial/more_view_classes/tutorial/views.py b/docs/quick_tutorial/more_view_classes/tutorial/views.py index fc0ccc37f..156e468a9 100644 --- a/docs/quick_tutorial/more_view_classes/tutorial/views.py +++ b/docs/quick_tutorial/more_view_classes/tutorial/views.py @@ -5,7 +5,7 @@ from pyramid.view import ( @view_defaults(route_name='hello') -class TutorialViews: +class TutorialViews(object): def __init__(self, request): self.request = request self.view_name = 'TutorialViews' @@ -25,13 +25,13 @@ class TutorialViews: def hello(self): return {'page_title': 'Hello View'} - # Posting to /hello via the "Edit" submit button + # Posting to /howdy/first/last via the "Edit" submit button @view_config(request_method='POST', renderer='edit.pt') def edit(self): new_name = self.request.params['new_name'] return {'page_title': 'Edit View', 'new_name': new_name} - # Posting to /hello via the "Delete" submit button + # Posting to /howdy/first/last via the "Delete" submit button @view_config(request_method='POST', request_param='form.delete', renderer='delete.pt') def delete(self): -- cgit v1.2.3 From ae6c883018560fe7b1ef02f21b1ceacf2e75528f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 7 May 2014 22:54:40 -0500 Subject: add config.root_package attribute --- CHANGES.txt | 5 +++++ pyramid/config/__init__.py | 17 +++++++++++++++++ pyramid/tests/test_config/test_init.py | 12 ++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 63987d980..d66534752 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,11 @@ Features - Cache busting for static resources has been added and is available via a new argument to ``pyramid.config.Configurator.add_static_view``: ``cachebust``. +- Add ``pyramid.config.Configurator.root_package`` attribute and init + parameter to assist with includeable packages that wish to resolve + resources relative to the package in which the ``Configurator`` was created. + See https://github.com/Pylons/pyramid/pull/1337 + Bug Fixes --------- diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index ebaae38a9..cfa35ec6c 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -125,6 +125,14 @@ class Configurator( is passed (the default), the package is assumed to be the Python package in which the *caller* of the ``Configurator`` constructor lives. + If the ``root_package`` is passed, it will propagate through the + configuration hierarchy as a way for included packages to locate + resources relative to the package in which the main ``Configurator`` was + created. If ``None`` is passed (the default), the ``root_package`` will + be derived from the ``package`` argument. The ``package`` attribute is + always pointing at the package being included when using :meth:`.include`, + whereas the ``root_package`` does not change. + If the ``settings`` argument is passed, it should be a Python dictionary representing the :term:`deployment settings` for this application. These are later retrievable using the @@ -243,6 +251,9 @@ class Configurator( .. versionadded:: 1.3 The ``introspection`` argument. + + .. versionadded:: 1.6 + The ``root_package`` argument. """ manager = manager # for testing injection venusian = venusian # for testing injection @@ -272,13 +283,17 @@ class Configurator( exceptionresponse_view=default_exceptionresponse_view, route_prefix=None, introspection=True, + root_package=None, ): if package is None: package = caller_package() + if root_package is None: + root_package = package name_resolver = DottedNameResolver(package) self.name_resolver = name_resolver self.package_name = name_resolver.get_package_name() self.package = name_resolver.get_package() + self.root_package = root_package self.registry = registry self.autocommit = autocommit self.route_prefix = route_prefix @@ -747,6 +762,7 @@ class Configurator( configurator = self.__class__( registry=self.registry, package=package_of(module), + root_package=self.root_package, autocommit=self.autocommit, route_prefix=route_prefix, ) @@ -806,6 +822,7 @@ class Configurator( configurator = self.__class__( registry=self.registry, package=package, + root_package=self.root_package, autocommit=self.autocommit, route_prefix=self.route_prefix, introspection=self.introspection, diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index d6dba17f6..1e58e4d0f 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -736,6 +736,18 @@ pyramid.tests.test_config.dummy_include2""", else: # pragma: no cover raise AssertionError + def test_include_constant_root_package(self): + from pyramid import tests + from pyramid.tests import test_config + config = self._makeOne(root_package=tests) + results = {} + def include(config): + results['package'] = config.package + results['root_package'] = config.root_package + config.include(include) + self.assertEqual(results['root_package'], tests) + self.assertEqual(results['package'], test_config) + def test_action_branching_kw_is_None(self): config = self._makeOne(autocommit=True) self.assertEqual(config.action('discrim'), None) -- cgit v1.2.3 From ab2a77274584700fbcd508d294ff39cb81a99cfd Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 20 Oct 2014 18:06:53 -0500 Subject: reference more pull requests in the change log --- CHANGES.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 63987d980..38c348e67 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,22 +6,26 @@ Features - Cache busting for static resources has been added and is available via a new argument to ``pyramid.config.Configurator.add_static_view``: ``cachebust``. + See https://github.com/Pylons/pyramid/pull/1380 Bug Fixes --------- - ``pyramid.wsgi.wsgiapp`` and ``pyramid.wsgi.wsgiapp2`` now raise ``ValueError`` when accidentally passed ``None``. + See https://github.com/Pylons/pyramid/pull/1320 - Fix an issue whereby predicates would be resolved as maybe_dotted in the introspectable but not when passed for registration. This would mean that - add_route_predicate for example can not take a string and turn it into the - actual callable function. + ``add_route_predicate`` for example can not take a string and turn it into + the actual callable function. + See https://github.com/Pylons/pyramid/pull/1306 - Fix ``pyramid.testing.setUp`` to return a ``Configurator`` with a proper package. Previously it was not possible to do package-relative includes using the returned ``Configurator`` during testing. There is now a ``package`` argument that can override this behavior as well. + See https://github.com/Pylons/pyramid/pull/1322 - Fix an issue where a ``pyramid.response.FileResponse`` may apply a charset where it does not belong. See https://github.com/Pylons/pyramid/pull/1251 -- cgit v1.2.3 From ba0593aa9488a32193113048f14189b76d374102 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 4 Nov 2014 17:16:27 -0600 Subject: fix squashed docstring on set_request_property fixes #1436 --- pyramid/config/factories.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py index 1990c377a..5ce1081c6 100644 --- a/pyramid/config/factories.py +++ b/pyramid/config/factories.py @@ -1,4 +1,4 @@ -from zope.deprecation import deprecate +from zope.deprecation import deprecated from zope.interface import implementer from pyramid.interfaces import ( @@ -180,8 +180,6 @@ class FactoriesConfiguratorMixin(object): introspectables=(intr,)) @action_method - @deprecate('set_request_propery() is deprecated as of Pyramid 1.5; use ' - 'add_request_method() with the property=True argument instead') def set_request_property(self, callable, name=None, reify=False): """ Add a property to the request object. @@ -195,6 +193,11 @@ class FactoriesConfiguratorMixin(object): self.add_request_method( callable, name=name, property=not reify, reify=reify) + deprecated( + set_request_property, + 'set_request_propery() is deprecated as of Pyramid 1.5; use ' + 'add_request_method() with the property=True argument instead') + @implementer(IRequestExtensions) class _RequestExtensions(object): def __init__(self): -- cgit v1.2.3 From a3033c77c423ad2065c1d7ae65b9c61db8ce6f01 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 6 Nov 2014 23:36:41 -0700 Subject: Update documentation for exceptions --- pyramid/httpexceptions.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index ebee39ada..415dfbe7f 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -868,7 +868,12 @@ class HTTPUnprocessableEntity(HTTPClientError): subclass of :class:`~HTTPClientError` This indicates that the server is unable to process the contained - instructions. Only for WebDAV. + instructions. + + May be used to notify the client that their JSON/XML is well formed, but + not correct for the current request. + + See RFC4918 section 11 for more information. code: 422, title: Unprocessable Entity """ @@ -881,7 +886,7 @@ class HTTPLocked(HTTPClientError): """ subclass of :class:`~HTTPClientError` - This indicates that the resource is locked. Only for WebDAV + This indicates that the resource is locked. code: 423, title: Locked """ @@ -896,7 +901,6 @@ class HTTPFailedDependency(HTTPClientError): This indicates that the method could not be performed because the requested action depended on another action and that action failed. - Only for WebDAV. code: 424, title: Failed Dependency """ -- cgit v1.2.3 From 2a079b541b7c917d2be360ea0c4bd0d1ac6a4556 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 9 Nov 2014 11:56:54 -0800 Subject: - add Translation Context term to Glossary to allow Sphinx to build docs, in reference to a recent update in the docstrings to the package translationstring https://github.com/Pylons/translationstring/blame/master/translationstring/__init__.py#L50 --- docs/glossary.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index deb4c1c8b..ef7e9a9ae 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -749,9 +749,16 @@ Glossary made. For example the word "java" might be translated differently if the translation domain is "programming-languages" than would be if the translation domain was "coffee". A - translation domain is represnted by a collection of ``.mo`` files + translation domain is represented by a collection of ``.mo`` files within one or more :term:`translation directory` directories. + Translation Context + A string representing the "context" in which a translation was + made within a given :term:`translation domain`. See the gettext + documentation, `11.2.5 Using contexts for solving ambiguities + `_ + for more information. + Translator A callable which receives a :term:`translation string` and returns a translated Unicode object for the purposes of internationalization. A -- cgit v1.2.3 From 903f48c1e2a9a309b7386f3d69ae20433d0e7dfa Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 9 Nov 2014 20:44:10 -0800 Subject: - rewrap - add missing clause in last paragraph --- docs/quick_tutorial/debugtoolbar.rst | 52 +++++++++++++++++------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/quick_tutorial/debugtoolbar.rst b/docs/quick_tutorial/debugtoolbar.rst index 90750c633..d138eb760 100644 --- a/docs/quick_tutorial/debugtoolbar.rst +++ b/docs/quick_tutorial/debugtoolbar.rst @@ -58,33 +58,31 @@ Steps Analysis ======== -``pyramid_debugtoolbar`` is a full-fledged Python package, -available on PyPI just like thousands of other Python packages. Thus we -start by installing the ``pyramid_debugtoolbar`` package into our -virtual environment using normal Python package installation commands. - -The ``pyramid_debugtoolbar`` Python package is also a Pyramid add-on, -which means we need to include its add-on configuration into our web -application. We could do this with imperative configuration in -``tutorial/__init__.py`` by using ``config.include``. Pyramid also -supports wiring in add-on configuration via our ``development.ini`` -using ``pyramid.includes``. We use this to load the configuration for -the debugtoolbar. - -You'll now see an attractive button on the right side of -your browser, which you may click to provide introspective access to debugging -information in a new browser tab. Even better, if your web application -generates an error, -you will see a nice traceback on the screen. When you want to disable -this toolbar, no need to change code: you can remove it from -``pyramid.includes`` in the relevant ``.ini`` configuration file (thus -showing why configuration files are handy.) - -Note injects a small amount of html/css into your app just before the closing -```` tag in order to display itself. If you -start to experience otherwise inexplicable client-side weirdness, you can shut -it off by commenting out the ``pyramid_debugtoolbar`` line in -``pyramid.includes`` temporarily. +``pyramid_debugtoolbar`` is a full-fledged Python package, available on PyPI +just like thousands of other Python packages. Thus we start by installing the +``pyramid_debugtoolbar`` package into our virtual environment using normal +Python package installation commands. + +The ``pyramid_debugtoolbar`` Python package is also a Pyramid add-on, which +means we need to include its add-on configuration into our web application. We +could do this with imperative configuration in ``tutorial/__init__.py`` by +using ``config.include``. Pyramid also supports wiring in add-on configuration +via our ``development.ini`` using ``pyramid.includes``. We use this to load +the configuration for the debugtoolbar. + +You'll now see an attractive button on the right side of your browser, which +you may click to provide introspective access to debugging information in a +new browser tab. Even better, if your web application generates an error, you +will see a nice traceback on the screen. When you want to disable this +toolbar, no need to change code: you can remove it from ``pyramid.includes`` +in the relevant ``.ini`` configuration file (thus showing why configuration +files are handy.) + +Note that the toolbar injects a small amount of html/css into your app just +before the closing ```` tag in order to display itself. If you start to +experience otherwise inexplicable client-side weirdness, you can shut it off +by commenting out the ``pyramid_debugtoolbar`` line in ``pyramid.includes`` +temporarily. .. seealso:: See also :ref:`pyramid_debugtoolbar `. -- cgit v1.2.3 From 95bf541f94513b5ec2585c5ecf9f9aa684853676 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 9 Nov 2014 20:45:37 -0800 Subject: - add missing "has" --- docs/quick_tutorial/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tutorial/logging.rst b/docs/quick_tutorial/logging.rst index 855ded59f..e07d23d6d 100644 --- a/docs/quick_tutorial/logging.rst +++ b/docs/quick_tutorial/logging.rst @@ -16,7 +16,7 @@ we might need to detect problems when other people use the site. We need *logging*. Fortunately Pyramid uses the normal Python approach to logging. The -scaffold generated, in your ``development.ini``, a number of lines that +scaffold generated, in your ``development.ini``, has a number of lines that configure the logging for you to some reasonable defaults. You then see messages sent by Pyramid (for example, when a new request comes in.) -- cgit v1.2.3 From 18566a29e5b3fa88c7ce4732ccb6beee2c8a05c6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 9 Nov 2014 23:41:14 -0600 Subject: update changelog from #1376 --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index d5ad8e094..617e1497c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -40,6 +40,9 @@ Bug Fixes type, unlike any previous version of Python. See https://github.com/Pylons/pyramid/issues/1360 for more information. +- ``pcreate`` now normalizes the package name by converting hyphens to + underscores. See https://github.com/Pylons/pyramid/pull/1376 + Docs ---- -- cgit v1.2.3 From 909486ab9321bbac8018e202a42b290a096d2705 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 9 Nov 2014 23:50:48 -0600 Subject: update changelog for #1373 --- CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 617e1497c..0605ed308 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -43,6 +43,10 @@ Bug Fixes - ``pcreate`` now normalizes the package name by converting hyphens to underscores. See https://github.com/Pylons/pyramid/pull/1376 +- Fix an issue with the final response/finished callback being unable to + add another callback to the list. See + https://github.com/Pylons/pyramid/pull/1373 + Docs ---- -- cgit v1.2.3 From 45eb7db00ca472ccd8230f79a01e0eff5c3597ce Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 10 Nov 2014 00:13:32 -0600 Subject: continue #1326 by adding line numbers to development.ini --- pyramid/scaffolds/alchemy/development.ini_tmpl | 2 +- pyramid/scaffolds/starter/development.ini_tmpl | 2 +- pyramid/scaffolds/zodb/development.ini_tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index e54a8609c..448803c8f 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -68,4 +68,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index 842cd61d9..c2a28e178 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -57,4 +57,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index f57d559bf..199ddfab4 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -62,4 +62,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s -- cgit v1.2.3 From ba5444531cccf50e7d8b146f80cd22b1508f4bcf Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 10 Nov 2014 00:15:53 -0600 Subject: update changelog --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 0605ed308..927e7ce2a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,6 +13,9 @@ Features resources relative to the package in which the ``Configurator`` was created. See https://github.com/Pylons/pyramid/pull/1337 +- Added line numbers to the log formatters in the scaffolds to assist with + debugging. See https://github.com/Pylons/pyramid/pull/1326 + Bug Fixes --------- -- cgit v1.2.3 From 7dd39020afbd50f6b27e03bb81ace700ae280bef Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 10 Nov 2014 00:27:46 -0600 Subject: update changelog with new http exceptions from #1372 --- CHANGES.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 927e7ce2a..c1b729b3f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -16,6 +16,11 @@ Features - Added line numbers to the log formatters in the scaffolds to assist with debugging. See https://github.com/Pylons/pyramid/pull/1326 +- Add new HTTP exception objects for status codes + ``428 Precondition Required``, ``429 Too Many Requests`` and + ``431 Request Header Fields Too Large`` in ``pyramid.httpexceptions``. + See https://github.com/Pylons/pyramid/pull/1372/files + Bug Fixes --------- -- cgit v1.2.3 From 73b1622d2610fd67ed2f8dd71dac2d9e22d76605 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 10 Nov 2014 01:49:03 -0600 Subject: moar changelogs! --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index c1b729b3f..cf2cced51 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,9 @@ Features - Add ``pyramid.config.Configurator.root_package`` attribute and init parameter to assist with includeable packages that wish to resolve resources relative to the package in which the ``Configurator`` was created. + This is especially useful for addons that need to load asset specs from + settings, in which case it is natural for a user to define things relative + to their own packages. See https://github.com/Pylons/pyramid/pull/1337 - Added line numbers to the log formatters in the scaffolds to assist with -- cgit v1.2.3 From 187fd8ed07693017d743351cfd58f1327c1abb08 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Mon, 10 Nov 2014 01:05:39 -0700 Subject: Change autoclass to autoexception Fixes #1388 or part thereof --- docs/api/exceptions.rst | 12 +++--- docs/api/httpexceptions.rst | 94 ++++++++++++++++++++++----------------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/docs/api/exceptions.rst b/docs/api/exceptions.rst index 0c630571f..faca0fbb6 100644 --- a/docs/api/exceptions.rst +++ b/docs/api/exceptions.rst @@ -5,14 +5,14 @@ .. automodule:: pyramid.exceptions - .. autoclass:: BadCSRFToken + .. autoexception:: BadCSRFToken - .. autoclass:: PredicateMismatch + .. autoexception:: PredicateMismatch - .. autoclass:: Forbidden + .. autoexception:: Forbidden - .. autoclass:: NotFound + .. autoexception:: NotFound - .. autoclass:: ConfigurationError + .. autoexception:: ConfigurationError - .. autoclass:: URLDecodeError + .. autoexception:: URLDecodeError diff --git a/docs/api/httpexceptions.rst b/docs/api/httpexceptions.rst index b50f10beb..d4cf97f1d 100644 --- a/docs/api/httpexceptions.rst +++ b/docs/api/httpexceptions.rst @@ -13,96 +13,96 @@ .. autofunction:: exception_response - .. autoclass:: HTTPException + .. autoexception:: HTTPException - .. autoclass:: HTTPOk + .. autoexception:: HTTPOk - .. autoclass:: HTTPRedirection + .. autoexception:: HTTPRedirection - .. autoclass:: HTTPError + .. autoexception:: HTTPError - .. autoclass:: HTTPClientError + .. autoexception:: HTTPClientError - .. autoclass:: HTTPServerError + .. autoexception:: HTTPServerError - .. autoclass:: HTTPCreated + .. autoexception:: HTTPCreated - .. autoclass:: HTTPAccepted + .. autoexception:: HTTPAccepted - .. autoclass:: HTTPNonAuthoritativeInformation + .. autoexception:: HTTPNonAuthoritativeInformation - .. autoclass:: HTTPNoContent + .. autoexception:: HTTPNoContent - .. autoclass:: HTTPResetContent + .. autoexception:: HTTPResetContent - .. autoclass:: HTTPPartialContent + .. autoexception:: HTTPPartialContent - .. autoclass:: HTTPMultipleChoices + .. autoexception:: HTTPMultipleChoices - .. autoclass:: HTTPMovedPermanently + .. autoexception:: HTTPMovedPermanently - .. autoclass:: HTTPFound + .. autoexception:: HTTPFound - .. autoclass:: HTTPSeeOther + .. autoexception:: HTTPSeeOther - .. autoclass:: HTTPNotModified + .. autoexception:: HTTPNotModified - .. autoclass:: HTTPUseProxy + .. autoexception:: HTTPUseProxy - .. autoclass:: HTTPTemporaryRedirect + .. autoexception:: HTTPTemporaryRedirect - .. autoclass:: HTTPBadRequest + .. autoexception:: HTTPBadRequest - .. autoclass:: HTTPUnauthorized + .. autoexception:: HTTPUnauthorized - .. autoclass:: HTTPPaymentRequired + .. autoexception:: HTTPPaymentRequired - .. autoclass:: HTTPForbidden + .. autoexception:: HTTPForbidden - .. autoclass:: HTTPNotFound + .. autoexception:: HTTPNotFound - .. autoclass:: HTTPMethodNotAllowed + .. autoexception:: HTTPMethodNotAllowed - .. autoclass:: HTTPNotAcceptable + .. autoexception:: HTTPNotAcceptable - .. autoclass:: HTTPProxyAuthenticationRequired + .. autoexception:: HTTPProxyAuthenticationRequired - .. autoclass:: HTTPRequestTimeout + .. autoexception:: HTTPRequestTimeout - .. autoclass:: HTTPConflict + .. autoexception:: HTTPConflict - .. autoclass:: HTTPGone + .. autoexception:: HTTPGone - .. autoclass:: HTTPLengthRequired + .. autoexception:: HTTPLengthRequired - .. autoclass:: HTTPPreconditionFailed + .. autoexception:: HTTPPreconditionFailed - .. autoclass:: HTTPRequestEntityTooLarge + .. autoexception:: HTTPRequestEntityTooLarge - .. autoclass:: HTTPRequestURITooLong + .. autoexception:: HTTPRequestURITooLong - .. autoclass:: HTTPUnsupportedMediaType + .. autoexception:: HTTPUnsupportedMediaType - .. autoclass:: HTTPRequestRangeNotSatisfiable + .. autoexception:: HTTPRequestRangeNotSatisfiable - .. autoclass:: HTTPExpectationFailed + .. autoexception:: HTTPExpectationFailed - .. autoclass:: HTTPUnprocessableEntity + .. autoexception:: HTTPUnprocessableEntity - .. autoclass:: HTTPLocked + .. autoexception:: HTTPLocked - .. autoclass:: HTTPFailedDependency + .. autoexception:: HTTPFailedDependency - .. autoclass:: HTTPInternalServerError + .. autoexception:: HTTPInternalServerError - .. autoclass:: HTTPNotImplemented + .. autoexception:: HTTPNotImplemented - .. autoclass:: HTTPBadGateway + .. autoexception:: HTTPBadGateway - .. autoclass:: HTTPServiceUnavailable + .. autoexception:: HTTPServiceUnavailable - .. autoclass:: HTTPGatewayTimeout + .. autoexception:: HTTPGatewayTimeout - .. autoclass:: HTTPVersionNotSupported + .. autoexception:: HTTPVersionNotSupported - .. autoclass:: HTTPInsufficientStorage + .. autoexception:: HTTPInsufficientStorage -- cgit v1.2.3 From 7a76cd0b183d5080ec863a7d494008e65469f683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 11 Nov 2014 08:02:09 +0100 Subject: fixes #1405 --- pyramid/tests/test_response.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pyramid/tests/test_response.py b/pyramid/tests/test_response.py index a16eb8d33..84ec57757 100644 --- a/pyramid/tests/test_response.py +++ b/pyramid/tests/test_response.py @@ -1,4 +1,5 @@ import io +import mimetypes import os import unittest from pyramid import testing @@ -51,15 +52,11 @@ class TestFileResponse(unittest.TestCase): r.app_iter.close() def test_without_content_type(self): - for suffix, content_type in ( - ('txt', 'text/plain; charset=UTF-8'), - ('xml', 'application/xml; charset=UTF-8'), - ('pdf', 'application/pdf') - ): + for suffix in ('txt', 'xml', 'pdf'): path = self._getPath(suffix) r = self._makeOne(path) - self.assertEqual(r.content_type, content_type.split(';')[0]) - self.assertEqual(r.headers['content-type'], content_type) + self.assertEqual(r.headers['content-type'].split(';')[0], + mimetypes.guess_type(path, strict=False)[0]) r.app_iter.close() def test_python_277_bug_15207(self): -- cgit v1.2.3 From f10d1e8f9e7a8d65218b9fb09efe3b6fa9511bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 12 Dec 2013 21:14:10 +0100 Subject: if view argument is not passed to config.add_notfound_view, use default_exceptionresponse_view --- pyramid/config/views.py | 7 +++++++ pyramid/tests/test_config/test_views.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 5ca696069..fbe7fc712 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -53,6 +53,7 @@ from pyramid.exceptions import ( from pyramid.httpexceptions import ( HTTPForbidden, HTTPNotFound, + default_exceptionresponse_view, ) from pyramid.registry import ( @@ -1671,6 +1672,9 @@ class ViewsConfiguratorMixin(object): config.add_notfound_view(notfound) + If ``view`` argument is not provided, the view callable defaults to + :func:`~pyramid.httpexceptions.default_exceptionresponse_view`. + All arguments except ``append_slash`` have the same meaning as :meth:`pyramid.config.Configurator.add_view` and each predicate argument restricts the set of circumstances under which this notfound @@ -1697,6 +1701,9 @@ class ViewsConfiguratorMixin(object): % arg ) + if not view: + view = default_exceptionresponse_view + settings = dict( view=view, context=HTTPNotFound, diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index a0d9ee0c3..0fb7c734a 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1860,6 +1860,21 @@ class TestViewsConfigurationMixin(unittest.TestCase): result = view(None, request) self.assertEqual(result, (None, request)) + def test_add_notfound_view_no_view_argument(self): + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.httpexceptions import HTTPNotFound + config = self._makeOne(autocommit=True) + config.setup_registry() + config.add_notfound_view() + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPNotFound), + request_iface=IRequest) + context = HTTPNotFound() + result = view(context, request) + self.assertEqual(result, context) + def test_add_notfound_view_allows_other_predicates(self): from pyramid.renderers import null_renderer config = self._makeOne(autocommit=True) -- cgit v1.2.3 From 41ba4dfda4dd0e7fb5c32aaa34c164fe3ad43142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 11 Feb 2014 22:02:55 +0100 Subject: properly detect undefined view --- pyramid/config/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/config/views.py b/pyramid/config/views.py index fbe7fc712..6de5646f6 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1701,7 +1701,7 @@ class ViewsConfiguratorMixin(object): % arg ) - if not view: + if view is None: view = default_exceptionresponse_view settings = dict( -- cgit v1.2.3 From dfa449126a8cb87c58e6e7519df5aecf252d5127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Tue, 11 Nov 2014 07:50:58 +0100 Subject: if view argument is not passed to config.add_forbidden_view, use default_exceptionresponse_view --- pyramid/config/views.py | 8 +++++++- pyramid/tests/test_config/test_views.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 6de5646f6..e4171b0c5 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1592,9 +1592,12 @@ class ViewsConfiguratorMixin(object): config.add_forbidden_view(forbidden) + If ``view`` argument is not provided, the view callable defaults to + :func:`~pyramid.httpexceptions.default_exceptionresponse_view`. + All arguments have the same meaning as :meth:`pyramid.config.Configurator.add_view` and each predicate - argument restricts the set of circumstances under which this notfound + argument restricts the set of circumstances under which this forbidden view will be invoked. Unlike :meth:`pyramid.config.Configurator.add_view`, this method will raise an exception if passed ``name``, ``permission``, ``context``, @@ -1610,6 +1613,9 @@ class ViewsConfiguratorMixin(object): % arg ) + if view is None: + view = default_exceptionresponse_view + settings = dict( view=view, context=HTTPForbidden, diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 0fb7c734a..39b8ba70d 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1783,6 +1783,21 @@ class TestViewsConfigurationMixin(unittest.TestCase): result = view(None, request) self.assertEqual(result, 'OK') + def test_add_forbidden_view_no_view_argument(self): + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.httpexceptions import HTTPForbidden + config = self._makeOne(autocommit=True) + config.setup_registry() + config.add_forbidden_view() + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPForbidden), + request_iface=IRequest) + context = HTTPForbidden() + result = view(context, request) + self.assertEqual(result, context) + def test_add_forbidden_view_allows_other_predicates(self): from pyramid.renderers import null_renderer config = self._makeOne(autocommit=True) -- cgit v1.2.3 From 46a268b3e0c3f80974bc9f4471afdc819ba28763 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 11 Nov 2014 01:15:23 -0600 Subject: update changelog --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index cf2cced51..4d697de64 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -58,6 +58,9 @@ Bug Fixes add another callback to the list. See https://github.com/Pylons/pyramid/pull/1373 +- Fix a failing unittest caused by differing mimetypes across various OSs. + See https://github.com/Pylons/pyramid/issues/1405 + Docs ---- -- cgit v1.2.3 From 7b1d4223db73163f46600cf3d3badf4961dddafb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 11 Nov 2014 01:19:36 -0600 Subject: update changelog --- CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 4d697de64..b5d08c8ff 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -24,6 +24,12 @@ Features ``431 Request Header Fields Too Large`` in ``pyramid.httpexceptions``. See https://github.com/Pylons/pyramid/pull/1372/files +- Make it simple to define notfound and forbidden views that wish to use + the default exception-response view but with altered predicates and other + configuration options. The ``view`` argument is now optional in + ``config.add_notfound_view`` and ``config.add_forbidden_view``.. + See https://github.com/Pylons/pyramid/issues/494 + Bug Fixes --------- -- cgit v1.2.3 From 555969e05458b2e19305fd0a4f15ac3d27d3a90c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 11 Nov 2014 00:50:29 -0800 Subject: fix grammar --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 3313f8dad..3c804a158 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -354,7 +354,7 @@ command from Gettext: $ mkdir -p es/LC_MESSAGES $ msginit -l es -o es/LC_MESSAGES/myapplication.po -This will create a new the message catalog ``.po`` file will in: +This will create a new message catalog ``.po`` file in: ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. -- cgit v1.2.3