From 3e2a692f4ee839d6c17850b51af9501a4d074a03 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 5 Jul 2016 11:25:00 -0600 Subject: Remove cachebust_match It was leftover from when this feature was removed in the 1.6 release cycle --- pyramid/static.py | 5 +---- pyramid/tests/test_static.py | 8 -------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/pyramid/static.py b/pyramid/static.py index 0965be95c..3abcd465c 100644 --- a/pyramid/static.py +++ b/pyramid/static.py @@ -83,7 +83,7 @@ class static_view(object): """ def __init__(self, root_dir, cache_max_age=3600, package_name=None, - use_subpath=False, index='index.html', cachebust_match=None): + use_subpath=False, index='index.html'): # package_name is for bw compat; it is preferred to pass in a # package-relative path as root_dir # (e.g. ``anotherpackage:foo/static``). @@ -96,15 +96,12 @@ class static_view(object): self.docroot = docroot self.norm_docroot = normcase(normpath(docroot)) self.index = index - self.cachebust_match = cachebust_match def __call__(self, context, request): if self.use_subpath: path_tuple = request.subpath else: path_tuple = traversal_path_info(request.environ['PATH_INFO']) - if self.cachebust_match: - path_tuple = self.cachebust_match(path_tuple) path = _secure_path(path_tuple) if path is None: diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py index 2ca86bc44..e264652dd 100644 --- a/pyramid/tests/test_static.py +++ b/pyramid/tests/test_static.py @@ -113,14 +113,6 @@ class Test_static_view_use_subpath_False(unittest.TestCase): response = inst(context, request) self.assertTrue(b'static' in response.body) - def test_cachebust_match(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - inst.cachebust_match = lambda subpath: subpath[1:] - request = self._makeRequest({'PATH_INFO':'/foo/index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - def test_resource_is_file_with_wsgi_file_wrapper(self): from pyramid.response import _BLOCK_SIZE inst = self._makeOne('pyramid.tests:fixtures/static') -- cgit v1.2.3 From 80b7e8975cacf1b4ef9b91765d52b6aef82761ca Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 2 Oct 2016 11:36:27 -0700 Subject: add deprecation warning in pcreate --- pyramid/scripts/pcreate.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index f3121a915..73139732f 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -19,10 +19,15 @@ def main(argv=sys.argv, quiet=False): except KeyboardInterrupt: # pragma: no cover return 1 - class PCreateCommand(object): verbosity = 1 # required - description = "Render Pyramid scaffolding to an output directory" + description = """\ +Render Pyramid scaffolding to an output directory. + +Note: As of Pyramid 1.8, this command is deprecated. Use a specific +cookiecutter instead: +https://github.com/pylons/?query=cookiecutter +""" usage = "usage: %prog [options] -s output_directory" parser = optparse.OptionParser(usage, description=description) parser.add_option('-s', '--scaffold', @@ -77,6 +82,7 @@ class PCreateCommand(object): self.scaffolds = self.all_scaffolds() def run(self): + self._warn_pcreate_deprecated() if self.options.list: return self.show_scaffolds() if not self.options.scaffold_name and not self.args: @@ -212,5 +218,12 @@ class PCreateCommand(object): answer = input_('{0} [y|N]: '.format(prompt)) return answer.strip().lower() == 'y' + def _warn_pcreate_deprecated(self): + self.out('''\ +Note: As of Pyramid 1.8, this command is deprecated. Use a specific +cookiecutter instead: +https://github.com/pylons/?query=cookiecutter +''') + if __name__ == '__main__': # pragma: no cover sys.exit(main() or 0) -- cgit v1.2.3 From a53db7ea6d996f9b03c15cb73fb08f883f54d4fd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 2 Oct 2016 11:36:58 -0700 Subject: fix tests, changing out.startswith to out.count --- pyramid/tests/test_scripts/test_pcreate.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py index eaa7c1464..8e6cc2847 100644 --- a/pyramid/tests/test_scripts/test_pcreate.py +++ b/pyramid/tests/test_scripts/test_pcreate.py @@ -26,7 +26,7 @@ class TestPCreateCommand(unittest.TestCase): result = cmd.run() self.assertEqual(result, 0) out = self.out_.getvalue() - self.assertTrue(out.startswith('Available scaffolds')) + self.assertTrue(out.count('Available scaffolds')) def test_run_show_scaffolds_none_exist(self): cmd = self._makeOne('-l') @@ -34,7 +34,7 @@ class TestPCreateCommand(unittest.TestCase): result = cmd.run() self.assertEqual(result, 0) out = self.out_.getvalue() - self.assertTrue(out.startswith('No scaffolds available')) + self.assertTrue(out.count('No scaffolds available')) def test_run_no_scaffold_no_args(self): cmd = self._makeOne(quiet=True) @@ -46,7 +46,7 @@ class TestPCreateCommand(unittest.TestCase): result = cmd.run() self.assertEqual(result, 2) out = self.out_.getvalue() - self.assertTrue(out.startswith( + self.assertTrue(out.count( 'You must provide at least one scaffold name')) def test_no_project_name(self): @@ -54,14 +54,14 @@ class TestPCreateCommand(unittest.TestCase): result = cmd.run() self.assertEqual(result, 2) out = self.out_.getvalue() - self.assertTrue(out.startswith('You must provide a project name')) + self.assertTrue(out.count('You must provide a project name')) def test_unknown_scaffold_name(self): cmd = self._makeOne('-s', 'dummyXX', 'distro') result = cmd.run() self.assertEqual(result, 2) out = self.out_.getvalue() - self.assertTrue(out.startswith('Unavailable scaffolds')) + self.assertTrue(out.count('Unavailable scaffolds')) def test_known_scaffold_single_rendered(self): import os -- cgit v1.2.3 From 8548e29e6a45fd65c8e49c6bcc6a5c6f70c8f980 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 2 Oct 2016 11:37:54 -0700 Subject: undo line removal --- pyramid/scripts/pcreate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 73139732f..52f8fea5e 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -19,6 +19,7 @@ def main(argv=sys.argv, quiet=False): except KeyboardInterrupt: # pragma: no cover return 1 + class PCreateCommand(object): verbosity = 1 # required description = """\ -- cgit v1.2.3 From 676ae0202d9c55379837abb3436e9470003a17fa Mon Sep 17 00:00:00 2001 From: Hannah Krager Date: Sat, 22 Oct 2016 12:02:32 -0400 Subject: move from chameleon to jinja2 for starter scaffold --- pyramid/scaffolds/starter/+package+/__init__.py | 2 +- .../starter/+package+/templates/layout.jinja2_tmpl | 66 +++++++++++++++++++++ .../+package+/templates/mytemplate.jinja2_tmpl | 8 +++ .../starter/+package+/templates/mytemplate.pt_tmpl | 67 ---------------------- pyramid/scaffolds/starter/+package+/views.py_tmpl | 2 +- pyramid/scaffolds/starter/setup.py_tmpl | 2 +- 6 files changed, 77 insertions(+), 70 deletions(-) create mode 100644 pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl create mode 100644 pyramid/scaffolds/starter/+package+/templates/mytemplate.jinja2_tmpl delete mode 100644 pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl diff --git a/pyramid/scaffolds/starter/+package+/__init__.py b/pyramid/scaffolds/starter/+package+/__init__.py index ad5ecbc6f..49dde36d4 100644 --- a/pyramid/scaffolds/starter/+package+/__init__.py +++ b/pyramid/scaffolds/starter/+package+/__init__.py @@ -5,7 +5,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(settings=settings) - config.include('pyramid_chameleon') + config.include('pyramid_jinja2') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl b/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl new file mode 100644 index 000000000..360855602 --- /dev/null +++ b/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl @@ -0,0 +1,66 @@ + + + + + + + + + + + Starter Scaffold for The Pyramid Web Framework + + + + + + + + + + + + + +
+
+
+
+ +
+
+ {% block content %} +

No content

+ {% endblock content %} +
+
+
+ +
+
+ +
+
+
+ + + + + + + + diff --git a/pyramid/scaffolds/starter/+package+/templates/mytemplate.jinja2_tmpl b/pyramid/scaffolds/starter/+package+/templates/mytemplate.jinja2_tmpl new file mode 100644 index 000000000..f826ff9e7 --- /dev/null +++ b/pyramid/scaffolds/starter/+package+/templates/mytemplate.jinja2_tmpl @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content%} +
+

Pyramid Starter scaffold

+

Welcome to \{\{project\}\}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

+
+{% endblock content %} diff --git a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl deleted file mode 100644 index 87fae3817..000000000 --- a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - Starter Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
-
-
-
- -
-
-
-

Pyramid Starter scaffold

-

Welcome to ${project}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

-
-
-
-
- -
-
- -
-
-
- - - - - - - - diff --git a/pyramid/scaffolds/starter/+package+/views.py_tmpl b/pyramid/scaffolds/starter/+package+/views.py_tmpl index ad9af7292..01b9d0130 100644 --- a/pyramid/scaffolds/starter/+package+/views.py_tmpl +++ b/pyramid/scaffolds/starter/+package+/views.py_tmpl @@ -1,6 +1,6 @@ from pyramid.view import view_config -@view_config(route_name='home', renderer='templates/mytemplate.pt') +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') def my_view(request): return {'project': '{{project}}'} diff --git a/pyramid/scaffolds/starter/setup.py_tmpl b/pyramid/scaffolds/starter/setup.py_tmpl index 2e5ce92c7..7f50bbbc2 100644 --- a/pyramid/scaffolds/starter/setup.py_tmpl +++ b/pyramid/scaffolds/starter/setup.py_tmpl @@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - 'pyramid_chameleon', + 'pyramid_jinja2', 'pyramid_debugtoolbar', 'waitress', ] -- cgit v1.2.3 From 84f8a58a61c36a91b4625ea14fdf998b95c30829 Mon Sep 17 00:00:00 2001 From: Hannah Krager Date: Sat, 22 Oct 2016 12:44:48 -0400 Subject: Move to Jinja2 from chameleon in zodb scaffold --- pyramid/scaffolds/zodb/+package+/__init__.py | 2 +- .../zodb/+package+/templates/layout.jinja2_tmpl | 66 +++++++++++++++++++++ .../+package+/templates/mytemplate.jinja2_tmpl | 7 +++ .../zodb/+package+/templates/mytemplate.pt_tmpl | 67 ---------------------- pyramid/scaffolds/zodb/+package+/views.py_tmpl | 2 +- pyramid/scaffolds/zodb/setup.py_tmpl | 2 +- 6 files changed, 76 insertions(+), 70 deletions(-) create mode 100644 pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl create mode 100644 pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl delete mode 100644 pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl diff --git a/pyramid/scaffolds/zodb/+package+/__init__.py b/pyramid/scaffolds/zodb/+package+/__init__.py index f2a86df47..0ca5198b6 100644 --- a/pyramid/scaffolds/zodb/+package+/__init__.py +++ b/pyramid/scaffolds/zodb/+package+/__init__.py @@ -12,7 +12,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=root_factory, settings=settings) - config.include('pyramid_chameleon') + config.include('pyramid_jinja2') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl b/pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl new file mode 100644 index 000000000..a0b3f22f4 --- /dev/null +++ b/pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl @@ -0,0 +1,66 @@ + + + + + + + + + + + ZODB Scaffold for The Pyramid Web Framework + + + + + + + + + + + + + +
+
+
+
+ +
+
+ {% block content %} +

No content

+ {% endblock content %} +
+
+
+ +
+
+ +
+
+
+ + + + + + + + diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl new file mode 100644 index 000000000..34d287b48 --- /dev/null +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl @@ -0,0 +1,7 @@ +{% extends "layout.jinja2" %} +{% block content %} +
+

Pyramid ZODB scaffold

+

Welcome to \{\{project\}\}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

+
+{% endblock content %} \ No newline at end of file diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl deleted file mode 100644 index e109ab829..000000000 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - ZODB Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
-
-
-
- -
-
-
-

Pyramid ZODB scaffold

-

Welcome to ${project}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

-
-
-
-
- -
-
- -
-
-
- - - - - - - - diff --git a/pyramid/scaffolds/zodb/+package+/views.py_tmpl b/pyramid/scaffolds/zodb/+package+/views.py_tmpl index 1e8a9b65a..0b176b365 100644 --- a/pyramid/scaffolds/zodb/+package+/views.py_tmpl +++ b/pyramid/scaffolds/zodb/+package+/views.py_tmpl @@ -2,6 +2,6 @@ from pyramid.view import view_config from .models import MyModel -@view_config(context=MyModel, renderer='templates/mytemplate.pt') +@view_config(context=MyModel, renderer='templates/mytemplate.jinja2') def my_view(request): return {'project': '{{project}}'} diff --git a/pyramid/scaffolds/zodb/setup.py_tmpl b/pyramid/scaffolds/zodb/setup.py_tmpl index 19771d756..a503d60ab 100644 --- a/pyramid/scaffolds/zodb/setup.py_tmpl +++ b/pyramid/scaffolds/zodb/setup.py_tmpl @@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - 'pyramid_chameleon', + 'pyramid_jinja2', 'pyramid_debugtoolbar', 'pyramid_tm', 'pyramid_zodbconn', -- cgit v1.2.3 From a5c633f1e7fdd49b4196f903f193268fb9d02bd3 Mon Sep 17 00:00:00 2001 From: Hannah Krager Date: Sat, 22 Oct 2016 12:52:00 -0400 Subject: Add name to CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index bb21337e2..dcca62d48 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -284,3 +284,5 @@ Contributors - Jon Davidson, 2016/07/18 - Keith Yang, 2016/07/22 + +- Hannah Krager, 2016/10/22 \ No newline at end of file -- cgit v1.2.3 From ecced84567266aa1d163423a02b951384e5f8b2e Mon Sep 17 00:00:00 2001 From: Hannah Krager Date: Sat, 22 Oct 2016 13:53:24 -0400 Subject: Add missing end of file newline --- pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl index 34d287b48..bb075e91d 100644 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl @@ -4,4 +4,4 @@

Pyramid ZODB scaffold

Welcome to \{\{project\}\}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

-{% endblock content %} \ No newline at end of file +{% endblock content %} -- cgit v1.2.3 From 6cb93803ae4bfabee422269192035c5c477564ea Mon Sep 17 00:00:00 2001 From: Hannah Krager Date: Sat, 22 Oct 2016 15:29:21 -0400 Subject: add jinja2 to manifest --- pyramid/scaffolds/starter/MANIFEST.in_tmpl | 2 +- pyramid/scaffolds/zodb/MANIFEST.in_tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/scaffolds/starter/MANIFEST.in_tmpl b/pyramid/scaffolds/starter/MANIFEST.in_tmpl index 0ff6eb7a0..4d1c86b44 100644 --- a/pyramid/scaffolds/starter/MANIFEST.in_tmpl +++ b/pyramid/scaffolds/starter/MANIFEST.in_tmpl @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/pyramid/scaffolds/zodb/MANIFEST.in_tmpl b/pyramid/scaffolds/zodb/MANIFEST.in_tmpl index 0ff6eb7a0..4d1c86b44 100644 --- a/pyramid/scaffolds/zodb/MANIFEST.in_tmpl +++ b/pyramid/scaffolds/zodb/MANIFEST.in_tmpl @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 -- cgit v1.2.3 From e4d66600324ea2d43a36e226933b480e39653bad Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 22 Oct 2016 16:27:11 -0400 Subject: update to match tox.ini --- scaffoldtests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scaffoldtests.sh b/scaffoldtests.sh index 84fd8e072..1de398991 100755 --- a/scaffoldtests.sh +++ b/scaffoldtests.sh @@ -1,3 +1,3 @@ #!/bin/bash -tox -e{py27,py33,py34,pypy}-scaffolds, +tox -e{py27,py34,py35,pypy}-scaffolds, -- cgit v1.2.3 From f362c7f88ead25e110caff7423c268c6c5370ef3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 22 Oct 2016 16:46:19 -0400 Subject: remove trailing comma on tox command --- HACKING.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.txt b/HACKING.txt index 953c386f9..f240492e7 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -216,7 +216,7 @@ Running Tests Alternatively: - $ tox -e{py27,py34,py35,pypy}-scaffolds, + $ tox -e{py27,py34,py35,pypy}-scaffolds Test Coverage -- cgit v1.2.3 From 38a10a0e8ea7ad8165f5d8d264c409ff531ac56d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 22 Oct 2016 16:47:38 -0400 Subject: remove trailing comma on tox command --- scaffoldtests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scaffoldtests.sh b/scaffoldtests.sh index 84fd8e072..69d8ad561 100755 --- a/scaffoldtests.sh +++ b/scaffoldtests.sh @@ -1,3 +1,3 @@ #!/bin/bash -tox -e{py27,py33,py34,pypy}-scaffolds, +tox -e{py27,py33,py34,pypy}-scaffolds -- cgit v1.2.3 From c9ee30029221626e9f65c7cb9a3ccb850ec85ff3 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 1 Nov 2016 00:16:52 -0500 Subject: enable py27 on appveyor ci --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 1350507b2..e10dbc580 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,8 @@ environment: matrix: - PYTHON: "C:\\Python35" TOXENV: "py35" + - PYTHON: "C:\\Python27" + TOXENV: "py27" install: - "%PYTHON%\\python.exe -m pip install tox" -- cgit v1.2.3 From 568ce319ef097f1e909398f9a5ec890e4de91601 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 1 Nov 2016 11:15:18 -0500 Subject: switch to 3.6-dev for py36 and update nightly to py37 on travis --- .travis.yml | 5 ++++- tox.ini | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b46f677a6..02e844196 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,10 +18,13 @@ matrix: env: TOXENV=docs - python: 3.5 env: TOXENV=pep8 - - python: nightly + - python: 3.6-dev env: TOXENV=py36 + - python: nightly + env: TOXENV=py37 allow_failures: - env: TOXENV=py36 + - env: TOXENV=py37 install: - travis_retry pip install tox diff --git a/tox.ini b/tox.ini index 8ceb142cb..884b78c68 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py27,py34,py35,py36,pypy, + py27,py34,py35,py36,py37,pypy, docs,pep8, {py2,py3}-cover,coverage, skip-missing-interpreters = True @@ -13,6 +13,7 @@ basepython = py34: python3.4 py35: python3.5 py36: python3.6 + py37: python3.7 pypy: pypy py2: python2.7 py3: python3.5 -- cgit v1.2.3 From ed06c68b7b622cf43dc09b0e475ad6c978ec3de4 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 9 Nov 2016 23:31:24 -0800 Subject: Avoid setting Content-Encoding header for static view responses. This was causing clients to decode the content of gzipped files when downloading them. We discussed this on IRC and @mmerickel pointed out that it may be a goal in some cases to serve gzipped precompiled assets (i.e. CSS/Javascript) with this header. But that's a new feature that would require thought about how to specify which files to serve that way. And it can already be implemented for a project using a tween. This just aims to fix the existing use case of serving files for download. --- CHANGES.txt | 5 +++++ pyramid/response.py | 25 +++++++++++++++---------- pyramid/static.py | 12 ++++++++++-- pyramid/tests/test_static.py | 4 ++-- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 434557f89..e6a015736 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -97,6 +97,11 @@ Bug Fixes from previous orders have executed. See https://github.com/Pylons/pyramid/pull/2757 +- Fix static view to avoid setting the ``Content-Encoding`` response header + to an encoding guessed using Python's ``mimetypes`` module. + This was causing clients to decode the content of gzipped files + when downloading them. + Deprecations ------------ diff --git a/pyramid/response.py b/pyramid/response.py index 892e5dfff..1d9daae7d 100644 --- a/pyramid/response.py +++ b/pyramid/response.py @@ -54,16 +54,7 @@ class FileResponse(Response): def __init__(self, path, request=None, cache_max_age=None, content_type=None, content_encoding=None): if content_type is None: - content_type, content_encoding = mimetypes.guess_type( - path, - strict=False - ) - if content_type is None: - content_type = 'application/octet-stream' - # str-ifying content_type is a workaround for a bug in Python 2.7.7 - # on Windows where mimetypes.guess_type returns unicode for the - # content_type. - content_type = str(content_type) + content_type, content_encoding = _guess_type(path) super(FileResponse, self).__init__( conditional_response=True, content_type=content_type, @@ -180,3 +171,17 @@ def _get_response_factory(registry): ) return response_factory + + +def _guess_type(path): + content_type, content_encoding = mimetypes.guess_type( + path, + strict=False + ) + if content_type is None: + content_type = 'application/octet-stream' + # str-ifying content_type is a workaround for a bug in Python 2.7.7 + # on Windows where mimetypes.guess_type returns unicode for the + # content_type. + content_type = str(content_type) + return content_type, content_encoding diff --git a/pyramid/static.py b/pyramid/static.py index 0965be95c..31e500e70 100644 --- a/pyramid/static.py +++ b/pyramid/static.py @@ -32,7 +32,12 @@ from pyramid.httpexceptions import ( ) from pyramid.path import caller_package -from pyramid.response import FileResponse + +from pyramid.response import ( + _guess_type, + FileResponse, +) + from pyramid.traversal import traversal_path_info slash = text_('/') @@ -134,7 +139,10 @@ class static_view(object): if not exists(filepath): raise HTTPNotFound(request.url) - return FileResponse(filepath, request, self.cache_max_age) + content_type, content_encoding = _guess_type(filepath) + return FileResponse( + filepath, request, self.cache_max_age, + content_type, content_encoding=None) def add_slash_redirect(self, request): url = request.path_url + '/' diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py index 2ca86bc44..2b200d72b 100644 --- a/pyramid/tests/test_static.py +++ b/pyramid/tests/test_static.py @@ -186,14 +186,14 @@ class Test_static_view_use_subpath_False(unittest.TestCase): from pyramid.httpexceptions import HTTPNotFound self.assertRaises(HTTPNotFound, inst, context, request) - def test_resource_with_content_encoding(self): + def test_gz_resource_no_content_encoding(self): inst = self._makeOne('pyramid.tests:fixtures/static') request = self._makeRequest({'PATH_INFO':'/arcs.svg.tgz'}) context = DummyContext() response = inst(context, request) self.assertEqual(response.status, '200 OK') self.assertEqual(response.content_type, 'application/x-tar') - self.assertEqual(response.content_encoding, 'gzip') + self.assertEqual(response.content_encoding, None) response.app_iter.close() def test_resource_no_content_encoding(self): -- cgit v1.2.3 From 734f241a961b6b1e4b2a43c0c4b5a4d972b65b80 Mon Sep 17 00:00:00 2001 From: David Glick Date: Thu, 10 Nov 2016 08:42:39 -0800 Subject: add link to PR --- CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.txt b/CHANGES.txt index e6a015736..1d69471f1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -101,6 +101,7 @@ Bug Fixes to an encoding guessed using Python's ``mimetypes`` module. This was causing clients to decode the content of gzipped files when downloading them. + See https://github.com/Pylons/pyramid/pull/2810 Deprecations ------------ -- cgit v1.2.3 From ece7e52ec48c8a0b41ba05d793f3fd803a654e9a Mon Sep 17 00:00:00 2001 From: Moriyoshi Koizumi Date: Sat, 12 Nov 2016 16:42:32 +0900 Subject: Mark a few more characters as safe when escaping path components in route path generation, according to pyramid.url.PATH_SAFE --- pyramid/tests/test_urldispatch.py | 4 ++++ pyramid/urldispatch.py | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pyramid/tests/test_urldispatch.py b/pyramid/tests/test_urldispatch.py index 2d20b24c3..06f4ad793 100644 --- a/pyramid/tests/test_urldispatch.py +++ b/pyramid/tests/test_urldispatch.py @@ -485,11 +485,15 @@ class TestCompileRouteFunctional(unittest.TestCase): def test_generator_functional_newstyle(self): self.generates('/{x}', {'x':''}, '/') self.generates('/{x}', {'x':'a'}, '/a') + self.generates('/{x}', {'x':'a/b/c'}, '/a/b/c') + self.generates('/{x}', {'x':':@&+$,'}, '/:@&+$,') self.generates('zzz/{x}', {'x':'abc'}, '/zzz/abc') self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':''}, '/zzz/abc') self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':'/def/g'}, '/zzz/abc/def/g') + self.generates('zzz/{x}*traverse', {'x':':@&+$,', 'traverse':'/:@&+$,'}, + '/zzz/:@&+$,/:@&+$,') self.generates('/{x}', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, '//La%20Pe%C3%B1a') self.generates('/{x}*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), diff --git a/pyramid/urldispatch.py b/pyramid/urldispatch.py index c88ad9590..0f7dd1490 100644 --- a/pyramid/urldispatch.py +++ b/pyramid/urldispatch.py @@ -207,6 +207,10 @@ def _compile_route(route): return d gen = ''.join(gen) + + def q(v): + return quote_path_segment(v, safe='/:@&+$,') + def generator(dict): newdict = {} for k, v in dict.items(): @@ -223,17 +227,17 @@ def _compile_route(route): # a stararg argument if is_nonstr_iter(v): v = '/'.join( - [quote_path_segment(x, safe='/') for x in v] + [q(x) for x in v] ) # native else: if v.__class__ not in string_types: v = str(v) - v = quote_path_segment(v, safe='/') + v = q(v) else: if v.__class__ not in string_types: v = str(v) # v may be bytes (py2) or native string (py3) - v = quote_path_segment(v, safe='/') + v = q(v) # at this point, the value will be a native string newdict[k] = v -- cgit v1.2.3 From 46bb00f493300f251cacb27d3ab6a221fbcb4473 Mon Sep 17 00:00:00 2001 From: Oladipo Odumosu Date: Mon, 14 Nov 2016 00:47:21 -0800 Subject: should be loaded from the virtualenv (cherry picked from commit 2552d88) --- docs/quick_tour.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 39b4cafb3..451830687 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -504,7 +504,7 @@ Pyramid's ``pcreate`` command can list the available scaffolds: .. code-block:: bash - $ pcreate --list + $ $VENV/bin/pcreate --list Available scaffolds: alchemy: Pyramid project using SQLAlchemy, SQLite, URL dispatch, and Jinja2 pyramid_jinja2_starter: Pyramid Jinja2 starter project @@ -517,7 +517,7 @@ that scaffold to make our project: .. code-block:: bash - $ pcreate --scaffold pyramid_jinja2_starter hello_world + $ $VENV/bin/pcreate --scaffold pyramid_jinja2_starter hello_world We next use the normal Python command to set up our package for development: -- cgit v1.2.3 From d84bc45c582cb8398608efebe21ccea957cc583b Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Nov 2016 10:40:53 -0500 Subject: Fix spelling of 'skip_missing_interpreters' option. See: http://tox.readthedocs.io/en/latest/config.html#confval-skip_missing_interpreters=BOOL --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 884b78c68..251e43406 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ envlist = py27,py34,py35,py36,py37,pypy, docs,pep8, {py2,py3}-cover,coverage, -skip-missing-interpreters = True +skip_missing_interpreters = True [testenv] # Most of these are defaults but if you specify any you can't fall back -- cgit v1.2.3 From c67be02ed80bb4f304914380287998c20c65f717 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Nov 2016 10:42:17 -0500 Subject: Silence pip spew. --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 251e43406..d1df0f031 100644 --- a/tox.ini +++ b/tox.ini @@ -19,7 +19,7 @@ basepython = py3: python3.5 commands = - pip install pyramid[testing] + pip install -q pyramid[testing] nosetests --with-xunit --xunit-file=nosetests-{envname}.xml {posargs:} [testenv:py27-scaffolds] @@ -72,7 +72,7 @@ commands = # combination of versions of coverage and nosexcover that i can find. [testenv:py2-cover] commands = - pip install pyramid[testing] + pip install -q pyramid[testing] coverage run --source=pyramid {envbindir}/nosetests coverage xml -o coverage-py2.xml setenv = @@ -80,7 +80,7 @@ setenv = [testenv:py3-cover] commands = - pip install pyramid[testing] + pip install -q pyramid[testing] coverage run --source=pyramid {envbindir}/nosetests coverage xml -o coverage-py3.xml setenv = -- cgit v1.2.3 From 3a21f7dfd350ea16808e7408c194328630471962 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Nov 2016 11:50:31 -0500 Subject: Annotate skipped flake8 rules. --- setup.cfg | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index b52d24bdb..85b6dd367 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,6 +14,48 @@ docs = develop easy_install pyramid[docs] universal = 1 [flake8] -ignore = E301,E302,E731,E261,E123,E121,E128,E129,E125,W291,E501,W293,E303,W391,E266,E231,E201,E202,E127,E262,E265 +ignore = + # E121: continuation line under-indented for hanging indent + E121, + # E123: closing bracket does not match indentation of opening bracket's line + E123, + # E125: continuation line with same indent as next logical line + E125, + # E127: continuation line over-indented for visual indent + E127, + # E128: continuation line under-indented for visual indent + E128, + # E129: visually indented line with same indent as next logical line + E129, + # E201: whitespace after ‘(‘ + E201, + # E202: whitespace before ‘)’ + E202, + # E231: missing whitespace after ‘,’, ‘;’, or ‘:’ + E231, + # E261: at least two spaces before inline comment + E261, + # E262: inline comment should start with ‘# ‘ + E262, + # E265: block comment should start with ‘# ‘ + E265, + # E266: too many leading ‘#’ for block comment + E266, + # E301: expected 1 blank line, found 0 + E301, + # E302: expected 2 blank lines, found 0 + E302, + # E303: too many blank lines (3) + E303, + # E501: line too long (82 > 79 characters) + E501, + # E731: do not assign a lambda expression, use a def + E731, + # W291: trailing whitespace + W291, + # W293: blank line contains whitespace + W293, + # W391: blank line at end of file + W391 exclude = pyramid/tests/,pyramid/compat.py,pyramid/resource.py show-source = True -- cgit v1.2.3 From 65e30325765c2816683a7432c80930becaa588bd Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Nov 2016 11:53:05 -0500 Subject: Suppress E305 and E306 errors, which were newly failing. --- setup.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup.cfg b/setup.cfg index 85b6dd367..df4013f6e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,10 @@ ignore = E302, # E303: too many blank lines (3) E303, + # E305: expected 2 blank lines after class or function definition, found 1 + E305, + # E306: expected 1 blank line before a nested definition, found 0 + E306, # E501: line too long (82 > 79 characters) E501, # E731: do not assign a lambda expression, use a def -- cgit v1.2.3 From 3c96b5bc898574d37ee3fc071503cd6daa800c4b Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Nov 2016 13:14:54 -0500 Subject: Strip allegedly-smart quotes in comments. They break installing on a LANG=C system. --- setup.cfg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup.cfg b/setup.cfg index df4013f6e..9a241ddf5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,19 +27,19 @@ ignore = E128, # E129: visually indented line with same indent as next logical line E129, - # E201: whitespace after ‘(‘ + # E201: whitespace after '(' E201, - # E202: whitespace before ‘)’ + # E202: whitespace before ')' E202, - # E231: missing whitespace after ‘,’, ‘;’, or ‘:’ + # E231: missing whitespace after ',', ';', or ':' E231, # E261: at least two spaces before inline comment E261, - # E262: inline comment should start with ‘# ‘ + # E262: inline comment should start with '# ' E262, - # E265: block comment should start with ‘# ‘ + # E265: block comment should start with '# ' E265, - # E266: too many leading ‘#’ for block comment + # E266: too many leading '#' for block comment E266, # E301: expected 1 blank line, found 0 E301, -- cgit v1.2.3 From 9c8d43a7101c2977f6bf388758f14c7c7fadcf71 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Nov 2016 22:34:28 -0600 Subject: turn on warnings by default for ``pyramid.deprecation.RemoveInVersion19Warning`` --- pyramid/config/factories.py | 9 +++- pyramid/config/routes.py | 4 +- pyramid/config/settings.py | 17 ------- pyramid/config/views.py | 9 +++- pyramid/deprecation.py | 9 ++++ pyramid/i18n.py | 18 +++++++ pyramid/interfaces.py | 12 +++-- pyramid/scripts/common.py | 12 ++++- pyramid/security.py | 19 +++++--- pyramid/session.py | 112 -------------------------------------------- pyramid/traversal.py | 10 ++-- 11 files changed, 83 insertions(+), 148 deletions(-) create mode 100644 pyramid/deprecation.py diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py index f0b6252ae..5c72ea73e 100644 --- a/pyramid/config/factories.py +++ b/pyramid/config/factories.py @@ -1,6 +1,10 @@ -from zope.deprecation import deprecated from zope.interface import implementer +from pyramid.deprecation import ( + RemoveInPyramid19Warning, + deprecated, +) + from pyramid.interfaces import ( IDefaultRootFactory, IRequestFactory, @@ -229,7 +233,8 @@ class FactoriesConfiguratorMixin(object): deprecated( set_request_property, 'set_request_propery() is deprecated as of Pyramid 1.5; use ' - 'add_request_method() with the property=True argument instead') + 'add_request_method() with the property=True argument instead', + RemoveInPyramid19Warning) @implementer(IRequestExtensions) diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 90d4d47d2..5ec8fe2c0 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -1,5 +1,7 @@ import warnings +from pyramid.deprecation import RemoveInPyramid19Warning + from pyramid.compat import urlparse from pyramid.interfaces import ( IRequest, @@ -285,7 +287,7 @@ class RoutesConfiguratorMixin(object): 'instead. See "Adding A Third Party View, Route, or ' 'Subscriber Predicate" in the "Hooks" chapter of the ' 'documentation for more information.'), - DeprecationWarning, + RemoveInPyramid19Warning, stacklevel=3 ) # these are route predicates; if they do not match, the next route diff --git a/pyramid/config/settings.py b/pyramid/config/settings.py index f9dbd752e..af2b359c7 100644 --- a/pyramid/config/settings.py +++ b/pyramid/config/settings.py @@ -1,5 +1,4 @@ import os -import warnings from zope.interface import implementer @@ -153,19 +152,3 @@ class Settings(dict): self.update(update) - def __getattr__(self, name): - try: - val = self[name] - # only deprecate on success; a probing getattr/hasattr should not - # print this warning - warnings.warn( - 'Obtaining settings via attributes of the settings dictionary ' - 'is deprecated as of Pyramid 1.2; use settings["foo"] instead ' - 'of settings.foo', - DeprecationWarning, - 2 - ) - return val - except KeyError: - raise AttributeError(name) - diff --git a/pyramid/config/views.py b/pyramid/config/views.py index acdc00704..104254217 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -11,6 +11,11 @@ from zope.interface import ( ) from zope.interface.interfaces import IInterface +from pyramid.deprecation import ( + RemoveInPyramid19Warning, + RemoveInPyramid110Warning, +) + from pyramid.interfaces import ( IExceptionViewClassifier, IException, @@ -724,7 +729,7 @@ class ViewsConfiguratorMixin(object): 'See "Adding A Third Party View, Route, or Subscriber ' 'Predicate" in the "Hooks" chapter of the documentation ' 'for more information.'), - DeprecationWarning, + RemoveInPyramid19Warning, stacklevel=4, ) @@ -735,7 +740,7 @@ class ViewsConfiguratorMixin(object): 'instead or see "Checking CSRF Tokens Automatically" in the ' '"Sessions" chapter of the documentation for more ' 'information.'), - DeprecationWarning, + RemoveInPyramid110Warning, stacklevel=4, ) diff --git a/pyramid/deprecation.py b/pyramid/deprecation.py new file mode 100644 index 000000000..dbb02720f --- /dev/null +++ b/pyramid/deprecation.py @@ -0,0 +1,9 @@ +from zope.deprecation import deprecated # noqa, internal api + +class RemoveInPyramid19Warning(DeprecationWarning): + pass + +class RemoveInPyramid110Warning(DeprecationWarning): + pass + +RemovedInNextVersionWarning = RemoveInPyramid19Warning diff --git a/pyramid/i18n.py b/pyramid/i18n.py index 79209d342..560be83d7 100644 --- a/pyramid/i18n.py +++ b/pyramid/i18n.py @@ -10,6 +10,10 @@ from translationstring import ( from pyramid.compat import PY2 from pyramid.decorator import reify +from pyramid.deprecation import ( + RemoveInPyramid19Warning, + deprecated, +) from pyramid.interfaces import ( ILocalizer, @@ -166,6 +170,13 @@ def get_locale_name(request): """ return request.locale_name +deprecated( + 'get_locale_name', + 'As of Pyramid 1.5 the "pyramid.i18n.get_locale_name" function is ' + 'scheduled to be removed. Use "request.locale_name" instead.', + RemoveInPyramid19Warning, +) + def make_localizer(current_locale_name, translation_directories): """ Create a :class:`pyramid.i18n.Localizer` object corresponding to the provided locale name from the @@ -218,6 +229,13 @@ def get_localizer(request): """ return request.localizer +deprecated( + 'get_localizer', + 'As of Pyramid 1.5 the "pyramid.i18n.get_localizer" method is scheduled ' + 'to be removed. Use "request.locale_name" instead.', + RemoveInPyramid19Warning, +) + class Translations(gettext.GNUTranslations, object): """An extended translation catalog class (ripped off from Babel) """ diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index c1ddea63f..33cf5408d 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -1,11 +1,13 @@ -from zope.deprecation import deprecated - from zope.interface import ( Attribute, Interface, ) from pyramid.compat import PY2 +from pyramid.deprecation import ( + RemoveInPyramid19Warning, + deprecated, +) # public API interfaces @@ -424,7 +426,8 @@ deprecated( 'ITemplateRenderer', 'As of Pyramid 1.5 the, "pyramid.interfaces.ITemplateRenderer" interface ' 'is scheduled to be removed. It was used by the Mako and Chameleon ' - 'renderers which have been split into their own packages.' + 'renderers which have been split into their own packages.', + RemoveInPyramid19Warning, ) class IViewMapper(Interface): @@ -848,7 +851,8 @@ deprecated( 'scheduled to be removed. Use the ' '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' - 'See the "What\'s new In Pyramid 1.3" document for more details.' + 'See the "What\'s new In Pyramid 1.3" document for more details.', + RemoveInPyramid19Warning, ) class IPEP302Loader(Interface): diff --git a/pyramid/scripts/common.py b/pyramid/scripts/common.py index fc141f6e2..f219e6d9a 100644 --- a/pyramid/scripts/common.py +++ b/pyramid/scripts/common.py @@ -1,6 +1,11 @@ import os -from pyramid.compat import configparser +import logging from logging.config import fileConfig +import sys +import warnings + +from pyramid.compat import configparser +from pyramid.deprecation import RemoveInNextVersionWarning def parse_vars(args): """ @@ -29,6 +34,11 @@ def setup_logging(config_uri, global_conf=None, and ``here`` variables, similar to PasteDeploy config loading. Extra defaults can optionally be specified as a dict in ``global_conf``. """ + logging.captureWarnings(True) + + if not sys.warnoptions: + warnings.simplefilter('default', RemoveInNextVersionWarning) + path = config_uri.split('#', 1)[0] parser = configparser.ConfigParser() parser.read([path]) diff --git a/pyramid/security.py b/pyramid/security.py index 82e6b73a9..f3ad9ef65 100644 --- a/pyramid/security.py +++ b/pyramid/security.py @@ -1,6 +1,9 @@ -from zope.deprecation import deprecated from zope.interface import providedBy +from pyramid.deprecation import ( + RemoveInPyramid19Warning, + deprecated, +) from pyramid.interfaces import ( IAuthenticationPolicy, IAuthorizationPolicy, @@ -62,7 +65,8 @@ deprecated( 'has_permission', 'As of Pyramid 1.5 the "pyramid.security.has_permission" API is now ' 'deprecated. It will be removed in Pyramid 1.8. Use the ' - '"has_permission" method of the Pyramid request instead.' + '"has_permission" method of the Pyramid request instead.', + RemoveInPyramid19Warning, ) @@ -80,7 +84,8 @@ deprecated( 'authenticated_userid', 'As of Pyramid 1.5 the "pyramid.security.authenticated_userid" API is now ' 'deprecated. It will be removed in Pyramid 1.8. Use the ' - '"authenticated_userid" attribute of the Pyramid request instead.' + '"authenticated_userid" attribute of the Pyramid request instead.', + RemoveInPyramid19Warning, ) def unauthenticated_userid(request): @@ -97,7 +102,8 @@ deprecated( 'unauthenticated_userid', 'As of Pyramid 1.5 the "pyramid.security.unauthenticated_userid" API is ' 'now deprecated. It will be removed in Pyramid 1.8. Use the ' - '"unauthenticated_userid" attribute of the Pyramid request instead.' + '"unauthenticated_userid" attribute of the Pyramid request instead.', + RemoveInPyramid19Warning, ) def effective_principals(request): @@ -114,7 +120,8 @@ deprecated( 'effective_principals', 'As of Pyramid 1.5 the "pyramid.security.effective_principals" API is ' 'now deprecated. It will be removed in Pyramid 1.8. Use the ' - '"effective_principals" attribute of the Pyramid request instead.' + '"effective_principals" attribute of the Pyramid request instead.', + RemoveInPyramid19Warning, ) def remember(request, userid=_marker, **kw): @@ -156,7 +163,7 @@ def remember(request, userid=_marker, **kw): 'principal', 'The "principal" argument was deprecated in Pyramid 1.6. ' 'It will be removed in Pyramid 1.9. Use the "userid" ' - 'argument instead.') + 'argument instead.', RemoveInPyramid19Warning) userid = principal policy = _get_authentication_policy(request) if policy is None: diff --git a/pyramid/session.py b/pyramid/session.py index a3cbe5172..d00902f2a 100644 --- a/pyramid/session.py +++ b/pyramid/session.py @@ -5,7 +5,6 @@ import hmac import os import time -from zope.deprecation import deprecated from zope.interface import implementer from webob.cookies import SignedSerializer @@ -519,117 +518,6 @@ def BaseCookieSessionFactory( return CookieSession - -def UnencryptedCookieSessionFactoryConfig( - secret, - timeout=1200, - cookie_name='session', - cookie_max_age=None, - cookie_path='/', - cookie_domain=None, - cookie_secure=False, - cookie_httponly=False, - cookie_on_exception=True, - signed_serialize=signed_serialize, - signed_deserialize=signed_deserialize, - ): - """ - .. deprecated:: 1.5 - Use :func:`pyramid.session.SignedCookieSessionFactory` instead. - Caveat: Cookies generated using ``SignedCookieSessionFactory`` are not - compatible with cookies generated using - ``UnencryptedCookieSessionFactory``, so existing user session data - will be destroyed if you switch to it. - - Configure a :term:`session factory` which will provide unencrypted - (but signed) cookie-based sessions. The return value of this - function is a :term:`session factory`, which may be provided as - the ``session_factory`` argument of a - :class:`pyramid.config.Configurator` constructor, or used - as the ``session_factory`` argument of the - :meth:`pyramid.config.Configurator.set_session_factory` - method. - - The session factory returned by this function will create sessions - which are limited to storing fewer than 4000 bytes of data (as the - payload must fit into a single cookie). - - Parameters: - - ``secret`` - A string which is used to sign the cookie. - - ``timeout`` - A number of seconds of inactivity before a session times out. - - ``cookie_name`` - The name of the cookie used for sessioning. - - ``cookie_max_age`` - The maximum age of the cookie used for sessioning (in seconds). - Default: ``None`` (browser scope). - - ``cookie_path`` - The path used for the session cookie. - - ``cookie_domain`` - The domain used for the session cookie. Default: ``None`` (no domain). - - ``cookie_secure`` - The 'secure' flag of the session cookie. - - ``cookie_httponly`` - The 'httpOnly' flag of the session cookie. - - ``cookie_on_exception`` - If ``True``, set a session cookie even if an exception occurs - while rendering a view. - - ``signed_serialize`` - A callable which takes more or less arbitrary Python data structure and - a secret and returns a signed serialization in bytes. - Default: ``signed_serialize`` (using pickle). - - ``signed_deserialize`` - A callable which takes a signed and serialized data structure in bytes - and a secret and returns the original data structure if the signature - is valid. Default: ``signed_deserialize`` (using pickle). - """ - - class SerializerWrapper(object): - def __init__(self, secret): - self.secret = secret - - def loads(self, bstruct): - return signed_deserialize(bstruct, secret) - - def dumps(self, appstruct): - return signed_serialize(appstruct, secret) - - serializer = SerializerWrapper(secret) - - return BaseCookieSessionFactory( - serializer, - cookie_name=cookie_name, - max_age=cookie_max_age, - path=cookie_path, - domain=cookie_domain, - secure=cookie_secure, - httponly=cookie_httponly, - timeout=timeout, - reissue_time=0, # to keep session.accessed == session.renewed - set_on_exception=cookie_on_exception, - ) - -deprecated( - 'UnencryptedCookieSessionFactoryConfig', - 'The UnencryptedCookieSessionFactoryConfig callable is deprecated as of ' - 'Pyramid 1.5. Use ``pyramid.session.SignedCookieSessionFactory`` instead.' - ' Caveat: Cookies generated using SignedCookieSessionFactory are not ' - 'compatible with cookies generated using UnencryptedCookieSessionFactory, ' - 'so existing user session data will be destroyed if you switch to it.' - ) - def SignedCookieSessionFactory( secret, cookie_name='session', diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 963a76bb5..5d49dce1d 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -1,12 +1,15 @@ import warnings -from zope.deprecation import deprecated - from zope.interface import implementer from zope.interface.interfaces import IInterface from repoze.lru import lru_cache +from pyramid.deprecation import ( + RemoveInPyramid19Warning, + deprecated, +) + from pyramid.interfaces import ( IResourceURL, IRequestFactory, @@ -811,7 +814,8 @@ deprecated( 'scheduled to be removed. Use the ' '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' - 'See the "What\'s new In Pyramid 1.3" document for a further description.' + 'See the "What\'s new In Pyramid 1.3" document for a further description.', + RemoveInPyramid19Warning, ) @lru_cache(1000) -- cgit v1.2.3 From b13b1c8de94a55ac99865c06598743899806c689 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 15 Nov 2016 19:50:24 -0600 Subject: fix docstring on check_csrf_token --- pyramid/session.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/session.py b/pyramid/session.py index d00902f2a..513628ce7 100644 --- a/pyramid/session.py +++ b/pyramid/session.py @@ -214,9 +214,9 @@ def check_csrf_token(request, supplied by ``request.session.get_csrf_token()``, and ``raises`` is ``True``, this function will raise an :exc:`pyramid.exceptions.BadCSRFToken` exception. - If the check does succeed and ``raises`` is ``False``, this - function will return ``False``. If the CSRF check is successful, this - function will return ``True`` unconditionally. + If the values differ and ``raises`` is ``False``, this function will + return ``False``. If the CSRF check is successful, this function will + return ``True`` unconditionally. Note that using this function requires that a :term:`session factory` is configured. -- cgit v1.2.3 From c151adb1ee83eb34005a9883e748831e2b79de21 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 15 Nov 2016 20:17:22 -0600 Subject: Revert "turn on warnings by default for ``pyramid.deprecation.RemoveInVersion19Warning``" This reverts commit 9c8d43a7101c2977f6bf388758f14c7c7fadcf71. --- pyramid/config/factories.py | 9 +--- pyramid/config/routes.py | 4 +- pyramid/config/settings.py | 17 +++++++ pyramid/config/views.py | 9 +--- pyramid/deprecation.py | 9 ---- pyramid/i18n.py | 18 ------- pyramid/interfaces.py | 12 ++--- pyramid/scripts/common.py | 12 +---- pyramid/security.py | 19 +++----- pyramid/session.py | 112 ++++++++++++++++++++++++++++++++++++++++++++ pyramid/traversal.py | 10 ++-- 11 files changed, 148 insertions(+), 83 deletions(-) delete mode 100644 pyramid/deprecation.py diff --git a/pyramid/config/factories.py b/pyramid/config/factories.py index 5c72ea73e..f0b6252ae 100644 --- a/pyramid/config/factories.py +++ b/pyramid/config/factories.py @@ -1,10 +1,6 @@ +from zope.deprecation import deprecated from zope.interface import implementer -from pyramid.deprecation import ( - RemoveInPyramid19Warning, - deprecated, -) - from pyramid.interfaces import ( IDefaultRootFactory, IRequestFactory, @@ -233,8 +229,7 @@ class FactoriesConfiguratorMixin(object): deprecated( set_request_property, 'set_request_propery() is deprecated as of Pyramid 1.5; use ' - 'add_request_method() with the property=True argument instead', - RemoveInPyramid19Warning) + 'add_request_method() with the property=True argument instead') @implementer(IRequestExtensions) diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 5ec8fe2c0..90d4d47d2 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -1,7 +1,5 @@ import warnings -from pyramid.deprecation import RemoveInPyramid19Warning - from pyramid.compat import urlparse from pyramid.interfaces import ( IRequest, @@ -287,7 +285,7 @@ class RoutesConfiguratorMixin(object): 'instead. See "Adding A Third Party View, Route, or ' 'Subscriber Predicate" in the "Hooks" chapter of the ' 'documentation for more information.'), - RemoveInPyramid19Warning, + DeprecationWarning, stacklevel=3 ) # these are route predicates; if they do not match, the next route diff --git a/pyramid/config/settings.py b/pyramid/config/settings.py index af2b359c7..f9dbd752e 100644 --- a/pyramid/config/settings.py +++ b/pyramid/config/settings.py @@ -1,4 +1,5 @@ import os +import warnings from zope.interface import implementer @@ -152,3 +153,19 @@ class Settings(dict): self.update(update) + def __getattr__(self, name): + try: + val = self[name] + # only deprecate on success; a probing getattr/hasattr should not + # print this warning + warnings.warn( + 'Obtaining settings via attributes of the settings dictionary ' + 'is deprecated as of Pyramid 1.2; use settings["foo"] instead ' + 'of settings.foo', + DeprecationWarning, + 2 + ) + return val + except KeyError: + raise AttributeError(name) + diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 104254217..acdc00704 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -11,11 +11,6 @@ from zope.interface import ( ) from zope.interface.interfaces import IInterface -from pyramid.deprecation import ( - RemoveInPyramid19Warning, - RemoveInPyramid110Warning, -) - from pyramid.interfaces import ( IExceptionViewClassifier, IException, @@ -729,7 +724,7 @@ class ViewsConfiguratorMixin(object): 'See "Adding A Third Party View, Route, or Subscriber ' 'Predicate" in the "Hooks" chapter of the documentation ' 'for more information.'), - RemoveInPyramid19Warning, + DeprecationWarning, stacklevel=4, ) @@ -740,7 +735,7 @@ class ViewsConfiguratorMixin(object): 'instead or see "Checking CSRF Tokens Automatically" in the ' '"Sessions" chapter of the documentation for more ' 'information.'), - RemoveInPyramid110Warning, + DeprecationWarning, stacklevel=4, ) diff --git a/pyramid/deprecation.py b/pyramid/deprecation.py deleted file mode 100644 index dbb02720f..000000000 --- a/pyramid/deprecation.py +++ /dev/null @@ -1,9 +0,0 @@ -from zope.deprecation import deprecated # noqa, internal api - -class RemoveInPyramid19Warning(DeprecationWarning): - pass - -class RemoveInPyramid110Warning(DeprecationWarning): - pass - -RemovedInNextVersionWarning = RemoveInPyramid19Warning diff --git a/pyramid/i18n.py b/pyramid/i18n.py index 560be83d7..79209d342 100644 --- a/pyramid/i18n.py +++ b/pyramid/i18n.py @@ -10,10 +10,6 @@ from translationstring import ( from pyramid.compat import PY2 from pyramid.decorator import reify -from pyramid.deprecation import ( - RemoveInPyramid19Warning, - deprecated, -) from pyramid.interfaces import ( ILocalizer, @@ -170,13 +166,6 @@ def get_locale_name(request): """ return request.locale_name -deprecated( - 'get_locale_name', - 'As of Pyramid 1.5 the "pyramid.i18n.get_locale_name" function is ' - 'scheduled to be removed. Use "request.locale_name" instead.', - RemoveInPyramid19Warning, -) - def make_localizer(current_locale_name, translation_directories): """ Create a :class:`pyramid.i18n.Localizer` object corresponding to the provided locale name from the @@ -229,13 +218,6 @@ def get_localizer(request): """ return request.localizer -deprecated( - 'get_localizer', - 'As of Pyramid 1.5 the "pyramid.i18n.get_localizer" method is scheduled ' - 'to be removed. Use "request.locale_name" instead.', - RemoveInPyramid19Warning, -) - class Translations(gettext.GNUTranslations, object): """An extended translation catalog class (ripped off from Babel) """ diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 33cf5408d..c1ddea63f 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -1,13 +1,11 @@ +from zope.deprecation import deprecated + from zope.interface import ( Attribute, Interface, ) from pyramid.compat import PY2 -from pyramid.deprecation import ( - RemoveInPyramid19Warning, - deprecated, -) # public API interfaces @@ -426,8 +424,7 @@ deprecated( 'ITemplateRenderer', 'As of Pyramid 1.5 the, "pyramid.interfaces.ITemplateRenderer" interface ' 'is scheduled to be removed. It was used by the Mako and Chameleon ' - 'renderers which have been split into their own packages.', - RemoveInPyramid19Warning, + 'renderers which have been split into their own packages.' ) class IViewMapper(Interface): @@ -851,8 +848,7 @@ deprecated( 'scheduled to be removed. Use the ' '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' - 'See the "What\'s new In Pyramid 1.3" document for more details.', - RemoveInPyramid19Warning, + 'See the "What\'s new In Pyramid 1.3" document for more details.' ) class IPEP302Loader(Interface): diff --git a/pyramid/scripts/common.py b/pyramid/scripts/common.py index f219e6d9a..fc141f6e2 100644 --- a/pyramid/scripts/common.py +++ b/pyramid/scripts/common.py @@ -1,11 +1,6 @@ import os -import logging -from logging.config import fileConfig -import sys -import warnings - from pyramid.compat import configparser -from pyramid.deprecation import RemoveInNextVersionWarning +from logging.config import fileConfig def parse_vars(args): """ @@ -34,11 +29,6 @@ def setup_logging(config_uri, global_conf=None, and ``here`` variables, similar to PasteDeploy config loading. Extra defaults can optionally be specified as a dict in ``global_conf``. """ - logging.captureWarnings(True) - - if not sys.warnoptions: - warnings.simplefilter('default', RemoveInNextVersionWarning) - path = config_uri.split('#', 1)[0] parser = configparser.ConfigParser() parser.read([path]) diff --git a/pyramid/security.py b/pyramid/security.py index f3ad9ef65..82e6b73a9 100644 --- a/pyramid/security.py +++ b/pyramid/security.py @@ -1,9 +1,6 @@ +from zope.deprecation import deprecated from zope.interface import providedBy -from pyramid.deprecation import ( - RemoveInPyramid19Warning, - deprecated, -) from pyramid.interfaces import ( IAuthenticationPolicy, IAuthorizationPolicy, @@ -65,8 +62,7 @@ deprecated( 'has_permission', 'As of Pyramid 1.5 the "pyramid.security.has_permission" API is now ' 'deprecated. It will be removed in Pyramid 1.8. Use the ' - '"has_permission" method of the Pyramid request instead.', - RemoveInPyramid19Warning, + '"has_permission" method of the Pyramid request instead.' ) @@ -84,8 +80,7 @@ deprecated( 'authenticated_userid', 'As of Pyramid 1.5 the "pyramid.security.authenticated_userid" API is now ' 'deprecated. It will be removed in Pyramid 1.8. Use the ' - '"authenticated_userid" attribute of the Pyramid request instead.', - RemoveInPyramid19Warning, + '"authenticated_userid" attribute of the Pyramid request instead.' ) def unauthenticated_userid(request): @@ -102,8 +97,7 @@ deprecated( 'unauthenticated_userid', 'As of Pyramid 1.5 the "pyramid.security.unauthenticated_userid" API is ' 'now deprecated. It will be removed in Pyramid 1.8. Use the ' - '"unauthenticated_userid" attribute of the Pyramid request instead.', - RemoveInPyramid19Warning, + '"unauthenticated_userid" attribute of the Pyramid request instead.' ) def effective_principals(request): @@ -120,8 +114,7 @@ deprecated( 'effective_principals', 'As of Pyramid 1.5 the "pyramid.security.effective_principals" API is ' 'now deprecated. It will be removed in Pyramid 1.8. Use the ' - '"effective_principals" attribute of the Pyramid request instead.', - RemoveInPyramid19Warning, + '"effective_principals" attribute of the Pyramid request instead.' ) def remember(request, userid=_marker, **kw): @@ -163,7 +156,7 @@ def remember(request, userid=_marker, **kw): 'principal', 'The "principal" argument was deprecated in Pyramid 1.6. ' 'It will be removed in Pyramid 1.9. Use the "userid" ' - 'argument instead.', RemoveInPyramid19Warning) + 'argument instead.') userid = principal policy = _get_authentication_policy(request) if policy is None: diff --git a/pyramid/session.py b/pyramid/session.py index 513628ce7..47b80f617 100644 --- a/pyramid/session.py +++ b/pyramid/session.py @@ -5,6 +5,7 @@ import hmac import os import time +from zope.deprecation import deprecated from zope.interface import implementer from webob.cookies import SignedSerializer @@ -518,6 +519,117 @@ def BaseCookieSessionFactory( return CookieSession + +def UnencryptedCookieSessionFactoryConfig( + secret, + timeout=1200, + cookie_name='session', + cookie_max_age=None, + cookie_path='/', + cookie_domain=None, + cookie_secure=False, + cookie_httponly=False, + cookie_on_exception=True, + signed_serialize=signed_serialize, + signed_deserialize=signed_deserialize, + ): + """ + .. deprecated:: 1.5 + Use :func:`pyramid.session.SignedCookieSessionFactory` instead. + Caveat: Cookies generated using ``SignedCookieSessionFactory`` are not + compatible with cookies generated using + ``UnencryptedCookieSessionFactory``, so existing user session data + will be destroyed if you switch to it. + + Configure a :term:`session factory` which will provide unencrypted + (but signed) cookie-based sessions. The return value of this + function is a :term:`session factory`, which may be provided as + the ``session_factory`` argument of a + :class:`pyramid.config.Configurator` constructor, or used + as the ``session_factory`` argument of the + :meth:`pyramid.config.Configurator.set_session_factory` + method. + + The session factory returned by this function will create sessions + which are limited to storing fewer than 4000 bytes of data (as the + payload must fit into a single cookie). + + Parameters: + + ``secret`` + A string which is used to sign the cookie. + + ``timeout`` + A number of seconds of inactivity before a session times out. + + ``cookie_name`` + The name of the cookie used for sessioning. + + ``cookie_max_age`` + The maximum age of the cookie used for sessioning (in seconds). + Default: ``None`` (browser scope). + + ``cookie_path`` + The path used for the session cookie. + + ``cookie_domain`` + The domain used for the session cookie. Default: ``None`` (no domain). + + ``cookie_secure`` + The 'secure' flag of the session cookie. + + ``cookie_httponly`` + The 'httpOnly' flag of the session cookie. + + ``cookie_on_exception`` + If ``True``, set a session cookie even if an exception occurs + while rendering a view. + + ``signed_serialize`` + A callable which takes more or less arbitrary Python data structure and + a secret and returns a signed serialization in bytes. + Default: ``signed_serialize`` (using pickle). + + ``signed_deserialize`` + A callable which takes a signed and serialized data structure in bytes + and a secret and returns the original data structure if the signature + is valid. Default: ``signed_deserialize`` (using pickle). + """ + + class SerializerWrapper(object): + def __init__(self, secret): + self.secret = secret + + def loads(self, bstruct): + return signed_deserialize(bstruct, secret) + + def dumps(self, appstruct): + return signed_serialize(appstruct, secret) + + serializer = SerializerWrapper(secret) + + return BaseCookieSessionFactory( + serializer, + cookie_name=cookie_name, + max_age=cookie_max_age, + path=cookie_path, + domain=cookie_domain, + secure=cookie_secure, + httponly=cookie_httponly, + timeout=timeout, + reissue_time=0, # to keep session.accessed == session.renewed + set_on_exception=cookie_on_exception, + ) + +deprecated( + 'UnencryptedCookieSessionFactoryConfig', + 'The UnencryptedCookieSessionFactoryConfig callable is deprecated as of ' + 'Pyramid 1.5. Use ``pyramid.session.SignedCookieSessionFactory`` instead.' + ' Caveat: Cookies generated using SignedCookieSessionFactory are not ' + 'compatible with cookies generated using UnencryptedCookieSessionFactory, ' + 'so existing user session data will be destroyed if you switch to it.' + ) + def SignedCookieSessionFactory( secret, cookie_name='session', diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 5d49dce1d..963a76bb5 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -1,15 +1,12 @@ import warnings +from zope.deprecation import deprecated + from zope.interface import implementer from zope.interface.interfaces import IInterface from repoze.lru import lru_cache -from pyramid.deprecation import ( - RemoveInPyramid19Warning, - deprecated, -) - from pyramid.interfaces import ( IResourceURL, IRequestFactory, @@ -814,8 +811,7 @@ deprecated( 'scheduled to be removed. Use the ' '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' - 'See the "What\'s new In Pyramid 1.3" document for a further description.', - RemoveInPyramid19Warning, + 'See the "What\'s new In Pyramid 1.3" document for a further description.' ) @lru_cache(1000) -- cgit v1.2.3 From 4db295a08c931328fa6bc0d15c7b9aa57ddad86c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 15 Nov 2016 20:58:40 -0600 Subject: add changelog for #2681 --- CHANGES.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1d69471f1..f2f412359 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -16,12 +16,16 @@ Backward Incompatibilities See https://github.com/Pylons/pyramid/pull/2615 -- ``pcreate`` is now interactive by default. You will be prompted if it +- ``pcreate`` is now interactive by default. You will be prompted if a file already exists with different content. Previously if there were similar files it would silently skip them unless you specified ``--interactive`` or ``--overwrite``. See https://github.com/Pylons/pyramid/pull/2775 +- Removed undocumented argument ``cachebust_match`` from + ``pyramid.static.static_view``. This argument was shipped accidentally + in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 + Features -------- -- cgit v1.2.3 From 371d1115aed2e0f99948e09d06e96e7ba4846609 Mon Sep 17 00:00:00 2001 From: Oladipo Odumosu Date: Wed, 16 Nov 2016 05:12:01 +0100 Subject: The updated pyramid-jinja2 scaffold already sets up test requirments in `setup.py` --- docs/quick_tour.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 451830687..47fdb0a88 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -678,10 +678,10 @@ egregious, as Pyramid has had a deep commitment to full test coverage since before its release. Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module with -one unit test in it. To run it, let's install the handy ``pytest`` test runner -by editing ``setup.py``. While we're at it, we'll throw in the ``pytest-cov`` -tool which yells at us for code that isn't tested. Insert and edit the -following lines as shown: +one unit test in it. It also setup ``setup.py`` with test requirements: +``py.test`` as the test runner, ``WebTest`` for running view tests, and the +``pytest-cov`` tool which yells at us for code that isn't tested. The +highlighted lines show this: .. code-block:: python :linenos: @@ -711,7 +711,7 @@ following lines as shown: 'testing': tests_require, }, -We changed ``setup.py`` which means we need to rerun ``$VENV/bin/pip install -e +To install the test requirements, run ``$VENV/bin/pip install -e ".[testing]"``. We can now run all our tests: .. code-block:: bash -- cgit v1.2.3 From b824f093bf3c9088ea3ca968fa85f508ebac79c7 Mon Sep 17 00:00:00 2001 From: Oladipo Odumosu Date: Wed, 16 Nov 2016 05:25:58 +0100 Subject: `pyramid-jinja2` 2.7 configured `setup.py` with test requirements out of the box --- docs/quick_tour.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 47fdb0a88..45c706b0d 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -678,7 +678,7 @@ egregious, as Pyramid has had a deep commitment to full test coverage since before its release. Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module with -one unit test in it. It also setup ``setup.py`` with test requirements: +one unit test in it. It also configured ``setup.py`` with test requirements: ``py.test`` as the test runner, ``WebTest`` for running view tests, and the ``pytest-cov`` tool which yells at us for code that isn't tested. The highlighted lines show this: -- cgit v1.2.3 From 8dfcfb9cf823175bb91ba39565524ff95a920809 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 16 Nov 2016 00:17:37 -0600 Subject: clarify the changes in #2810 as bw-incompatible --- CHANGES.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f2f412359..1939ad125 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -26,6 +26,15 @@ Backward Incompatibilities ``pyramid.static.static_view``. This argument was shipped accidentally in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 +- Change static view to avoid setting the ``Content-Encoding`` response header + to an encoding guessed using Python's ``mimetypes`` module. This was causing + clients to decode the content of gzipped files when downloading them. The + client would end up with a ``foo.txt.gz`` file on disk that was already + decoded, thus should really be ``foo.txt``. Also, the ``Content-Encoding`` + should only have been used if the client itself broadcast support for the + encoding via ``Accept-Encoding`` request headers. + See https://github.com/Pylons/pyramid/pull/2810 + Features -------- @@ -101,12 +110,6 @@ Bug Fixes from previous orders have executed. See https://github.com/Pylons/pyramid/pull/2757 -- Fix static view to avoid setting the ``Content-Encoding`` response header - to an encoding guessed using Python's ``mimetypes`` module. - This was causing clients to decode the content of gzipped files - when downloading them. - See https://github.com/Pylons/pyramid/pull/2810 - Deprecations ------------ -- cgit v1.2.3 From f52759bf3149e197481c954ae94cc04e5555f9ba Mon Sep 17 00:00:00 2001 From: Moriyoshi Koizumi Date: Sat, 19 Nov 2016 11:36:46 +0900 Subject: Split PATH_SAFE into PATH_SEGMENT_SAFE in addition to moving it to pyramid.traversal and apply each to the applicable. --- pyramid/tests/test_traversal.py | 12 +++++++++++- pyramid/traversal.py | 7 +++++-- pyramid/url.py | 7 ++++--- pyramid/urldispatch.py | 3 ++- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py index 0decd04d6..5fc878a32 100644 --- a/pyramid/tests/test_traversal.py +++ b/pyramid/tests/test_traversal.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import unittest import warnings @@ -839,7 +840,7 @@ class QuotePathSegmentTests(unittest.TestCase): def test_string(self): s = '/ hello!' result = self._callFUT(s) - self.assertEqual(result, '%2F%20hello%21') + self.assertEqual(result, '%2F%20hello!') def test_int(self): s = 12345 @@ -1299,6 +1300,15 @@ class Test__join_path_tuple(unittest.TestCase): result = self._callFUT(('x',)) self.assertEqual(result, 'x') + def test_segments_with_unsafes(self): + safe_segments = tuple(u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=:@") + result = self._callFUT(safe_segments) + self.assertEqual(result, u'/'.join(safe_segments)) + unsafe_segments = tuple(chr(i) for i in range(0x20, 0x80) if not chr(i) in safe_segments) + (u'あ',) + result = self._callFUT(unsafe_segments) + self.assertEqual(result, u'/'.join(''.join('%%%02X' % (ord(c) if isinstance(c, str) else c) for c in unsafe_segment.encode('utf-8')) for unsafe_segment in unsafe_segments)) + + def make_traverser(result): class DummyTraverser(object): def __init__(self, context): diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 963a76bb5..1ca52692a 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -35,6 +35,9 @@ with warnings.catch_warnings(): warnings.filterwarnings('ignore') from pyramid.interfaces import IContextURL +PATH_SEGMENT_SAFE = "~!$&'()*+,;=:@" # from webob +PATH_SAFE = PATH_SEGMENT_SAFE + "/" + empty = text_('') def find_root(resource): @@ -577,7 +580,7 @@ the ``safe`` argument to this function. This corresponds to the if PY2: # special-case on Python 2 for speed? unchecked - def quote_path_segment(segment, safe=''): + def quote_path_segment(segment, safe=PATH_SEGMENT_SAFE): """ %s """ % quote_path_segment_doc # The bit of this code that deals with ``_segment_cache`` is an # optimization: we cache all the computation of URL path segments @@ -596,7 +599,7 @@ if PY2: _segment_cache[(segment, safe)] = result return result else: - def quote_path_segment(segment, safe=''): + def quote_path_segment(segment, safe=PATH_SEGMENT_SAFE): """ %s """ % quote_path_segment_doc # The bit of this code that deals with ``_segment_cache`` is an # optimization: we cache all the computation of URL path segments diff --git a/pyramid/url.py b/pyramid/url.py index fd62f0057..0214d35ad 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -25,10 +25,11 @@ from pyramid.threadlocal import get_current_registry from pyramid.traversal import ( ResourceURL, quote_path_segment, + PATH_SAFE, + PATH_SEGMENT_SAFE, ) -PATH_SAFE = '/:@&+$,' # from webob -QUERY_SAFE = '/?:@!$&\'()*+,;=' # RFC 3986 +QUERY_SAFE = "/?:@!$&'()*+,;=" # RFC 3986 ANCHOR_SAFE = QUERY_SAFE def parse_url_overrides(kw): @@ -947,4 +948,4 @@ def current_route_path(request, *elements, **kw): @lru_cache(1000) def _join_elements(elements): - return '/'.join([quote_path_segment(s, safe=':@&+$,') for s in elements]) + return '/'.join([quote_path_segment(s, safe=PATH_SEGMENT_SAFE) for s in elements]) diff --git a/pyramid/urldispatch.py b/pyramid/urldispatch.py index 0f7dd1490..a61071845 100644 --- a/pyramid/urldispatch.py +++ b/pyramid/urldispatch.py @@ -22,6 +22,7 @@ from pyramid.exceptions import URLDecodeError from pyramid.traversal import ( quote_path_segment, split_path_info, + PATH_SAFE, ) _marker = object() @@ -209,7 +210,7 @@ def _compile_route(route): gen = ''.join(gen) def q(v): - return quote_path_segment(v, safe='/:@&+$,') + return quote_path_segment(v, safe=PATH_SAFE) def generator(dict): newdict = {} -- cgit v1.2.3 From 663c2648e2a946f44eeec0e490effb2ebdb8a11c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 00:05:07 -0600 Subject: improve view decorator return type documentation Fixes #2770. --- docs/narr/viewconfig.rst | 8 +++++--- pyramid/config/views.py | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 7cb8e0306..3b683ff79 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -252,7 +252,7 @@ Non-Predicate Arguments def myview(request): ... - Is similar to doing:: + Is similar to decorating the view callable directly:: @view_config(...) @decorator2 @@ -260,8 +260,10 @@ Non-Predicate Arguments def myview(request): ... - All view callables in the decorator chain must return a response object - implementing :class:`pyramid.interfaces.IResponse` or raise an exception: + An important distinction is that each decorator will receive a response + object implementing :class:`pyramid.interfaces.IResponse` instead of the + raw value returned from the view callable. All decorators in the chain must + return a response object or raise an exception: .. code-block:: python diff --git a/pyramid/config/views.py b/pyramid/config/views.py index acdc00704..6082d8b48 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -444,9 +444,11 @@ class ViewsConfiguratorMixin(object): think about preserving function attributes such as ``__name__`` and ``__module__`` within decorator logic). - All view callables in the decorator chain must return a response - object implementing :class:`pyramid.interfaces.IResponse` or raise - an exception: + An important distinction is that each decorator will receive a + response object implementing :class:`pyramid.interfaces.IResponse` + instead of the raw value returned from the view callable. All + decorators in the chain must return a response object or raise an + exception: .. code-block:: python -- cgit v1.2.3 From 7764d4ab81e52b6702ae1921fbe5ebde2e2e4b2e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 00:11:10 -0600 Subject: fix variable names in request.resource_url examples to match Fixes #2658. --- pyramid/url.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/url.py b/pyramid/url.py index fd62f0057..7c8e401d0 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -454,7 +454,7 @@ class URLMethodsMixin(object): ``resource_url(someresource, 'element1', 'element2', query={'a':1}, route_name='blogentry')`` is roughly equivalent to doing:: - remainder_path = request.resource_path(someobject) + traversal_path = request.resource_path(someobject) url = request.route_url( 'blogentry', 'element1', @@ -486,7 +486,7 @@ class URLMethodsMixin(object): 'element2', route_name='blogentry', route_kw={'id':'4'}, _query={'a':'1'})`` is roughly equivalent to:: - remainder_path = request.resource_path_tuple(someobject) + traversal_path = request.resource_path_tuple(someobject) kw = {'id':'4', '_query':{'a':'1'}, 'traverse':traversal_path} url = request.route_url( 'blogentry', -- cgit v1.2.3 From 7fe6c3435999bf9d6cebefeee4268846dff9b444 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 00:27:51 -0600 Subject: fix function reference in request.resource_url docs --- pyramid/url.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/url.py b/pyramid/url.py index 7c8e401d0..646cc857d 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -364,7 +364,7 @@ class URLMethodsMixin(object): of ``query`` may be a sequence of two-tuples *or* a data structure with an ``.items()`` method that returns a sequence of two-tuples (presumably a dictionary). This data structure will be turned into a - query string per the documentation of :func:``pyramid.url.urlencode`` + query string per the documentation of :func:`pyramid.url.urlencode` function. This will produce a query string in the ``x-www-form-urlencoded`` encoding. A non-``x-www-form-urlencoded`` query string may be used by passing a *string* value as ``query`` in -- cgit v1.2.3 From f6fb4be7c8b0924688a9a057afcd8bb602d32643 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 00:59:51 -0600 Subject: add warnings about how notfound/forbidden views are only invoked for raised exceptions fixes #1531 --- docs/narr/hooks.rst | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b22b31bf9..28d9bc801 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -116,14 +116,6 @@ callable: .. note:: - Both :meth:`pyramid.config.Configurator.add_notfound_view` and - :class:`pyramid.view.notfound_view_config` are new as of Pyramid 1.3. - Older Pyramid documentation instructed users to use ``add_view`` instead, - with a ``context`` of ``HTTPNotFound``. This still works; the convenience - method and decorator are just wrappers around this functionality. - -.. warning:: - When a Not Found View callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` passed as the first argument to the view callable will be the @@ -131,6 +123,13 @@ callable: available, the resource context will still be available as ``request.context``. +.. warning:: + + The :term:`Not Found View` callables are only invoked when a + :exc:`~pyramid.httpexceptions.HTTPNotFound` exception is raised. If the + exception is returned from a view then it will be treated as a regular + response object and it will not trigger the custom view. + .. index:: single: forbidden view @@ -210,6 +209,13 @@ Here's some sample code that implements a minimal forbidden view: whether the ``pyramid.debug_authorization`` environment setting is true or false. +.. warning:: + + The :term:`forbidden view` callables are only invoked when a + :exc:`~pyramid.httpexceptions.HTTPForbidden` exception is raised. If the + exception is returned from a view then it will be treated as a regular + response object and it will not trigger the custom view. + .. index:: single: request factory -- cgit v1.2.3 From 44563d94a71587ba33a055df1e9008027af23497 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 01:11:21 -0600 Subject: require tuple variants on IResourceURL as well --- docs/narr/hooks.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 28d9bc801..d21edc7b4 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -750,7 +750,9 @@ The API that must be implemented by a class that provides """ Accept the resource and request and set self.physical_path and self.virtual_path """ self.virtual_path = some_function_of(resource, request) + self.virtual_path_tuple = some_function_of(resource, request) self.physical_path = some_other_function_of(resource, request) + self.physical_path_tuple = some_function_of(resource, request) The default context URL generator is available for perusal as the class :class:`pyramid.traversal.ResourceURL` in the `traversal module -- cgit v1.2.3 From 85672acc4da0335defc2a77e5d2121ab9195871c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 11:45:38 -0600 Subject: update todo --- TODO.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 797f8acef..d62efee5a 100644 --- a/TODO.txt +++ b/TODO.txt @@ -120,9 +120,7 @@ Future - 1.6: Remove IContextURL and TraversalContextURL. -- 1.8: Remove set_request_property. -- 1.8: Drop Python 3.3 support. - +- 1.9: Remove set_request_property. - 1.9: Remove extra code enabling ``pyramid.security.remember(principal=...)`` and force use of ``userid``. -- cgit v1.2.3 From d35851138f3b7d1888893efbf0ec991dcd8cf566 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 13:11:16 -0600 Subject: make settings only accessible using dictionary lookup Remove the deprecated ability to access settings using attribute lookup. --- TODO.txt | 4 - pyramid/config/settings.py | 169 +++++++++-------------------- pyramid/tests/test_config/test_settings.py | 20 ---- 3 files changed, 52 insertions(+), 141 deletions(-) diff --git a/TODO.txt b/TODO.txt index d62efee5a..b064cd8e8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -114,10 +114,6 @@ Nice-to-Have Future ------ -- 1.6: turn ``pyramid.settings.Settings`` into a function that returns the - original dict (after ``__getattr__`` deprecation period, it was deprecated - in 1.2). - - 1.6: Remove IContextURL and TraversalContextURL. - 1.9: Remove set_request_property. diff --git a/pyramid/config/settings.py b/pyramid/config/settings.py index f9dbd752e..5684f1867 100644 --- a/pyramid/config/settings.py +++ b/pyramid/config/settings.py @@ -1,11 +1,6 @@ import os -import warnings -from zope.interface import implementer - -from pyramid.interfaces import ISettings - -from pyramid.settings import asbool +from pyramid.settings import asbool, aslist class SettingsConfiguratorMixin(object): def _set_settings(self, mapping): @@ -54,118 +49,58 @@ class SettingsConfiguratorMixin(object): return self.registry.settings -@implementer(ISettings) -class Settings(dict): +def Settings(d=None, _environ_=os.environ, **kw): """ Deployment settings. Update application settings (usually from PasteDeploy keywords) with framework-specific key/value pairs (e.g. find ``PYRAMID_DEBUG_AUTHORIZATION`` in os.environ and jam into keyword args).""" - # _environ_ is dep inj for testing - def __init__(self, d=None, _environ_=os.environ, **kw): - if d is None: - d = {} - dict.__init__(self, d, **kw) - eget = _environ_.get - config_debug_all = self.get('debug_all', '') - config_debug_all = self.get('pyramid.debug_all', config_debug_all) - eff_debug_all = asbool(eget('PYRAMID_DEBUG_ALL', config_debug_all)) - config_reload_all = self.get('reload_all', '') - config_reload_all = self.get('pyramid.reload_all', config_reload_all) - eff_reload_all = asbool(eget('PYRAMID_RELOAD_ALL', config_reload_all)) - config_debug_auth = self.get('debug_authorization', '') - config_debug_auth = self.get('pyramid.debug_authorization', - config_debug_auth) - eff_debug_auth = asbool(eget('PYRAMID_DEBUG_AUTHORIZATION', - config_debug_auth)) - config_debug_notfound = self.get('debug_notfound', '') - config_debug_notfound = self.get('pyramid.debug_notfound', - config_debug_notfound) - eff_debug_notfound = asbool(eget('PYRAMID_DEBUG_NOTFOUND', - config_debug_notfound)) - config_debug_routematch = self.get('debug_routematch', '') - config_debug_routematch = self.get('pyramid.debug_routematch', - config_debug_routematch) - eff_debug_routematch = asbool(eget('PYRAMID_DEBUG_ROUTEMATCH', - config_debug_routematch)) - config_debug_templates = self.get('debug_templates', '') - config_debug_templates = self.get('pyramid.debug_templates', - config_debug_templates) - eff_debug_templates = asbool(eget('PYRAMID_DEBUG_TEMPLATES', - config_debug_templates)) - config_reload_templates = self.get('reload_templates', '') - config_reload_templates = self.get('pyramid.reload_templates', - config_reload_templates) - eff_reload_templates = asbool(eget('PYRAMID_RELOAD_TEMPLATES', - config_reload_templates)) - config_reload_assets = self.get('reload_assets', '') - config_reload_assets = self.get('pyramid.reload_assets', - config_reload_assets) - reload_assets = asbool(eget('PYRAMID_RELOAD_ASSETS', - config_reload_assets)) - config_reload_resources = self.get('reload_resources', '') - config_reload_resources = self.get('pyramid.reload_resources', - config_reload_resources) - reload_resources = asbool(eget('PYRAMID_RELOAD_RESOURCES', - config_reload_resources)) - # reload_resources is an older alias for reload_assets - eff_reload_assets = reload_assets or reload_resources - locale_name = self.get('default_locale_name', 'en') - locale_name = self.get('pyramid.default_locale_name', locale_name) - eff_locale_name = eget('PYRAMID_DEFAULT_LOCALE_NAME', locale_name) - config_prevent_http_cache = self.get('prevent_http_cache', '') - config_prevent_http_cache = self.get('pyramid.prevent_http_cache', - config_prevent_http_cache) - eff_prevent_http_cache = asbool(eget('PYRAMID_PREVENT_HTTP_CACHE', - config_prevent_http_cache)) - config_prevent_cachebust = self.get('prevent_cachebust', '') - config_prevent_cachebust = self.get('pyramid.prevent_cachebust', - config_prevent_cachebust) - eff_prevent_cachebust = asbool(eget('PYRAMID_PREVENT_CACHEBUST', - config_prevent_cachebust)) - csrf_trusted_origins = self.get("pyramid.csrf_trusted_origins", []) - eff_csrf_trusted_origins = csrf_trusted_origins - - update = { - 'debug_authorization': eff_debug_all or eff_debug_auth, - 'debug_notfound': eff_debug_all or eff_debug_notfound, - 'debug_routematch': eff_debug_all or eff_debug_routematch, - 'debug_templates': eff_debug_all or eff_debug_templates, - 'reload_templates': eff_reload_all or eff_reload_templates, - 'reload_resources':eff_reload_all or eff_reload_assets, - 'reload_assets':eff_reload_all or eff_reload_assets, - 'default_locale_name':eff_locale_name, - 'prevent_http_cache':eff_prevent_http_cache, - 'prevent_cachebust':eff_prevent_cachebust, - 'csrf_trusted_origins':eff_csrf_trusted_origins, - - 'pyramid.debug_authorization': eff_debug_all or eff_debug_auth, - 'pyramid.debug_notfound': eff_debug_all or eff_debug_notfound, - 'pyramid.debug_routematch': eff_debug_all or eff_debug_routematch, - 'pyramid.debug_templates': eff_debug_all or eff_debug_templates, - 'pyramid.reload_templates': eff_reload_all or eff_reload_templates, - 'pyramid.reload_resources':eff_reload_all or eff_reload_assets, - 'pyramid.reload_assets':eff_reload_all or eff_reload_assets, - 'pyramid.default_locale_name':eff_locale_name, - 'pyramid.prevent_http_cache':eff_prevent_http_cache, - 'pyramid.prevent_cachebust':eff_prevent_cachebust, - 'pyramid.csrf_trusted_origins':eff_csrf_trusted_origins, - } - - self.update(update) - - def __getattr__(self, name): - try: - val = self[name] - # only deprecate on success; a probing getattr/hasattr should not - # print this warning - warnings.warn( - 'Obtaining settings via attributes of the settings dictionary ' - 'is deprecated as of Pyramid 1.2; use settings["foo"] instead ' - 'of settings.foo', - DeprecationWarning, - 2 - ) - return val - except KeyError: - raise AttributeError(name) - + if d is None: + d = {} + d.update(**kw) + + eget = _environ_.get + def expand_key(key): + keys = [key] + if not key.startswith('pyramid.'): + keys.append('pyramid.' + key) + return keys + def S(settings_key, env_key=None, type_=str, default=False): + value = default + keys = expand_key(settings_key) + for key in keys: + value = d.get(key, value) + if env_key: + value = eget(env_key, value) + value = type_(value) + d.update({k: value for k in keys}) + def O(settings_key, override_key): + for key in expand_key(settings_key): + d[key] = d[key] or d[override_key] + + S('debug_all', 'PYRAMID_DEBUG_ALL', asbool) + S('debug_authorization', 'PYRAMID_DEBUG_AUTHORIZATION', asbool) + O('debug_authorization', 'debug_all') + S('debug_notfound', 'PYRAMID_DEBUG_NOTFOUND', asbool) + O('debug_notfound', 'debug_all') + S('debug_routematch', 'PYRAMID_DEBUG_ROUTEMATCH', asbool) + O('debug_routematch', 'debug_all') + S('debug_templates', 'PYRAMID_DEBUG_TEMPLATES', asbool) + O('debug_templates', 'debug_all') + + S('reload_all', 'PYRAMID_RELOAD_ALL', asbool) + S('reload_templates', 'PYRAMID_RELOAD_TEMPLATES', asbool) + O('reload_templates', 'reload_all') + S('reload_assets', 'PYRAMID_RELOAD_ASSETS', asbool) + O('reload_assets', 'reload_all') + S('reload_resources', 'PYRAMID_RELOAD_RESOURCES', asbool) + O('reload_resources', 'reload_all') + # reload_resources is an older alias for reload_assets + for k in expand_key('reload_assets') + expand_key('reload_resources'): + d[k] = d['reload_assets'] or d['reload_resources'] + + S('default_locale_name', 'PYRAMID_DEFAULT_LOCALE_NAME', str, 'en') + S('prevent_http_cache', 'PYRAMID_PREVENT_HTTP_CACHE', asbool) + S('prevent_cachebust', 'PYRAMID_PREVENT_CACHEBUST', asbool) + S('csrf_trusted_origins', 'PYRAMID_CSRF_TRUSTED_ORIGINS', aslist, []) + + return d diff --git a/pyramid/tests/test_config/test_settings.py b/pyramid/tests/test_config/test_settings.py index d2a98b347..78198298b 100644 --- a/pyramid/tests/test_config/test_settings.py +++ b/pyramid/tests/test_config/test_settings.py @@ -68,26 +68,6 @@ class TestSettings(unittest.TestCase): klass = self._getTargetClass() return klass(d, _environ_=environ) - def test_getattr_success(self): - import warnings - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - settings = self._makeOne({'reload_templates':False}) - self.assertEqual(settings.reload_templates, False) - self.assertEqual(len(w), 1) - - def test_getattr_fail(self): - import warnings - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - settings = self._makeOne({}) - self.assertRaises(AttributeError, settings.__getattr__, 'wontexist') - self.assertEqual(len(w), 0) - - def test_getattr_raises_attribute_error(self): - settings = self._makeOne() - self.assertRaises(AttributeError, settings.__getattr__, 'mykey') - def test_noargs(self): settings = self._makeOne() self.assertEqual(settings['debug_authorization'], False) -- cgit v1.2.3 From 7b58c0f003107aba5fde6cde57f13491d5248c76 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 14:51:40 -0600 Subject: update changelog for #2823 --- CHANGES.txt | 13 +++++++++++++ pyramid/config/settings.py | 2 +- pyramid/tests/test_config/test_settings.py | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1939ad125..a0a928f83 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -35,6 +35,10 @@ Backward Incompatibilities encoding via ``Accept-Encoding`` request headers. See https://github.com/Pylons/pyramid/pull/2810 +- Settings are no longer accessible as attributes on the settings object + (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. + See https://github.com/Pylons/pyramid/pull/2823 + Features -------- @@ -80,6 +84,15 @@ Features as soon as possible before importing the rest of pyramid. See https://github.com/Pylons/pyramid/pull/2797 +- Pyramid no longer copies the settings object passed to the + ``pyramid.config.Configurator(settings=)``. The original ``dict`` is kept. + See https://github.com/Pylons/pyramid/pull/2823 + +- The csrf trusted origins setting may now be a whitespace-separated list of + domains. Previously only a python list was allowed. Also, it can now be set + using the ``PYRAMID_CSRF_TRUSTED_ORIGINS`` environment variable similar to + other settings. See https://github.com/Pylons/pyramid/pull/2823 + Bug Fixes --------- diff --git a/pyramid/config/settings.py b/pyramid/config/settings.py index 5684f1867..26eb48951 100644 --- a/pyramid/config/settings.py +++ b/pyramid/config/settings.py @@ -4,7 +4,7 @@ from pyramid.settings import asbool, aslist class SettingsConfiguratorMixin(object): def _set_settings(self, mapping): - if not mapping: + if mapping is None: mapping = {} settings = Settings(mapping) self.registry.settings = settings diff --git a/pyramid/tests/test_config/test_settings.py b/pyramid/tests/test_config/test_settings.py index 78198298b..2dbe9b1bb 100644 --- a/pyramid/tests/test_config/test_settings.py +++ b/pyramid/tests/test_config/test_settings.py @@ -11,6 +11,13 @@ class TestSettingsConfiguratorMixin(unittest.TestCase): settings = config._set_settings(None) self.assertTrue(settings) + def test__set_settings_uses_original_dict(self): + config = self._makeOne() + dummy = {} + result = config._set_settings(dummy) + self.assertTrue(dummy is result) + self.assertEqual(dummy['pyramid.debug_all'], False) + def test__set_settings_as_dictwithvalues(self): config = self._makeOne() settings = config._set_settings({'a':'1'}) @@ -537,6 +544,18 @@ class TestSettings(unittest.TestCase): self.assertEqual(result['default_locale_name'], 'abc') self.assertEqual(result['pyramid.default_locale_name'], 'abc') + def test_csrf_trusted_origins(self): + result = self._makeOne({}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], []) + result = self._makeOne({'pyramid.csrf_trusted_origins': 'example.com'}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], ['example.com']) + result = self._makeOne({'pyramid.csrf_trusted_origins': ['example.com']}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], ['example.com']) + result = self._makeOne({'pyramid.csrf_trusted_origins': ( + 'example.com foo.example.com\nasdf.example.com')}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], [ + 'example.com', 'foo.example.com', 'asdf.example.com']) + def test_originals_kept(self): result = self._makeOne({'a':'i am so a'}) self.assertEqual(result['a'], 'i am so a') -- cgit v1.2.3 From 8034f05953669f0c0d03315adb8345e7b79f850c Mon Sep 17 00:00:00 2001 From: Moriyoshi Koizumi Date: Sun, 20 Nov 2016 11:48:50 +0900 Subject: Add myself to CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index bb21337e2..98e243c1f 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -284,3 +284,5 @@ Contributors - Jon Davidson, 2016/07/18 - Keith Yang, 2016/07/22 + +- Moriyoshi Koizumi, 2016/11/20 -- cgit v1.2.3 From fb88f053a2a6ffaf3d597d49790fb19e956358e0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 02:15:23 -0800 Subject: Rename Typographical Conventions to Style Guide --- docs/conventions.rst | 107 -------------------------------------------------- docs/index.rst | 6 +-- docs/latexindex.rst | 2 +- docs/style-guide.rst | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 111 deletions(-) delete mode 100644 docs/conventions.rst create mode 100644 docs/style-guide.rst diff --git a/docs/conventions.rst b/docs/conventions.rst deleted file mode 100644 index de041da04..000000000 --- a/docs/conventions.rst +++ /dev/null @@ -1,107 +0,0 @@ -Typographical Conventions -========================= - -Literals, filenames, and function arguments are presented using the -following style: - - ``argument1`` - -Warnings which represent limitations and need-to-know information -related to a topic or concept are presented in the following style: - - .. warning:: - - This is a warning. - -Notes which represent additional information related to a topic or -concept are presented in the following style: - - .. note:: - - This is a note. - -We present Python method names using the following style: - - :meth:`pyramid.config.Configurator.add_view` - -We present Python class names, module names, attributes, and global -variables using the following style: - - :class:`pyramid.config.Configurator.registry` - -References to glossary terms are presented using the following style: - - :term:`Pylons` - -URLs are presented using the following style: - - `Pylons `_ - -References to sections and chapters are presented using the following -style: - - :ref:`traversal_chapter` - -Code and configuration file blocks are presented in the following style: - - .. code-block:: python - :linenos: - - def foo(abc): - pass - -Example blocks representing UNIX shell commands are prefixed with a ``$`` -character, e.g.: - - .. code-block:: bash - - $ $VENV/bin/py.test -q - -See :term:`venv` for the meaning of ``$VENV``. - -Example blocks representing Windows commands are prefixed with a drive letter -with an optional directory name, e.g.: - - .. code-block:: doscon - - c:\examples> %VENV%\Scripts\py.test -q - -See :term:`venv` for the meaning of ``%VENV%``. - -When a command that should be typed on one line is too long to fit on a page, -the backslash ``\`` is used to indicate that the following printed line should -be part of the command: - - .. code-block:: bash - - $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ - --cov=tutorial -q - -A sidebar, which presents a concept tangentially related to content discussed -on a page, is rendered like so: - -.. sidebar:: This is a sidebar - - Sidebar information. - -When multiple objects are imported from the same package, the following -convention is used: - - .. code-block:: python - - from foo import ( - bar, - baz, - ) - -It may look unusual, but it has advantages: - -* It allows one to swap out the higher-level package ``foo`` for something else - that provides the similar API. An example would be swapping out one database - for another (e.g., graduating from SQLite to PostgreSQL). - -* Looks more neat in cases where a large number of objects get imported from - that package. - -* Adding or removing imported objects from the package is quicker and results - in simpler diffs. diff --git a/docs/index.rst b/docs/index.rst index 02c35866a..f41154c19 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -213,13 +213,13 @@ Copyright, Trademarks, and Attributions copyright -Typographical Conventions -========================= +Style Guide +=========== .. toctree:: :maxdepth: 1 - conventions + style-guide Index and Glossary diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 05199d313..83a139917 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -15,7 +15,7 @@ Front Matter :maxdepth: 1 copyright - conventions + style-guide authorintro designdefense diff --git a/docs/style-guide.rst b/docs/style-guide.rst new file mode 100644 index 000000000..856d6ea85 --- /dev/null +++ b/docs/style-guide.rst @@ -0,0 +1,109 @@ +.. _style_guide: + +Style Guide +=========== + +Literals, filenames, and function arguments are presented using the +following style: + + ``argument1`` + +Warnings which represent limitations and need-to-know information +related to a topic or concept are presented in the following style: + + .. warning:: + + This is a warning. + +Notes which represent additional information related to a topic or +concept are presented in the following style: + + .. note:: + + This is a note. + +We present Python method names using the following style: + + :meth:`pyramid.config.Configurator.add_view` + +We present Python class names, module names, attributes, and global +variables using the following style: + + :class:`pyramid.config.Configurator.registry` + +References to glossary terms are presented using the following style: + + :term:`Pylons` + +URLs are presented using the following style: + + `Pylons `_ + +References to sections and chapters are presented using the following +style: + + :ref:`traversal_chapter` + +Code and configuration file blocks are presented in the following style: + + .. code-block:: python + :linenos: + + def foo(abc): + pass + +Example blocks representing UNIX shell commands are prefixed with a ``$`` +character, e.g.: + + .. code-block:: bash + + $ $VENV/bin/py.test -q + +See :term:`venv` for the meaning of ``$VENV``. + +Example blocks representing Windows commands are prefixed with a drive letter +with an optional directory name, e.g.: + + .. code-block:: doscon + + c:\examples> %VENV%\Scripts\py.test -q + +See :term:`venv` for the meaning of ``%VENV%``. + +When a command that should be typed on one line is too long to fit on a page, +the backslash ``\`` is used to indicate that the following printed line should +be part of the command: + + .. code-block:: bash + + $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ + --cov=tutorial -q + +A sidebar, which presents a concept tangentially related to content discussed +on a page, is rendered like so: + +.. sidebar:: This is a sidebar + + Sidebar information. + +When multiple objects are imported from the same package, the following +convention is used: + + .. code-block:: python + + from foo import ( + bar, + baz, + ) + +It may look unusual, but it has advantages: + +* It allows one to swap out the higher-level package ``foo`` for something else + that provides the similar API. An example would be swapping out one database + for another (e.g., graduating from SQLite to PostgreSQL). + +* Looks more neat in cases where a large number of objects get imported from + that package. + +* Adding or removing imported objects from the package is quicker and results + in simpler diffs. -- cgit v1.2.3 From 8cc4f7891056c085a4060ffe7ec9ce580943133e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 03:33:56 -0800 Subject: Add Introduction - add how to update and contribute - add file conventions - add line conventions --- docs/style-guide.rst | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 856d6ea85..ae56ad9ba 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -1,8 +1,55 @@ -.. _style_guide: +.. _style-guide: Style Guide =========== +This chapter describes how to edit, update, and build the :app:`Pyramid` documentation. + + +.. _style-guide-contribute: + +How to update and contribute to documentation +--------------------------------------------- + +All projects under the Pylons Projects, including this one, follow the guidelines established at `How to Contribute `_ and `Coding Style and Standards `_. + +By building the documentation locally, you can preview the output before committing and pushing your changes to the repository. Follow the instructions for `Building documentation for a Pylons Project project `_. These instructions also include how to install packages required to build the documentation, and how to follow our recommended git workflow. + +When submitting a pull request for the first time in a project, sign `CONTRIBUTORS.txt `_ and commit it along with your pull request. + + +.. _style-guide-file-conventions: + +Location, referencing, and naming of files +------------------------------------------ + +* reStructuredText (reST) files must be located in ``docs/`` and its subdirectories. +* Image files must be located in ``docs/_static/``. +* reST directives must refer to files either relative to the source file or absolute from the top source directory. For example, in ``docs/narr/source.rst``, you could refer to a file in a different directory as either ``.. include:: ../diff-dir/diff-source.rst`` or ``.. include:: /diff-dir/diff-source.rst``. +* File names should be lower-cased and have words separated with either a hyphen "-" or an underscore "_". +* reST files must have an extension of ``.rst``. +* Image files may be any format but must have lower-cased file names and have standard file extensions that consist three letters (``.gif``, ``.jpg``, ``.png``, ``.svg``). ``.gif`` and ``.svg`` are not currently supported by PDF builders in Sphinx, but you can allow the Sphinx builder to automatically select the correct image format for the desired output by replacing the three-letter file extension with ``*``. For example: + + .. code-block:: rst + + .. image:: ../_static/pyramid_request_processing.* + + will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related [Stack Overflow post](http://stackoverflow.com/questions/6473660/using-sphinx-docs-how-can-i-specify-png-image-formats-for-html-builds-and-pdf-im/6486713#6486713). + + +.. _style-guide-lines: + +Line length and paragraphs +-------------------------- + +Narrative documentation is not code, and should therefore not adhere to PEP8 or other line length conventions. When a translator sees only part of a sentence or paragraph, it makes it more difficult to translate the concept. Text editors can soft wrap lines for display to avoid horizontal scrolling. We admit, we boofed it by using arbitrary 79-character line lengths in our own documentation, but we have seen the error of our ways and wish to correct this going forward. + +A paragraph should be on one line. Paragraphs must be separated by two line feeds. + + + + + Literals, filenames, and function arguments are presented using the following style: -- cgit v1.2.3 From 18a6375cadb8cbf7e44f494c36e0d6c3f696f141 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 05:06:36 -0800 Subject: Add moar sections - trailing white space - indentation - split line lengths and paragraphs --- docs/style-guide.rst | 53 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index ae56ad9ba..5946314e3 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -23,30 +23,55 @@ When submitting a pull request for the first time in a project, sign `CONTRIBUTO Location, referencing, and naming of files ------------------------------------------ -* reStructuredText (reST) files must be located in ``docs/`` and its subdirectories. -* Image files must be located in ``docs/_static/``. -* reST directives must refer to files either relative to the source file or absolute from the top source directory. For example, in ``docs/narr/source.rst``, you could refer to a file in a different directory as either ``.. include:: ../diff-dir/diff-source.rst`` or ``.. include:: /diff-dir/diff-source.rst``. -* File names should be lower-cased and have words separated with either a hyphen "-" or an underscore "_". -* reST files must have an extension of ``.rst``. -* Image files may be any format but must have lower-cased file names and have standard file extensions that consist three letters (``.gif``, ``.jpg``, ``.png``, ``.svg``). ``.gif`` and ``.svg`` are not currently supported by PDF builders in Sphinx, but you can allow the Sphinx builder to automatically select the correct image format for the desired output by replacing the three-letter file extension with ``*``. For example: +- reStructuredText (reST) files must be located in ``docs/`` and its subdirectories. +- Image files must be located in ``docs/_static/``. +- reST directives must refer to files either relative to the source file or absolute from the top source directory. For example, in ``docs/narr/source.rst``, you could refer to a file in a different directory as either ``.. include:: ../diff-dir/diff-source.rst`` or ``.. include:: /diff-dir/diff-source.rst``. +- File names should be lower-cased and have words separated with either a hyphen "-" or an underscore "_". +- reST files must have an extension of ``.rst``. +- Image files may be any format but must have lower-cased file names and have standard file extensions that consist three letters (``.gif``, ``.jpg``, ``.png``, ``.svg``). ``.gif`` and ``.svg`` are not currently supported by PDF builders in Sphinx, but you can allow the Sphinx builder to automatically select the correct image format for the desired output by replacing the three-letter file extension with ``*``. For example: .. code-block:: rst - .. image:: ../_static/pyramid_request_processing.* + .. image:: ../_static/pyramid_request_processing.- will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related [Stack Overflow post](http://stackoverflow.com/questions/6473660/using-sphinx-docs-how-can-i-specify-png-image-formats-for-html-builds-and-pdf-im/6486713#6486713). -.. _style-guide-lines: +.. _style-guide-line-lengths: -Line length and paragraphs --------------------------- +Line lengths +------------ -Narrative documentation is not code, and should therefore not adhere to PEP8 or other line length conventions. When a translator sees only part of a sentence or paragraph, it makes it more difficult to translate the concept. Text editors can soft wrap lines for display to avoid horizontal scrolling. We admit, we boofed it by using arbitrary 79-character line lengths in our own documentation, but we have seen the error of our ways and wish to correct this going forward. +Narrative documentation is not code, and should therefore not adhere to PEP8 or other line length conventions. When a translator sees only part of a sentence or paragraph, it makes it more difficult to translate the concept. Line lengths make ``diff`` more difficult. Text editors can soft wrap lines for display to avoid horizontal scrolling. We admit, we boofed it by using arbitrary 79-character line lengths in our own documentation, but we have seen the error of our ways and wish to correct this going forward. + + +.. _style-guide-trailing-white-space: + +Trailing white spaces +--------------------- + +- No trailing white spaces. +- Always use a line feed or carriage return at the end of a file. + + +.. _style-guide-paragraphs: + +Paragraphs +---------- A paragraph should be on one line. Paragraphs must be separated by two line feeds. +.. _style-guide-indentation: + +Indentation +----------- + +- Indent using four spaces. +- Do not use tabs to indent. + + + @@ -145,12 +170,12 @@ convention is used: It may look unusual, but it has advantages: -* It allows one to swap out the higher-level package ``foo`` for something else +- It allows one to swap out the higher-level package ``foo`` for something else that provides the similar API. An example would be swapping out one database for another (e.g., graduating from SQLite to PostgreSQL). -* Looks more neat in cases where a large number of objects get imported from +- Looks more neat in cases where a large number of objects get imported from that package. -* Adding or removing imported objects from the package is quicker and results +- Adding or removing imported objects from the package is quicker and results in simpler diffs. -- cgit v1.2.3 From 1b7d853a09d97968af708c7ebe10ff26827090ed Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 30 Sep 2016 18:28:14 -0500 Subject: replace the reloader with the hupper package --- pyramid/scripts/pserve.py | 451 +----------------------------- pyramid/tests/test_scripts/test_pserve.py | 70 ----- setup.py | 1 + 3 files changed, 11 insertions(+), 511 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 0d22c9f3f..eb0c0b126 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -8,50 +8,21 @@ # Code taken also from QP: http://www.mems-exchange.org/software/qp/ From # lib/site.py -import atexit -import ctypes import optparse import os -import py_compile import re -import subprocess import sys -import tempfile import textwrap -import threading -import time -import traceback -import webbrowser +import hupper from paste.deploy import loadserver from paste.deploy import loadapp -from paste.deploy.loadwsgi import loadcontext, SERVER from pyramid.compat import PY2 -from pyramid.compat import WIN from pyramid.scripts.common import parse_vars from pyramid.scripts.common import setup_logging -MAXFD = 1024 - -try: - import termios -except ImportError: # pragma: no cover - termios = None - -if WIN and not hasattr(os, 'kill'): # pragma: no cover - # py 2.6 on windows - def kill(pid, sig=None): - """kill function for Win32""" - # signal is ignored, semibogus raise message - kernel32 = ctypes.windll.kernel32 - handle = kernel32.OpenProcess(1, 0, pid) - if (0 == kernel32.TerminateProcess(handle, 0)): - raise OSError('No such process %s' % pid) -else: - kill = os.kill - def main(argv=sys.argv, quiet=False): command = PServeCommand(argv, quiet=quiet) return command.run() @@ -119,9 +90,6 @@ class PServeCommand(object): _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) - _reloader_environ_key = 'PYTHON_RELOADER_SHOULD_RUN' - _monitor_environ_key = 'PASTE_MONITOR_SHOULD_RUN' - def __init__(self, argv, quiet=False): self.options, self.args = self.parser.parse_args(argv[1:]) if quiet: @@ -141,15 +109,15 @@ class PServeCommand(object): return 2 app_spec = self.args[0] - if self.options.reload: - if os.environ.get(self._reloader_environ_key): - if self.options.verbose > 1: - self.out('Running reloading file monitor') - install_reloader(int(self.options.reload_interval), [app_spec]) - # if self.requires_config_file: - # watch_file(self.args[0]) - else: - return self.restart_with_reloader() + if self.options.reload and not hupper.is_active(): + if self.options.verbose > 1: + self.out('Running reloading file monitor') + hupper.start_reloader( + 'pyramid.scripts.pserve.main', + reload_interval=int(self.options.reload_interval), + verbose=self.options.verbose, + ) + return 0 app_name = self.options.app_name @@ -200,17 +168,6 @@ class PServeCommand(object): msg = '' self.out('Exiting%s (-v to see traceback)' % msg) - if self.options.browser: - def open_browser(): - context = loadcontext(SERVER, app_spec, name=server_name, relative_to=base, - global_conf=vars) - url = 'http://127.0.0.1:{port}/'.format(**context.config()) - time.sleep(1) - webbrowser.open(url) - t = threading.Thread(target=open_browser) - t.setDaemon(True) - t.start() - serve() def loadapp(self, app_spec, name, relative_to, **kw): # pragma: no cover @@ -220,394 +177,6 @@ class PServeCommand(object): return loadserver( server_spec, name=name, relative_to=relative_to, **kw) - def quote_first_command_arg(self, arg): # pragma: no cover - """ - There's a bug in Windows when running an executable that's - located inside a path with a space in it. This method handles - that case, or on non-Windows systems or an executable with no - spaces, it just leaves well enough alone. - """ - if (sys.platform != 'win32' or ' ' not in arg): - # Problem does not apply: - return arg - try: - import win32api - except ImportError: - raise ValueError( - "The executable %r contains a space, and in order to " - "handle this issue you must have the win32api module " - "installed" % arg) - arg = win32api.GetShortPathName(arg) - return arg - - def find_script_path(self, name): # pragma: no cover - """ - Return the path to the script being invoked by the python interpreter. - - There's an issue on Windows when running the executable from - a console_script causing the script name (sys.argv[0]) to - not end with .exe or .py and thus cannot be run via popen. - """ - if sys.platform == 'win32': - if not name.endswith('.exe') and not name.endswith('.py'): - name += '.exe' - return name - - def restart_with_reloader(self): # pragma: no cover - self.restart_with_monitor(reloader=True) - - def restart_with_monitor(self, reloader=False): # pragma: no cover - if self.options.verbose > 0: - if reloader: - self.out('Starting subprocess with file monitor') - else: - self.out('Starting subprocess with monitor parent') - while 1: - args = [ - self.quote_first_command_arg(sys.executable), - self.find_script_path(sys.argv[0]), - ] + sys.argv[1:] - new_environ = os.environ.copy() - if reloader: - new_environ[self._reloader_environ_key] = 'true' - else: - new_environ[self._monitor_environ_key] = 'true' - proc = None - try: - try: - _turn_sigterm_into_systemexit() - proc = subprocess.Popen(args, env=new_environ) - exit_code = proc.wait() - proc = None - except KeyboardInterrupt: - self.out('^C caught in monitor process') - if self.options.verbose > 1: - raise - return 1 - finally: - if proc is not None: - import signal - try: - kill(proc.pid, signal.SIGTERM) - except (OSError, IOError): - pass - - if reloader: - # Reloader always exits with code 3; but if we are - # a monitor, any exit code will restart - if exit_code != 3: - return exit_code - if self.options.verbose > 0: - self.out('%s %s %s' % ('-' * 20, 'Restarting', '-' * 20)) - -class LazyWriter(object): - - """ - File-like object that opens a file lazily when it is first written - to. - """ - - def __init__(self, filename, mode='w'): - self.filename = filename - self.fileobj = None - self.lock = threading.Lock() - self.mode = mode - - def open(self): - if self.fileobj is None: - with self.lock: - self.fileobj = open(self.filename, self.mode) - return self.fileobj - - def close(self): - fileobj = self.fileobj - if fileobj is not None: - fileobj.close() - - def __del__(self): - self.close() - - def write(self, text): - fileobj = self.open() - fileobj.write(text) - fileobj.flush() - - def writelines(self, text): - fileobj = self.open() - fileobj.writelines(text) - fileobj.flush() - - def flush(self): - self.open().flush() - -def ensure_port_cleanup( - bound_addresses, maxtries=30, sleeptime=2): # pragma: no cover - """ - This makes sure any open ports are closed. - - Does this by connecting to them until they give connection - refused. Servers should call like:: - - ensure_port_cleanup([80, 443]) - """ - atexit.register(_cleanup_ports, bound_addresses, maxtries=maxtries, - sleeptime=sleeptime) - -def _cleanup_ports( - bound_addresses, maxtries=30, sleeptime=2): # pragma: no cover - # Wait for the server to bind to the port. - import socket - import errno - for bound_address in bound_addresses: - for attempt in range(maxtries): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - sock.connect(bound_address) - except socket.error as e: - if e.args[0] != errno.ECONNREFUSED: - raise - break - else: - time.sleep(sleeptime) - else: - raise SystemExit('Timeout waiting for port.') - sock.close() - -def _turn_sigterm_into_systemexit(): # pragma: no cover - """ - Attempts to turn a SIGTERM exception into a SystemExit exception. - """ - try: - import signal - except ImportError: - return - def handle_term(signo, frame): - raise SystemExit - signal.signal(signal.SIGTERM, handle_term) - -def ensure_echo_on(): # pragma: no cover - if termios: - fd = sys.stdin - if fd.isatty(): - attr_list = termios.tcgetattr(fd) - if not attr_list[3] & termios.ECHO: - attr_list[3] |= termios.ECHO - termios.tcsetattr(fd, termios.TCSANOW, attr_list) - -def install_reloader(poll_interval=1, extra_files=None): # pragma: no cover - """ - Install the reloading monitor. - - On some platforms server threads may not terminate when the main - thread does, causing ports to remain open/locked. - """ - ensure_echo_on() - mon = Monitor(poll_interval=poll_interval) - if extra_files is None: - extra_files = [] - mon.extra_files.extend(extra_files) - t = threading.Thread(target=mon.periodic_reload) - t.setDaemon(True) - t.start() - -class classinstancemethod(object): - """ - Acts like a class method when called from a class, like an - instance method when called by an instance. The method should - take two arguments, 'self' and 'cls'; one of these will be None - depending on how the method was called. - """ - - def __init__(self, func): - self.func = func - self.__doc__ = func.__doc__ - - def __get__(self, obj, type=None): - return _methodwrapper(self.func, obj=obj, type=type) - -class _methodwrapper(object): - - def __init__(self, func, obj, type): - self.func = func - self.obj = obj - self.type = type - - def __call__(self, *args, **kw): - assert 'self' not in kw and 'cls' not in kw, ( - "You cannot use 'self' or 'cls' arguments to a " - "classinstancemethod") - return self.func(*((self.obj, self.type) + args), **kw) - - -class Monitor(object): # pragma: no cover - """ - A file monitor and server restarter. - - Use this like: - - ..code-block:: Python - - install_reloader() - - Then make sure your server is installed with a shell script like:: - - err=3 - while test "$err" -eq 3 ; do - python server.py - err="$?" - done - - or is run from this .bat file (if you use Windows):: - - @echo off - :repeat - python server.py - if %errorlevel% == 3 goto repeat - - or run a monitoring process in Python (``pserve --reload`` does - this). - - Use the ``watch_file(filename)`` function to cause a reload/restart for - other non-Python files (e.g., configuration files). If you have - a dynamic set of files that grows over time you can use something like:: - - def watch_config_files(): - return CONFIG_FILE_CACHE.keys() - add_file_callback(watch_config_files) - - Then every time the reloader polls files it will call - ``watch_config_files`` and check all the filenames it returns. - """ - instances = [] - global_extra_files = [] - global_file_callbacks = [] - - def __init__(self, poll_interval): - self.module_mtimes = {} - self.keep_running = True - self.poll_interval = poll_interval - self.extra_files = list(self.global_extra_files) - self.instances.append(self) - self.syntax_error_files = set() - self.pending_reload = False - self.file_callbacks = list(self.global_file_callbacks) - temp_pyc_fp = tempfile.NamedTemporaryFile(delete=False) - self.temp_pyc = temp_pyc_fp.name - temp_pyc_fp.close() - - def _exit(self): - try: - os.unlink(self.temp_pyc) - except IOError: - # not worried if the tempfile can't be removed - pass - # use os._exit() here and not sys.exit() since within a - # thread sys.exit() just closes the given thread and - # won't kill the process; note os._exit does not call - # any atexit callbacks, nor does it do finally blocks, - # flush open files, etc. In otherwords, it is rude. - os._exit(3) - - def periodic_reload(self): - while True: - if not self.check_reload(): - self._exit() - break - time.sleep(self.poll_interval) - - def check_reload(self): - filenames = list(self.extra_files) - for file_callback in self.file_callbacks: - try: - filenames.extend(file_callback()) - except: - print( - "Error calling reloader callback %r:" % file_callback) - traceback.print_exc() - for module in list(sys.modules.values()): - try: - filename = module.__file__ - except (AttributeError, ImportError): - continue - if filename is not None: - filenames.append(filename) - new_changes = False - for filename in filenames: - try: - stat = os.stat(filename) - if stat: - mtime = stat.st_mtime - else: - mtime = 0 - except (OSError, IOError): - continue - if filename.endswith('.pyc') and os.path.exists(filename[:-1]): - mtime = max(os.stat(filename[:-1]).st_mtime, mtime) - pyc = True - else: - pyc = False - old_mtime = self.module_mtimes.get(filename) - self.module_mtimes[filename] = mtime - if old_mtime is not None and old_mtime < mtime: - new_changes = True - if pyc: - filename = filename[:-1] - is_valid = True - if filename.endswith('.py'): - is_valid = self.check_syntax(filename) - if is_valid: - print("%s changed ..." % filename) - if new_changes: - self.pending_reload = True - if self.syntax_error_files: - for filename in sorted(self.syntax_error_files): - print("%s has a SyntaxError; NOT reloading." % filename) - if self.pending_reload and not self.syntax_error_files: - self.pending_reload = False - return False - return True - - def check_syntax(self, filename): - # check if a file has syntax errors. - # If so, track it until it's fixed. - try: - py_compile.compile(filename, cfile=self.temp_pyc, doraise=True) - except py_compile.PyCompileError as ex: - print(ex.msg) - self.syntax_error_files.add(filename) - return False - else: - if filename in self.syntax_error_files: - self.syntax_error_files.remove(filename) - return True - - def watch_file(self, cls, filename): - """Watch the named file for changes""" - filename = os.path.abspath(filename) - if self is None: - for instance in cls.instances: - instance.watch_file(filename) - cls.global_extra_files.append(filename) - else: - self.extra_files.append(filename) - - watch_file = classinstancemethod(watch_file) - - def add_file_callback(self, cls, callback): - """Add a callback -- a function that takes no parameters -- that will - return a list of filenames to watch for changes.""" - if self is None: - for instance in cls.instances: - instance.add_file_callback(callback) - cls.global_file_callbacks.append(callback) - else: - self.file_callbacks.append(callback) - - add_file_callback = classinstancemethod(add_file_callback) - -watch_file = Monitor.watch_file -add_file_callback = Monitor.add_file_callback - # For paste.deploy server instantiation (egg:pyramid#wsgiref) def wsgiref_server_runner(wsgi_app, global_conf, **kw): # pragma: no cover from wsgiref.simple_server import make_server diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index bf4763602..e84de92d4 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -1,5 +1,3 @@ -import os -import tempfile import unittest class TestPServeCommand(unittest.TestCase): @@ -69,71 +67,3 @@ class Test_main(unittest.TestCase): def test_it(self): result = self._callFUT(['pserve']) self.assertEqual(result, 2) - -class TestLazyWriter(unittest.TestCase): - def _makeOne(self, filename, mode='w'): - from pyramid.scripts.pserve import LazyWriter - return LazyWriter(filename, mode) - - def test_open(self): - filename = tempfile.mktemp() - try: - inst = self._makeOne(filename) - fp = inst.open() - self.assertEqual(fp.name, filename) - finally: - fp.close() - os.remove(filename) - - def test_write(self): - filename = tempfile.mktemp() - try: - inst = self._makeOne(filename) - inst.write('hello') - finally: - with open(filename) as f: - data = f.read() - self.assertEqual(data, 'hello') - inst.close() - os.remove(filename) - - def test_writeline(self): - filename = tempfile.mktemp() - try: - inst = self._makeOne(filename) - inst.writelines('hello') - finally: - with open(filename) as f: - data = f.read() - self.assertEqual(data, 'hello') - inst.close() - os.remove(filename) - - def test_flush(self): - filename = tempfile.mktemp() - try: - inst = self._makeOne(filename) - inst.flush() - fp = inst.fileobj - self.assertEqual(fp.name, filename) - finally: - fp.close() - os.remove(filename) - -class Test__methodwrapper(unittest.TestCase): - def _makeOne(self, func, obj, type): - from pyramid.scripts.pserve import _methodwrapper - return _methodwrapper(func, obj, type) - - def test___call__succeed(self): - def foo(self, cls, a=1): return 1 - class Bar(object): pass - wrapper = self._makeOne(foo, Bar, None) - result = wrapper(a=1) - self.assertEqual(result, 1) - - def test___call__fail(self): - def foo(self, cls, a=1): return 1 - class Bar(object): pass - wrapper = self._makeOne(foo, Bar, None) - self.assertRaises(AssertionError, wrapper, cls=1) diff --git a/setup.py b/setup.py index f738ee623..36615f36b 100644 --- a/setup.py +++ b/setup.py @@ -46,6 +46,7 @@ install_requires = [ 'venusian >= 1.0a3', # ``ignore`` 'translationstring >= 0.4', # py3 compat 'PasteDeploy >= 1.5.0', # py3 compat + 'hupper', ] tests_require = [ -- cgit v1.2.3 From 38fc72ca66f718414b66782518c3698d7a5d8f2f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 4 Nov 2016 02:20:53 -0500 Subject: restore --browser support and watch the ini file --- pyramid/scripts/pserve.py | 58 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index eb0c0b126..969bc07f1 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -13,10 +13,19 @@ import os import re import sys import textwrap +import threading +import time +import webbrowser import hupper -from paste.deploy import loadserver -from paste.deploy import loadapp +from paste.deploy import ( + loadapp, + loadserver, +) +from paste.deploy.loadwsgi import ( + SERVER, + loadcontext, +) from pyramid.compat import PY2 @@ -109,19 +118,8 @@ class PServeCommand(object): return 2 app_spec = self.args[0] - if self.options.reload and not hupper.is_active(): - if self.options.verbose > 1: - self.out('Running reloading file monitor') - hupper.start_reloader( - 'pyramid.scripts.pserve.main', - reload_interval=int(self.options.reload_interval), - verbose=self.options.verbose, - ) - return 0 - - app_name = self.options.app_name - vars = self.get_options() + app_name = self.options.app_name if not self._scheme_re.search(app_spec): app_spec = 'config:' + app_spec @@ -134,6 +132,34 @@ class PServeCommand(object): server_spec = app_spec base = os.getcwd() + # do not open the browser on each reload so check hupper first + if self.options.browser and not hupper.is_active(): + def open_browser(): + context = loadcontext( + SERVER, app_spec, name=server_name, relative_to=base, + global_conf=vars) + url = 'http://127.0.0.1:{port}/'.format(**context.config()) + time.sleep(1) + webbrowser.open(url) + t = threading.Thread(target=open_browser) + t.setDaemon(True) + t.start() + + if self.options.reload and not hupper.is_active(): + if self.options.verbose > 1: + self.out('Running reloading file monitor') + hupper.start_reloader( + 'pyramid.scripts.pserve.main', + reload_interval=int(self.options.reload_interval), + verbose=self.options.verbose, + ) + return 0 + + if hupper.is_active(): + reloader = hupper.get_reloader() + if app_spec.startswith('config:'): + reloader.watch_files([app_spec[len('config:'):]]) + log_fn = app_spec if log_fn.startswith('config:'): log_fn = app_spec[len('config:'):] @@ -146,8 +172,8 @@ class PServeCommand(object): server = self.loadserver(server_spec, name=server_name, relative_to=base, global_conf=vars) - app = self.loadapp(app_spec, name=app_name, relative_to=base, - global_conf=vars) + app = self.loadapp( + app_spec, name=app_name, relative_to=base, global_conf=vars) if self.options.verbose > 0: if hasattr(os, 'getpid'): -- cgit v1.2.3 From 1644efffa25dcc70c9e01f709fbd203351e2f6ba Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 15:49:19 -0600 Subject: link to documentation on hupper fixes #2806 --- docs/narr/project.rst | 20 ++++++++++++++++++++ docs/tutorials/wiki/installation.rst | 3 ++- docs/tutorials/wiki2/installation.rst | 3 ++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 71bd176f6..6c42881f4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1045,3 +1045,23 @@ Another good production alternative is :term:`Green Unicorn` (aka mod_wsgi, although it depends, in its default configuration, on having a buffering HTTP proxy in front of it. It does not, as of this writing, work on Windows. + +Automatically Reloading Your Code +--------------------------------- + +During development, it can be really useful to automatically have the +webserver restart when you make changes. ``pserve`` has a ``--reload`` switch +to enable this. It uses the +`hupper ` package +to enable this behavior. When your code crashes, ``hupper`` will wait for +another change or the ``SIGHUP`` signal before restarting again. + +inotify support +~~~~~~~~~~~~~~~ + +By default, ``hupper`` will poll the filesystem for changes to all python +code. This can be pretty inefficient in larger projects. To be nicer to your +hard drive, you should install the +`watchdog ` package in development. +``hupper`` will automatically use ``watchdog`` to more efficiently poll the +filesystem. diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 6172b122b..03e183739 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -370,7 +370,8 @@ coverage. Start the application --------------------- -Start the application. +Start the application. See :ref:`what_is_this_pserve_thing` for more +information on ``pserve``. On UNIX ^^^^^^^ diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 0440c2d1d..75d5d4abd 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -457,7 +457,8 @@ working directory. This is an SQLite database with a single table defined in it Start the application --------------------- -Start the application. +Start the application. See :ref:`what_is_this_pserve_thing` for more +information on ``pserve``. On UNIX ^^^^^^^ -- cgit v1.2.3 From 067ce0528a4c108e502c968b0865d213dbdda271 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 15:54:49 -0600 Subject: add changes for #2805 --- CHANGES.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index a0a928f83..dac61678d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -93,6 +93,29 @@ Features using the ``PYRAMID_CSRF_TRUSTED_ORIGINS`` environment variable similar to other settings. See https://github.com/Pylons/pyramid/pull/2823 +- ``pserve --reload`` now uses the + `hupper ` + library to monitor file changes. This comes with many improvements: + + - If the `watchdog `_ package is + installed then monitoring will be done using inotify instead of + cpu and disk-intensive polling. + + - The monitor is now a separate process that will not crash and starts up + before any of your code. + + - The monitor will not restart the process after a crash until a file is + saved. + + - The monitor works on windows. + + - You can now trigger a reload manually from a pyramid view or any other + code via ``hupper.get_reloader().trigger_reload()``. Kind of neat. + + - You can trigger a reload by issuing a ``SIGHUP`` to the monitor process. + + See https://github.com/Pylons/pyramid/pull/2805 + Bug Fixes --------- -- cgit v1.2.3 From f69e9035d16110d67de5b5a5c0c94bde5bd6b359 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 15:32:42 -0800 Subject: Add Page structure section - add description - add introduction - add headings - add grammar, spelling, capitalization preferences --- docs/style-guide.rst | 87 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 5946314e3..3f2b630d3 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -3,7 +3,17 @@ Style Guide =========== -This chapter describes how to edit, update, and build the :app:`Pyramid` documentation. +.. admonition:: description + + This chapter describes how to edit, update, and build the :app:`Pyramid` documentation. + + +.. _style-guide-introduction: + +Introduction +------------ + +This chapter provides details of how to contribute updates to the documentation following style guidelines and conventions. We provide examples, including reStructuredText code and its rendered output for both visual and technical reference. .. _style-guide-contribute: @@ -37,6 +47,43 @@ Location, referencing, and naming of files will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related [Stack Overflow post](http://stackoverflow.com/questions/6473660/using-sphinx-docs-how-can-i-specify-png-image-formats-for-html-builds-and-pdf-im/6486713#6486713). +.. _style-guide-page-structure: + +Page structure +-------------- + +Each page should contain in order the following. + +- The main heading. This will be visible in the table of contents. + + .. code-block:: rst + + ================ + The main heading + ================ + +- The description of the page. This text will be displayed to the reader below the main heading as well as be inserted into the description metadata field of the document. It will be displayed in search engine listings for the page. This is created using the reST ``admonition`` directive. A single paragraph of text consisting of no more than three sentences is recommended, so that the same text fits into search engine results: + + .. code-block:: rst + + .. admonition:: description + + This is a description of the page, which will appear inline and in the description metadata field. + + .. note:: The ``description`` metadata field is not yet implemented in the documentation's Sphinx theme, but it is a `feature request `_, so it is helpful to start using the ``description`` admonition now. + +- Introduction paragraph. + + .. code-block:: rst + + Introduction + ------------ + + This chapter is an introduction. + +- Finally the content of the document page, consisting of reST elements such as headings, paragraphs, tables, and so on. + + .. _style-guide-line-lengths: Line lengths @@ -54,6 +101,23 @@ Trailing white spaces - Always use a line feed or carriage return at the end of a file. +.. _style-guide-indentation: + +Indentation +----------- + +- Indent using four spaces. +- Do not use tabs to indent. + + +.. _style-guide-headings: + +Headings +-------- + +Capitalize only the first letter in a heading, unless other words are proper nouns or acronyms, e.g., "Pyramid" or "HTML". + + .. _style-guide-paragraphs: Paragraphs @@ -62,14 +126,25 @@ Paragraphs A paragraph should be on one line. Paragraphs must be separated by two line feeds. -.. _style-guide-indentation: +.. _style-guide-grammar-spelling-preferences: -Indentation ------------ +Grammar, spelling, and capitalization preferences +------------------------------------------------- -- Indent using four spaces. -- Do not use tabs to indent. +Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. +========== ====================== +Preferred Avoid +========== ====================== +add-on addon +and so on etc. +GitHub Github, github +JavaScript Javascript, javascript +plug-in plugin +select check, tick (checkbox) +such as like +verify be sure +========== ====================== -- cgit v1.2.3 From 9089d33cfa59d84cf76b9f52f8bf181c98c6a121 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 20 Nov 2016 18:54:52 -0600 Subject: cache pip artifacts --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index e10dbc580..5691130eb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,9 @@ environment: - PYTHON: "C:\\Python27" TOXENV: "py27" +cache: + - '%LOCALAPPDATA%\pip\Cache' + install: - "%PYTHON%\\python.exe -m pip install tox" -- cgit v1.2.3 From 52bfe0a8f2f6d305f0e3d8cead290427fd71e926 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 20 Nov 2016 19:37:24 -0600 Subject: automate build names for appveyor --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 5691130eb..4c684bfc6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,6 +8,8 @@ environment: cache: - '%LOCALAPPDATA%\pip\Cache' +version: '{branch}.{build}' + install: - "%PYTHON%\\python.exe -m pip install tox" -- cgit v1.2.3 From 7285651ecf3458c61158b8fcf7dbd269f067ffaf Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 21:39:35 -0800 Subject: Add section structure --- docs/style-guide.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 3f2b630d3..49c9d5950 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -47,6 +47,26 @@ Location, referencing, and naming of files will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related [Stack Overflow post](http://stackoverflow.com/questions/6473660/using-sphinx-docs-how-can-i-specify-png-image-formats-for-html-builds-and-pdf-im/6486713#6486713). +.. _style-guide-section-structure: + +Section structure +----------------- + +Each section, or a subdirectory of reST files, such as a tutorial, must contain an ``index.rst`` file. ``index.rst`` must contain the following. + +- A section heading. This will be visible in the table of contents. +- A single paragraph describing this section. +- A Sphinx ``toctree`` directive, with a ``maxdepth`` of 2. Each ``.rst`` file in the folder should be linked to this ``toctree``. + + .. code-block:: rst + + .. toctree:: + :maxdepth: 2 + + chapter1 + chapter2 + chapter3 + .. _style-guide-page-structure: Page structure -- cgit v1.2.3 From 2954362448347a6a3efd55222a50ece8e2fae6a0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 21:53:39 -0800 Subject: update headings --- docs/style-guide.rst | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 49c9d5950..4a17e1d2b 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -67,6 +67,7 @@ Each section, or a subdirectory of reST files, such as a tutorial, must contain chapter2 chapter3 + .. _style-guide-page-structure: Page structure @@ -104,10 +105,18 @@ Each page should contain in order the following. - Finally the content of the document page, consisting of reST elements such as headings, paragraphs, tables, and so on. +.. _style-guide-page-content: + +Page content +------------ + +Within a page, content should adhere to specific guidelines. + + .. _style-guide-line-lengths: Line lengths ------------- +^^^^^^^^^^^^ Narrative documentation is not code, and should therefore not adhere to PEP8 or other line length conventions. When a translator sees only part of a sentence or paragraph, it makes it more difficult to translate the concept. Line lengths make ``diff`` more difficult. Text editors can soft wrap lines for display to avoid horizontal scrolling. We admit, we boofed it by using arbitrary 79-character line lengths in our own documentation, but we have seen the error of our ways and wish to correct this going forward. @@ -115,7 +124,7 @@ Narrative documentation is not code, and should therefore not adhere to PEP8 or .. _style-guide-trailing-white-space: Trailing white spaces ---------------------- +^^^^^^^^^^^^^^^^^^^^^ - No trailing white spaces. - Always use a line feed or carriage return at the end of a file. @@ -124,7 +133,7 @@ Trailing white spaces .. _style-guide-indentation: Indentation ------------ +^^^^^^^^^^^ - Indent using four spaces. - Do not use tabs to indent. @@ -133,15 +142,37 @@ Indentation .. _style-guide-headings: Headings --------- +^^^^^^^^ + +Capitalize only the first letter in a heading (sentence-case), unless other words are proper nouns or acronyms, e.g., "Pyramid" or "HTML". + +For consistent heading characters throughout the documentation, follow the guidelines stated in the `Python Developer's Guide `_. Specifically: + +- =, for sections +- -, for subsections +- ^, for subsubsections +- ", for paragraphs + +As individual files do not have so-called "parts" or "chapters", the headings would be underlined with characters as shown. + + .. code-block:: rst + + Heading Level 1 + =============== + + Heading Level 2 + --------------- -Capitalize only the first letter in a heading, unless other words are proper nouns or acronyms, e.g., "Pyramid" or "HTML". + Heading Level 3 + ^^^^^^^^^^^^^^^ + Heading Level 4 + ``````````````` .. _style-guide-paragraphs: Paragraphs ----------- +^^^^^^^^^^ A paragraph should be on one line. Paragraphs must be separated by two line feeds. @@ -149,7 +180,7 @@ A paragraph should be on one line. Paragraphs must be separated by two line feed .. _style-guide-grammar-spelling-preferences: Grammar, spelling, and capitalization preferences -------------------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. -- cgit v1.2.3 From c13e6cc241d1f52382435a56a18e791b6b9bbe1a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 21:58:43 -0800 Subject: add links --- docs/style-guide.rst | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 4a17e1d2b..911949862 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -139,6 +139,27 @@ Indentation - Do not use tabs to indent. +.. _style-guide-grammar-spelling-preferences: + +Grammar, spelling, and capitalization preferences +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. + +========== ====================== +Preferred Avoid +========== ====================== +add-on addon +and so on etc. +GitHub Github, github +JavaScript Javascript, javascript +plug-in plugin +select check, tick (checkbox) +such as like +verify be sure +========== ====================== + + .. _style-guide-headings: Headings @@ -177,25 +198,14 @@ Paragraphs A paragraph should be on one line. Paragraphs must be separated by two line feeds. -.. _style-guide-grammar-spelling-preferences: +Links +^^^^^ -Grammar, spelling, and capitalization preferences -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use inline links to keep the context or link label together with the URL. Do not use targets and links at the end of the page, because the separation makes it difficult to update and translate. Here is an example of inline links, our required method. -Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. + .. code-block:: rst -========== ====================== -Preferred Avoid -========== ====================== -add-on addon -and so on etc. -GitHub Github, github -JavaScript Javascript, javascript -plug-in plugin -select check, tick (checkbox) -such as like -verify be sure -========== ====================== + `Example `_ -- cgit v1.2.3 From e33b2ce88af4fb6d9412757ca0ac4f6a95bfc578 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 22:01:15 -0800 Subject: add topic --- docs/style-guide.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 911949862..2304e9d6b 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -198,6 +198,8 @@ Paragraphs A paragraph should be on one line. Paragraphs must be separated by two line feeds. +.. _style-guide-links: + Links ^^^^^ @@ -208,7 +210,22 @@ Use inline links to keep the context or link label together with the URL. Do not `Example `_ +.. _style-guide-topic: + +Topic +^^^^^ + +A topic is similar to a block quote with a title, or a self-contained section with no subsections. Use the ``topic`` directive to indicate a self-contained idea that is separate from the flow of the document. Topics may occur anywhere a section or transition may occur. Body elements and topics may not contain nested topics. + +The directive's sole argument is interpreted as the topic title, and next line must be blank. All subsequent lines make up the topic body, interpreted as body elements. + + .. code-block:: rst + + .. topic:: Topic Title + Subsequent indented lines comprise + the body of the topic, and are + interpreted as body elements. Literals, filenames, and function arguments are presented using the -- cgit v1.2.3 From ff8acd6f545ca55f9c9588ee77aee559d68ab194 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 20 Nov 2016 22:15:19 -0800 Subject: add syntax highlighting --- docs/style-guide.rst | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 2304e9d6b..cb1a15be1 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -228,6 +228,96 @@ The directive's sole argument is interpreted as the topic title, and next line m interpreted as body elements. +.. _style-guide-syntax-highlighting: + +Syntax highlighting +^^^^^^^^^^^^^^^^^^^ + +Sphinx does syntax highlighting using the `Pygments `_ library. + +Do not use two colons "::" at the end of a line, followed by a blank line, then indented code. Always specify the language to be used for syntax highlighting by using the ``code-block`` directive and indenting the code. + + .. code-block:: rst + + .. code-block:: python + + if "foo" == "bar": + # This is Python code + pass + +XML: + + .. code-block:: rst + + .. code-block:: xml + + Some XML + +Unix shell: + + .. code-block:: rst + + .. code-block:: bash + + # Start Plone in foreground mode for a test run + cd ~/Plone/zinstance + bin/plonectl fg + +Windows console: + + .. code-block:: rst + + .. code-block:: doscon + + c:\> %VENV%\Scripts\pcreate -s starter MyProject + +cfg: + + .. code-block:: rst + + .. code-block:: cfg + + [some-part] + # A random part in the buildout + recipe = collective.recipe.foo + option = value + +ini: + + .. code-block:: rst + + .. code-block:: ini + + [nosetests] + match=^test + where=pyramid + nocapture=1 + +Interactive Python: + + .. code-block:: rst + + .. code-block:: pycon + + >>> class Foo: + ... bar = 100 + ... + >>> f = Foo() + >>> f.bar + 100 + >>> f.bar / 0 + Traceback (most recent call last): + File "", line 1, in + ZeroDivisionError: integer division or modulo by zero + +If syntax highlighting is not enabled for your code block, you probably have a syntax error and Pygments will fail silently. + +View the `full list of lexers and associated short names `_. + + + + + Literals, filenames, and function arguments are presented using the following style: -- cgit v1.2.3 From 3f130937bcce073e9933e28c332e59c559025e07 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 21 Nov 2016 00:14:26 -0600 Subject: support a [pserve] config section with a list of files to watch fixes #2732 --- docs/narr/project.rst | 20 +++++++++++ pyramid/scripts/pserve.py | 58 ++++++++++++++++++++----------- pyramid/tests/test_scripts/test_pserve.py | 24 ++++++++----- 3 files changed, 73 insertions(+), 29 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 6c42881f4..b4ad6948e 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1065,3 +1065,23 @@ hard drive, you should install the `watchdog ` package in development. ``hupper`` will automatically use ``watchdog`` to more efficiently poll the filesystem. + +Monitoring Custom Files +~~~~~~~~~~~~~~~~~~~~~~~ + +By default, ``pserve --reload`` will monitor all imported Python code +(everything in ``sys.modules``) as well as the config file passed to +``pserve`` (e.g. ``development.ini``). You can instruct ``pserve`` to watch +other files for changes as well by defining a ``[pserve]`` section in your +configuration file. For example, let's say your application loads the +``favicon.ico`` file at startup and stores it in memory to efficiently +serve it many times. When you change it you want ``pserve`` to restart: + +.. code-block:: ini + + [pserve] + watch_files = + myapp/static/favicon.ico + +Paths are relative to the configuration file and are passed to ``hupper`` +to watch. Currently it does not support globs but this may change. diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 969bc07f1..c67dc86ba 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -28,9 +28,11 @@ from paste.deploy.loadwsgi import ( ) from pyramid.compat import PY2 +from pyramid.compat import configparser from pyramid.scripts.common import parse_vars from pyramid.scripts.common import setup_logging +from pyramid.settings import aslist def main(argv=sys.argv, quiet=False): command = PServeCommand(argv, quiet=quiet) @@ -97,12 +99,17 @@ class PServeCommand(object): dest='verbose', help="Suppress verbose output") + ConfigParser = configparser.ConfigParser # testing + loadapp = staticmethod(loadapp) # testing + loadserver = staticmethod(loadserver) # testing + _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) def __init__(self, argv, quiet=False): self.options, self.args = self.parser.parse_args(argv[1:]) if quiet: self.options.verbose = 0 + self.watch_files = [] def out(self, msg): # pragma: no cover if self.options.verbose > 0: @@ -112,6 +119,24 @@ class PServeCommand(object): restvars = self.args[1:] return parse_vars(restvars) + def pserve_file_config(self, filename): + config = self.ConfigParser() + config.optionxform = str + config.read(filename) + try: + items = dict(config.items('pserve')) + except configparser.NoSectionError: + return + + watch_files = aslist(items.get('watch_files', ''), flatten=False) + + # track file paths relative to the ini file + basedir = os.path.dirname(filename) + for file in watch_files: + if not os.path.isabs(file): + file = os.path.join(basedir, file) + self.watch_files.append(os.path.normpath(file)) + def run(self): # pragma: no cover if not self.args: self.out('You must give a config file') @@ -121,8 +146,12 @@ class PServeCommand(object): vars = self.get_options() app_name = self.options.app_name + base = os.getcwd() if not self._scheme_re.search(app_spec): + config_path = os.path.join(base, app_spec) app_spec = 'config:' + app_spec + else: + config_path = None server_name = self.options.server_name if self.options.server: server_spec = 'egg:pyramid' @@ -130,7 +159,6 @@ class PServeCommand(object): server_name = self.options.server else: server_spec = app_spec - base = os.getcwd() # do not open the browser on each reload so check hupper first if self.options.browser and not hupper.is_active(): @@ -155,22 +183,17 @@ class PServeCommand(object): ) return 0 + if config_path: + setup_logging(config_path, global_conf=vars) + self.watch_files.append(config_path) + self.pserve_file_config(config_path) + if hupper.is_active(): reloader = hupper.get_reloader() - if app_spec.startswith('config:'): - reloader.watch_files([app_spec[len('config:'):]]) - - log_fn = app_spec - if log_fn.startswith('config:'): - log_fn = app_spec[len('config:'):] - elif log_fn.startswith('egg:'): - log_fn = None - if log_fn: - log_fn = os.path.join(base, log_fn) - setup_logging(log_fn, global_conf=vars) + reloader.watch_files(self.watch_files) - server = self.loadserver(server_spec, name=server_name, - relative_to=base, global_conf=vars) + server = self.loadserver( + server_spec, name=server_name, relative_to=base, global_conf=vars) app = self.loadapp( app_spec, name=app_name, relative_to=base, global_conf=vars) @@ -196,13 +219,6 @@ class PServeCommand(object): serve() - def loadapp(self, app_spec, name, relative_to, **kw): # pragma: no cover - return loadapp(app_spec, name=name, relative_to=relative_to, **kw) - - def loadserver(self, server_spec, name, relative_to, **kw):# pragma:no cover - return loadserver( - server_spec, name=name, relative_to=relative_to, **kw) - # For paste.deploy server instantiation (egg:pyramid#wsgiref) def wsgiref_server_runner(wsgi_app, global_conf, **kw): # pragma: no cover from wsgiref.simple_server import make_server diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index e84de92d4..cf9426943 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -1,9 +1,12 @@ +import os import unittest +from pyramid.tests.test_scripts import dummy class TestPServeCommand(unittest.TestCase): def setUp(self): from pyramid.compat import NativeIO self.out_ = NativeIO() + self.config_factory = dummy.DummyConfigParserFactory() def out(self, msg): self.out_.write(msg) @@ -11,7 +14,6 @@ class TestPServeCommand(unittest.TestCase): def _get_server(*args, **kwargs): def server(app): return '' - return server def _getTargetClass(self): @@ -23,6 +25,7 @@ class TestPServeCommand(unittest.TestCase): effargs.extend(args) cmd = self._getTargetClass()(effargs) cmd.out = self.out + cmd.ConfigParser = self.config_factory return cmd def test_run_no_args(self): @@ -38,20 +41,15 @@ class TestPServeCommand(unittest.TestCase): self.assertEqual(result, {'a': '1', 'b': '2'}) def test_parse_vars_good(self): - from pyramid.tests.test_scripts.dummy import DummyApp - inst = self._makeOne('development.ini', 'a=1', 'b=2') inst.loadserver = self._get_server - - app = DummyApp() - + app = dummy.DummyApp() def get_app(*args, **kwargs): app.global_conf = kwargs.get('global_conf', None) - inst.loadapp = get_app - inst.run() + inst.run() self.assertEqual(app.global_conf, {'a': '1', 'b': '2'}) def test_parse_vars_bad(self): @@ -59,6 +57,16 @@ class TestPServeCommand(unittest.TestCase): inst.loadserver = self._get_server self.assertRaises(ValueError, inst.run) + def test_config_file_finds_watch_files(self): + inst = self._makeOne('development.ini') + self.config_factory.items = [('watch_files', 'foo\nbar\n/baz')] + inst.pserve_file_config('/base/path.ini') + self.assertEqual(inst.watch_files, [ + os.path.normpath('/base/foo'), + os.path.normpath('/base/bar'), + os.path.normpath('/baz'), + ]) + class Test_main(unittest.TestCase): def _callFUT(self, argv): from pyramid.scripts.pserve import main -- cgit v1.2.3 From abfb2f61458b111008fd1d9de1553380715889a3 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 21 Nov 2016 01:01:47 -0600 Subject: add changelog for #2827 --- CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index dac61678d..0686e1ad1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -116,6 +116,10 @@ Features See https://github.com/Pylons/pyramid/pull/2805 +- A new ``[pserve]`` section is supported in your config files with a + ``watch_files`` key that can configure ``pserve --reload`` to monitor custom + file paths. See https://github.com/Pylons/pyramid/pull/2827 + Bug Fixes --------- -- cgit v1.2.3 From 90db2bc106822be4ba3ca92a51a932f17d5ce4f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 21 Nov 2016 02:09:01 -0800 Subject: add code block options - add literal includes - add displaying long commands - add sphinx to intersphinx - garden --- docs/conf.py | 1 + docs/style-guide.rst | 276 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 194 insertions(+), 83 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c3a7170fc..ace921247 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -68,6 +68,7 @@ intersphinx_mapping = { 'pylonswebframework': ('http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/', None), 'python': ('https://docs.python.org/3', None), 'pytest': ('http://pytest.org/latest/', None), + 'sphinx': ('http://www.sphinx-doc.org/en/latest', None), 'sqla': ('http://docs.sqlalchemy.org/en/latest', None), 'tm': ('http://docs.pylonsproject.org/projects/pyramid-tm/en/latest/', None), 'toolbar': ('http://docs.pylonsproject.org/projects/pyramid-debugtoolbar/en/latest', None), diff --git a/docs/style-guide.rst b/docs/style-guide.rst index cb1a15be1..c30b199a6 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -5,7 +5,7 @@ Style Guide .. admonition:: description - This chapter describes how to edit, update, and build the :app:`Pyramid` documentation. + This chapter describes how to edit, update, and build the :app:`Pyramid` documentation. For coding style guidelines, see `Coding Style `_. .. _style-guide-introduction: @@ -146,18 +146,18 @@ Grammar, spelling, and capitalization preferences Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. -========== ====================== -Preferred Avoid -========== ====================== -add-on addon -and so on etc. -GitHub Github, github -JavaScript Javascript, javascript -plug-in plugin -select check, tick (checkbox) -such as like -verify be sure -========== ====================== +========== ====================== +Preferred Avoid +========== ====================== +add-on addon +and so on etc. +GitHub Github, github +JavaScript Javascript, javascript +plug-in plugin +select check, tick (checkbox) +such as like +verify be sure +========== ====================== .. _style-guide-headings: @@ -228,12 +228,22 @@ The directive's sole argument is interpreted as the topic title, and next line m interpreted as body elements. +.. _style-guide-displaying-code: + +Displaying code +^^^^^^^^^^^^^^^ + +Code may be displayed in blocks or inline. You can include blocks of code from other source files. Blocks of code should use syntax highlighting. + +.. seealso:: See also the Sphinx documentation for :ref:`Showing code examples `. + + .. _style-guide-syntax-highlighting: Syntax highlighting -^^^^^^^^^^^^^^^^^^^ +``````````````````` -Sphinx does syntax highlighting using the `Pygments `_ library. +Sphinx does syntax highlighting of code blocks using the `Pygments `_ library. Do not use two colons "::" at the end of a line, followed by a blank line, then indented code. Always specify the language to be used for syntax highlighting by using the ``code-block`` directive and indenting the code. @@ -253,17 +263,15 @@ XML: Some XML -Unix shell: +Unix shell commands are prefixed with a ``$`` character. (See :term:`venv` for the meaning of ``$VENV``.) .. code-block:: rst .. code-block:: bash - # Start Plone in foreground mode for a test run - cd ~/Plone/zinstance - bin/plonectl fg + $ $VENV/bin/pip install -e . -Windows console: +Windows commands are prefixed with a drive letter with an optional directory name. (See :term:`venv` for the meaning of ``%VENV%``.) .. code-block:: rst @@ -271,6 +279,8 @@ Windows console: c:\> %VENV%\Scripts\pcreate -s starter MyProject + .. code-block:: doscon + cfg: .. code-block:: rst @@ -315,110 +325,210 @@ If syntax highlighting is not enabled for your code block, you probably have a s View the `full list of lexers and associated short names `_. +.. _style-guide-long-commands: +Displaying long commands +```````````````````````` +When a command that should be typed on one line is too long to fit on the displayed width of a page, the backslash character ``\`` is used to indicate that the subsequent printed line should be part of the command: -Literals, filenames, and function arguments are presented using the -following style: + .. code-block:: rst - ``argument1`` + .. code-block:: bash -Warnings which represent limitations and need-to-know information -related to a topic or concept are presented in the following style: + $ $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ + --cov=tutorial -q - .. warning:: - This is a warning. +.. _style-guide-code-block-options: -Notes which represent additional information related to a topic or -concept are presented in the following style: +Code block options +`````````````````` - .. note:: +To emphasize lines (give the appearance that a highlighting pen has been used on the code), use the ``emphasize-lines`` option. The argument passed to ``emphasize-lines`` must be a comma-separated list of either single or ranges of line numbers. - This is a note. +.. code-block:: rst -We present Python method names using the following style: + .. code-block:: python + :emphasize-lines: 1,3 - :meth:`pyramid.config.Configurator.add_view` + if "foo" == "bar": + # This is Python code + pass -We present Python class names, module names, attributes, and global -variables using the following style: +The above code renders as follows. - :class:`pyramid.config.Configurator.registry` +.. code-block:: python + :emphasize-lines: 1,3 -References to glossary terms are presented using the following style: + if "foo" == "bar": + # This is Python code + pass - :term:`Pylons` +To display a code block with line numbers, use the ``linenos`` option. -URLs are presented using the following style: +.. code-block:: rst - `Pylons `_ + .. code-block:: python + :linenos: -References to sections and chapters are presented using the following -style: + if "foo" == "bar": + # This is Python code + pass - :ref:`traversal_chapter` +The above code renders as follows. -Code and configuration file blocks are presented in the following style: +.. code-block:: python + :linenos: - .. code-block:: python - :linenos: + if "foo" == "bar": + # This is Python code + pass - def foo(abc): - pass +Code blocks may be given a caption, which may serve as a filename or other description, using the ``caption`` option. They may also be given a ``name`` option, providing an implicit target name that can be referenced by using ``ref``. -Example blocks representing UNIX shell commands are prefixed with a ``$`` -character, e.g.: +.. code-block:: rst - .. code-block:: bash + .. code-block:: python + :caption: sample.py + :name: sample-py - $ $VENV/bin/py.test -q + if "foo" == "bar": + # This is Python code + pass -See :term:`venv` for the meaning of ``$VENV``. +The above code renders as follows. -Example blocks representing Windows commands are prefixed with a drive letter -with an optional directory name, e.g.: +.. code-block:: python + :caption: sample.py + :name: sample-py - .. code-block:: doscon + if "foo" == "bar": + # This is Python code + pass - c:\examples> %VENV%\Scripts\py.test -q +To specify the starting number to use for line numbering, use the ``lineno-start`` directive. -See :term:`venv` for the meaning of ``%VENV%``. +.. code-block:: rst -When a command that should be typed on one line is too long to fit on a page, -the backslash ``\`` is used to indicate that the following printed line should -be part of the command: + .. code-block:: python + :lineno-start: 2 - .. code-block:: bash + if "foo" == "bar": + # This is Python code + pass - $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ - --cov=tutorial -q +The above code renders as follows. As you can see, ``lineno-start`` is not altogether meaningful. -A sidebar, which presents a concept tangentially related to content discussed -on a page, is rendered like so: +.. code-block:: python + :lineno-start: 2 -.. sidebar:: This is a sidebar + if "foo" == "bar": + # This is Python code + pass - Sidebar information. -When multiple objects are imported from the same package, the following -convention is used: +.. _style-guide-includes: - .. code-block:: python +Includes +```````` + +Longer displays of verbatim text may be included by storing the example text in an external file containing only plain text or code. The file may be included using the ``literalinclude`` directive. The file name follows the conventions of :ref:`style-guide-file-conventions`. + +.. code-block:: rst + + .. literalinclude:: narr/helloworld.py + :language: python + +The above code renders as follows. + +.. literalinclude:: narr/helloworld.py + :language: python + +Like code blocks, ``literalinclude`` supports the following options. + +- ``language`` to select a language for syntax highlighting +- ``linenos`` to switch on line numbers +- ``lineno-start`` to specify the starting number to use for line numbering +- ``emphasize-lines`` to emphasize particular lines + +.. code-block:: rst + + .. literalinclude:: narr/helloworld.py + :language: python + :linenos: + :lineno-start: 11 + :emphasize-lines: 1,6-7,9- + +The above code renders as follows. Note that ``lineno-start`` and ``emphasize-lines`` do not align. The former displays numbering starting from the *arbitrarily provided value*, whereas the latter emphasizes the line numbers of the *source file*. - from foo import ( - bar, - baz, - ) +.. literalinclude:: narr/helloworld.py + :language: python + :linenos: + :lineno-start: 11 + :emphasize-lines: 1,6-7,9- -It may look unusual, but it has advantages: +Additional options include the following. -- It allows one to swap out the higher-level package ``foo`` for something else - that provides the similar API. An example would be swapping out one database - for another (e.g., graduating from SQLite to PostgreSQL). +.. literalinclude:: narr/helloworld.py + :lines: 1-3 + :emphasize-lines: 3 + :lineno-match: + :language: python -- Looks more neat in cases where a large number of objects get imported from - that package. +.. literalinclude:: narr/helloworld.py + :linenos: + :pyobject: hello_world -- Adding or removing imported objects from the package is quicker and results - in simpler diffs. +.. literalinclude:: quick_tour/sqla_demo/sqla_demo/models/mymodel.py + :language: python + :start-after: Start Sphinx Include + :end-before: End Sphinx Include + + +.. _style-guide-inline-code: + +Inline code +``````````` + + + + + + +Literals, filenames, and function arguments are presented using the +following style: + + ``argument1`` + +Warnings which represent limitations and need-to-know information +related to a topic or concept are presented in the following style: + + .. warning:: + + This is a warning. + +Notes which represent additional information related to a topic or +concept are presented in the following style: + + .. note:: + + This is a note. + +We present Python method names using the following style: + + :meth:`pyramid.config.Configurator.add_view` + +We present Python class names, module names, attributes, and global +variables using the following style: + + :class:`pyramid.config.Configurator.registry` + +References to glossary terms are presented using the following style: + + :term:`Pylons` + +References to sections and chapters are presented using the following +style: + + :ref:`traversal_chapter` -- cgit v1.2.3 From 60ff6ab9d2c1fcbbe97a39e8e9535d167605d6de Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 21 Nov 2016 04:15:54 -0800 Subject: add literalinclude options --- docs/style-guide.rst | 61 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index c30b199a6..7868f97e7 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -468,22 +468,65 @@ The above code renders as follows. Note that ``lineno-start`` and ``emphasize-li :lineno-start: 11 :emphasize-lines: 1,6-7,9- -Additional options include the following. +``literalinclude`` also supports including only parts of a file. If it is a Python module, you can select a class, function, or method to include using the ``pyobject`` option. + +.. code-block:: rst + + .. literalinclude:: narr/helloworld.py + :language: python + :pyobject: hello_world + +The above code renders as follows. It returns the function ``hello_world`` in the source file. .. literalinclude:: narr/helloworld.py - :lines: 1-3 - :emphasize-lines: 3 - :lineno-match: :language: python + :pyobject: hello_world + +Alternatively, you can specify exactly which lines to include by giving a ``lines`` option. + +.. code-block:: rst + + .. literalinclude:: narr/helloworld.py + :language: python + :lines: 6-7 + +The above code renders as follows. .. literalinclude:: narr/helloworld.py - :linenos: - :pyobject: hello_world + :language: python + :lines: 6-7 + +Another way to control which part of the file is included is to use the ``start-after`` and ``end-before`` options (or only one of them). If ``start-after`` is given as a string option, only lines that follow the first line containing that string are included. If ``end-before`` is given as a string option, only lines that precede the first lines containing that string are included. -.. literalinclude:: quick_tour/sqla_demo/sqla_demo/models/mymodel.py +.. code-block:: rst + + .. literalinclude:: narr/helloworld.py + :language: python + :start-after: from pyramid.response import Response + :end-before: if __name__ == '__main__': + +The above code renders as follows. + +.. literalinclude:: narr/helloworld.py + :language: python + :start-after: from pyramid.response import Response + :end-before: if __name__ == '__main__': + +When specifying particular parts of a file to display, it can be useful to display exactly which lines are being presented. This can be done using the ``lineno-match`` option. + +.. code-block:: rst + + .. literalinclude:: narr/helloworld.py + :language: python + :lines: 6-7 + :lineno-match: + +The above code renders as follows. + +.. literalinclude:: narr/helloworld.py :language: python - :start-after: Start Sphinx Include - :end-before: End Sphinx Include + :lines: 6-7 + :lineno-match: .. _style-guide-inline-code: -- cgit v1.2.3 From 9cab0e7cc24dc95e357db026cead2507111ee93a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 21 Nov 2016 21:31:41 -0600 Subject: support asset specs in watch_files and variable interpolation --- pyramid/scripts/pserve.py | 46 +++++++++++++++++-------------- pyramid/tests/test_scripts/dummy.py | 8 ++++-- pyramid/tests/test_scripts/test_pserve.py | 19 +++++++++---- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index c67dc86ba..b8776d44f 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -32,6 +32,7 @@ from pyramid.compat import configparser from pyramid.scripts.common import parse_vars from pyramid.scripts.common import setup_logging +from pyramid.path import AssetResolver from pyramid.settings import aslist def main(argv=sys.argv, quiet=False): @@ -119,8 +120,14 @@ class PServeCommand(object): restvars = self.args[1:] return parse_vars(restvars) - def pserve_file_config(self, filename): - config = self.ConfigParser() + def pserve_file_config(self, filename, global_conf=None): + here = os.path.abspath(os.path.dirname(filename)) + defaults = {} + if global_conf: + defaults.update(global_conf) + defaults['here'] = here + + config = self.ConfigParser(defaults=defaults) config.optionxform = str config.read(filename) try: @@ -131,11 +138,13 @@ class PServeCommand(object): watch_files = aslist(items.get('watch_files', ''), flatten=False) # track file paths relative to the ini file - basedir = os.path.dirname(filename) + resolver = AssetResolver(package=None) for file in watch_files: - if not os.path.isabs(file): - file = os.path.join(basedir, file) - self.watch_files.append(os.path.normpath(file)) + if ':' in file: + file = resolver.resolve(file).abspath() + elif not os.path.isabs(file): + file = os.path.join(here, file) + self.watch_files.append(os.path.abspath(file)) def run(self): # pragma: no cover if not self.args: @@ -185,8 +194,8 @@ class PServeCommand(object): if config_path: setup_logging(config_path, global_conf=vars) + self.pserve_file_config(config_path, global_conf=vars) self.watch_files.append(config_path) - self.pserve_file_config(config_path) if hupper.is_active(): reloader = hupper.get_reloader() @@ -205,19 +214,16 @@ class PServeCommand(object): msg = 'Starting server.' self.out(msg) - def serve(): - try: - server(app) - except (SystemExit, KeyboardInterrupt) as e: - if self.options.verbose > 1: - raise - if str(e): - msg = ' ' + str(e) - else: - msg = '' - self.out('Exiting%s (-v to see traceback)' % msg) - - serve() + try: + server(app) + except (SystemExit, KeyboardInterrupt) as e: + if self.options.verbose > 1: + raise + if str(e): + msg = ' ' + str(e) + else: + msg = '' + self.out('Exiting%s (-v to see traceback)' % msg) # For paste.deploy server instantiation (egg:pyramid#wsgiref) def wsgiref_server_runner(wsgi_app, global_conf, **kw): # pragma: no cover diff --git a/pyramid/tests/test_scripts/dummy.py b/pyramid/tests/test_scripts/dummy.py index f3aa20e7c..ced09d0b0 100644 --- a/pyramid/tests/test_scripts/dummy.py +++ b/pyramid/tests/test_scripts/dummy.py @@ -82,8 +82,9 @@ class DummyMultiView(object): self.__request_attrs__ = attrs class DummyConfigParser(object): - def __init__(self, result): + def __init__(self, result, defaults=None): self.result = result + self.defaults = defaults def read(self, filename): self.filename = filename @@ -98,8 +99,9 @@ class DummyConfigParser(object): class DummyConfigParserFactory(object): items = None - def __call__(self): - self.parser = DummyConfigParser(self.items) + def __call__(self, defaults=None): + self.defaults = defaults + self.parser = DummyConfigParser(self.items, defaults) return self.parser class DummyCloser(object): diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index cf9426943..18f7c8c2f 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -2,6 +2,8 @@ import os import unittest from pyramid.tests.test_scripts import dummy +here = os.path.abspath(os.path.dirname(__file__)) + class TestPServeCommand(unittest.TestCase): def setUp(self): from pyramid.compat import NativeIO @@ -59,12 +61,19 @@ class TestPServeCommand(unittest.TestCase): def test_config_file_finds_watch_files(self): inst = self._makeOne('development.ini') - self.config_factory.items = [('watch_files', 'foo\nbar\n/baz')] - inst.pserve_file_config('/base/path.ini') + self.config_factory.items = [( + 'watch_files', + 'foo\n/baz\npyramid.tests.test_scripts:*.py', + )] + inst.pserve_file_config('/base/path.ini', global_conf={'a': '1'}) + self.assertEqual(self.config_factory.defaults, { + 'a': '1', + 'here': os.path.abspath('/base'), + }) self.assertEqual(inst.watch_files, [ - os.path.normpath('/base/foo'), - os.path.normpath('/base/bar'), - os.path.normpath('/baz'), + os.path.abspath('/base/foo'), + os.path.abspath('/baz'), + os.path.abspath(os.path.join(here, '*.py')), ]) class Test_main(unittest.TestCase): -- cgit v1.2.3 From ff0da73a8922b5e82c676715078c7b9e60a6a1da Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 21 Nov 2016 22:42:55 -0600 Subject: document globbing --- docs/narr/project.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b4ad6948e..77c637571 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1083,5 +1083,7 @@ serve it many times. When you change it you want ``pserve`` to restart: watch_files = myapp/static/favicon.ico -Paths are relative to the configuration file and are passed to ``hupper`` -to watch. Currently it does not support globs but this may change. +Paths may be absolute or relative to the configuration file. They may also +be an :term:`asset specification`. These paths are passed to ``hupper`` which +has some basic support for globbing. Acceptable glob patterns depend on the +version of Python being used. -- cgit v1.2.3 From 7ba90759841b62cee5aee411f08772c753049338 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Nov 2016 03:16:30 -0600 Subject: remove the deprecated IContextURL --- docs/narr/vhosting.rst | 14 +-- pyramid/interfaces.py | 52 --------- pyramid/tests/test_traversal.py | 226 +++++++--------------------------------- pyramid/tests/test_url.py | 22 ---- pyramid/traversal.py | 111 ++++---------------- pyramid/url.py | 148 ++++++++++++-------------- 6 files changed, 132 insertions(+), 441 deletions(-) diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index 0edf03353..e4cee9882 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -26,20 +26,20 @@ Hosting an Application Under a URL Prefix ``http://example.com/``). If you use a "pure Python" environment, this functionality can be provided by -Paste's `urlmap `_ "composite" WSGI -application. Alternatively, you can use :term:`mod_wsgi` to serve your +`rutter `_, forming a "composite" +WSGI application. Alternatively, you can use :term:`mod_wsgi` to serve your application, which handles this virtual hosting translation for you "under the hood". -If you use the ``urlmap`` composite application "in front" of a :app:`Pyramid` +If you use the ``rutter`` composite application "in front" of a :app:`Pyramid` application or if you use :term:`mod_wsgi` to serve up a :app:`Pyramid` application, nothing special needs to be done within the application for URLs -to be generated that contain a prefix. :mod:`paste.urlmap` and :term:`mod_wsgi` +to be generated that contain a prefix. Rutter and :term:`mod_wsgi` manipulate the :term:`WSGI` environment in such a way that the ``PATH_INFO`` and ``SCRIPT_NAME`` variables are correct for some given prefix. Here's an example of a PasteDeploy configuration snippet that includes a -``urlmap`` composite. +``rutter`` composite. .. code-block:: ini :linenos: @@ -48,13 +48,13 @@ Here's an example of a PasteDeploy configuration snippet that includes a use = egg:mypyramidapp [composite:main] - use = egg:Paste#urlmap + use = egg:rutter#urlmap /pyramidapp = mypyramidapp This "roots" the :app:`Pyramid` application at the prefix ``/pyramidapp`` and serves up the composite as the "main" application in the file. -.. note:: If you're using an Apache server to proxy to a Paste ``urlmap`` +.. note:: If you're using an Apache server to proxy to a ``urlmap`` composite, you may have to use the `ProxyPreserveHost `_ directive to pass the original ``HTTP_HOST`` header along to the diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index c1ddea63f..450cd9c24 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -799,58 +799,6 @@ class IResourceURL(Interface): 'The physical url path of the resource as a tuple. (New in 1.5)' ) -class IContextURL(IResourceURL): - """ - .. deprecated:: 1.3 - An adapter which deals with URLs related to a context. Use - :class:`pyramid.interfaces.IResourceURL` instead. - """ - # this class subclasses IResourceURL because request.resource_url looks - # for IResourceURL via queryAdapter. queryAdapter will find a deprecated - # IContextURL registration if no registration for IResourceURL exists. - # In reality, however, IContextURL objects were never required to have - # the virtual_path or physical_path attributes spelled in IResourceURL. - # The inheritance relationship is purely to benefit adapter lookup, - # not to imply an inheritance relationship of interface attributes - # and methods. - # - # Mechanics: - # - # class Fudge(object): - # def __init__(self, one, two): - # print(one, two) - # class Another(object): - # def __init__(self, one, two): - # print(one, two) - # ob = object() - # r.registerAdapter(Fudge, (Interface, Interface), IContextURL) - # print(r.queryMultiAdapter((ob, ob), IResourceURL)) - # r.registerAdapter(Another, (Interface, Interface), IResourceURL) - # print(r.queryMultiAdapter((ob, ob), IResourceURL)) - # - # prints - # - # - # <__main__.Fudge object at 0x1cda890> - # - # <__main__.Another object at 0x1cda850> - - def virtual_root(): - """ Return the virtual root related to a request and the - current context""" - - def __call__(): - """ Return a URL that points to the context. """ - -deprecated( - 'IContextURL', - 'As of Pyramid 1.3 the, "pyramid.interfaces.IContextURL" interface is ' - 'scheduled to be removed. Use the ' - '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' - 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' - 'See the "What\'s new In Pyramid 1.3" document for more details.' - ) - class IPEP302Loader(Interface): """ See http://www.python.org/dev/peps/pep-0302/#id30. """ diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py index 5fc878a32..437fe46df 100644 --- a/pyramid/tests/test_traversal.py +++ b/pyramid/tests/test_traversal.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import unittest -import warnings from pyramid.testing import cleanUp @@ -12,11 +11,6 @@ from pyramid.compat import ( PY2, ) -with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - from pyramid.interfaces import IContextURL - assert(len(w) == 1) - class TraversalPathTests(unittest.TestCase): def _callFUT(self, path): from pyramid.traversal import traversal_path @@ -871,182 +865,12 @@ class ResourceURLTests(unittest.TestCase): from pyramid.traversal import ResourceURL return ResourceURL - def _registerTraverser(self, traverser): - from pyramid.threadlocal import get_current_registry - reg = get_current_registry() - from pyramid.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_class_conforms_to_IContextURL(self): - # bw compat - from zope.interface.verify import verifyClass - verifyClass(IContextURL, self._getTargetClass()) - - def test_instance_conforms_to_IContextURL(self): - from zope.interface.verify import verifyObject - context = DummyContext() - request = DummyRequest() - verifyObject(IContextURL, self._makeOne(context, request)) - def test_instance_conforms_to_IResourceURL(self): from pyramid.interfaces import IResourceURL from zope.interface.verify import verifyObject context = DummyContext() request = DummyRequest() verifyObject(IResourceURL, self._makeOne(context, request)) - - def test_call_withlineage(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = None - foo.__parent__ = root - foo.__name__ = 'foo ' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - request = DummyRequest() - context_url = self._makeOne(baz, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/foo%20/bar/baz/') - - def test_call_nolineage(self): - context = DummyContext() - context.__name__ = '' - context.__parent__ = None - request = DummyRequest() - context_url = self._makeOne(context, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/') - - def test_call_unicode_mixed_with_bytes_in_resource_names(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = text_(b'La Pe\xc3\xb1a', 'utf-8') - two = DummyContext() - two.__parent__ = one - two.__name__ = b'La Pe\xc3\xb1a' - request = DummyRequest() - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual( - result, - 'http://example.com:5432/La%20Pe%C3%B1a/La%20Pe%C3%B1a/') - - def test_call_with_virtual_root_path(self): - from pyramid.interfaces import VH_ROOT_KEY - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = 'one' - two = DummyContext() - two.__parent__ = one - two.__name__ = 'two' - request = DummyRequest({VH_ROOT_KEY:'/one'}) - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/two/') - - request = DummyRequest({VH_ROOT_KEY:'/one/two'}) - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/') - - def test_call_with_virtual_root_path_physical_not_startwith_vroot(self): - from pyramid.interfaces import VH_ROOT_KEY - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = 'one' - two = DummyContext() - two.__parent__ = one - two.__name__ = 'two' - request = DummyRequest({VH_ROOT_KEY:'/wrong'}) - context_url = self._makeOne(two, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/one/two/') - - def test_call_empty_names_not_ignored(self): - bar = DummyContext() - empty = DummyContext(bar) - root = DummyContext(empty) - root.__parent__ = None - root.__name__ = None - empty.__parent__ = root - empty.__name__ = '' - bar.__parent__ = empty - bar.__name__ = 'bar' - request = DummyRequest() - context_url = self._makeOne(bar, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432//bar/') - - def test_call_local_url_returns_None(self): - resource = DummyContext() - def resource_url(request, info): - self.assertEqual(info['virtual_path'], '/') - self.assertEqual(info['physical_path'], '/') - return None - resource.__resource_url__ = resource_url - request = DummyRequest() - context_url = self._makeOne(resource, request) - result = context_url() - self.assertEqual(result, 'http://example.com:5432/') - - def test_call_local_url_returns_url(self): - resource = DummyContext() - def resource_url(request, info): - self.assertEqual(info['virtual_path'], '/') - self.assertEqual(info['physical_path'], '/') - return 'abc' - resource.__resource_url__ = resource_url - request = DummyRequest() - context_url = self._makeOne(resource, request) - result = context_url() - self.assertEqual(result, 'abc') - - def test_virtual_root_no_virtual_root_path(self): - root = DummyContext() - root.__name__ = None - root.__parent__ = None - one = DummyContext() - one.__name__ = 'one' - one.__parent__ = root - request = DummyRequest() - context_url = self._makeOne(one, request) - self.assertEqual(context_url.virtual_root(), root) - - def test_virtual_root_no_virtual_root_path_with_root_on_request(self): - context = DummyContext() - context.__parent__ = None - request = DummyRequest() - request.root = DummyContext() - context_url = self._makeOne(context, request) - self.assertEqual(context_url.virtual_root(), request.root) - - def test_virtual_root_with_virtual_root_path(self): - from pyramid.interfaces import VH_ROOT_KEY - context = DummyContext() - context.__parent__ = None - traversed_to = DummyContext() - environ = {VH_ROOT_KEY:'/one'} - request = DummyRequest(environ) - traverser = make_traverser({'context':traversed_to, 'view_name':''}) - self._registerTraverser(traverser) - context_url = self._makeOne(context, request) - self.assertEqual(context_url.virtual_root(), traversed_to) - self.assertEqual(context.request.environ['PATH_INFO'], '/one') def test_IResourceURL_attributes_with_vroot(self): from pyramid.interfaces import VH_ROOT_KEY @@ -1115,14 +939,47 @@ class TestVirtualRoot(unittest.TestCase): from pyramid.traversal import virtual_root return virtual_root(resource, request) - def test_registered(self): + def _registerTraverser(self, traverser): + from pyramid.threadlocal import get_current_registry + reg = get_current_registry() + from pyramid.interfaces import ITraverser from zope.interface import Interface - request = _makeRequest() - request.registry.registerAdapter(DummyContextURL, (Interface,Interface), - IContextURL) + reg.registerAdapter(traverser, (Interface,), ITraverser) + + def test_virtual_root_no_virtual_root_path(self): + root = DummyContext() + root.__name__ = None + root.__parent__ = None + one = DummyContext() + one.__name__ = 'one' + one.__parent__ = root + request = DummyRequest() + result = self._callFUT(one, request) + self.assertEqual(result, root) + + def test_virtual_root_no_virtual_root_path_with_root_on_request(self): context = DummyContext() + context.__parent__ = None + request = DummyRequest() + request.root = DummyContext() result = self._callFUT(context, request) - self.assertEqual(result, '123') + self.assertEqual(result, request.root) + + def test_virtual_root_with_virtual_root_path(self): + from pyramid.interfaces import VH_ROOT_KEY + root = DummyContext() + root.__parent__ = None + context = DummyContext() + context.__name__ = 'one' + context.__parent__ = root + traversed_to = DummyContext() + environ = {VH_ROOT_KEY:'/one'} + request = DummyRequest(environ) + traverser = make_traverser({'context':traversed_to, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(context, request) + self.assertEqual(result, traversed_to) + self.assertEqual(root.request.environ['PATH_INFO'], '/one') def test_default(self): context = DummyContext() @@ -1357,13 +1214,6 @@ class DummyRequest: path_info = property(_get_path_info, _set_path_info) -class DummyContextURL: - def __init__(self, context, request): - pass - - def virtual_root(self): - return '123' - def _makeRequest(environ=None): from pyramid.registry import Registry request = DummyRequest() diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 0a788ba97..ddf28e0b0 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -29,18 +29,6 @@ class TestURLMethodsMixin(unittest.TestCase): request.registry = self.config.registry return request - def _registerContextURL(self, reg): - with warnings.catch_warnings(record=True): - from pyramid.interfaces import IContextURL - from zope.interface import Interface - class DummyContextURL(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'http://example.com/context/' - reg.registerAdapter(DummyContextURL, (Interface, Interface), - IContextURL) - def _registerResourceURL(self, reg): from pyramid.interfaces import IResourceURL from zope.interface import Interface @@ -186,16 +174,6 @@ class TestURLMethodsMixin(unittest.TestCase): root = DummyContext() result = request.resource_url(root) self.assertEqual(result, 'http://example.com:5432/context/') - - def test_resource_url_finds_IContextURL(self): - request = self._makeOne() - self._registerContextURL(request.registry) - root = DummyContext() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - result = request.resource_url(root) - self.assertEqual(len(w), 1) - self.assertEqual(result, 'http://example.com/context/') def test_resource_url_with_app_url(self): request = self._makeOne() diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 1ca52692a..641445067 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -1,7 +1,3 @@ -import warnings - -from zope.deprecation import deprecated - from zope.interface import implementer from zope.interface.interfaces import IInterface @@ -31,10 +27,6 @@ from pyramid.exceptions import URLDecodeError from pyramid.location import lineage from pyramid.threadlocal import get_current_registry -with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - from pyramid.interfaces import IContextURL - PATH_SEGMENT_SAFE = "~!$&'()*+,;=:@" # from webob PATH_SAFE = PATH_SEGMENT_SAFE + "/" @@ -100,10 +92,6 @@ def find_resource(resource, path): object representing a resource name). Resource path tuples generated by :func:`pyramid.traversal.resource_path_tuple` can always be resolved by ``find_resource``. - - .. note:: For backwards compatibility purposes, this function can also - be imported as :func:`pyramid.traversal.find_model`, although doing so - will emit a deprecation warning. """ if isinstance(path, text_type): path = ascii_native_(path) @@ -174,12 +162,6 @@ def resource_path(resource, *elements): properly. If the root resource has a non-null ``__name__`` attribute, its name will be prepended to the generated path rather than a single leading '/' character. - - .. note:: - - For backwards compatibility purposes, this function can also - be imported as ``model_path``, although doing so will cause - a deprecation warning to be emitted. """ # joining strings is a bit expensive so we delegate to a function # which caches the joined result for us @@ -381,12 +363,6 @@ def resource_path_tuple(resource, *elements): generated properly. If the root resource has a non-null ``__name__`` attribute, its name will be the first element in the generated path tuple rather than the empty string. - - .. note:: - - For backwards compatibility purposes, this function can also be imported - as ``model_path_tuple``, although doing so will cause a deprecation - warning to be emitted. """ return tuple(_resource_path_list(resource, *elements)) @@ -407,8 +383,8 @@ def virtual_root(resource, request): the resource object representing the :term:`virtual root` of the current :term:`request`. Using a virtual root in a :term:`traversal` -based :app:`Pyramid` application permits - rooting, for example, the resource at the traversal path ``/cms`` at - ``http://example.com/`` instead of rooting it at + rooting. For example, the resource at the traversal path ``/cms`` will + be found at ``http://example.com/`` instead of rooting it at ``http://example.com/cms/``. If the ``resource`` passed in is a context obtained via @@ -430,11 +406,20 @@ def virtual_root(resource, request): try: reg = request.registry except AttributeError: - reg = get_current_registry() # b/c - urlgenerator = reg.queryMultiAdapter((resource, request), IContextURL) - if urlgenerator is None: - urlgenerator = TraversalContextURL(resource, request) - return urlgenerator.virtual_root() + reg = get_current_registry() + url_adapter = reg.queryMultiAdapter((resource, request), IResourceURL) + if url_adapter is None: + url_adapter = ResourceURL(resource, request) + + vpath, rpath = url_adapter.virtual_path, url_adapter.physical_path + if rpath != vpath and rpath.endswith(vpath): + vroot_path = rpath[:-len(vpath)] + return find_resource(resource, vroot_path) + + try: + return request.root + except AttributeError: + return find_root(resource) def traversal_path(path): """ Variant of :func:`pyramid.traversal.traversal_path_info` suitable for @@ -627,6 +612,7 @@ class ResourceTreeTraverser(object): :term:`location` aware) .""" + VH_ROOT_KEY = VH_ROOT_KEY VIEW_SELECTOR = '@@' def __init__(self, root): @@ -665,9 +651,9 @@ class ResourceTreeTraverser(object): raise URLDecodeError(e.encoding, e.object, e.start, e.end, e.reason) - if VH_ROOT_KEY in environ: + if self.VH_ROOT_KEY in environ: # HTTP_X_VHM_ROOT - vroot_path = decode_path_info(environ[VH_ROOT_KEY]) + vroot_path = decode_path_info(environ[self.VH_ROOT_KEY]) vroot_tuple = split_path_info(vroot_path) vpath = vroot_path + path # both will (must) be unicode or asciistr vroot_idx = len(vroot_tuple) - 1 @@ -731,9 +717,9 @@ class ResourceTreeTraverser(object): ModelGraphTraverser = ResourceTreeTraverser # b/w compat, not API, used in wild -@implementer(IResourceURL, IContextURL) +@implementer(IResourceURL) class ResourceURL(object): - vroot_varname = VH_ROOT_KEY + VH_ROOT_KEY = VH_ROOT_KEY def __init__(self, resource, request): physical_path_tuple = resource_path_tuple(resource) @@ -747,7 +733,7 @@ class ResourceURL(object): virtual_path_tuple = physical_path_tuple environ = request.environ - vroot_path = environ.get(self.vroot_varname) + vroot_path = environ.get(self.VH_ROOT_KEY) # if the physical path starts with the virtual root path, trim it out # of the virtual path @@ -764,59 +750,6 @@ class ResourceURL(object): self.virtual_path_tuple = virtual_path_tuple # IResourceURL attr (1.5) self.physical_path_tuple = physical_path_tuple # IResourceURL attr (1.5) - # bw compat for IContextURL methods - self.resource = resource - self.context = resource - self.request = request - - # IContextURL method (deprecated in 1.3) - def virtual_root(self): - environ = self.request.environ - vroot_varname = self.vroot_varname - if vroot_varname in environ: - return find_resource(self.context, environ[vroot_varname]) - # shortcut instead of using find_root; we probably already - # have it on the request - try: - return self.request.root - except AttributeError: - return find_root(self.context) - - # IContextURL method (deprecated in 1.3) - def __call__(self): - """ Generate a URL based on the :term:`lineage` of a :term:`resource` - object that is ``self.context``. If any resource in the context - lineage has a Unicode name, it will be converted to a UTF-8 string - before being attached to the URL. If a ``HTTP_X_VHM_ROOT`` key is - present in the WSGI environment, its value will be treated as a - 'virtual root path': the path of the URL generated by this will be - left-stripped of this virtual root path value. - """ - local_url = getattr(self.context, '__resource_url__', None) - if local_url is not None: - result = local_url( - self.request, - {'virtual_path':self.virtual_path, - 'physical_path':self.physical_path}, - ) - if result is not None: - # allow it to punt by returning ``None`` - return result - - app_url = self.request.application_url # never ends in a slash - return app_url + self.virtual_path - -TraversalContextURL = ResourceURL # deprecated as of 1.3 - -deprecated( - 'TraversalContextURL', - 'As of Pyramid 1.3 the, "pyramid.traversal.TraversalContextURL" class is ' - 'scheduled to be removed. Use the ' - '"pyramid.config.Configurator.add_resource_url_adapter" method to register ' - 'a class that implements "pyramid.interfaces.IResourceURL" instead. ' - 'See the "What\'s new In Pyramid 1.3" document for a further description.' - ) - @lru_cache(1000) def _join_path_tuple(tuple): return tuple and '/'.join([quote_path_segment(x) for x in tuple]) or '/' diff --git a/pyramid/url.py b/pyramid/url.py index d6587e783..9634f61da 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -1,7 +1,6 @@ """ Utility functions for dealing with URLs in pyramid """ import os -import warnings from repoze.lru import lru_cache @@ -534,89 +533,72 @@ class URLMethodsMixin(object): virtual_path = getattr(url_adapter, 'virtual_path', None) - if virtual_path is None: - # old-style IContextURL adapter (Pyramid 1.2 and previous) - warnings.warn( - 'Pyramid is using an IContextURL adapter to generate a ' - 'resource URL; any "app_url", "host", "port", or "scheme" ' - 'arguments passed to resource_url are being ignored. To ' - 'avoid this behavior, as of Pyramid 1.3, register an ' - 'IResourceURL adapter instead of an IContextURL ' - 'adapter for the resource type(s). IContextURL adapters ' - 'will be ignored in a later major release of Pyramid.', - DeprecationWarning, - 2) - - resource_url = url_adapter() + app_url = None + scheme = None + host = None + port = None + + if 'route_name' in kw: + newkw = {} + route_name = kw['route_name'] + remainder = getattr(url_adapter, 'virtual_path_tuple', None) + if remainder is None: + # older user-supplied IResourceURL adapter without 1.5 + # virtual_path_tuple + remainder = tuple(url_adapter.virtual_path.split('/')) + remainder_name = kw.get('route_remainder_name', 'traverse') + newkw[remainder_name] = remainder + + for name in ( + 'app_url', 'scheme', 'host', 'port', 'query', 'anchor' + ): + val = kw.get(name, None) + if val is not None: + newkw['_' + name] = val + + if 'route_kw' in kw: + route_kw = kw.get('route_kw') + if route_kw is not None: + newkw.update(route_kw) + + return self.route_url(route_name, *elements, **newkw) + + if 'app_url' in kw: + app_url = kw['app_url'] + + if 'scheme' in kw: + scheme = kw['scheme'] + + if 'host' in kw: + host = kw['host'] + + if 'port' in kw: + port = kw['port'] - else: - # IResourceURL adapter (Pyramid 1.3 and after) - app_url = None - scheme = None - host = None - port = None - - if 'route_name' in kw: - newkw = {} - route_name = kw['route_name'] - remainder = getattr(url_adapter, 'virtual_path_tuple', None) - if remainder is None: - # older user-supplied IResourceURL adapter without 1.5 - # virtual_path_tuple - remainder = tuple(url_adapter.virtual_path.split('/')) - remainder_name = kw.get('route_remainder_name', 'traverse') - newkw[remainder_name] = remainder - - for name in ( - 'app_url', 'scheme', 'host', 'port', 'query', 'anchor' - ): - val = kw.get(name, None) - if val is not None: - newkw['_' + name] = val - - if 'route_kw' in kw: - route_kw = kw.get('route_kw') - if route_kw is not None: - newkw.update(route_kw) - - return self.route_url(route_name, *elements, **newkw) - - if 'app_url' in kw: - app_url = kw['app_url'] - - if 'scheme' in kw: - scheme = kw['scheme'] - - if 'host' in kw: - host = kw['host'] - - if 'port' in kw: - port = kw['port'] - - if app_url is None: - if scheme or host or port: - app_url = self._partial_application_url(scheme, host, port) - else: - app_url = self.application_url - - resource_url = None - local_url = getattr(resource, '__resource_url__', None) - - if local_url is not None: - # the resource handles its own url generation - d = dict( - virtual_path=virtual_path, - physical_path=url_adapter.physical_path, - app_url=app_url, - ) - - # allow __resource_url__ to punt by returning None - resource_url = local_url(self, d) - - if resource_url is None: - # the resource did not handle its own url generation or the - # __resource_url__ function returned None - resource_url = app_url + virtual_path + if app_url is None: + if scheme or host or port: + app_url = self._partial_application_url(scheme, host, port) + else: + app_url = self.application_url + + resource_url = None + local_url = getattr(resource, '__resource_url__', None) + + if local_url is not None: + # the resource handles its own url generation + d = dict( + virtual_path=virtual_path, + physical_path=url_adapter.physical_path, + app_url=app_url, + ) + + # allow __resource_url__ to punt by returning None + resource_url = local_url(self, d) + + if resource_url is None: + # the resource did not handle its own url generation or the + # __resource_url__ function returned None + resource_url = app_url + virtual_path qs = '' anchor = '' -- cgit v1.2.3 From cdee90a86d50667054d140c0a77bbc94a2b788ec Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 22 Nov 2016 05:36:33 -0800 Subject: improve include section - start work on inline and block reST sections --- docs/style-guide.rst | 85 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 7868f97e7..f665846d2 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -468,7 +468,9 @@ The above code renders as follows. Note that ``lineno-start`` and ``emphasize-li :lineno-start: 11 :emphasize-lines: 1,6-7,9- -``literalinclude`` also supports including only parts of a file. If it is a Python module, you can select a class, function, or method to include using the ``pyobject`` option. +``literalinclude`` also supports including only parts of a file. + +If the source code is a Python module, you can select a class, function, or method to include using the ``pyobject`` option. .. code-block:: rst @@ -482,35 +484,35 @@ The above code renders as follows. It returns the function ``hello_world`` in th :language: python :pyobject: hello_world -Alternatively, you can specify exactly which lines to include by giving a ``lines`` option. +Another way to control which part of the file is included is to use the ``start-after`` and ``end-before`` options (or only one of them). If ``start-after`` is given as a string option, only lines that follow the first line containing that string are included. If ``end-before`` is given as a string option, only lines that precede the first lines containing that string are included. .. code-block:: rst .. literalinclude:: narr/helloworld.py :language: python - :lines: 6-7 + :start-after: from pyramid.response import Response + :end-before: if __name__ == '__main__': The above code renders as follows. .. literalinclude:: narr/helloworld.py :language: python - :lines: 6-7 + :start-after: from pyramid.response import Response + :end-before: if __name__ == '__main__': -Another way to control which part of the file is included is to use the ``start-after`` and ``end-before`` options (or only one of them). If ``start-after`` is given as a string option, only lines that follow the first line containing that string are included. If ``end-before`` is given as a string option, only lines that precede the first lines containing that string are included. +You can specify exactly which lines to include by giving a ``lines`` option. .. code-block:: rst .. literalinclude:: narr/helloworld.py :language: python - :start-after: from pyramid.response import Response - :end-before: if __name__ == '__main__': + :lines: 6-7 The above code renders as follows. .. literalinclude:: narr/helloworld.py :language: python - :start-after: from pyramid.response import Response - :end-before: if __name__ == '__main__': + :lines: 6-7 When specifying particular parts of a file to display, it can be useful to display exactly which lines are being presented. This can be done using the ``lineno-match`` option. @@ -528,42 +530,86 @@ The above code renders as follows. :lines: 6-7 :lineno-match: +.. literalinclude:: narr/helloworld.py + :language: python + :lines: 6-7 + :linenos: + +Out of all the ways to include parts of a file, ``pyobject`` is the most preferred option because if you change your code and add or remove lines, you don't need to adjust line numbering, whereas with ``lines`` you would have to adjust. ``start-after`` and ``end-before`` are less desirable because they depend on source code not changing, or you can insert comments into your source code to act as the delimiters but that just adds comments that have nothing to do with the functionality of your code. + +Above all with includes, if you use line numbering, it's much preferred to use ``lineno-match`` over ``linenos`` with ``lineno-start`` because it "just works" without thinking. + .. _style-guide-inline-code: Inline code ``````````` +Inline code is surrounded by double backtick marks. Literals, filenames, and function arguments are presented using this style. +.. code-block:: rst + Install requirements for building documentation: ``pip install -e ".[docs]"`` +The above code renders as follows. +Install requirements for building documentation: ``pip install -e ".[docs]"`` -Literals, filenames, and function arguments are presented using the -following style: - ``argument1`` +.. _style-guide-block-rest-markup: -Warnings which represent limitations and need-to-know information -related to a topic or concept are presented in the following style: +Block reST markup +----------------- + +Warnings which represent limitations and need-to-know information related to a topic or concept are presented in the following style: .. warning:: This is a warning. -Notes which represent additional information related to a topic or -concept are presented in the following style: +Notes which represent additional information related to a topic or concept are presented in the following style: .. note:: This is a note. + + +.. _style-guide-inline-rest-markup: + +Inline reST markup +------------------ + +Italics. + +.. code-block:: rst + + This *word* is italicized. + +The above code renders as follows. + +This *word* is italicized. + +Strong. + +.. code-block:: rst + + This **word** is in bold text. + +The above code renders as follows. + +This **word** is in bold text. + + + + + + We present Python method names using the following style: :meth:`pyramid.config.Configurator.add_view` -We present Python class names, module names, attributes, and global -variables using the following style: +We present Python class names, module names, attributes, and global variables using the following style: :class:`pyramid.config.Configurator.registry` @@ -571,7 +617,6 @@ References to glossary terms are presented using the following style: :term:`Pylons` -References to sections and chapters are presented using the following -style: +References to sections and chapters are presented using the following style: :ref:`traversal_chapter` -- cgit v1.2.3 From 732c748a392a28294769d5413ef383501c3c40c9 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 23 Nov 2016 11:40:57 -0600 Subject: clarify comment fixes #2831 --- pyramid/asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/asset.py b/pyramid/asset.py index e6a145341..9d7a3ee63 100644 --- a/pyramid/asset.py +++ b/pyramid/asset.py @@ -33,7 +33,7 @@ def asset_spec_from_abspath(abspath, package): relpath.replace(os.path.sep, '/')) return abspath -# bw compat only; use pyramid.path.AssetDescriptor.abspath() instead +# bw compat only; use pyramid.path.AssetResolver().resolve(spec).abspath() def abspath_from_asset_spec(spec, pname='__main__'): if pname is None: return spec -- cgit v1.2.3 From a7f3065da246480e674077786d0ab707a9c1c964 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 24 Nov 2016 01:09:16 -0800 Subject: improve links section - add rendering of headings for testing - add topic directive - dedent displaying code - add italics, strong - add Pytyon modules, classes, methods, functions - add tables heading (WIP) - add API documenation (WIP) --- docs/style-guide.rst | 233 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 174 insertions(+), 59 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index f665846d2..45eaed634 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -190,6 +190,20 @@ As individual files do not have so-called "parts" or "chapters", the headings wo Heading Level 4 ``````````````` +The above code renders as follows. + +Heading Level 1 +=============== + +Heading Level 2 +--------------- + +Heading Level 3 +^^^^^^^^^^^^^^^ + +Heading Level 4 +``````````````` + .. _style-guide-paragraphs: Paragraphs @@ -205,9 +219,43 @@ Links Use inline links to keep the context or link label together with the URL. Do not use targets and links at the end of the page, because the separation makes it difficult to update and translate. Here is an example of inline links, our required method. - .. code-block:: rst +.. code-block:: rst + + `TryPyramid `_ + +The above code renders as follows. + +`TryPyramid `_ + +To link to pages within this documentation: + +.. code-block:: rst + + :doc:`quick_tour` + +The above code renders as follows. + +:doc:`quick_tour` + +To link to a section within a page in this documentation: + +.. code-block:: rst + + :ref:`quick_tour` + +The above code renders as follows. - `Example `_ +:ref:`quick_tour` + +To link to pages configured via intersphinx: + +.. code-block:: rst + + :ref:`Deform ` + +The above code renders as follows. + +:ref:`Deform ` .. _style-guide-topic: @@ -227,6 +275,13 @@ The directive's sole argument is interpreted as the topic title, and next line m the body of the topic, and are interpreted as body elements. +The above code renders as follows. + +.. topic:: Topic Title + + Subsequent indented lines comprise + the body of the topic, and are + interpreted as body elements. .. _style-guide-displaying-code: @@ -247,78 +302,76 @@ Sphinx does syntax highlighting of code blocks using the `Pygments Some XML + Some XML Unix shell commands are prefixed with a ``$`` character. (See :term:`venv` for the meaning of ``$VENV``.) - .. code-block:: rst +.. code-block:: rst - .. code-block:: bash + .. code-block:: bash - $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install -e . Windows commands are prefixed with a drive letter with an optional directory name. (See :term:`venv` for the meaning of ``%VENV%``.) - .. code-block:: rst - - .. code-block:: doscon +.. code-block:: rst - c:\> %VENV%\Scripts\pcreate -s starter MyProject + .. code-block:: doscon - .. code-block:: doscon + c:\> %VENV%\Scripts\pcreate -s starter MyProject cfg: - .. code-block:: rst +.. code-block:: rst - .. code-block:: cfg + .. code-block:: cfg - [some-part] - # A random part in the buildout - recipe = collective.recipe.foo - option = value + [some-part] + # A random part in the buildout + recipe = collective.recipe.foo + option = value ini: - .. code-block:: rst +.. code-block:: rst - .. code-block:: ini + .. code-block:: ini - [nosetests] - match=^test - where=pyramid - nocapture=1 + [nosetests] + match=^test + where=pyramid + nocapture=1 Interactive Python: - .. code-block:: rst +.. code-block:: rst - .. code-block:: pycon + .. code-block:: pycon - >>> class Foo: - ... bar = 100 - ... - >>> f = Foo() - >>> f.bar - 100 - >>> f.bar / 0 - Traceback (most recent call last): - File "", line 1, in - ZeroDivisionError: integer division or modulo by zero + >>> class Foo: + ... bar = 100 + ... + >>> f = Foo() + >>> f.bar + 100 + >>> f.bar / 0 + Traceback (most recent call last): + File "", line 1, in + ZeroDivisionError: integer division or modulo by zero If syntax highlighting is not enabled for your code block, you probably have a syntax error and Pygments will fail silently. @@ -332,12 +385,12 @@ Displaying long commands When a command that should be typed on one line is too long to fit on the displayed width of a page, the backslash character ``\`` is used to indicate that the subsequent printed line should be part of the command: - .. code-block:: rst +.. code-block:: rst - .. code-block:: bash + .. code-block:: bash - $ $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ - --cov=tutorial -q + $ $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ + --cov=tutorial -q .. _style-guide-code-block-options: @@ -530,14 +583,9 @@ The above code renders as follows. :lines: 6-7 :lineno-match: -.. literalinclude:: narr/helloworld.py - :language: python - :lines: 6-7 - :linenos: - -Out of all the ways to include parts of a file, ``pyobject`` is the most preferred option because if you change your code and add or remove lines, you don't need to adjust line numbering, whereas with ``lines`` you would have to adjust. ``start-after`` and ``end-before`` are less desirable because they depend on source code not changing, or you can insert comments into your source code to act as the delimiters but that just adds comments that have nothing to do with the functionality of your code. +Out of all the ways to include parts of a file, ``pyobject`` is the most preferred option because if you change your code and add or remove lines, you don't need to adjust line numbering, whereas with ``lines`` you would have to adjust. ``start-after`` and ``end-before`` are less desirable because they depend on source code not changing. Alternatively you can insert comments into your source code to act as the delimiters, but that just adds comments that have nothing to do with the functionality of your code. -Above all with includes, if you use line numbering, it's much preferred to use ``lineno-match`` over ``linenos`` with ``lineno-start`` because it "just works" without thinking. +Above all with includes, if you use line numbering, it's much preferred to use ``lineno-match`` over ``linenos`` with ``lineno-start`` because it "just works" without thinking and with less markup. .. _style-guide-inline-code: @@ -580,7 +628,13 @@ Notes which represent additional information related to a topic or concept are p Inline reST markup ------------------ -Italics. +Within a block of content, inline markup is useful to apply styles and links to other files. + + +.. _style-guide-italics: + +Italics +^^^^^^^ .. code-block:: rst @@ -590,7 +644,11 @@ The above code renders as follows. This *word* is italicized. -Strong. + +.. _style-guide-strong: + +Strong +^^^^^^ .. code-block:: rst @@ -601,17 +659,59 @@ The above code renders as follows. This **word** is in bold text. +.. _style-guide-python: + +Python modules, classes, methods, and functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Python module names use the ``mod`` directive, with the module name as the argument. + +.. code-block:: rst + + :mod:`pyramid.config` + +The above code renders as follows. + +:mod:`pyramid.config` + +Python class names use the ``class`` directive, with the class name as the argument. + +.. code-block:: rst + + :class:`pyramid.config.Configurator` + +The above code renders as follows. + +:class:`pyramid.config.Configurator` + +Python method names use the ``meth`` directive, with the method name as the argument. + +.. code-block:: rst + + :meth:`pyramid.config.Configurator.add_view` + +The above code renders as follows. + +:meth:`pyramid.config.Configurator.add_view` + +Python function names use the ``func`` directive, with the function name as the argument. + +.. code-block:: rst + + :func:`pyramid.renderers.render_to_response` + +The above code renders as follows. +:func:`pyramid.renderers.render_to_response` -We present Python method names using the following style: - :meth:`pyramid.config.Configurator.add_view` -We present Python class names, module names, attributes, and global variables using the following style: - :class:`pyramid.config.Configurator.registry` +:app:`Pyramid` + +:ref:`i18n_chapter` References to glossary terms are presented using the following style: @@ -620,3 +720,18 @@ References to glossary terms are presented using the following style: References to sections and chapters are presented using the following style: :ref:`traversal_chapter` + +.. _style-guide-tables: + +Tables +^^^^^^ + +API documentation +----------------- + +.. automodule:: pyramid.i18n + +.. autoclass:: TranslationString + +.. autofunction:: TranslationStringFactory + -- cgit v1.2.3 From 88dd1fc665b0f2f87e276dde85f4df53d88c6898 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 24 Nov 2016 01:40:58 -0800 Subject: comment out autodoc of TranslationString to get docs to build on Travis-CI https://travis-ci.org/Pylons/pyramid/jobs/178536008#L406 --- docs/api/i18n.rst | 1 + docs/style-guide.rst | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/api/i18n.rst b/docs/api/i18n.rst index 3b9abbc1d..7a61246df 100644 --- a/docs/api/i18n.rst +++ b/docs/api/i18n.rst @@ -6,6 +6,7 @@ .. automodule:: pyramid.i18n .. autoclass:: TranslationString + :noindex: .. autofunction:: TranslationStringFactory diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 45eaed634..641d0fad5 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -731,7 +731,7 @@ API documentation .. automodule:: pyramid.i18n -.. autoclass:: TranslationString +.. .. autoclass:: TranslationString -.. autofunction:: TranslationStringFactory +.. .. autofunction:: TranslationStringFactory -- cgit v1.2.3 From bf5c9eaa7e9041fe76cafddf7bad0f397899a6e9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 14:58:20 -0800 Subject: add todo Sphinx extension for todo blocks - add lists, tables, danger, todo, comments --- docs/conf.py | 8 +- docs/style-guide.rst | 252 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 239 insertions(+), 21 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index ace921247..0e3f03068 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -51,9 +51,10 @@ book = os.environ.get('BOOK') extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', - 'repoze.sphinx.autointerface', - 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.viewcode', + 'repoze.sphinx.autointerface', 'sphinxcontrib.programoutput', # enable pylons_sphinx_latesturl when this branch is no longer "latest" # 'pylons_sphinx_latesturl', @@ -120,6 +121,9 @@ exclude_patterns = ['_themes/README.rst', ] # unit titles (such as .. function::). add_module_names = False +# Add support for todo items +todo_include_todos = True + # The name of the Pygments (syntax highlighting) style to use. #pygments_style = book and 'bw' or 'tango' if book: diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 641d0fad5..73cba0859 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -146,9 +146,9 @@ Grammar, spelling, and capitalization preferences Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. -========== ====================== +========== ===== Preferred Avoid -========== ====================== +========== ===== add-on addon and so on etc. GitHub Github, github @@ -157,7 +157,7 @@ plug-in plugin select check, tick (checkbox) such as like verify be sure -========== ====================== +========== ===== .. _style-guide-headings: @@ -604,31 +604,244 @@ The above code renders as follows. Install requirements for building documentation: ``pip install -e ".[docs]"`` -.. _style-guide-block-rest-markup: +.. _style-guide-rest-block-markup: -Block reST markup +reST block markup ----------------- -Warnings which represent limitations and need-to-know information related to a topic or concept are presented in the following style: +This section contains miscellaneous reST block markup for items not already covered. - .. warning:: - This is a warning. +.. _style-guide-lists: -Notes which represent additional information related to a topic or concept are presented in the following style: +Lists +^^^^^ + +Bulleted lists use an asterisk "``*``". + +.. code-block:: rst + + * This is an item in a bulleted list. + * This is another item in a bulleted list. + +The above code renders as follows. + +* This is an item in a bulleted list. +* This is another item in a bulleted list. + +Numbered lists should use a number sign followed by a period "``#.``" and will be numbered automatically. + +.. code-block:: rst + + #. This is an item in a numbered list. + #. This is another item in a numbered list. + +The above code renders as follows. + +#. This is an item in a numbered list. +#. This is another item in a numbered list. + +The appearance of nested lists can be created by separating the child lists from their parent list by blank lines, and indenting by two spaces. Note that Sphinx renders the reST markup not as nested HTML lists, but instead merely indents the children using ``
``. + +.. code-block:: rst + + #. This is a list item in the parent list. + #. This is another list item in the parent list. + + #. This is a list item in the child list. + #. This is another list item in the child list. + + #. This is one more list item in the parent list. + +The above code renders as follows. + +#. This is a list item in the parent list. +#. This is another list item in the parent list. + + #. This is a list item in the child list. + #. This is another list item in the child list. + +#. This is one more list item in the parent list. + + +.. _style-guide-tables: - .. note:: +Tables +^^^^^^ + +Two forms of tables are supported, `simple `_ and `grid `_. + +Simple tables require less markup but have fewer features and some constraints compared to grid tables. The right-most column in simple tables is unbound to the length of the underline in the column header. + +.. code-block:: rst + + ===== ===== + col 1 col 2 + ===== ===== + 1 Second column of row 1. + 2 Second column of row 2. + Second line of paragraph. + 3 - Second column of row 3. + + - Second item in bullet + list (row 3, column 2). + \ Row 4; column 1 will be empty. + ===== ===== + +The above code renders as follows. + +===== ===== +col 1 col 2 +===== ===== +1 Second column of row 1. +2 Second column of row 2. + Second line of paragraph. +3 - Second column of row 3. + + - Second item in bullet + list (row 3, column 2). +\ Row 4; column 1 will be empty. +===== ===== + +Grid tables have much more cumbersome markup, although Emacs' table mode may lessen the tedium. + +.. code-block:: rst + + +------------------------+------------+----------+----------+ + | Header row, column 1 | Header 2 | Header 3 | Header 4 | + | (header rows optional) | | | | + +========================+============+==========+==========+ + | body row 1, column 1 | column 2 | column 3 | column 4 | + +------------------------+------------+----------+----------+ + | body row 2 | Cells may span columns. | + +------------------------+------------+---------------------+ + | body row 3 | Cells may | - Table cells | + +------------------------+ span rows. | - contain | + | body row 4 | | - body elements. | + +------------------------+------------+---------------------+ + +The above code renders as follows. + ++------------------------+------------+----------+----------+ +| Header row, column 1 | Header 2 | Header 3 | Header 4 | +| (header rows optional) | | | | ++========================+============+==========+==========+ +| body row 1, column 1 | column 2 | column 3 | column 4 | ++------------------------+------------+----------+----------+ +| body row 2 | Cells may span columns. | ++------------------------+------------+---------------------+ +| body row 3 | Cells may | - Table cells | ++------------------------+ span rows. | - contain | +| body row 4 | | - body elements. | ++------------------------+------------+---------------------+ + + +.. _style-guide-danger-errors: + +Danger and errors +^^^^^^^^^^^^^^^^^ + +Danger and errors represent critical information related to a topic or concept, and should recommend to the user "don't do this dangerous thing". ``danger`` and ``error`` appear similarly when rendered, but the HTML generated has the appropriate semantic context. + +.. code-block:: rst + + .. danger:: + + This is danger or an error. + +The above code renders as follows. - This is a note. +.. danger:: + This is danger or an error. +.. todo:: -.. _style-guide-inline-rest-markup: + The style for ``danger`` and ``error`` has not yet been created. -Inline reST markup + +.. _style-guide-warnings: + +Warnings +^^^^^^^^ + +Warnings represent limitations and advice related to a topic or concept. + +.. code-block:: rst + + .. warning:: + + This is a warning. + +The above code renders as follows. + +.. warning:: + + This is a warning. + + +.. _style-guide-notes: + +Notes +^^^^^ + +Notes represent additional information related to a topic or concept. + +.. code-block:: rst + + .. note:: + + This is a note. + +The above code renders as follows. + +.. note:: + + This is a note. + + +.. _style-guide-todo: + +Todo +^^^^ + +Todo items designated tasks that require further work. + +.. code-block:: rst + + .. todo:: + + This is a todo item. + +The above code renders as follows. + +.. todo:: + + This is a todo item. + +.. todo:: + + The todo style is not yet implemented and needs further work. + + +.. _style-guide-comments: + +Comments +^^^^^^^^ + +Comments of the documentation within the documentation may be generated with two periods ``..``. Comments are not rendered, but provide information to documentation authors. + +.. code-block:: rst + + .. This is an example comment. + + +.. _style-guide-rest-inline-markup: + +reST inline markup ------------------ -Within a block of content, inline markup is useful to apply styles and links to other files. +This section contains miscellaneous reST inline markup for items not already covered. Within a block of content, inline markup is useful to apply styles and links to other files. .. _style-guide-italics: @@ -704,8 +917,9 @@ The above code renders as follows. :func:`pyramid.renderers.render_to_response` +.. seealso:: - + See also the Sphinx documentation for the :ref:`reStructuredText Primer `. @@ -717,14 +931,14 @@ References to glossary terms are presented using the following style: :term:`Pylons` +Glossary terms appear in the Glossary + +.. glossary:: :sorted: + References to sections and chapters are presented using the following style: :ref:`traversal_chapter` -.. _style-guide-tables: - -Tables -^^^^^^ API documentation ----------------- -- cgit v1.2.3 From f4518e72c82ad3ef7aeba65ad1221924767b32ea Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 15:45:27 -0800 Subject: replace description with meta - add parsed-literals --- docs/style-guide.rst | 55 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 73cba0859..f13671704 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -3,9 +3,9 @@ Style Guide =========== -.. admonition:: description - - This chapter describes how to edit, update, and build the :app:`Pyramid` documentation. For coding style guidelines, see `Coding Style `_. +.. meta:: + :description: This chapter describes how to edit, update, and build the Pyramid documentation. + :keywords: Pyramid, Style Guide .. _style-guide-introduction: @@ -15,6 +15,8 @@ Introduction This chapter provides details of how to contribute updates to the documentation following style guidelines and conventions. We provide examples, including reStructuredText code and its rendered output for both visual and technical reference. +For coding style guidelines, see `Coding Style `_. + .. _style-guide-contribute: @@ -75,7 +77,7 @@ Page structure Each page should contain in order the following. -- The main heading. This will be visible in the table of contents. +#. The main heading. This will be visible in the table of contents. .. code-block:: rst @@ -83,17 +85,22 @@ Each page should contain in order the following. The main heading ================ -- The description of the page. This text will be displayed to the reader below the main heading as well as be inserted into the description metadata field of the document. It will be displayed in search engine listings for the page. This is created using the reST ``admonition`` directive. A single paragraph of text consisting of no more than three sentences is recommended, so that the same text fits into search engine results: +#. Meta tag information. The "meta" directive is used to specify HTML metadata stored in HTML META tags. "Metadata" is data about data, in this case data about web pages. Metadata is used to describe and classify web pages in the World Wide Web, in a form that is easy for search engines to extract and collate. .. code-block:: rst - .. admonition:: description + .. meta:: + :description: This chapter describes how to edit, update, and build the Pyramid documentation. + :keywords: Pyramid, Style Guide - This is a description of the page, which will appear inline and in the description metadata field. + The above code renders as follows. - .. note:: The ``description`` metadata field is not yet implemented in the documentation's Sphinx theme, but it is a `feature request `_, so it is helpful to start using the ``description`` admonition now. + .. code-block:: xml -- Introduction paragraph. + + + +#. Introduction paragraph. .. code-block:: rst @@ -102,7 +109,7 @@ Each page should contain in order the following. This chapter is an introduction. -- Finally the content of the document page, consisting of reST elements such as headings, paragraphs, tables, and so on. +#. Finally the content of the document page, consisting of reST elements such as headings, paragraphs, tables, and so on. .. _style-guide-page-content: @@ -378,6 +385,26 @@ If syntax highlighting is not enabled for your code block, you probably have a s View the `full list of lexers and associated short names `_. +.. _style-guide-parsed-literals: + +Parsed literals +``````````````` + +Parsed literals are used to render, for example, a specific version number of the application in code blocks. Use the directive ``parsed-literal``. Note that syntax highlighting is not supported and code is rendered as plain text. + +.. code-block:: rst + + .. parsed-literal:: + + $ $VENV/bin/pip install "pyramid==\ |release|\ " + +The above code renders as follows. + +.. parsed-literal:: + + $ $VENV/bin/pip install "pyramid==\ |release|\ " + + .. _style-guide-long-commands: Displaying long commands @@ -736,12 +763,12 @@ The above code renders as follows. +------------------------+------------+---------------------+ -.. _style-guide-danger-errors: +.. _style-guide-danger: -Danger and errors -^^^^^^^^^^^^^^^^^ +Danger +^^^^^^ -Danger and errors represent critical information related to a topic or concept, and should recommend to the user "don't do this dangerous thing". ``danger`` and ``error`` appear similarly when rendered, but the HTML generated has the appropriate semantic context. +Danger represents critical information related to a topic or concept, and should recommend to the user "don't do this dangerous thing". .. code-block:: rst -- cgit v1.2.3 From 78254d48a39e2b4938297dd568b02ab055b54c3f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 19:20:34 -0800 Subject: add feature versioning, seealso --- docs/style-guide.rst | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index f13671704..51a2efde5 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -763,6 +763,70 @@ The above code renders as follows. +------------------------+------------+---------------------+ +.. _style-guide-feature-versioning: + +Feature versioning +^^^^^^^^^^^^^^^^^^ + +Three directives designate the version in which something is added, changed, or deprecated in the project. + + +.. _style-guide-version-added: + +Version added +````````````` + +To indicate the version in which a feature is added to a project, use the ``versionadded`` directive. If the feature is an entire module, then the directive should be placed at the top of the module section before any prose. + +The first argument is the version. An optional second argument must appear upon a subsequent line, without blank lines in between, and indented. + +.. code-block:: rst + + .. versionadded:: 1.1 + :func:`pyramid.paster.bootstrap` + +The above code renders as follows. + +.. versionadded:: 1.1 + :func:`pyramid.paster.bootstrap` + + +.. _style-guide-version-changed: + +Version changed +``````````````` + +To indicate the version in which a feature is changed in a project, use the ``versionchanged`` directive. Its arguments are the same as ``versionadded``. + +.. code-block:: rst + + .. versionchanged:: 1.8 + Added the ability for ``bootstrap`` to cleanup automatically via the ``with`` statement. + +The above code renders as follows. + +.. versionchanged:: 1.8 + Added the ability for ``bootstrap`` to cleanup automatically via the ``with`` statement. + + +.. _style-guide-deprecated: + +Deprecated +`````````` + +Similar to ``versionchanged``, ``deprecated`` describes when the feature was deprecated. An explanation can also be given, for example, to inform the reader what should be used instead. + +.. code-block:: rst + + .. deprecated:: 1.7 + Use the ``require_csrf`` option or read :ref:`auto_csrf_checking` instead to have :class:`pyramid.exceptions.BadCSRFToken` exceptions raised. + +The above code renders as follows. + +.. deprecated:: 1.7 + Use the ``require_csrf`` option or read :ref:`auto_csrf_checking` instead to have :class:`pyramid.exceptions.BadCSRFToken` exceptions raised. + + .. _style-guide-danger: Danger @@ -827,6 +891,26 @@ The above code renders as follows. This is a note. +.. _style-guide-see-also: + +See also +^^^^^^^^ + +"See also" messages refer to topics that are related to the current topic, but have a narrative tone to them instead of merely a link without explanation. "See also" is rendered in a block as well, so that it stands out for the reader's attention. + +.. code-block:: rst + + .. seealso:: + + See :ref:`Quick Tutorial section on Requirements `. + +The above code renders as follows. + +.. seealso:: + + See :ref:`Quick Tutorial section on Requirements `. + + .. _style-guide-todo: Todo -- cgit v1.2.3 From d586ff5c7f22e3bc8e206d865a0760fb28efdb40 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 19:45:42 -0800 Subject: add glossary --- docs/style-guide.rst | 119 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 41 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 51a2efde5..95bfcccfa 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -35,18 +35,60 @@ When submitting a pull request for the first time in a project, sign `CONTRIBUTO Location, referencing, and naming of files ------------------------------------------ -- reStructuredText (reST) files must be located in ``docs/`` and its subdirectories. -- Image files must be located in ``docs/_static/``. -- reST directives must refer to files either relative to the source file or absolute from the top source directory. For example, in ``docs/narr/source.rst``, you could refer to a file in a different directory as either ``.. include:: ../diff-dir/diff-source.rst`` or ``.. include:: /diff-dir/diff-source.rst``. -- File names should be lower-cased and have words separated with either a hyphen "-" or an underscore "_". -- reST files must have an extension of ``.rst``. -- Image files may be any format but must have lower-cased file names and have standard file extensions that consist three letters (``.gif``, ``.jpg``, ``.png``, ``.svg``). ``.gif`` and ``.svg`` are not currently supported by PDF builders in Sphinx, but you can allow the Sphinx builder to automatically select the correct image format for the desired output by replacing the three-letter file extension with ``*``. For example: +* reStructuredText (reST) files must be located in ``docs/`` and its subdirectories. +* Image files must be located in ``docs/_static/``. +* reST directives must refer to files either relative to the source file or absolute from the top source directory. For example, in ``docs/narr/source.rst``, you could refer to a file in a different directory as either ``.. include:: ../diff-dir/diff-source.rst`` or ``.. include:: /diff-dir/diff-source.rst``. +* File names should be lower-cased and have words separated with either a hyphen "-" or an underscore "_". +* reST files must have an extension of ``.rst``. +* Image files may be any format but must have lower-cased file names and have standard file extensions that consist three letters (``.gif``, ``.jpg``, ``.png``, ``.svg``). ``.gif`` and ``.svg`` are not currently supported by PDF builders in Sphinx, but you can allow the Sphinx builder to automatically select the correct image format for the desired output by replacing the three-letter file extension with ``*``. For example: .. code-block:: rst - .. image:: ../_static/pyramid_request_processing.- + .. image:: ../_static/pyramid_request_processing. - will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related [Stack Overflow post](http://stackoverflow.com/questions/6473660/using-sphinx-docs-how-can-i-specify-png-image-formats-for-html-builds-and-pdf-im/6486713#6486713). + will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related `Stack Overflow post `_. + + +.. _style-guide-glossary: + +Glossary +-------- + +A glossary defines terms used throughout the documentation. + +The glossary file must be named ``glossary.rst``. Its content must begin with the directive ``glossary``. An optional ``sorted`` argument should be used to sort the terms alphabetically when rendered, making it easier for the user to find a given term. Without the argument ``sorted``, terms will appear in the order of the ``glossary`` source file. + +.. code-block:: rst + + .. glossary:: + :sorted: + + voom + Theoretically, the sound a parrot makes when four-thousand volts of electricity pass through it. + + pining + What the Norwegien Blue does when it misses its homeland, e.g., pining for the fjords. + +The above code renders as follows. + +.. glossary:: + :sorted: + + voom + Theoretically, the sound a parrot makes when four-thousand volts of electricity pass through it. + + pining + What the Norwegien Blue does when it misses its homeland, e.g., pining for the fjords. + +References to glossary terms use the ``term`` directive. + +.. code-block:: rst + + :term:`voom` + +The above code renders as follows. Note it is hyperlinked, and when clicked it will take the user to the term in the Glossary and highlight the term. + +:term:`voom` .. _style-guide-section-structure: @@ -56,9 +98,9 @@ Section structure Each section, or a subdirectory of reST files, such as a tutorial, must contain an ``index.rst`` file. ``index.rst`` must contain the following. -- A section heading. This will be visible in the table of contents. -- A single paragraph describing this section. -- A Sphinx ``toctree`` directive, with a ``maxdepth`` of 2. Each ``.rst`` file in the folder should be linked to this ``toctree``. +* A section heading. This will be visible in the table of contents. +* A single paragraph describing this section. +* A Sphinx ``toctree`` directive, with a ``maxdepth`` of 2. Each ``.rst`` file in the folder should be linked to this ``toctree``. .. code-block:: rst @@ -133,8 +175,8 @@ Narrative documentation is not code, and should therefore not adhere to PEP8 or Trailing white spaces ^^^^^^^^^^^^^^^^^^^^^ -- No trailing white spaces. -- Always use a line feed or carriage return at the end of a file. +* No trailing white spaces. +* Always use a line feed or carriage return at the end of a file. .. _style-guide-indentation: @@ -142,8 +184,8 @@ Trailing white spaces Indentation ^^^^^^^^^^^ -- Indent using four spaces. -- Do not use tabs to indent. +* Indent using four spaces. +* Do not use tabs to indent. .. _style-guide-grammar-spelling-preferences: @@ -151,7 +193,7 @@ Indentation Grammar, spelling, and capitalization preferences ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. +Use any commercial or free professional style guide in general. Use a spell* and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. ========== ===== Preferred Avoid @@ -176,10 +218,10 @@ Capitalize only the first letter in a heading (sentence-case), unless other word For consistent heading characters throughout the documentation, follow the guidelines stated in the `Python Developer's Guide `_. Specifically: -- =, for sections -- -, for subsections -- ^, for subsubsections -- ", for paragraphs +* =, for sections +* -, for subsections +* ^, for subsubsections +* ", for paragraphs As individual files do not have so-called "parts" or "chapters", the headings would be underlined with characters as shown. @@ -527,10 +569,10 @@ The above code renders as follows. Like code blocks, ``literalinclude`` supports the following options. -- ``language`` to select a language for syntax highlighting -- ``linenos`` to switch on line numbers -- ``lineno-start`` to specify the starting number to use for line numbering -- ``emphasize-lines`` to emphasize particular lines +* ``language`` to select a language for syntax highlighting +* ``linenos`` to switch on line numbers +* ``lineno-start`` to specify the starting number to use for line numbering +* ``emphasize-lines`` to emphasize particular lines .. code-block:: rst @@ -708,9 +750,9 @@ Simple tables require less markup but have fewer features and some constraints c 1 Second column of row 1. 2 Second column of row 2. Second line of paragraph. - 3 - Second column of row 3. + 3 * Second column of row 3. - - Second item in bullet + * Second item in bullet list (row 3, column 2). \ Row 4; column 1 will be empty. ===== ===== @@ -723,9 +765,9 @@ col 1 col 2 1 Second column of row 1. 2 Second column of row 2. Second line of paragraph. -3 - Second column of row 3. +3 * Second column of row 3. - - Second item in bullet + * Second item in bullet list (row 3, column 2). \ Row 4; column 1 will be empty. ===== ===== @@ -742,9 +784,9 @@ Grid tables have much more cumbersome markup, although Emacs' table mode may les +------------------------+------------+----------+----------+ | body row 2 | Cells may span columns. | +------------------------+------------+---------------------+ - | body row 3 | Cells may | - Table cells | - +------------------------+ span rows. | - contain | - | body row 4 | | - body elements. | + | body row 3 | Cells may | * Table cells | + +------------------------+ span rows. | * contain | + | body row 4 | | * body elements. | +------------------------+------------+---------------------+ The above code renders as follows. @@ -757,9 +799,9 @@ The above code renders as follows. +------------------------+------------+----------+----------+ | body row 2 | Cells may span columns. | +------------------------+------------+---------------------+ -| body row 3 | Cells may | - Table cells | -+------------------------+ span rows. | - contain | -| body row 4 | | - body elements. | +| body row 3 | Cells may | * Table cells | ++------------------------+ span rows. | * contain | +| body row 4 | | * body elements. | +------------------------+------------+---------------------+ @@ -1034,17 +1076,12 @@ The above code renders as follows. -:app:`Pyramid` - -:ref:`i18n_chapter` -References to glossary terms are presented using the following style: - :term:`Pylons` -Glossary terms appear in the Glossary +:app:`Pyramid` -.. glossary:: :sorted: +:ref:`i18n_chapter` References to sections and chapters are presented using the following style: -- cgit v1.2.3 From d1d6a7d9617461ce79bf224ef47aa6af308ff645 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 20:10:00 -0800 Subject: add toctree --- docs/style-guide.rst | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 95bfcccfa..166421eaf 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -49,6 +49,72 @@ Location, referencing, and naming of files will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related `Stack Overflow post `_. +.. _style-guide-table-of-contents-tree: + +Table of contents tree +---------------------- + +To insert a table of contents (TOC), use the ``toctree`` directive. Entries listed under the ``toctree`` directive follow :ref:`location conventions `. A numeric ``maxdepth`` option may be given to indicate the depth of the tree; by default, all levels are included. + +.. code-block:: rst + + .. toctree:: + :maxdepth: 2 + + narr/introduction + narr/install + +The above code renders as follows. + +.. toctree:: + :maxdepth: 2 + + narr/introduction + narr/install + +Globbing can be used. + +.. code-block:: rst + + .. toctree:: + :maxdepth: 1 + :glob: + + pscripts/index + pscripts/* + +The above code renders as follows. + +.. toctree:: + :maxdepth: 1 + :glob: + + pscripts/index + pscripts/* + +To notify Sphinx of the document hierarchy, but not insert links into the document at the location of the directive, use the option ``hidden``. This makes sense when you want to insert these links yourself, in a different style, or in the HTML sidebar. + +.. code-block:: rst + + .. toctree:: + :hidden: + + quick_tour + + * :doc:`quick_tour` gives an overview of the major features in Pyramid, covering a little about a lot. + +The above code renders as follows. + +.. toctree:: + :hidden: + + quick_tour + +* :doc:`quick_tour` gives an overview of the major features in Pyramid, covering a little about a lot. + +.. seealso:: Sphinx documentation of :ref:`The TOC tree `. + + .. _style-guide-glossary: Glossary -- cgit v1.2.3 From d7a6a905d55d6c21953812991dafb4163bbf0db1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 21:05:51 -0800 Subject: add cross-referencing --- docs/style-guide.rst | 93 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 166421eaf..02f8c18fa 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -112,7 +112,7 @@ The above code renders as follows. * :doc:`quick_tour` gives an overview of the major features in Pyramid, covering a little about a lot. -.. seealso:: Sphinx documentation of :ref:`The TOC tree `. +.. seealso:: Sphinx documentation of :ref:`toctree-directive`. .. _style-guide-glossary: @@ -342,35 +342,7 @@ The above code renders as follows. `TryPyramid `_ -To link to pages within this documentation: - -.. code-block:: rst - - :doc:`quick_tour` - -The above code renders as follows. - -:doc:`quick_tour` - -To link to a section within a page in this documentation: - -.. code-block:: rst - - :ref:`quick_tour` - -The above code renders as follows. - -:ref:`quick_tour` - -To link to pages configured via intersphinx: - -.. code-block:: rst - - :ref:`Deform ` - -The above code renders as follows. - -:ref:`Deform ` +.. seealso:: See also :ref:`style-guide-cross-references` for generating links throughout the entire documentation. .. _style-guide-topic: @@ -405,7 +377,7 @@ Displaying code Code may be displayed in blocks or inline. You can include blocks of code from other source files. Blocks of code should use syntax highlighting. -.. seealso:: See also the Sphinx documentation for :ref:`Showing code examples `. +.. seealso:: See also the Sphinx documentation for :ref:`code-examples`. .. _style-guide-syntax-highlighting: @@ -1138,20 +1110,71 @@ The above code renders as follows. .. seealso:: - See also the Sphinx documentation for the :ref:`reStructuredText Primer `. + See also the Sphinx documentation for the :ref:`rst-primer`. +.. _style-guide-cross-references: +Cross-references +^^^^^^^^^^^^^^^^ +To create cross-references to an arbitrary location, object, document, or other items, use variations of the following syntax. +* ``:role:`target``` creates a link to the item named ``target`` of the type indicated by ``role``, with the link's text as the title of the target. ``target`` may need to be disambiguated between documentation sets linked through intersphinx, in which case the syntax would be ``deform:overview``. +* ``:role:`~target``` displays the link as only the last component of the target. +* ``:role:`title ``` creates a custom title, instead of the default title of the target. -:app:`Pyramid` + +.. _style-guide-cross-referencing-documents: + +Cross-referencing documents +``````````````````````````` + +To link to pages within this documentation: + +.. code-block:: rst + + :doc:`quick_tour` + +The above code renders as follows. + +:doc:`quick_tour` + + +.. _style-guide-cross-referencing-arbitrary-locations: + +Cross-referencing arbitrary locations +````````````````````````````````````` + +To support cross-referencing to arbitrary locations in any document and between documentation sets via intersphinx, the standard reST labels are used. For this to work, label names must be unique throughout the entire documentation including externally linked intersphinx references. There are two ways in which you can refer to labels, if they are placed directly before a section title, a figure, or table with a caption, or at any other location. The following section has a label with the syntax ``.. _label_name:`` followed by the section title. + +.. code-block:: rst + + .. _i18n_chapter: + + Internationalization and Localization + ===================================== + +To generate a link to that section with its title, use the following syntax. + +.. code-block:: rst + + :ref:`i18n_chapter` + +The above code renders as follows. :ref:`i18n_chapter` -References to sections and chapters are presented using the following style: +The same syntax works figures and tables with captions. + +For labels that are not placed as mentioned, the link must be given an explicit title, such as ``:ref:`Link title ```. + +.. seealso:: See also the Sphinx documentation, :ref:`inline-markup`. + - :ref:`traversal_chapter` + + +:app:`Pyramid` API documentation -- cgit v1.2.3 From d7150db81721df046017632e597193f3250b08e3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 23:02:18 -0800 Subject: add sphinx extensions --- docs/style-guide.rst | 161 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 121 insertions(+), 40 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 02f8c18fa..0adea0e38 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -1062,11 +1062,74 @@ The above code renders as follows. This **word** is in bold text. +.. seealso:: + + See also the Sphinx documentation for the :ref:`rst-primer`. + + +.. _style-guide-cross-references: + +Cross-references +^^^^^^^^^^^^^^^^ + +To create cross-references to a document, arbitrary location, object, or other items, use variations of the following syntax. + +* ``:role:`target``` creates a link to the item named ``target`` of the type indicated by ``role``, with the link's text as the title of the target. ``target`` may need to be disambiguated between documentation sets linked through intersphinx, in which case the syntax would be ``deform:overview``. +* ``:role:`~target``` displays the link as only the last component of the target. +* ``:role:`title ``` creates a custom title, instead of the default title of the target. + + +.. _style-guide-cross-referencing-documents: + +Cross-referencing documents +``````````````````````````` + +To link to pages within this documentation: + +.. code-block:: rst + + :doc:`quick_tour` + +The above code renders as follows. -.. _style-guide-python: +:doc:`quick_tour` + + +.. _style-guide-cross-referencing-arbitrary-locations: + +Cross-referencing arbitrary locations +````````````````````````````````````` + +To support cross-referencing to arbitrary locations in any document and between documentation sets via intersphinx, the standard reST labels are used. For this to work, label names must be unique throughout the entire documentation including externally linked intersphinx references. There are two ways in which you can refer to labels, if they are placed directly before a section title, a figure, or table with a caption, or at any other location. The following section has a label with the syntax ``.. _label_name:`` followed by the section title. + +.. code-block:: rst + + .. _i18n_chapter: + + Internationalization and Localization + ===================================== + +To generate a link to that section with its title, use the following syntax. + +.. code-block:: rst + + :ref:`i18n_chapter` + +The above code renders as follows. + +:ref:`i18n_chapter` + +The same syntax works figures and tables with captions. + +For labels that are not placed as mentioned, the link must be given an explicit title, such as ``:ref:`Link title ```. + +.. seealso:: See also the Sphinx documentation, :ref:`inline-markup`. + + +.. _style-guide-cross-referencing-python: Python modules, classes, methods, and functions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``````````````````````````````````````````````` Python module names use the ``mod`` directive, with the module name as the argument. @@ -1108,81 +1171,99 @@ The above code renders as follows. :func:`pyramid.renderers.render_to_response` -.. seealso:: - - See also the Sphinx documentation for the :ref:`rst-primer`. +Note that you can use either or combine the ``~`` and ``.`` prefixes. However, we prefer not to use the ``.`` prefix because Sphinx might generate an error if it cannot disambiguate the reference. +.. code-block:: rst -.. _style-guide-cross-references: + :func:`~.render_to_response` -Cross-references -^^^^^^^^^^^^^^^^ +The above code renders as follows. -To create cross-references to an arbitrary location, object, document, or other items, use variations of the following syntax. +:func:`~.render_to_response` -* ``:role:`target``` creates a link to the item named ``target`` of the type indicated by ``role``, with the link's text as the title of the target. ``target`` may need to be disambiguated between documentation sets linked through intersphinx, in which case the syntax would be ``deform:overview``. -* ``:role:`~target``` displays the link as only the last component of the target. -* ``:role:`title ``` creates a custom title, instead of the default title of the target. +.. _style-guide-role-app-pyramid: -.. _style-guide-cross-referencing-documents: +The role ``:app:`Pyramid``` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Cross-referencing documents -``````````````````````````` +We use the special role ``app`` to refer to the application "Pyramid". -To link to pages within this documentation: .. code-block:: rst - :doc:`quick_tour` + :app:`Pyramid` The above code renders as follows. -:doc:`quick_tour` +:app:`Pyramid` -.. _style-guide-cross-referencing-arbitrary-locations: +.. _style-guide-sphinx-extensions: -Cross-referencing arbitrary locations -````````````````````````````````````` +Sphinx extensions +----------------- -To support cross-referencing to arbitrary locations in any document and between documentation sets via intersphinx, the standard reST labels are used. For this to work, label names must be unique throughout the entire documentation including externally linked intersphinx references. There are two ways in which you can refer to labels, if they are placed directly before a section title, a figure, or table with a caption, or at any other location. The following section has a label with the syntax ``.. _label_name:`` followed by the section title. +We use several Sphinx extensions to add features to our documentation. Extensions need to be enabled and configured in ``docs/conf.py`` before they can be used. -.. code-block:: rst - .. _i18n_chapter: +.. _style-guide-sphinx-extension-autodoc: - Internationalization and Localization - ===================================== +:mod:`sphinx.ext.autodoc` +------------------------- -To generate a link to that section with its title, use the following syntax. +API documentation uses the Sphinx extension :mod:`sphinx.ext.autodoc` to include documentation from docstrings. -.. code-block:: rst +See the source of any documentation within the ``docs/api/`` directory for conventions and usage, as well as the Sphinx extension's :mod:`documentation `. - :ref:`i18n_chapter` -The above code renders as follows. +.. _style-guide-sphinx-extension-doctest: -:ref:`i18n_chapter` +:mod:`sphinx.ext.doctest` +------------------------- -The same syntax works figures and tables with captions. +:mod:`sphinx.ext.doctest` allows you to test code snippets in the documentation in a natural way. It works by collecting specially-marked up code blocks and running them as doctest tests. We have only a few tests in our Pyramid documentation which can be found in ``narr/sessions.rst`` and ``narr/hooks.rst``. -For labels that are not placed as mentioned, the link must be given an explicit title, such as ``:ref:`Link title ```. -.. seealso:: See also the Sphinx documentation, :ref:`inline-markup`. +.. _style-guide-sphinx-extension-intersphinx: +:mod:`sphinx.ext.intersphinx` +----------------------------- +:mod:`sphinx.ext.intersphinx` generates links to the documentation of objects in other projects. -:app:`Pyramid` +.. _style-guide-sphinx-extension-todo: +:mod:`sphinx.ext.todo` +---------------------- + +:mod:`sphinx.ext.todo` adds support for todo items. + + +.. _style-guide-sphinx-extension-viewcode: + +:mod:`sphinx.ext.viewcode` +-------------------------- + +:mod:`sphinx.ext.viewcode` looks at your Python object descriptions and tries to find the source files where the objects are contained. When found, a separate HTML page will be output for each module with a highlighted version of the source code, and a link will be added to all object descriptions that leads to the source code of the described object. A link back from the source to the description will also be inserted. -API documentation ------------------ -.. automodule:: pyramid.i18n +.. _style-guide-sphinx-extension-repoze-sphinx-autointerface: -.. .. autoclass:: TranslationString +`repoze.sphinx.autointerface `_ +----------------------------------------------------------------------------------------- -.. .. autofunction:: TranslationStringFactory +`repoze.sphinx.autointerface `_ auto-generates API docs from Zope interfaces. + + +.. _style-guide-script-documentation: + +Script documentation +-------------------- + +We currently use `sphinxcontrib-programoutput `_ to generate program output of the p* scripts. It is no longer maintained and may cause future builds of the documentation to fail. + +.. todo:: + See `issue #2804 `_ for further discussion. -- cgit v1.2.3 From 0eb59ec16a05171e0a6e5e4649b7c03448413d76 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 25 Nov 2016 23:43:25 -0800 Subject: eat dog food: use " not ` for headings --- docs/style-guide.rst | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 0adea0e38..ca6d7279b 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -259,7 +259,7 @@ Indentation Grammar, spelling, and capitalization preferences ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Use any commercial or free professional style guide in general. Use a spell* and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. +Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. ========== ===== Preferred Avoid @@ -303,7 +303,7 @@ As individual files do not have so-called "parts" or "chapters", the headings wo ^^^^^^^^^^^^^^^ Heading Level 4 - ``````````````` + """"""""""""""" The above code renders as follows. @@ -317,7 +317,7 @@ Heading Level 3 ^^^^^^^^^^^^^^^ Heading Level 4 -``````````````` +""""""""""""""" .. _style-guide-paragraphs: @@ -383,7 +383,7 @@ Code may be displayed in blocks or inline. You can include blocks of code from o .. _style-guide-syntax-highlighting: Syntax highlighting -``````````````````` +""""""""""""""""""" Sphinx does syntax highlighting of code blocks using the `Pygments `_ library. @@ -468,7 +468,7 @@ View the `full list of lexers and associated short names Date: Sat, 26 Nov 2016 00:06:41 -0800 Subject: minor gardening --- docs/style-guide.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/style-guide.rst b/docs/style-guide.rst index ca6d7279b..70f899651 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -250,7 +250,7 @@ Trailing white spaces Indentation ^^^^^^^^^^^ -* Indent using four spaces. +* Indent using four spaces, except for :ref:`nested lists `. * Do not use tabs to indent. @@ -387,7 +387,7 @@ Syntax highlighting Sphinx does syntax highlighting of code blocks using the `Pygments `_ library. -Do not use two colons "::" at the end of a line, followed by a blank line, then indented code. Always specify the language to be used for syntax highlighting by using the ``code-block`` directive and indenting the code. +Do not use two colons "::" at the end of a line, followed by a blank line, then code. Always specify the language to be used for syntax highlighting by using a language argument in the ``code-block`` directive. Always indent the subsequent code. .. code-block:: rst @@ -449,16 +449,16 @@ Interactive Python: .. code-block:: pycon - >>> class Foo: - ... bar = 100 - ... - >>> f = Foo() - >>> f.bar - 100 - >>> f.bar / 0 - Traceback (most recent call last): - File "", line 1, in - ZeroDivisionError: integer division or modulo by zero + >>> class Foo: + ... bar = 100 + ... + >>> f = Foo() + >>> f.bar + 100 + >>> f.bar / 0 + Traceback (most recent call last): + File "", line 1, in + ZeroDivisionError: integer division or modulo by zero If syntax highlighting is not enabled for your code block, you probably have a syntax error and Pygments will fail silently. @@ -545,7 +545,7 @@ The above code renders as follows. # This is Python code pass -Code blocks may be given a caption, which may serve as a filename or other description, using the ``caption`` option. They may also be given a ``name`` option, providing an implicit target name that can be referenced by using ``ref``. +Code blocks may be given a caption, which may serve as a filename or other description, using the ``caption`` option. They may also be given a ``name`` option, providing an implicit target name that can be referenced by using ``ref`` (see :ref:`style-guide-cross-referencing-arbitrary-locations`). .. code-block:: rst @@ -578,7 +578,7 @@ To specify the starting number to use for line numbering, use the ``lineno-start # This is Python code pass -The above code renders as follows. As you can see, ``lineno-start`` is not altogether meaningful. +The above code renders as follows. As you can see, ``lineno-start`` is not altogether accurate. .. code-block:: python :lineno-start: 2 @@ -1171,15 +1171,15 @@ The above code renders as follows. :func:`pyramid.renderers.render_to_response` -Note that you can use either or combine the ``~`` and ``.`` prefixes. However, we prefer not to use the ``.`` prefix because Sphinx might generate an error if it cannot disambiguate the reference. +Note that you can use the ``~`` prefix to show only the last segment of a Python object's name. We prefer not to use the ``.`` prefix, even though it may seem to be a convenience to documentation authors, because Sphinx might generate an error if it cannot disambiguate the reference. .. code-block:: rst - :func:`~.render_to_response` + :func:`~pyramid.renderers.render_to_response` The above code renders as follows. -:func:`~.render_to_response` +:func:`~pyramid.renderers.render_to_response` .. _style-guide-role-app-pyramid: -- cgit v1.2.3 From 5f5e757dadae19a0c69069733a139eaf217f3ddd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 26 Nov 2016 00:10:34 -0800 Subject: add change note --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 1939ad125..59f77368f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -115,6 +115,9 @@ Deprecations Documentation Changes --------------------- +- Replace Typographical Conventions with an enhanced Style Guide. + https://github.com/Pylons/pyramid/pull/2838 + - Add pyramid_nacl_session to session factories. See https://github.com/Pylons/pyramid/issues/2791 -- cgit v1.2.3 From c8a5e024478d274309935251d59cd20908a95067 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 26 Nov 2016 00:31:54 -0800 Subject: add 3.6 support to documentation - See #2835 --- CHANGES.txt | 3 +++ HACKING.txt | 4 ++-- RELEASING.txt | 4 ++-- docs/narr/install.rst | 2 +- docs/narr/introduction.rst | 2 +- docs/quick_tour.rst | 4 ++-- docs/quick_tutorial/requirements.rst | 6 +++--- docs/tutorials/wiki/installation.rst | 6 +++--- docs/tutorials/wiki2/installation.rst | 6 +++--- setup.py | 1 + 10 files changed, 21 insertions(+), 17 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index dac61678d..65a1f15cd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -42,6 +42,9 @@ Backward Incompatibilities Features -------- +- Python 3.6 compatibility. + https://github.com/Pylons/pyramid/issues/2835 + - pcreate learned about --package-name to allow you to create a new project in an existing folder with a different package name than the project name. See https://github.com/Pylons/pyramid/pull/2783 diff --git a/HACKING.txt b/HACKING.txt index f240492e7..bbebb5165 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -118,8 +118,8 @@ In order to add a feature to Pyramid: - The feature must be documented in both the API and narrative documentation (in ``docs/``). -- The feature must work fully on the following CPython versions: 2.7, 3.4, - and 3.5 on both UNIX and Windows. +- The feature must work fully on the following CPython versions: 2.7, 3.4, 3.5, + and 3.6 on both UNIX and Windows. - The feature must work on the latest version of PyPy. diff --git a/RELEASING.txt b/RELEASING.txt index 4690fbd37..73cf38aa7 100644 --- a/RELEASING.txt +++ b/RELEASING.txt @@ -33,8 +33,8 @@ Prepare new release branch - Run tests on Windows if feasible. -- Make sure all scaffold tests pass (CPython 2.7, 3.4, and 3.5, and PyPy on - UNIX; this doesn't work on Windows): +- Make sure all scaffold tests pass (CPython 2.7, 3.4, 3.5, and 3.6, and PyPy + on UNIX; this doesn't work on Windows): $ ./scaffoldtests.sh diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 570cb2285..c3c2ba64c 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -22,7 +22,7 @@ the following sections. .. sidebar:: Python Versions As of this writing, :app:`Pyramid` is tested against Python 2.7, - Python 3.4, Python 3.5, PyPy. + Python 3.4, Python 3.5, Python 3.6, and PyPy. :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, Mac OS X, and FreeBSD, as well as on Windows platforms. It is also known to diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 47638579b..adad196e4 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -860,7 +860,7 @@ Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by Travis, -and Jenkins on Python 2.7, Python 3.4, Python 3.5, and PyPy +and Jenkins on Python 2.7, Python 3.4, Python 3.5, Python 3.6, and PyPy after each commit to its GitHub repository. Official Pyramid add-ons are held to a similar testing standard. We still find bugs in Pyramid and its official add-ons, but we've noticed we find a lot more of them while working on other diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 45c706b0d..5dc7d8816 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -26,7 +26,7 @@ To save a little bit of typing and to be certain that we use the modules, scripts, and packages installed in our virtual environment, we'll set an environment variable, too. -As an example, for Python 3.5+ on Linux: +As an example, for Python 3.6+ on Linux: .. parsed-literal:: @@ -729,7 +729,7 @@ This yields the following output. collected 1 items hello_world/tests.py . - ------------- coverage: platform darwin, python 3.5.0-final-0 ------------- + ------------- coverage: platform darwin, python 3.6.0-final-0 ------------- Name Stmts Miss Cover Missing -------------------------------------------------------- hello_world/__init__.py 11 8 27% 11-23 diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index afa8ed104..913e08a62 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -19,11 +19,11 @@ virtual environment.) This *Quick Tutorial* is based on: -* **Python 3.5**. Pyramid fully supports Python 3.4+ and Python 2.7+. This - tutorial uses **Python 3.5** but runs fine under Python 2.7. +* **Python 3.6**. Pyramid fully supports Python 3.4+ and Python 2.7+. This + tutorial uses **Python 3.6** but runs fine under Python 2.7. * **venv**. We believe in virtual environments. For this tutorial, we use - Python 3.5's built-in solution :term:`venv`. For Python 2.7, you can install + Python 3.6's built-in solution :term:`venv`. For Python 2.7, you can install :term:`virtualenv`. * **pip**. We use :term:`pip` for package management. diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 03e183739..ec79a4e9c 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -66,7 +66,7 @@ Python 2.7: c:\> c:\Python27\Scripts\virtualenv %VENV% -Python 3.5: +Python 3.6: .. code-block:: doscon @@ -310,13 +310,13 @@ If successful, you will see output something like this: .. code-block:: bash ======================== test session starts ======================== - platform Python 3.5.1, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 + platform Python 3.6.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile: plugins: cov-2.2.1 collected 1 items tutorial/tests.py . - ------------------ coverage: platform Python 3.5.1 ------------------ + ------------------ coverage: platform Python 3.6.0 ------------------ Name Stmts Miss Cover Missing ---------------------------------------------------- tutorial/__init__.py 12 7 42% 7-8, 14-18 diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 75d5d4abd..fa990fb01 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -66,7 +66,7 @@ Python 2.7: c:\> c:\Python27\Scripts\virtualenv %VENV% -Python 3.5: +Python 3.6: .. code-block:: doscon @@ -327,13 +327,13 @@ If successful, you will see output something like this: .. code-block:: bash ======================== test session starts ======================== - platform Python 3.5.1, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 + platform Python 3.6.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile: plugins: cov-2.2.1 collected 2 items tutorial/tests.py .. - ------------------ coverage: platform Python 3.5.1 ------------------ + ------------------ coverage: platform Python 3.6.0 ------------------ Name Stmts Miss Cover Missing ---------------------------------------------------------------- tutorial/__init__.py 8 6 25% 7-12 diff --git a/setup.py b/setup.py index 36615f36b..450529bc4 100644 --- a/setup.py +++ b/setup.py @@ -83,6 +83,7 @@ setup(name='pyramid', "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Framework :: Pyramid", -- cgit v1.2.3 From fa0da6844171e4d983092de1421a385f81f604d2 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 26 Nov 2016 15:19:52 -0600 Subject: only warn about py33, do not error this is squashed by pip unfortunately but it's better than a hard error --- setup.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 36615f36b..d437bb546 100644 --- a/setup.py +++ b/setup.py @@ -14,19 +14,21 @@ import os import sys +import warnings from setuptools import setup, find_packages py_version = sys.version_info[:2] -PY3 = py_version[0] == 3 +PY2 = py_version[0] == 2 -if PY3: - if py_version < (3, 4): - raise RuntimeError('On Python 3, Pyramid requires Python 3.4 or better') -else: - if py_version < (2, 7): - raise RuntimeError('On Python 2, Pyramid requires Python 2.7 or better') +if (3, 0) <= py_version < (3, 4): + warnings.warn( + 'On Python 3, Pyramid only supports Python 3.4 or better', + UserWarning, + ) +elif py_version < (2, 7): + raise RuntimeError('On Python 2, Pyramid requires Python 2.7 or better') here = os.path.abspath(os.path.dirname(__file__)) try: @@ -53,7 +55,7 @@ tests_require = [ 'WebTest >= 1.3.1', # py3 compat ] -if not PY3: +if PY2: tests_require.append('zope.component>=3.11.0') docs_extras = [ -- cgit v1.2.3 From af01a5ac5e31a778be8d634a560983fe818746bf Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 27 Nov 2016 17:09:32 -0600 Subject: fix nocover statements, should be "no cover" --- pyramid/tests/test_config/test_views.py | 4 ++-- pyramid/tests/test_httpexceptions.py | 2 +- pyramid/util.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index f020485de..211632730 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -2309,9 +2309,9 @@ class TestViewsConfigurationMixin(unittest.TestCase): # Since Python 3 has to be all cool and fancy and different... def _assertBody(self, response, value): from pyramid.compat import text_type - if isinstance(value, text_type): # pragma: nocover + if isinstance(value, text_type): # pragma: no cover self.assertEqual(response.text, value) - else: # pragma: nocover + else: # pragma: no cover self.assertEqual(response.body, value) def test_add_notfound_view_with_renderer(self): diff --git a/pyramid/tests/test_httpexceptions.py b/pyramid/tests/test_httpexceptions.py index 6c6e16d55..224fa4cf0 100644 --- a/pyramid/tests/test_httpexceptions.py +++ b/pyramid/tests/test_httpexceptions.py @@ -348,7 +348,7 @@ class TestHTTPException(unittest.TestCase): exc = cls(body_template='${REQUEST_METHOD}') environ = _makeEnviron() class Choke(object): - def __str__(self): # pragma nocover + def __str__(self): # pragma no cover raise ValueError environ['gardentheory.user'] = Choke() start_response = DummyStartResponse() diff --git a/pyramid/util.py b/pyramid/util.py index 4936dcb24..d5b3c6d72 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -3,7 +3,7 @@ import functools try: # py2.7.7+ and py3.3+ have native comparison support from hmac import compare_digest -except ImportError: # pragma: nocover +except ImportError: # pragma: no cover compare_digest = None import inspect import traceback -- cgit v1.2.3 From b99ada66150f9155ed959338f2053e544a6c8265 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 23:14:16 -0800 Subject: restore Typographical Conventions, an edited and condensed version of the Style Guide --- docs/index.rst | 5 +- docs/style-guide.rst | 34 ++- docs/typographical-conventions.rst | 427 +++++++++++++++++++++++++++++++++++++ 3 files changed, 442 insertions(+), 24 deletions(-) create mode 100644 docs/typographical-conventions.rst diff --git a/docs/index.rst b/docs/index.rst index f41154c19..a783e8a70 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -213,12 +213,13 @@ Copyright, Trademarks, and Attributions copyright -Style Guide -=========== +Typographical Conventions and Style Guide +========================================= .. toctree:: :maxdepth: 1 + typographical-conventions style-guide diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 70f899651..bdca45a06 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -293,31 +293,21 @@ As individual files do not have so-called "parts" or "chapters", the headings wo .. code-block:: rst - Heading Level 1 - =============== + ================================== + The main heading or web page title + ================================== - Heading Level 2 + Heading Level 1 --------------- - Heading Level 3 + Heading Level 2 ^^^^^^^^^^^^^^^ - Heading Level 4 + Heading Level 3 """"""""""""""" -The above code renders as follows. - -Heading Level 1 -=============== - -Heading Level 2 ---------------- +Note, we do not render heading levels here because doing so causes a loss in page structure. -Heading Level 3 -^^^^^^^^^^^^^^^ - -Heading Level 4 -""""""""""""""" .. _style-guide-paragraphs: @@ -375,7 +365,7 @@ The above code renders as follows. Displaying code ^^^^^^^^^^^^^^^ -Code may be displayed in blocks or inline. You can include blocks of code from other source files. Blocks of code should use syntax highlighting. +Code may be displayed in blocks or inline. You can include blocks of code from other source files. Blocks of code should use syntax highlighting, and may use line numbering or emphasis. .. seealso:: See also the Sphinx documentation for :ref:`code-examples`. @@ -427,10 +417,10 @@ cfg: .. code-block:: cfg - [some-part] - # A random part in the buildout - recipe = collective.recipe.foo - option = value + [some-part] + # A random part in the buildout + recipe = collective.recipe.foo + option = value ini: diff --git a/docs/typographical-conventions.rst b/docs/typographical-conventions.rst new file mode 100644 index 000000000..cd4de8800 --- /dev/null +++ b/docs/typographical-conventions.rst @@ -0,0 +1,427 @@ +.. _typographical-conventions: + +Typographical Conventions +========================= + +.. meta:: + :description: This chapter describes typographical conventions used in the Pyramid documentation. + :keywords: Pyramid, Typographical Conventions + + +.. _typographical-conventions-introduction: + +Introduction +------------ + +This chapter describes typographical conventions used in the Pyramid documentation. Documentation authors and contributors should review the :ref:`style-guide`. + + +.. _typographical-conventions-glossary: + +Glossary +-------- + +A glossary defines terms used throughout the documentation. References to glossary terms appear as follows. + +:term:`request` + +Note it is hyperlinked, and when clicked it will take the user to the term in the Glossary and highlight the term. + + +.. _typographical-conventions-headings: + +Headings +-------- + +Sections, sub-sections, and sub-sub-sections within a web page or chapter are denoted with headings at various levels. The immediately preceding heading "Headings" is a section heading. Sub-section and sub-sub-section headings are shown as follows. + +Heading Level 2 +^^^^^^^^^^^^^^^ + +sub-section + +Heading Level 3 +""""""""""""""" + +sub-sub-section + + +.. _typographical-conventions-paragraphs: + +Paragraphs +---------- + +A paragraph of text looks exactly like this paragraph. + + +.. _typographical-conventions-links: + +Links +----- + +Links are presented as follows, and may be clickable. + +`TryPyramid `_ + +.. seealso:: See also :ref:`typographical-conventions-cross-references` for other links within the documentation. + + +.. _typographical-conventions-topic: + +Topic +----- + +A topic is similar to a block quote with a title, or a self-contained section with no subsections. A topic indicates a self-contained idea that is separate from the flow of the document. Topics may occur anywhere a section or transition may occur. + +.. topic:: Topic Title + + Subsequent indented lines comprise + the body of the topic, and are + interpreted as body elements. + + +.. _typographical-conventions-displaying-code: + +Code +---- + +Code may be displayed in blocks or inline. Blocks of code may use syntax highlighting, line numbering, and emphasis. + + +.. _typographical-conventions-syntax-highlighting: + +Syntax highlighting +^^^^^^^^^^^^^^^^^^^ + +XML: + +.. code-block:: xml + + Some XML + +Unix shell commands are prefixed with a ``$`` character. (See :term:`venv` for the meaning of ``$VENV``.) + +.. code-block:: bash + + $ $VENV/bin/pip install -e . + +Windows commands are prefixed with a drive letter with an optional directory name. (See :term:`venv` for the meaning of ``%VENV%``.) + +.. code-block:: doscon + + c:\> %VENV%\Scripts\pcreate -s starter MyProject + +cfg: + +.. code-block:: cfg + + [some-part] + # A random part in the buildout + recipe = collective.recipe.foo + option = value + +ini: + +.. code-block:: ini + + [nosetests] + match=^test + where=pyramid + nocapture=1 + +Interactive Python: + +.. code-block:: pycon + + >>> class Foo: + ... bar = 100 + ... + >>> f = Foo() + >>> f.bar + 100 + >>> f.bar / 0 + Traceback (most recent call last): + File "", line 1, in + ZeroDivisionError: integer division or modulo by zero + + +.. _typographical-conventions-long-commands: + +Displaying long commands +^^^^^^^^^^^^^^^^^^^^^^^^ + +When a command that should be typed on one line is too long to fit on the displayed width of a page, the backslash character ``\`` is used to indicate that the subsequent printed line should be part of the command: + +.. code-block:: bash + + $ $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ + --cov=tutorial -q + + +.. _typographical-conventions-code-block-options: + +Code block options +^^^^^^^^^^^^^^^^^^ + +To emphasize lines, we give the appearance that a highlighting pen has been used on the code. + +.. code-block:: python + :emphasize-lines: 1,3 + + if "foo" == "bar": + # This is Python code + pass + +A code block with line numbers. + +.. code-block:: python + :linenos: + + if "foo" == "bar": + # This is Python code + pass + +Some code blocks may be given a caption. + +.. code-block:: python + :caption: sample.py + :name: sample-py + + if "foo" == "bar": + # This is Python code + pass + + +.. _typographical-conventions-inline-code: + +Inline code +^^^^^^^^^^^ + +Inline code is displayed as follows, where the inline code is 'pip install -e ".[docs]"'. + +Install requirements for building documentation: ``pip install -e ".[docs]"`` + + +.. _typographical-conventions-lists: + +Lists +----- + +Bulleted lists display as follows. + +* This is an item in a bulleted list. +* This is another item in a bulleted list. + +Numbered lists display as follows. + +#. This is an item in a numbered list. +#. This is another item in a numbered list. + +Nested lists display as follows. + +#. This is a list item in the parent list. +#. This is another list item in the parent list. + + #. This is a list item in the child list. + #. This is another list item in the child list. + +#. This is one more list item in the parent list. + + +.. _typographical-conventions-tables: + +Tables +------ + +Tables display as follows. + +===== ===== +col 1 col 2 +===== ===== +1 Second column of row 1. +2 Second column of row 2. + Second line of paragraph. +3 * Second column of row 3. + + * Second item in bullet + list (row 3, column 2). +\ Row 4; column 1 will be empty. +===== ===== + + +.. _typographical-conventions-feature-versioning: + +Feature versioning +------------------ + +We designate the version in which something is added, changed, or deprecated in the project. + + +.. _typographical-conventions-version-added: + +Version added +^^^^^^^^^^^^^ + +The version in which a feature is added to a project is displayed as follows. + +.. versionadded:: 1.1 + :func:`pyramid.paster.bootstrap` + + +.. _typographical-conventions-version-changed: + +Version changed +^^^^^^^^^^^^^^^ + +The version in which a feature is changed in a project is displayed as follows. + +.. versionchanged:: 1.8 + Added the ability for ``bootstrap`` to cleanup automatically via the ``with`` statement. + + +.. _typographical-conventions-deprecated: + +Deprecated +^^^^^^^^^^ + +The version in which a feature is deprecated in a project is displayed as follows. + +.. deprecated:: 1.7 + Use the ``require_csrf`` option or read :ref:`auto_csrf_checking` instead to have :class:`pyramid.exceptions.BadCSRFToken` exceptions raised. + + +.. _typographical-conventions-danger: + +Danger +------ + +Danger represents critical information related to a topic or concept, and should recommend to the user "don't do this dangerous thing". + +.. danger:: + + This is danger or an error. + + +.. _typographical-conventions-warnings: + +Warnings +-------- + +Warnings represent limitations and advice related to a topic or concept. + +.. warning:: + + This is a warning. + + +.. _typographical-conventions-notes: + +Notes +----- + +Notes represent additional information related to a topic or concept. + +.. note:: + + This is a note. + + +.. _typographical-conventions-see-also: + +See also +-------- + +"See also" messages refer to topics that are related to the current topic, but have a narrative tone to them instead of merely a link without explanation. "See also" is rendered in a block as well, so that it stands out for the reader's attention. + +.. seealso:: + + See :ref:`Quick Tutorial section on Requirements `. + + +.. _typographical-conventions-todo: + +Todo +---- + +Todo items designated tasks that require further work. + +.. todo:: + + This is a todo item. + + +.. _typographical-conventions-italics: + +Italics +------- + +This *word* is italicized. + + +.. _typographical-conventions-strong: + +Strong +------ + +This **word** is in bold text. + + +.. _typographical-conventions-cross-references: + +Cross-references +---------------- + +Cross-references are links that may be to a document, arbitrary location, object, or other items. + + +.. _typographical-conventions-cross-referencing-documents: + +Cross-referencing documents +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Links to pages within this documentation display as follows. + +:doc:`quick_tour` + + +.. _typographical-conventions-cross-referencing-arbitrary-locations: + +Cross-referencing arbitrary locations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Links to sections, and tables and figures with captions, within this documentation display as follows. + +:ref:`i18n_chapter` + + +.. _typographical-conventions-cross-referencing-python: + +Python modules, classes, methods, and functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All of the following are clickable links to Python modules, classes, methods, and functions. + +Python module names display as follows. + +:mod:`pyramid.config` + +Python class names display as follows. + +:class:`pyramid.config.Configurator` + +Python method names display as follows. + +:meth:`pyramid.config.Configurator.add_view` + +Python function names display as follows. + +:func:`pyramid.renderers.render_to_response` + +Sometimes we show only the last segment of a Python object's name, which displays as follows. + +:func:`~pyramid.renderers.render_to_response` + +The application "Pyramid" itself displays as follows. + +:app:`Pyramid` + -- cgit v1.2.3 From fa842555b41f807c8f4a8528113d7742eb7633e8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 23:21:18 -0800 Subject: fix warning about duplicate name --- docs/typographical-conventions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/typographical-conventions.rst b/docs/typographical-conventions.rst index cd4de8800..5c7efea31 100644 --- a/docs/typographical-conventions.rst +++ b/docs/typographical-conventions.rst @@ -185,7 +185,7 @@ Some code blocks may be given a caption. .. code-block:: python :caption: sample.py - :name: sample-py + :name: sample-py-typographical-conventions if "foo" == "bar": # This is Python code -- cgit v1.2.3 From c7974fe0a3363d84afd0db506dbc71b97cb84247 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 5 Dec 2016 22:08:37 -0600 Subject: move predicates into top-level package instead of inside config this better mirrors the view derivers design where the config package uses implementations from the pyramid namespace --- pyramid/config/predicates.py | 303 +-------------- pyramid/config/routes.py | 10 +- pyramid/config/security.py | 2 +- pyramid/config/tweens.py | 2 +- pyramid/config/util.py | 12 - pyramid/config/views.py | 6 +- pyramid/predicates.py | 300 +++++++++++++++ pyramid/tests/test_config/test_predicates.py | 526 --------------------------- pyramid/tests/test_config/test_util.py | 11 +- pyramid/tests/test_predicates.py | 526 +++++++++++++++++++++++++++ pyramid/util.py | 15 +- 11 files changed, 860 insertions(+), 853 deletions(-) create mode 100644 pyramid/predicates.py delete mode 100644 pyramid/tests/test_config/test_predicates.py create mode 100644 pyramid/tests/test_predicates.py diff --git a/pyramid/config/predicates.py b/pyramid/config/predicates.py index 0b76bbd70..5d99d6564 100644 --- a/pyramid/config/predicates.py +++ b/pyramid/config/predicates.py @@ -1,301 +1,2 @@ -import re - -from pyramid.exceptions import ConfigurationError - -from pyramid.compat import is_nonstr_iter - -from pyramid.traversal import ( - find_interface, - traversal_path, - resource_path_tuple - ) - -from pyramid.urldispatch import _compile_route -from pyramid.util import object_description -from pyramid.session import check_csrf_token - -from .util import as_sorted_tuple - -_marker = object() - -class XHRPredicate(object): - def __init__(self, val, config): - self.val = bool(val) - - def text(self): - return 'xhr = %s' % self.val - - phash = text - - def __call__(self, context, request): - return bool(request.is_xhr) is self.val - -class RequestMethodPredicate(object): - def __init__(self, val, config): - request_method = as_sorted_tuple(val) - if 'GET' in request_method and 'HEAD' not in request_method: - # GET implies HEAD too - request_method = as_sorted_tuple(request_method + ('HEAD',)) - self.val = request_method - - def text(self): - return 'request_method = %s' % (','.join(self.val)) - - phash = text - - def __call__(self, context, request): - return request.method in self.val - -class PathInfoPredicate(object): - def __init__(self, val, config): - self.orig = val - try: - val = re.compile(val) - except re.error as why: - raise ConfigurationError(why.args[0]) - self.val = val - - def text(self): - return 'path_info = %s' % (self.orig,) - - phash = text - - def __call__(self, context, request): - return self.val.match(request.upath_info) is not None - -class RequestParamPredicate(object): - def __init__(self, val, config): - val = as_sorted_tuple(val) - reqs = [] - for p in val: - k = p - v = None - if p.startswith('='): - if '=' in p[1:]: - k, v = p[1:].split('=', 1) - k = '=' + k - k, v = k.strip(), v.strip() - elif '=' in p: - k, v = p.split('=', 1) - k, v = k.strip(), v.strip() - reqs.append((k, v)) - self.val = val - self.reqs = reqs - - def text(self): - return 'request_param %s' % ','.join( - ['%s=%s' % (x,y) if y else x for x, y in self.reqs] - ) - - phash = text - - def __call__(self, context, request): - for k, v in self.reqs: - actual = request.params.get(k) - if actual is None: - return False - if v is not None and actual != v: - return False - return True - -class HeaderPredicate(object): - def __init__(self, val, config): - name = val - v = None - if ':' in name: - name, val_str = name.split(':', 1) - try: - v = re.compile(val_str) - except re.error as why: - raise ConfigurationError(why.args[0]) - if v is None: - self._text = 'header %s' % (name,) - else: - self._text = 'header %s=%s' % (name, val_str) - self.name = name - self.val = v - - def text(self): - return self._text - - phash = text - - def __call__(self, context, request): - if self.val is None: - return self.name in request.headers - val = request.headers.get(self.name) - if val is None: - return False - return self.val.match(val) is not None - -class AcceptPredicate(object): - def __init__(self, val, config): - self.val = val - - def text(self): - return 'accept = %s' % (self.val,) - - phash = text - - def __call__(self, context, request): - return self.val in request.accept - -class ContainmentPredicate(object): - def __init__(self, val, config): - self.val = config.maybe_dotted(val) - - def text(self): - return 'containment = %s' % (self.val,) - - phash = text - - def __call__(self, context, request): - ctx = getattr(request, 'context', context) - return find_interface(ctx, self.val) is not None - -class RequestTypePredicate(object): - def __init__(self, val, config): - self.val = val - - def text(self): - return 'request_type = %s' % (self.val,) - - phash = text - - def __call__(self, context, request): - return self.val.providedBy(request) - -class MatchParamPredicate(object): - def __init__(self, val, config): - val = as_sorted_tuple(val) - self.val = val - reqs = [ p.split('=', 1) for p in val ] - self.reqs = [ (x.strip(), y.strip()) for x, y in reqs ] - - def text(self): - return 'match_param %s' % ','.join( - ['%s=%s' % (x,y) for x, y in self.reqs] - ) - - phash = text - - def __call__(self, context, request): - if not request.matchdict: - # might be None - return False - for k, v in self.reqs: - if request.matchdict.get(k) != v: - return False - return True - -class CustomPredicate(object): - def __init__(self, func, config): - self.func = func - - def text(self): - return getattr( - self.func, - '__text__', - 'custom predicate: %s' % object_description(self.func) - ) - - def phash(self): - # using hash() here rather than id() is intentional: we - # want to allow custom predicates that are part of - # frameworks to be able to define custom __hash__ - # functions for custom predicates, so that the hash output - # of predicate instances which are "logically the same" - # may compare equal. - return 'custom:%r' % hash(self.func) - - def __call__(self, context, request): - return self.func(context, request) - - -class TraversePredicate(object): - # Can only be used as a *route* "predicate"; it adds 'traverse' to the - # matchdict if it's specified in the routing args. This causes the - # ResourceTreeTraverser to use the resolved traverse pattern as the - # traversal path. - def __init__(self, val, config): - _, self.tgenerate = _compile_route(val) - self.val = val - - def text(self): - return 'traverse matchdict pseudo-predicate' - - def phash(self): - # This isn't actually a predicate, it's just a infodict modifier that - # injects ``traverse`` into the matchdict. As a result, we don't - # need to update the hash. - return '' - - def __call__(self, context, request): - if 'traverse' in context: - return True - m = context['match'] - tvalue = self.tgenerate(m) # tvalue will be urlquoted string - m['traverse'] = traversal_path(tvalue) - # This isn't actually a predicate, it's just a infodict modifier that - # injects ``traverse`` into the matchdict. As a result, we just - # return True. - return True - -class CheckCSRFTokenPredicate(object): - - check_csrf_token = staticmethod(check_csrf_token) # testing - - def __init__(self, val, config): - self.val = val - - def text(self): - return 'check_csrf = %s' % (self.val,) - - phash = text - - def __call__(self, context, request): - val = self.val - if val: - if val is True: - val = 'csrf_token' - return self.check_csrf_token(request, val, raises=False) - return True - -class PhysicalPathPredicate(object): - def __init__(self, val, config): - if is_nonstr_iter(val): - self.val = tuple(val) - else: - val = tuple(filter(None, val.split('/'))) - self.val = ('',) + val - - def text(self): - return 'physical_path = %s' % (self.val,) - - phash = text - - def __call__(self, context, request): - if getattr(context, '__name__', _marker) is not _marker: - return resource_path_tuple(context) == self.val - return False - -class EffectivePrincipalsPredicate(object): - def __init__(self, val, config): - if is_nonstr_iter(val): - self.val = set(val) - else: - self.val = set((val,)) - - def text(self): - return 'effective_principals = %s' % sorted(list(self.val)) - - phash = text - - def __call__(self, context, request): - req_principals = request.effective_principals - if is_nonstr_iter(req_principals): - rpset = set(req_principals) - if self.val.issubset(rpset): - return True - return False - +import zope.deprecation +zope.deprecation.moved('pyramid.predicates', 'Pyramid 2.0') diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 90d4d47d2..203baa128 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -13,12 +13,10 @@ from pyramid.registry import predvalseq from pyramid.request import route_request_iface from pyramid.urldispatch import RoutesMapper -from pyramid.config.util import ( - action_method, - as_sorted_tuple, - ) +from pyramid.config.util import action_method +from pyramid.util import as_sorted_tuple -import pyramid.config.predicates +import pyramid.predicates class RoutesConfiguratorMixin(object): @action_method @@ -446,7 +444,7 @@ class RoutesConfiguratorMixin(object): ) def add_default_route_predicates(self): - p = pyramid.config.predicates + p = pyramid.predicates for (name, factory) in ( ('xhr', p.XHRPredicate), ('request_method', p.RequestMethodPredicate), diff --git a/pyramid/config/security.py b/pyramid/config/security.py index 02732c042..33593376b 100644 --- a/pyramid/config/security.py +++ b/pyramid/config/security.py @@ -9,9 +9,9 @@ from pyramid.interfaces import ( PHASE2_CONFIG, ) -from pyramid.config.util import as_sorted_tuple from pyramid.exceptions import ConfigurationError from pyramid.util import action_method +from pyramid.util import as_sorted_tuple class SecurityConfiguratorMixin(object): @action_method diff --git a/pyramid/config/tweens.py b/pyramid/config/tweens.py index 0aeb01fe3..16712ab16 100644 --- a/pyramid/config/tweens.py +++ b/pyramid/config/tweens.py @@ -17,9 +17,9 @@ from pyramid.tweens import ( from pyramid.config.util import ( action_method, - is_string_or_iterable, TopologicalSorter, ) +from pyramid.util import is_string_or_iterable class TweensConfiguratorMixin(object): def add_tween(self, tween_factory, under=None, over=None): diff --git a/pyramid/config/util.py b/pyramid/config/util.py index 626e8d5fe..b70dae7f3 100644 --- a/pyramid/config/util.py +++ b/pyramid/config/util.py @@ -24,18 +24,6 @@ ActionInfo = ActionInfo # support bw compat imports MAX_ORDER = 1 << 30 DEFAULT_PHASH = md5().hexdigest() -def is_string_or_iterable(v): - if isinstance(v, string_types): - return True - if hasattr(v, '__iter__'): - return True - -def as_sorted_tuple(val): - if not is_nonstr_iter(val): - val = (val,) - val = tuple(sorted(val)) - return val - class not_(object): """ diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 6082d8b48..65c9da585 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -70,10 +70,11 @@ import pyramid.util from pyramid.util import ( viewdefaults, action_method, + as_sorted_tuple, TopologicalSorter, ) -import pyramid.config.predicates +import pyramid.predicates import pyramid.viewderivers from pyramid.viewderivers import ( @@ -89,7 +90,6 @@ from pyramid.viewderivers import ( from pyramid.config.util import ( DEFAULT_PHASH, MAX_ORDER, - as_sorted_tuple, ) urljoin = urlparse.urljoin @@ -1143,7 +1143,7 @@ class ViewsConfiguratorMixin(object): ) def add_default_view_predicates(self): - p = pyramid.config.predicates + p = pyramid.predicates for (name, factory) in ( ('xhr', p.XHRPredicate), ('request_method', p.RequestMethodPredicate), diff --git a/pyramid/predicates.py b/pyramid/predicates.py new file mode 100644 index 000000000..7c3a778ca --- /dev/null +++ b/pyramid/predicates.py @@ -0,0 +1,300 @@ +import re + +from pyramid.exceptions import ConfigurationError + +from pyramid.compat import is_nonstr_iter + +from pyramid.session import check_csrf_token +from pyramid.traversal import ( + find_interface, + traversal_path, + resource_path_tuple + ) + +from pyramid.urldispatch import _compile_route +from pyramid.util import object_description +from pyramid.util import as_sorted_tuple + +_marker = object() + +class XHRPredicate(object): + def __init__(self, val, config): + self.val = bool(val) + + def text(self): + return 'xhr = %s' % self.val + + phash = text + + def __call__(self, context, request): + return bool(request.is_xhr) is self.val + +class RequestMethodPredicate(object): + def __init__(self, val, config): + request_method = as_sorted_tuple(val) + if 'GET' in request_method and 'HEAD' not in request_method: + # GET implies HEAD too + request_method = as_sorted_tuple(request_method + ('HEAD',)) + self.val = request_method + + def text(self): + return 'request_method = %s' % (','.join(self.val)) + + phash = text + + def __call__(self, context, request): + return request.method in self.val + +class PathInfoPredicate(object): + def __init__(self, val, config): + self.orig = val + try: + val = re.compile(val) + except re.error as why: + raise ConfigurationError(why.args[0]) + self.val = val + + def text(self): + return 'path_info = %s' % (self.orig,) + + phash = text + + def __call__(self, context, request): + return self.val.match(request.upath_info) is not None + +class RequestParamPredicate(object): + def __init__(self, val, config): + val = as_sorted_tuple(val) + reqs = [] + for p in val: + k = p + v = None + if p.startswith('='): + if '=' in p[1:]: + k, v = p[1:].split('=', 1) + k = '=' + k + k, v = k.strip(), v.strip() + elif '=' in p: + k, v = p.split('=', 1) + k, v = k.strip(), v.strip() + reqs.append((k, v)) + self.val = val + self.reqs = reqs + + def text(self): + return 'request_param %s' % ','.join( + ['%s=%s' % (x,y) if y else x for x, y in self.reqs] + ) + + phash = text + + def __call__(self, context, request): + for k, v in self.reqs: + actual = request.params.get(k) + if actual is None: + return False + if v is not None and actual != v: + return False + return True + +class HeaderPredicate(object): + def __init__(self, val, config): + name = val + v = None + if ':' in name: + name, val_str = name.split(':', 1) + try: + v = re.compile(val_str) + except re.error as why: + raise ConfigurationError(why.args[0]) + if v is None: + self._text = 'header %s' % (name,) + else: + self._text = 'header %s=%s' % (name, val_str) + self.name = name + self.val = v + + def text(self): + return self._text + + phash = text + + def __call__(self, context, request): + if self.val is None: + return self.name in request.headers + val = request.headers.get(self.name) + if val is None: + return False + return self.val.match(val) is not None + +class AcceptPredicate(object): + def __init__(self, val, config): + self.val = val + + def text(self): + return 'accept = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + return self.val in request.accept + +class ContainmentPredicate(object): + def __init__(self, val, config): + self.val = config.maybe_dotted(val) + + def text(self): + return 'containment = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + ctx = getattr(request, 'context', context) + return find_interface(ctx, self.val) is not None + +class RequestTypePredicate(object): + def __init__(self, val, config): + self.val = val + + def text(self): + return 'request_type = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + return self.val.providedBy(request) + +class MatchParamPredicate(object): + def __init__(self, val, config): + val = as_sorted_tuple(val) + self.val = val + reqs = [ p.split('=', 1) for p in val ] + self.reqs = [ (x.strip(), y.strip()) for x, y in reqs ] + + def text(self): + return 'match_param %s' % ','.join( + ['%s=%s' % (x,y) for x, y in self.reqs] + ) + + phash = text + + def __call__(self, context, request): + if not request.matchdict: + # might be None + return False + for k, v in self.reqs: + if request.matchdict.get(k) != v: + return False + return True + +class CustomPredicate(object): + def __init__(self, func, config): + self.func = func + + def text(self): + return getattr( + self.func, + '__text__', + 'custom predicate: %s' % object_description(self.func) + ) + + def phash(self): + # using hash() here rather than id() is intentional: we + # want to allow custom predicates that are part of + # frameworks to be able to define custom __hash__ + # functions for custom predicates, so that the hash output + # of predicate instances which are "logically the same" + # may compare equal. + return 'custom:%r' % hash(self.func) + + def __call__(self, context, request): + return self.func(context, request) + + +class TraversePredicate(object): + # Can only be used as a *route* "predicate"; it adds 'traverse' to the + # matchdict if it's specified in the routing args. This causes the + # ResourceTreeTraverser to use the resolved traverse pattern as the + # traversal path. + def __init__(self, val, config): + _, self.tgenerate = _compile_route(val) + self.val = val + + def text(self): + return 'traverse matchdict pseudo-predicate' + + def phash(self): + # This isn't actually a predicate, it's just a infodict modifier that + # injects ``traverse`` into the matchdict. As a result, we don't + # need to update the hash. + return '' + + def __call__(self, context, request): + if 'traverse' in context: + return True + m = context['match'] + tvalue = self.tgenerate(m) # tvalue will be urlquoted string + m['traverse'] = traversal_path(tvalue) + # This isn't actually a predicate, it's just a infodict modifier that + # injects ``traverse`` into the matchdict. As a result, we just + # return True. + return True + +class CheckCSRFTokenPredicate(object): + + check_csrf_token = staticmethod(check_csrf_token) # testing + + def __init__(self, val, config): + self.val = val + + def text(self): + return 'check_csrf = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + val = self.val + if val: + if val is True: + val = 'csrf_token' + return self.check_csrf_token(request, val, raises=False) + return True + +class PhysicalPathPredicate(object): + def __init__(self, val, config): + if is_nonstr_iter(val): + self.val = tuple(val) + else: + val = tuple(filter(None, val.split('/'))) + self.val = ('',) + val + + def text(self): + return 'physical_path = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + if getattr(context, '__name__', _marker) is not _marker: + return resource_path_tuple(context) == self.val + return False + +class EffectivePrincipalsPredicate(object): + def __init__(self, val, config): + if is_nonstr_iter(val): + self.val = set(val) + else: + self.val = set((val,)) + + def text(self): + return 'effective_principals = %s' % sorted(list(self.val)) + + phash = text + + def __call__(self, context, request): + req_principals = request.effective_principals + if is_nonstr_iter(req_principals): + rpset = set(req_principals) + if self.val.issubset(rpset): + return True + return False + diff --git a/pyramid/tests/test_config/test_predicates.py b/pyramid/tests/test_config/test_predicates.py deleted file mode 100644 index 9cd8f2734..000000000 --- a/pyramid/tests/test_config/test_predicates.py +++ /dev/null @@ -1,526 +0,0 @@ -import unittest - -from pyramid import testing - -from pyramid.compat import text_ - -class TestXHRPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import XHRPredicate - return XHRPredicate(val, None) - - def test___call___true(self): - inst = self._makeOne(True) - request = Dummy() - request.is_xhr = True - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne(True) - request = Dummy() - request.is_xhr = False - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne(True) - self.assertEqual(inst.text(), 'xhr = True') - - def test_phash(self): - inst = self._makeOne(True) - self.assertEqual(inst.phash(), 'xhr = True') - -class TestRequestMethodPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import RequestMethodPredicate - return RequestMethodPredicate(val, None) - - def test_ctor_get_but_no_head(self): - inst = self._makeOne('GET') - self.assertEqual(inst.val, ('GET', 'HEAD')) - - def test___call___true_single(self): - inst = self._makeOne('GET') - request = Dummy() - request.method = 'GET' - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_multi(self): - inst = self._makeOne(('GET','HEAD')) - request = Dummy() - request.method = 'GET' - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne(('GET','HEAD')) - request = Dummy() - request.method = 'POST' - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne(('HEAD','GET')) - self.assertEqual(inst.text(), 'request_method = GET,HEAD') - - def test_phash(self): - inst = self._makeOne(('HEAD','GET')) - self.assertEqual(inst.phash(), 'request_method = GET,HEAD') - -class TestPathInfoPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import PathInfoPredicate - return PathInfoPredicate(val, None) - - def test_ctor_compilefail(self): - from pyramid.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, self._makeOne, '\\') - - def test___call___true(self): - inst = self._makeOne(r'/\d{2}') - request = Dummy() - request.upath_info = text_('/12') - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne(r'/\d{2}') - request = Dummy() - request.upath_info = text_('/n12') - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne('/') - self.assertEqual(inst.text(), 'path_info = /') - - def test_phash(self): - inst = self._makeOne('/') - self.assertEqual(inst.phash(), 'path_info = /') - -class TestRequestParamPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import RequestParamPredicate - return RequestParamPredicate(val, None) - - def test___call___true_exists(self): - inst = self._makeOne('abc') - request = Dummy() - request.params = {'abc':1} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_withval(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.params = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_multi(self): - inst = self._makeOne(('abc', '=def =2= ')) - request = Dummy() - request.params = {'abc':'1', '=def': '2='} - result = inst(None, request) - self.assertTrue(result) - - def test___call___false_multi(self): - inst = self._makeOne(('abc=3', 'def =2 ')) - request = Dummy() - request.params = {'abc':'3', 'def': '1'} - result = inst(None, request) - self.assertFalse(result) - - def test___call___false(self): - inst = self._makeOne('abc') - request = Dummy() - request.params = {} - result = inst(None, request) - self.assertFalse(result) - - def test_text_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.text(), 'request_param abc') - - def test_text_exists_equal_sign(self): - inst = self._makeOne('=abc') - self.assertEqual(inst.text(), 'request_param =abc') - - def test_text_withval(self): - inst = self._makeOne('abc= 1') - self.assertEqual(inst.text(), 'request_param abc=1') - - def test_text_multi(self): - inst = self._makeOne(('abc= 1', 'def')) - self.assertEqual(inst.text(), 'request_param abc=1,def') - - def test_text_multi_equal_sign(self): - inst = self._makeOne(('abc= 1', '=def= 2')) - self.assertEqual(inst.text(), 'request_param =def=2,abc=1') - - def test_phash_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.phash(), 'request_param abc') - - def test_phash_exists_equal_sign(self): - inst = self._makeOne('=abc') - self.assertEqual(inst.phash(), 'request_param =abc') - - def test_phash_withval(self): - inst = self._makeOne('abc= 1') - self.assertEqual(inst.phash(), "request_param abc=1") - -class TestMatchParamPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import MatchParamPredicate - return MatchParamPredicate(val, None) - - def test___call___true_single(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.matchdict = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - - def test___call___true_multi(self): - inst = self._makeOne(('abc=1', 'def=2')) - request = Dummy() - request.matchdict = {'abc':'1', 'def':'2'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.matchdict = {} - result = inst(None, request) - self.assertFalse(result) - - def test___call___matchdict_is_None(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.matchdict = None - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne(('def= 1', 'abc =2')) - self.assertEqual(inst.text(), 'match_param abc=2,def=1') - - def test_phash(self): - inst = self._makeOne(('def= 1', 'abc =2')) - self.assertEqual(inst.phash(), 'match_param abc=2,def=1') - -class TestCustomPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import CustomPredicate - return CustomPredicate(val, None) - - def test___call___true(self): - def func(context, request): - self.assertEqual(context, None) - self.assertEqual(request, None) - return True - inst = self._makeOne(func) - result = inst(None, None) - self.assertTrue(result) - - def test___call___false(self): - def func(context, request): - self.assertEqual(context, None) - self.assertEqual(request, None) - return False - inst = self._makeOne(func) - result = inst(None, None) - self.assertFalse(result) - - def test_text_func_has___text__(self): - pred = predicate() - pred.__text__ = 'text' - inst = self._makeOne(pred) - self.assertEqual(inst.text(), 'text') - - def test_text_func_repr(self): - pred = predicate() - inst = self._makeOne(pred) - self.assertEqual(inst.text(), 'custom predicate: object predicate') - - def test_phash(self): - pred = predicate() - inst = self._makeOne(pred) - self.assertEqual(inst.phash(), 'custom:1') - -class TestTraversePredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import TraversePredicate - return TraversePredicate(val, None) - - def test___call__traverse_has_remainder_already(self): - inst = self._makeOne('/1/:a/:b') - info = {'traverse':'abc'} - request = Dummy() - result = inst(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'traverse':'abc'}) - - def test___call__traverse_matches(self): - inst = self._makeOne('/1/:a/:b') - info = {'match':{'a':'a', 'b':'b'}} - request = Dummy() - result = inst(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'match': - {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) - - def test___call__traverse_matches_with_highorder_chars(self): - inst = self._makeOne(text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) - info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}} - request = Dummy() - result = inst(info, request) - self.assertEqual(result, True) - self.assertEqual( - info['match']['traverse'], - (text_(b'La Pe\xc3\xb1a', 'utf-8'), - text_(b'Qu\xc3\xa9bec', 'utf-8')) - ) - - def test_text(self): - inst = self._makeOne('/abc') - self.assertEqual(inst.text(), 'traverse matchdict pseudo-predicate') - - def test_phash(self): - inst = self._makeOne('/abc') - self.assertEqual(inst.phash(), '') - -class Test_CheckCSRFTokenPredicate(unittest.TestCase): - def _makeOne(self, val, config): - from pyramid.config.predicates import CheckCSRFTokenPredicate - return CheckCSRFTokenPredicate(val, config) - - def test_text(self): - inst = self._makeOne(True, None) - self.assertEqual(inst.text(), 'check_csrf = True') - - def test_phash(self): - inst = self._makeOne(True, None) - self.assertEqual(inst.phash(), 'check_csrf = True') - - def test_it_call_val_True(self): - inst = self._makeOne(True, None) - request = Dummy() - def check_csrf_token(req, val, raises=True): - self.assertEqual(req, request) - self.assertEqual(val, 'csrf_token') - self.assertEqual(raises, False) - return True - inst.check_csrf_token = check_csrf_token - result = inst(None, request) - self.assertEqual(result, True) - - def test_it_call_val_str(self): - inst = self._makeOne('abc', None) - request = Dummy() - def check_csrf_token(req, val, raises=True): - self.assertEqual(req, request) - self.assertEqual(val, 'abc') - self.assertEqual(raises, False) - return True - inst.check_csrf_token = check_csrf_token - result = inst(None, request) - self.assertEqual(result, True) - - def test_it_call_val_False(self): - inst = self._makeOne(False, None) - request = Dummy() - result = inst(None, request) - self.assertEqual(result, True) - -class TestHeaderPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.config.predicates import HeaderPredicate - return HeaderPredicate(val, None) - - def test___call___true_exists(self): - inst = self._makeOne('abc') - request = Dummy() - request.headers = {'abc':1} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_withval(self): - inst = self._makeOne('abc:1') - request = Dummy() - request.headers = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_withregex(self): - inst = self._makeOne(r'abc:\d+') - request = Dummy() - request.headers = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___false_withregex(self): - inst = self._makeOne(r'abc:\d+') - request = Dummy() - request.headers = {'abc':'a'} - result = inst(None, request) - self.assertFalse(result) - - def test___call___false(self): - inst = self._makeOne('abc') - request = Dummy() - request.headers = {} - result = inst(None, request) - self.assertFalse(result) - - def test_text_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.text(), 'header abc') - - def test_text_withval(self): - inst = self._makeOne('abc:1') - self.assertEqual(inst.text(), 'header abc=1') - - def test_text_withregex(self): - inst = self._makeOne(r'abc:\d+') - self.assertEqual(inst.text(), r'header abc=\d+') - - def test_phash_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.phash(), 'header abc') - - def test_phash_withval(self): - inst = self._makeOne('abc:1') - self.assertEqual(inst.phash(), "header abc=1") - - def test_phash_withregex(self): - inst = self._makeOne(r'abc:\d+') - self.assertEqual(inst.phash(), r'header abc=\d+') - -class Test_PhysicalPathPredicate(unittest.TestCase): - def _makeOne(self, val, config): - from pyramid.config.predicates import PhysicalPathPredicate - return PhysicalPathPredicate(val, config) - - def test_text(self): - inst = self._makeOne('/', None) - self.assertEqual(inst.text(), "physical_path = ('',)") - - def test_phash(self): - inst = self._makeOne('/', None) - self.assertEqual(inst.phash(), "physical_path = ('',)") - - def test_it_call_val_tuple_True(self): - inst = self._makeOne(('', 'abc'), None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertTrue(inst(context, None)) - - def test_it_call_val_list_True(self): - inst = self._makeOne(['', 'abc'], None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertTrue(inst(context, None)) - - def test_it_call_val_str_True(self): - inst = self._makeOne('/abc', None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertTrue(inst(context, None)) - - def test_it_call_False(self): - inst = self._makeOne('/', None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertFalse(inst(context, None)) - - def test_it_call_context_has_no_name(self): - inst = self._makeOne('/', None) - context = Dummy() - self.assertFalse(inst(context, None)) - -class Test_EffectivePrincipalsPredicate(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, val, config): - from pyramid.config.predicates import EffectivePrincipalsPredicate - return EffectivePrincipalsPredicate(val, config) - - def test_text(self): - inst = self._makeOne(('verna', 'fred'), None) - self.assertEqual(inst.text(), - "effective_principals = ['fred', 'verna']") - - def test_text_noniter(self): - inst = self._makeOne('verna', None) - self.assertEqual(inst.text(), - "effective_principals = ['verna']") - - def test_phash(self): - inst = self._makeOne(('verna', 'fred'), None) - self.assertEqual(inst.phash(), - "effective_principals = ['fred', 'verna']") - - def test_it_call_no_authentication_policy(self): - request = testing.DummyRequest() - inst = self._makeOne(('verna', 'fred'), None) - context = Dummy() - self.assertFalse(inst(context, request)) - - def test_it_call_authentication_policy_provides_superset(self): - request = testing.DummyRequest() - self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) - inst = self._makeOne(('verna', 'fred'), None) - context = Dummy() - self.assertTrue(inst(context, request)) - - def test_it_call_authentication_policy_provides_superset_implicit(self): - from pyramid.security import Authenticated - request = testing.DummyRequest() - self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) - inst = self._makeOne(Authenticated, None) - context = Dummy() - self.assertTrue(inst(context, request)) - - def test_it_call_authentication_policy_doesnt_provide_superset(self): - request = testing.DummyRequest() - self.config.testing_securitypolicy('fred') - inst = self._makeOne(('verna', 'fred'), None) - context = Dummy() - self.assertFalse(inst(context, request)) - -class predicate(object): - def __repr__(self): - return 'predicate' - def __hash__(self): - return 1 - -class Dummy(object): - def __init__(self, **kw): - self.__dict__.update(**kw) - diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py index ccf7fa260..398b6fba8 100644 --- a/pyramid/tests/test_config/test_util.py +++ b/pyramid/tests/test_config/test_util.py @@ -5,7 +5,7 @@ class TestPredicateList(unittest.TestCase): def _makeOne(self): from pyramid.config.util import PredicateList - from pyramid.config import predicates + from pyramid import predicates inst = PredicateList() for name, factory in ( ('xhr', predicates.XHRPredicate), @@ -594,6 +594,15 @@ class TestNotted(unittest.TestCase): self.assertEqual(inst.phash(), '') self.assertEqual(inst(None, None), True) + +class TestDeprecatedPredicates(unittest.TestCase): + def test_it(self): + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + from pyramid.config.predicates import XHRPredicate + self.assertEqual(len(w), 1) + class DummyPredicate(object): def __init__(self, result): self.result = result diff --git a/pyramid/tests/test_predicates.py b/pyramid/tests/test_predicates.py new file mode 100644 index 000000000..8a002c24e --- /dev/null +++ b/pyramid/tests/test_predicates.py @@ -0,0 +1,526 @@ +import unittest + +from pyramid import testing + +from pyramid.compat import text_ + +class TestXHRPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import XHRPredicate + return XHRPredicate(val, None) + + def test___call___true(self): + inst = self._makeOne(True) + request = Dummy() + request.is_xhr = True + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne(True) + request = Dummy() + request.is_xhr = False + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne(True) + self.assertEqual(inst.text(), 'xhr = True') + + def test_phash(self): + inst = self._makeOne(True) + self.assertEqual(inst.phash(), 'xhr = True') + +class TestRequestMethodPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import RequestMethodPredicate + return RequestMethodPredicate(val, None) + + def test_ctor_get_but_no_head(self): + inst = self._makeOne('GET') + self.assertEqual(inst.val, ('GET', 'HEAD')) + + def test___call___true_single(self): + inst = self._makeOne('GET') + request = Dummy() + request.method = 'GET' + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_multi(self): + inst = self._makeOne(('GET','HEAD')) + request = Dummy() + request.method = 'GET' + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne(('GET','HEAD')) + request = Dummy() + request.method = 'POST' + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne(('HEAD','GET')) + self.assertEqual(inst.text(), 'request_method = GET,HEAD') + + def test_phash(self): + inst = self._makeOne(('HEAD','GET')) + self.assertEqual(inst.phash(), 'request_method = GET,HEAD') + +class TestPathInfoPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import PathInfoPredicate + return PathInfoPredicate(val, None) + + def test_ctor_compilefail(self): + from pyramid.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, self._makeOne, '\\') + + def test___call___true(self): + inst = self._makeOne(r'/\d{2}') + request = Dummy() + request.upath_info = text_('/12') + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne(r'/\d{2}') + request = Dummy() + request.upath_info = text_('/n12') + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne('/') + self.assertEqual(inst.text(), 'path_info = /') + + def test_phash(self): + inst = self._makeOne('/') + self.assertEqual(inst.phash(), 'path_info = /') + +class TestRequestParamPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import RequestParamPredicate + return RequestParamPredicate(val, None) + + def test___call___true_exists(self): + inst = self._makeOne('abc') + request = Dummy() + request.params = {'abc':1} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_withval(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.params = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_multi(self): + inst = self._makeOne(('abc', '=def =2= ')) + request = Dummy() + request.params = {'abc':'1', '=def': '2='} + result = inst(None, request) + self.assertTrue(result) + + def test___call___false_multi(self): + inst = self._makeOne(('abc=3', 'def =2 ')) + request = Dummy() + request.params = {'abc':'3', 'def': '1'} + result = inst(None, request) + self.assertFalse(result) + + def test___call___false(self): + inst = self._makeOne('abc') + request = Dummy() + request.params = {} + result = inst(None, request) + self.assertFalse(result) + + def test_text_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.text(), 'request_param abc') + + def test_text_exists_equal_sign(self): + inst = self._makeOne('=abc') + self.assertEqual(inst.text(), 'request_param =abc') + + def test_text_withval(self): + inst = self._makeOne('abc= 1') + self.assertEqual(inst.text(), 'request_param abc=1') + + def test_text_multi(self): + inst = self._makeOne(('abc= 1', 'def')) + self.assertEqual(inst.text(), 'request_param abc=1,def') + + def test_text_multi_equal_sign(self): + inst = self._makeOne(('abc= 1', '=def= 2')) + self.assertEqual(inst.text(), 'request_param =def=2,abc=1') + + def test_phash_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.phash(), 'request_param abc') + + def test_phash_exists_equal_sign(self): + inst = self._makeOne('=abc') + self.assertEqual(inst.phash(), 'request_param =abc') + + def test_phash_withval(self): + inst = self._makeOne('abc= 1') + self.assertEqual(inst.phash(), "request_param abc=1") + +class TestMatchParamPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import MatchParamPredicate + return MatchParamPredicate(val, None) + + def test___call___true_single(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.matchdict = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + + def test___call___true_multi(self): + inst = self._makeOne(('abc=1', 'def=2')) + request = Dummy() + request.matchdict = {'abc':'1', 'def':'2'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.matchdict = {} + result = inst(None, request) + self.assertFalse(result) + + def test___call___matchdict_is_None(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.matchdict = None + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne(('def= 1', 'abc =2')) + self.assertEqual(inst.text(), 'match_param abc=2,def=1') + + def test_phash(self): + inst = self._makeOne(('def= 1', 'abc =2')) + self.assertEqual(inst.phash(), 'match_param abc=2,def=1') + +class TestCustomPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import CustomPredicate + return CustomPredicate(val, None) + + def test___call___true(self): + def func(context, request): + self.assertEqual(context, None) + self.assertEqual(request, None) + return True + inst = self._makeOne(func) + result = inst(None, None) + self.assertTrue(result) + + def test___call___false(self): + def func(context, request): + self.assertEqual(context, None) + self.assertEqual(request, None) + return False + inst = self._makeOne(func) + result = inst(None, None) + self.assertFalse(result) + + def test_text_func_has___text__(self): + pred = predicate() + pred.__text__ = 'text' + inst = self._makeOne(pred) + self.assertEqual(inst.text(), 'text') + + def test_text_func_repr(self): + pred = predicate() + inst = self._makeOne(pred) + self.assertEqual(inst.text(), 'custom predicate: object predicate') + + def test_phash(self): + pred = predicate() + inst = self._makeOne(pred) + self.assertEqual(inst.phash(), 'custom:1') + +class TestTraversePredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import TraversePredicate + return TraversePredicate(val, None) + + def test___call__traverse_has_remainder_already(self): + inst = self._makeOne('/1/:a/:b') + info = {'traverse':'abc'} + request = Dummy() + result = inst(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'traverse':'abc'}) + + def test___call__traverse_matches(self): + inst = self._makeOne('/1/:a/:b') + info = {'match':{'a':'a', 'b':'b'}} + request = Dummy() + result = inst(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'match': + {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) + + def test___call__traverse_matches_with_highorder_chars(self): + inst = self._makeOne(text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) + info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}} + request = Dummy() + result = inst(info, request) + self.assertEqual(result, True) + self.assertEqual( + info['match']['traverse'], + (text_(b'La Pe\xc3\xb1a', 'utf-8'), + text_(b'Qu\xc3\xa9bec', 'utf-8')) + ) + + def test_text(self): + inst = self._makeOne('/abc') + self.assertEqual(inst.text(), 'traverse matchdict pseudo-predicate') + + def test_phash(self): + inst = self._makeOne('/abc') + self.assertEqual(inst.phash(), '') + +class Test_CheckCSRFTokenPredicate(unittest.TestCase): + def _makeOne(self, val, config): + from pyramid.predicates import CheckCSRFTokenPredicate + return CheckCSRFTokenPredicate(val, config) + + def test_text(self): + inst = self._makeOne(True, None) + self.assertEqual(inst.text(), 'check_csrf = True') + + def test_phash(self): + inst = self._makeOne(True, None) + self.assertEqual(inst.phash(), 'check_csrf = True') + + def test_it_call_val_True(self): + inst = self._makeOne(True, None) + request = Dummy() + def check_csrf_token(req, val, raises=True): + self.assertEqual(req, request) + self.assertEqual(val, 'csrf_token') + self.assertEqual(raises, False) + return True + inst.check_csrf_token = check_csrf_token + result = inst(None, request) + self.assertEqual(result, True) + + def test_it_call_val_str(self): + inst = self._makeOne('abc', None) + request = Dummy() + def check_csrf_token(req, val, raises=True): + self.assertEqual(req, request) + self.assertEqual(val, 'abc') + self.assertEqual(raises, False) + return True + inst.check_csrf_token = check_csrf_token + result = inst(None, request) + self.assertEqual(result, True) + + def test_it_call_val_False(self): + inst = self._makeOne(False, None) + request = Dummy() + result = inst(None, request) + self.assertEqual(result, True) + +class TestHeaderPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import HeaderPredicate + return HeaderPredicate(val, None) + + def test___call___true_exists(self): + inst = self._makeOne('abc') + request = Dummy() + request.headers = {'abc':1} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_withval(self): + inst = self._makeOne('abc:1') + request = Dummy() + request.headers = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_withregex(self): + inst = self._makeOne(r'abc:\d+') + request = Dummy() + request.headers = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___false_withregex(self): + inst = self._makeOne(r'abc:\d+') + request = Dummy() + request.headers = {'abc':'a'} + result = inst(None, request) + self.assertFalse(result) + + def test___call___false(self): + inst = self._makeOne('abc') + request = Dummy() + request.headers = {} + result = inst(None, request) + self.assertFalse(result) + + def test_text_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.text(), 'header abc') + + def test_text_withval(self): + inst = self._makeOne('abc:1') + self.assertEqual(inst.text(), 'header abc=1') + + def test_text_withregex(self): + inst = self._makeOne(r'abc:\d+') + self.assertEqual(inst.text(), r'header abc=\d+') + + def test_phash_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.phash(), 'header abc') + + def test_phash_withval(self): + inst = self._makeOne('abc:1') + self.assertEqual(inst.phash(), "header abc=1") + + def test_phash_withregex(self): + inst = self._makeOne(r'abc:\d+') + self.assertEqual(inst.phash(), r'header abc=\d+') + +class Test_PhysicalPathPredicate(unittest.TestCase): + def _makeOne(self, val, config): + from pyramid.predicates import PhysicalPathPredicate + return PhysicalPathPredicate(val, config) + + def test_text(self): + inst = self._makeOne('/', None) + self.assertEqual(inst.text(), "physical_path = ('',)") + + def test_phash(self): + inst = self._makeOne('/', None) + self.assertEqual(inst.phash(), "physical_path = ('',)") + + def test_it_call_val_tuple_True(self): + inst = self._makeOne(('', 'abc'), None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertTrue(inst(context, None)) + + def test_it_call_val_list_True(self): + inst = self._makeOne(['', 'abc'], None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertTrue(inst(context, None)) + + def test_it_call_val_str_True(self): + inst = self._makeOne('/abc', None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertTrue(inst(context, None)) + + def test_it_call_False(self): + inst = self._makeOne('/', None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertFalse(inst(context, None)) + + def test_it_call_context_has_no_name(self): + inst = self._makeOne('/', None) + context = Dummy() + self.assertFalse(inst(context, None)) + +class Test_EffectivePrincipalsPredicate(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self, val, config): + from pyramid.predicates import EffectivePrincipalsPredicate + return EffectivePrincipalsPredicate(val, config) + + def test_text(self): + inst = self._makeOne(('verna', 'fred'), None) + self.assertEqual(inst.text(), + "effective_principals = ['fred', 'verna']") + + def test_text_noniter(self): + inst = self._makeOne('verna', None) + self.assertEqual(inst.text(), + "effective_principals = ['verna']") + + def test_phash(self): + inst = self._makeOne(('verna', 'fred'), None) + self.assertEqual(inst.phash(), + "effective_principals = ['fred', 'verna']") + + def test_it_call_no_authentication_policy(self): + request = testing.DummyRequest() + inst = self._makeOne(('verna', 'fred'), None) + context = Dummy() + self.assertFalse(inst(context, request)) + + def test_it_call_authentication_policy_provides_superset(self): + request = testing.DummyRequest() + self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) + inst = self._makeOne(('verna', 'fred'), None) + context = Dummy() + self.assertTrue(inst(context, request)) + + def test_it_call_authentication_policy_provides_superset_implicit(self): + from pyramid.security import Authenticated + request = testing.DummyRequest() + self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) + inst = self._makeOne(Authenticated, None) + context = Dummy() + self.assertTrue(inst(context, request)) + + def test_it_call_authentication_policy_doesnt_provide_superset(self): + request = testing.DummyRequest() + self.config.testing_securitypolicy('fred') + inst = self._makeOne(('verna', 'fred'), None) + context = Dummy() + self.assertFalse(inst(context, request)) + +class predicate(object): + def __repr__(self): + return 'predicate' + def __hash__(self): + return 1 + +class Dummy(object): + def __init__(self, **kw): + self.__dict__.update(**kw) + diff --git a/pyramid/util.py b/pyramid/util.py index d5b3c6d72..3337d410d 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -28,13 +28,24 @@ from pyramid.compat import ( from pyramid.interfaces import IActionInfo from pyramid.path import DottedNameResolver as _DottedNameResolver +_marker = object() + class DottedNameResolver(_DottedNameResolver): def __init__(self, package=None): # default to package = None for bw compat _DottedNameResolver.__init__(self, package) -_marker = object() - +def is_string_or_iterable(v): + if isinstance(v, string_types): + return True + if hasattr(v, '__iter__'): + return True + +def as_sorted_tuple(val): + if not is_nonstr_iter(val): + val = (val,) + val = tuple(sorted(val)) + return val class InstancePropertyHelper(object): """A helper object for assigning properties and descriptors to instances. -- cgit v1.2.3 From 1bf417e4c1b2865f44357a61ca16fadde310077e Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 6 Dec 2016 10:43:22 +0100 Subject: Changed 'host' and 'port' configuration to a new 'listen' style that is now supported by waitress server. --- docs/narr/MyProject/development.ini | 3 +-- docs/narr/MyProject/production.ini | 3 +-- docs/narr/project.rst | 11 +++++------ docs/narr/startup.rst | 4 ++-- docs/quick_tour/package/development.ini | 3 +-- docs/quick_tour/sqla_demo/development.ini | 3 +-- docs/quick_tour/sqla_demo/production.ini | 3 +-- docs/quick_tutorial/authentication/development.ini | 3 +-- docs/quick_tutorial/authorization/development.ini | 3 +-- docs/quick_tutorial/databases/development.ini | 3 +-- docs/quick_tutorial/debugtoolbar/development.ini | 3 +-- docs/quick_tutorial/forms/development.ini | 3 +-- docs/quick_tutorial/functional_testing/development.ini | 3 +-- docs/quick_tutorial/ini/development.ini | 3 +-- docs/quick_tutorial/jinja2/development.ini | 3 +-- docs/quick_tutorial/json/development.ini | 3 +-- docs/quick_tutorial/logging/development.ini | 3 +-- docs/quick_tutorial/more_view_classes/development.ini | 3 +-- docs/quick_tutorial/request_response/development.ini | 3 +-- docs/quick_tutorial/retail_forms/development.ini | 3 +-- docs/quick_tutorial/routing/development.ini | 3 +-- docs/quick_tutorial/scaffolds/development.ini | 3 +-- docs/quick_tutorial/scaffolds/production.ini | 3 +-- docs/quick_tutorial/sessions/development.ini | 3 +-- docs/quick_tutorial/static_assets/development.ini | 3 +-- docs/quick_tutorial/templating/development.ini | 3 +-- docs/quick_tutorial/unit_testing/development.ini | 3 +-- docs/quick_tutorial/view_classes/development.ini | 3 +-- docs/quick_tutorial/views/development.ini | 3 +-- docs/tutorials/wiki/src/authorization/development.ini | 3 +-- docs/tutorials/wiki/src/authorization/production.ini | 3 +-- docs/tutorials/wiki/src/basiclayout/development.ini | 3 +-- docs/tutorials/wiki/src/basiclayout/production.ini | 3 +-- docs/tutorials/wiki/src/installation/development.ini | 3 +-- docs/tutorials/wiki/src/installation/production.ini | 3 +-- docs/tutorials/wiki/src/models/development.ini | 3 +-- docs/tutorials/wiki/src/models/production.ini | 3 +-- docs/tutorials/wiki/src/tests/development.ini | 3 +-- docs/tutorials/wiki/src/tests/production.ini | 3 +-- docs/tutorials/wiki/src/views/development.ini | 3 +-- docs/tutorials/wiki/src/views/production.ini | 3 +-- docs/tutorials/wiki2/src/authentication/development.ini | 3 +-- docs/tutorials/wiki2/src/authentication/production.ini | 3 +-- docs/tutorials/wiki2/src/authorization/development.ini | 3 +-- docs/tutorials/wiki2/src/authorization/production.ini | 3 +-- docs/tutorials/wiki2/src/basiclayout/development.ini | 3 +-- docs/tutorials/wiki2/src/basiclayout/production.ini | 3 +-- docs/tutorials/wiki2/src/installation/development.ini | 3 +-- docs/tutorials/wiki2/src/installation/production.ini | 3 +-- docs/tutorials/wiki2/src/models/development.ini | 3 +-- docs/tutorials/wiki2/src/models/production.ini | 3 +-- docs/tutorials/wiki2/src/tests/development.ini | 3 +-- docs/tutorials/wiki2/src/tests/production.ini | 3 +-- docs/tutorials/wiki2/src/views/development.ini | 3 +-- docs/tutorials/wiki2/src/views/production.ini | 3 +-- pyramid/scaffolds/alchemy/development.ini_tmpl | 3 +-- pyramid/scaffolds/alchemy/production.ini_tmpl | 3 +-- pyramid/scaffolds/starter/development.ini_tmpl | 3 +-- pyramid/scaffolds/starter/production.ini_tmpl | 3 +-- pyramid/scaffolds/zodb/development.ini_tmpl | 3 +-- pyramid/scaffolds/zodb/production.ini_tmpl | 3 +-- .../test_scaffolds/fixture_scaffold/development.ini_tmpl | 3 +-- .../tests/test_scaffolds/fixture_scaffold/production.ini_tmpl | 3 +-- 63 files changed, 68 insertions(+), 130 deletions(-) diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 94fece8ce..42c514794 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -24,8 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 1174b1cc7..3114b9d4d 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -18,8 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 6c42881f4..ec26b880e 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -295,16 +295,15 @@ Here's sample output from a run of ``pserve`` on UNIX: Access is restricted such that only a browser running on the same machine as Pyramid will be able to access your Pyramid application. However, if you want to open access to other machines on the same network, then edit the -``development.ini`` file, and replace the ``host`` value in the -``[server:main]`` section, changing it from ``127.0.0.1`` to ``0.0.0.0``. For +``development.ini`` file, and replace the ``listen`` value in the +``[server:main]`` section, changing it from ``127.0.0.1:6543`` to ``0.0.0.0:6543``. For example: .. code-block:: ini [server:main] use = egg:waitress#main - host = 0.0.0.0 - port = 6543 + listen = 0.0.0.0:6543 Now when you use ``pserve`` to start the application, it will respond to requests on *all* IP addresses possessed by your system, not just requests to @@ -320,8 +319,8 @@ browser by visiting ``http://192.168.1.50:6543/``. You can change the port on which the server runs on by changing the same portion of the ``development.ini`` file. For example, you can change the -``port = 6543`` line in the ``development.ini`` file's ``[server:main]`` -section to ``port = 8080`` to run the server on port 8080 instead of port 6543. +``listen = 127.0.0.1:6543`` line in the ``development.ini`` file's ``[server:main]`` +section to ``listen = 127:0.0.1:8080`` to run the server on port 8080 instead of port 6543. You can shut down a server started this way by pressing ``Ctrl-C`` (or ``Ctrl-Break`` on Windows). diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 3e168eaea..b71cff57d 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -130,8 +130,8 @@ Here's a high-level time-ordered overview of what happens when you press #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the Waitress server (``use = - egg:waitress#main``), and it will listen on all interfaces (``host = - 127.0.0.1``), on port number 6543 (``port = 6543``). The server code itself + egg:waitress#main``), and it will listen on all interfaces (``listen = + 127.0.0.1:6543``), on port number 6543. The server code itself is what prints ``serving on http://127.0.0.1:6543``. The server serves the application, and the application is running, waiting to receive requests. diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini index 20f9817a9..05571183d 100644 --- a/docs/quick_tour/package/development.ini +++ b/docs/quick_tour/package/development.ini @@ -25,8 +25,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini index 0db0950a0..a14402769 100644 --- a/docs/quick_tour/sqla_demo/development.ini +++ b/docs/quick_tour/sqla_demo/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini index 38f3b6318..e0bfd8ea0 100644 --- a/docs/quick_tour/sqla_demo/production.ini +++ b/docs/quick_tour/sqla_demo/production.ini @@ -18,8 +18,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/quick_tutorial/authentication/development.ini b/docs/quick_tutorial/authentication/development.ini index 8a39b2fe7..cbf694b2c 100644 --- a/docs/quick_tutorial/authentication/development.ini +++ b/docs/quick_tutorial/authentication/development.ini @@ -7,5 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/authorization/development.ini b/docs/quick_tutorial/authorization/development.ini index 8a39b2fe7..cbf694b2c 100644 --- a/docs/quick_tutorial/authorization/development.ini +++ b/docs/quick_tutorial/authorization/development.ini @@ -7,5 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 5da87d602..6145b5817 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -9,8 +9,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration diff --git a/docs/quick_tutorial/debugtoolbar/development.ini b/docs/quick_tutorial/debugtoolbar/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/debugtoolbar/development.ini +++ b/docs/quick_tutorial/debugtoolbar/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/forms/development.ini b/docs/quick_tutorial/forms/development.ini index 4d47e54a5..7114a48bb 100644 --- a/docs/quick_tutorial/forms/development.ini +++ b/docs/quick_tutorial/forms/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 \ No newline at end of file diff --git a/docs/quick_tutorial/functional_testing/development.ini b/docs/quick_tutorial/functional_testing/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/functional_testing/development.ini +++ b/docs/quick_tutorial/functional_testing/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/ini/development.ini b/docs/quick_tutorial/ini/development.ini index 8853e2c2b..14dfcd36d 100644 --- a/docs/quick_tutorial/ini/development.ini +++ b/docs/quick_tutorial/ini/development.ini @@ -3,5 +3,4 @@ use = egg:tutorial [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/jinja2/development.ini b/docs/quick_tutorial/jinja2/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/jinja2/development.ini +++ b/docs/quick_tutorial/jinja2/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/json/development.ini b/docs/quick_tutorial/json/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/json/development.ini +++ b/docs/quick_tutorial/json/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/logging/development.ini b/docs/quick_tutorial/logging/development.ini index 62e0c5123..fa22c0c51 100644 --- a/docs/quick_tutorial/logging/development.ini +++ b/docs/quick_tutorial/logging/development.ini @@ -6,8 +6,7 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration diff --git a/docs/quick_tutorial/more_view_classes/development.ini b/docs/quick_tutorial/more_view_classes/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/more_view_classes/development.ini +++ b/docs/quick_tutorial/more_view_classes/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/request_response/development.ini b/docs/quick_tutorial/request_response/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/request_response/development.ini +++ b/docs/quick_tutorial/request_response/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index 4d47e54a5..7114a48bb 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 \ No newline at end of file diff --git a/docs/quick_tutorial/routing/development.ini b/docs/quick_tutorial/routing/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/routing/development.ini +++ b/docs/quick_tutorial/routing/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/scaffolds/development.ini b/docs/quick_tutorial/scaffolds/development.ini index b31d06194..a9ad1e60d 100644 --- a/docs/quick_tutorial/scaffolds/development.ini +++ b/docs/quick_tutorial/scaffolds/development.ini @@ -24,8 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/quick_tutorial/scaffolds/production.ini b/docs/quick_tutorial/scaffolds/production.ini index 1418e6bf6..64f04dbec 100644 --- a/docs/quick_tutorial/scaffolds/production.ini +++ b/docs/quick_tutorial/scaffolds/production.ini @@ -18,8 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/quick_tutorial/sessions/development.ini b/docs/quick_tutorial/sessions/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/sessions/development.ini +++ b/docs/quick_tutorial/sessions/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/static_assets/development.ini b/docs/quick_tutorial/static_assets/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/static_assets/development.ini +++ b/docs/quick_tutorial/static_assets/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/templating/development.ini b/docs/quick_tutorial/templating/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/templating/development.ini +++ b/docs/quick_tutorial/templating/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/unit_testing/development.ini b/docs/quick_tutorial/unit_testing/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/unit_testing/development.ini +++ b/docs/quick_tutorial/unit_testing/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/view_classes/development.ini b/docs/quick_tutorial/view_classes/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/view_classes/development.ini +++ b/docs/quick_tutorial/view_classes/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/views/development.ini b/docs/quick_tutorial/views/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/views/development.ini +++ b/docs/quick_tutorial/views/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/authorization/production.ini +++ b/docs/tutorials/wiki/src/authorization/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/basiclayout/production.ini +++ b/docs/tutorials/wiki/src/basiclayout/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/development.ini b/docs/tutorials/wiki/src/installation/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/installation/development.ini +++ b/docs/tutorials/wiki/src/installation/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/production.ini b/docs/tutorials/wiki/src/installation/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/installation/production.ini +++ b/docs/tutorials/wiki/src/installation/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/models/production.ini +++ b/docs/tutorials/wiki/src/models/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/tests/development.ini +++ b/docs/tutorials/wiki/src/tests/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/tests/production.ini +++ b/docs/tutorials/wiki/src/tests/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/views/production.ini +++ b/docs/tutorials/wiki/src/views/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index 4a6c9325c..89ee6388b 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -29,8 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index a13a0ca19..4a5023c67 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -18,8 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 4a6c9325c..62a7edd48 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -29,8 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index a13a0ca19..ac9672654 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -18,8 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 4a6c9325c..89ee6388b 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -29,8 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index a13a0ca19..4a5023c67 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -18,8 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index f8ee290be..fd16826cb 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -26,8 +26,7 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index 4d9f835d4..d6a7c5a7b 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index ae9460b11..18b2d7a2a 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -24,8 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/production.ini_tmpl b/pyramid/scaffolds/starter/production.ini_tmpl index b2681c71d..a55b4d2e0 100644 --- a/pyramid/scaffolds/starter/production.ini_tmpl +++ b/pyramid/scaffolds/starter/production.ini_tmpl @@ -18,8 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index a44b61686..3f5c3710b 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index 522ff7651..05be225ed 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl index 4d3a80286..d9fd3dd33 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl @@ -11,8 +11,7 @@ pyramid.includes = pyramid_debugtoolbar [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl index 931cfa510..5406fca80 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl @@ -10,8 +10,7 @@ pyramid.default_locale_name = en [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration -- cgit v1.2.3 From 8bb7a4ba3593895a12ded27260ece7c1d673de56 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 6 Dec 2016 11:05:34 +0100 Subject: fixing no new line at the end of file --- docs/quick_tutorial/retail_forms/development.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index 7114a48bb..e2b176d9c 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 \ No newline at end of file +listen = 0.0.0.0:6543 -- cgit v1.2.3 From 7363ebfe8f0e9b65e493780628a7e558dbb74741 Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Tue, 6 Dec 2016 11:25:07 +0100 Subject: Fix docs for Sphinx 1.5 --- CONTRIBUTORS.txt | 2 ++ docs/conf.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 98e243c1f..b4e30e085 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -286,3 +286,5 @@ Contributors - Keith Yang, 2016/07/22 - Moriyoshi Koizumi, 2016/11/20 + +- Mikko Ohtamaa, 2016/12/6 diff --git a/docs/conf.py b/docs/conf.py index c3a7170fc..f35f7b34f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -191,7 +191,7 @@ latex_documents = [ # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -latex_use_parts = True +latex_toplevel_sectioning = "section" # If false, no module index is generated. latex_use_modindex = False -- cgit v1.2.3 From 9d1d5776c76d63af6241a995ff648059f12d15ea Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Tue, 6 Dec 2016 11:32:23 +0100 Subject: Another Sphinx 1.5 configuraition file change. --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index f35f7b34f..84fd5cf1b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -194,7 +194,7 @@ latex_documents = [ latex_toplevel_sectioning = "section" # If false, no module index is generated. -latex_use_modindex = False +latex_domain_indices = False ## Say, for a moment that you have a twoside document that needs a 3cm ## inner margin to allow for binding and at least two centimetres the -- cgit v1.2.3 From 9c120b5e9983c89bd9824269801b4d463d5c892a Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Tue, 6 Dec 2016 11:35:58 +0100 Subject: Fix pep8 error on config/util.py --- pyramid/config/util.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyramid/config/util.py b/pyramid/config/util.py index b70dae7f3..67bba9593 100644 --- a/pyramid/config/util.py +++ b/pyramid/config/util.py @@ -4,8 +4,7 @@ import inspect from pyramid.compat import ( bytes_, getargspec, - is_nonstr_iter, - string_types, + is_nonstr_iter ) from pyramid.compat import im_func -- cgit v1.2.3 From fb45a123a26f29ad391f27e4f6f6ccc0818a68eb Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 6 Dec 2016 12:14:42 +0100 Subject: Signed CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b4e30e085..126b286f8 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -288,3 +288,5 @@ Contributors - Moriyoshi Koizumi, 2016/11/20 - Mikko Ohtamaa, 2016/12/6 + +- Martin Frlin, 2016/12/6 -- cgit v1.2.3 From 0705eeaa820b32a4c3f2a05df21e99077586cf5e Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 6 Dec 2016 13:16:19 +0100 Subject: Added changes for #2656 --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 65a1f15cd..1c5f1a00e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -119,6 +119,9 @@ Features See https://github.com/Pylons/pyramid/pull/2805 +- Scaffolds, documentation and tutorials now use ``listen`` option instead + of ``host`` and ``port`` to configure Waitress server. + Bug Fixes --------- -- cgit v1.2.3 From b01a0233aa03b4b5a9ddd640a7a114f68d1c763d Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 6 Dec 2016 16:36:56 +0100 Subject: Changed wiki tutorial to showcase passwrd hashing with bcrypt. Relates to #2204 --- docs/tutorials/wiki/authorization.rst | 35 +++++++++++++++++++++- docs/tutorials/wiki/definingviews.rst | 1 + docs/tutorials/wiki/src/authorization/setup.py | 1 + .../wiki/src/authorization/tutorial/security.py | 15 ++++++++-- .../wiki/src/authorization/tutorial/views.py | 4 +-- docs/tutorials/wiki/src/tests/setup.py | 1 + docs/tutorials/wiki/src/tests/tutorial/security.py | 15 ++++++++-- docs/tutorials/wiki/src/tests/tutorial/tests.py | 11 +++++++ docs/tutorials/wiki/src/tests/tutorial/views.py | 4 +-- 9 files changed, 78 insertions(+), 9 deletions(-) diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 44097b35b..699e34355 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -18,6 +18,7 @@ require permission, instead of a default "403 Forbidden" page. We will implement the access control with the following steps: +* Add password hashing dependencies * Add users and groups (``security.py``, a new module). * Add an :term:`ACL` (``models.py``). * Add an :term:`authentication policy` and an :term:`authorization policy` @@ -38,6 +39,25 @@ Then we will add the login and logout feature: Access control -------------- +Add dependencies +~~~~~~~~~~~~~~~~ + +Just like in :ref:`wiki_defining_views` we need a new dependency. +We need to add the ``bcrypt`` package, to our tutorial package's +``setup.py`` file by assigning this dependency to the ``requires`` parameter +in the ``setup()`` function. + +Open ``setup.py`` and edit it to look like the following: + +.. literalinclude:: src/authorization/setup.py + :linenos: + :emphasize-lines: 21 + :language: python + +Only the highlighted line needs to be added. + +Do not forget to run ``pip install -e .`` just like in :ref:`wiki-running-pip-install`. + Add users and groups ~~~~~~~~~~~~~~~~~~~~ @@ -61,7 +81,20 @@ request)`` returns ``None``. We will use ``groupfinder()`` as an :term:`authentication policy` "callback" that will provide the :term:`principal` or principals for a user. -In a production system, user and group data will most often come from a +There are two helper methods that will help us later when loging-in users. +The first is ``hash_password`` which takes a raw password and transforms it using +bcrypt into an irreversible representation, a process known as "hashing". The +second method, ``check_password``, will allow us to compare the hashed value of the +submitted password against the hashed value of the password stored in the user's +record. If the two hashed values match, then the submitted +password is valid, and we can authenticate the user. + +We hash passwords so that it is impossible to decrypt them and use them to +authenticate in the application. If we stored passwords foolishly in clear text, +then anyone with access to the database could retrieve any password to authenticate +as any user. + +In a production system, user and group data will most often be saved and come from a database, but here we use "dummy" data to represent user and groups sources. Add an ACL diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index ac94d8059..3859d2cad 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -52,6 +52,7 @@ Open ``setup.py`` and edit it to look like the following: Only the highlighted line needs to be added. +.. _wiki-running-pip-install: Running ``pip install -e .`` ============================ diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py index beeed75c9..68e3c0abd 100644 --- a/docs/tutorials/wiki/src/authorization/setup.py +++ b/docs/tutorials/wiki/src/authorization/setup.py @@ -18,6 +18,7 @@ requires = [ 'ZODB3', 'waitress', 'docutils', + 'bcrypt', ] tests_require = [ diff --git a/docs/tutorials/wiki/src/authorization/tutorial/security.py b/docs/tutorials/wiki/src/authorization/tutorial/security.py index d88c9c71f..4115c780c 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/security.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/security.py @@ -1,5 +1,16 @@ -USERS = {'editor':'editor', - 'viewer':'viewer'} +import bcrypt + + +def hash_password(pw): + return bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt()) + +def check_password(expected_hash, pw): + if expected_hash is not None: + return bcrypt.checkpw(pw.encode('utf-8'), expected_hash) + return False + +USERS = {'editor': hash_password('editor'), + 'viewer': hash_password('viewer')} GROUPS = {'editor':['group:editors']} def groupfinder(userid, request): diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py index c271d2cc1..e4560dfe1 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py @@ -14,7 +14,7 @@ from pyramid.security import ( ) -from .security import USERS +from .security import USERS, check_password from .models import Page # regular expression used to find WikiWords @@ -94,7 +94,7 @@ def login(request): if 'form.submitted' in request.params: login = request.params['login'] password = request.params['password'] - if USERS.get(login) == password: + if check_password(USERS.get(login), password): headers = remember(request, login) return HTTPFound(location=came_from, headers=headers) diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py index beeed75c9..68e3c0abd 100644 --- a/docs/tutorials/wiki/src/tests/setup.py +++ b/docs/tutorials/wiki/src/tests/setup.py @@ -18,6 +18,7 @@ requires = [ 'ZODB3', 'waitress', 'docutils', + 'bcrypt', ] tests_require = [ diff --git a/docs/tutorials/wiki/src/tests/tutorial/security.py b/docs/tutorials/wiki/src/tests/tutorial/security.py index d88c9c71f..4115c780c 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/security.py +++ b/docs/tutorials/wiki/src/tests/tutorial/security.py @@ -1,5 +1,16 @@ -USERS = {'editor':'editor', - 'viewer':'viewer'} +import bcrypt + + +def hash_password(pw): + return bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt()) + +def check_password(expected_hash, pw): + if expected_hash is not None: + return bcrypt.checkpw(pw.encode('utf-8'), expected_hash) + return False + +USERS = {'editor': hash_password('editor'), + 'viewer': hash_password('viewer')} GROUPS = {'editor':['group:editors']} def groupfinder(userid, request): diff --git a/docs/tutorials/wiki/src/tests/tutorial/tests.py b/docs/tutorials/wiki/src/tests/tutorial/tests.py index 04beaea44..098e9c1bd 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/tests.py +++ b/docs/tutorials/wiki/src/tests/tutorial/tests.py @@ -122,6 +122,17 @@ class EditPageTests(unittest.TestCase): self.assertEqual(response.location, 'http://example.com/') self.assertEqual(context.data, 'Hello yo!') +class SecurityTests(unittest.TestCase): + def test_hashing(self): + from .security import hash_password, check_password + password = 'secretpassword' + hashed_password = hash_password(password) + self.assertTrue(check_password(hashed_password, password)) + + self.assertFalse(check_password(hashed_password, 'attackerpassword')) + + self.assertFalse(check_password(None, password)) + class FunctionalTests(unittest.TestCase): viewer_login = '/login?login=viewer&password=viewer' \ diff --git a/docs/tutorials/wiki/src/tests/tutorial/views.py b/docs/tutorials/wiki/src/tests/tutorial/views.py index c271d2cc1..e4560dfe1 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/views.py +++ b/docs/tutorials/wiki/src/tests/tutorial/views.py @@ -14,7 +14,7 @@ from pyramid.security import ( ) -from .security import USERS +from .security import USERS, check_password from .models import Page # regular expression used to find WikiWords @@ -94,7 +94,7 @@ def login(request): if 'form.submitted' in request.params: login = request.params['login'] password = request.params['password'] - if USERS.get(login) == password: + if check_password(USERS.get(login), password): headers = remember(request, login) return HTTPFound(location=came_from, headers=headers) -- cgit v1.2.3 From 988c1f789faf9662abead1e1be40969be37867a8 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 6 Dec 2016 16:00:56 -0800 Subject: =?UTF-8?q?Revert=20"Changed=20'host'=20and=20'port'=20configurati?= =?UTF-8?q?on=20to=20a=20new=20'listen'=20style=20that=20=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.txt | 3 --- CONTRIBUTORS.txt | 2 -- docs/narr/MyProject/development.ini | 3 ++- docs/narr/MyProject/production.ini | 3 ++- docs/narr/project.rst | 11 ++++++----- docs/narr/startup.rst | 4 ++-- docs/quick_tour/package/development.ini | 3 ++- docs/quick_tour/sqla_demo/development.ini | 3 ++- docs/quick_tour/sqla_demo/production.ini | 3 ++- docs/quick_tutorial/authentication/development.ini | 3 ++- docs/quick_tutorial/authorization/development.ini | 3 ++- docs/quick_tutorial/databases/development.ini | 3 ++- docs/quick_tutorial/debugtoolbar/development.ini | 3 ++- docs/quick_tutorial/forms/development.ini | 3 ++- docs/quick_tutorial/functional_testing/development.ini | 3 ++- docs/quick_tutorial/ini/development.ini | 3 ++- docs/quick_tutorial/jinja2/development.ini | 3 ++- docs/quick_tutorial/json/development.ini | 3 ++- docs/quick_tutorial/logging/development.ini | 3 ++- docs/quick_tutorial/more_view_classes/development.ini | 3 ++- docs/quick_tutorial/request_response/development.ini | 3 ++- docs/quick_tutorial/retail_forms/development.ini | 3 ++- docs/quick_tutorial/routing/development.ini | 3 ++- docs/quick_tutorial/scaffolds/development.ini | 3 ++- docs/quick_tutorial/scaffolds/production.ini | 3 ++- docs/quick_tutorial/sessions/development.ini | 3 ++- docs/quick_tutorial/static_assets/development.ini | 3 ++- docs/quick_tutorial/templating/development.ini | 3 ++- docs/quick_tutorial/unit_testing/development.ini | 3 ++- docs/quick_tutorial/view_classes/development.ini | 3 ++- docs/quick_tutorial/views/development.ini | 3 ++- docs/tutorials/wiki/src/authorization/development.ini | 3 ++- docs/tutorials/wiki/src/authorization/production.ini | 3 ++- docs/tutorials/wiki/src/basiclayout/development.ini | 3 ++- docs/tutorials/wiki/src/basiclayout/production.ini | 3 ++- docs/tutorials/wiki/src/installation/development.ini | 3 ++- docs/tutorials/wiki/src/installation/production.ini | 3 ++- docs/tutorials/wiki/src/models/development.ini | 3 ++- docs/tutorials/wiki/src/models/production.ini | 3 ++- docs/tutorials/wiki/src/tests/development.ini | 3 ++- docs/tutorials/wiki/src/tests/production.ini | 3 ++- docs/tutorials/wiki/src/views/development.ini | 3 ++- docs/tutorials/wiki/src/views/production.ini | 3 ++- docs/tutorials/wiki2/src/authentication/development.ini | 3 ++- docs/tutorials/wiki2/src/authentication/production.ini | 3 ++- docs/tutorials/wiki2/src/authorization/development.ini | 3 ++- docs/tutorials/wiki2/src/authorization/production.ini | 3 ++- docs/tutorials/wiki2/src/basiclayout/development.ini | 3 ++- docs/tutorials/wiki2/src/basiclayout/production.ini | 3 ++- docs/tutorials/wiki2/src/installation/development.ini | 3 ++- docs/tutorials/wiki2/src/installation/production.ini | 3 ++- docs/tutorials/wiki2/src/models/development.ini | 3 ++- docs/tutorials/wiki2/src/models/production.ini | 3 ++- docs/tutorials/wiki2/src/tests/development.ini | 3 ++- docs/tutorials/wiki2/src/tests/production.ini | 3 ++- docs/tutorials/wiki2/src/views/development.ini | 3 ++- docs/tutorials/wiki2/src/views/production.ini | 3 ++- pyramid/scaffolds/alchemy/development.ini_tmpl | 3 ++- pyramid/scaffolds/alchemy/production.ini_tmpl | 3 ++- pyramid/scaffolds/starter/development.ini_tmpl | 3 ++- pyramid/scaffolds/starter/production.ini_tmpl | 3 ++- pyramid/scaffolds/zodb/development.ini_tmpl | 3 ++- pyramid/scaffolds/zodb/production.ini_tmpl | 3 ++- .../test_scaffolds/fixture_scaffold/development.ini_tmpl | 3 ++- .../tests/test_scaffolds/fixture_scaffold/production.ini_tmpl | 3 ++- 65 files changed, 130 insertions(+), 73 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1c5f1a00e..65a1f15cd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -119,9 +119,6 @@ Features See https://github.com/Pylons/pyramid/pull/2805 -- Scaffolds, documentation and tutorials now use ``listen`` option instead - of ``host`` and ``port`` to configure Waitress server. - Bug Fixes --------- diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 126b286f8..b4e30e085 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -288,5 +288,3 @@ Contributors - Moriyoshi Koizumi, 2016/11/20 - Mikko Ohtamaa, 2016/12/6 - -- Martin Frlin, 2016/12/6 diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 42c514794..94fece8ce 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -24,7 +24,8 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 3114b9d4d..1174b1cc7 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -18,7 +18,8 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ec26b880e..6c42881f4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -295,15 +295,16 @@ Here's sample output from a run of ``pserve`` on UNIX: Access is restricted such that only a browser running on the same machine as Pyramid will be able to access your Pyramid application. However, if you want to open access to other machines on the same network, then edit the -``development.ini`` file, and replace the ``listen`` value in the -``[server:main]`` section, changing it from ``127.0.0.1:6543`` to ``0.0.0.0:6543``. For +``development.ini`` file, and replace the ``host`` value in the +``[server:main]`` section, changing it from ``127.0.0.1`` to ``0.0.0.0``. For example: .. code-block:: ini [server:main] use = egg:waitress#main - listen = 0.0.0.0:6543 + host = 0.0.0.0 + port = 6543 Now when you use ``pserve`` to start the application, it will respond to requests on *all* IP addresses possessed by your system, not just requests to @@ -319,8 +320,8 @@ browser by visiting ``http://192.168.1.50:6543/``. You can change the port on which the server runs on by changing the same portion of the ``development.ini`` file. For example, you can change the -``listen = 127.0.0.1:6543`` line in the ``development.ini`` file's ``[server:main]`` -section to ``listen = 127:0.0.1:8080`` to run the server on port 8080 instead of port 6543. +``port = 6543`` line in the ``development.ini`` file's ``[server:main]`` +section to ``port = 8080`` to run the server on port 8080 instead of port 6543. You can shut down a server started this way by pressing ``Ctrl-C`` (or ``Ctrl-Break`` on Windows). diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index b71cff57d..3e168eaea 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -130,8 +130,8 @@ Here's a high-level time-ordered overview of what happens when you press #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the Waitress server (``use = - egg:waitress#main``), and it will listen on all interfaces (``listen = - 127.0.0.1:6543``), on port number 6543. The server code itself + egg:waitress#main``), and it will listen on all interfaces (``host = + 127.0.0.1``), on port number 6543 (``port = 6543``). The server code itself is what prints ``serving on http://127.0.0.1:6543``. The server serves the application, and the application is running, waiting to receive requests. diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini index 05571183d..20f9817a9 100644 --- a/docs/quick_tour/package/development.ini +++ b/docs/quick_tour/package/development.ini @@ -25,7 +25,8 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini index a14402769..0db0950a0 100644 --- a/docs/quick_tour/sqla_demo/development.ini +++ b/docs/quick_tour/sqla_demo/development.ini @@ -27,7 +27,8 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini index e0bfd8ea0..38f3b6318 100644 --- a/docs/quick_tour/sqla_demo/production.ini +++ b/docs/quick_tour/sqla_demo/production.ini @@ -18,7 +18,8 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/quick_tutorial/authentication/development.ini b/docs/quick_tutorial/authentication/development.ini index cbf694b2c..8a39b2fe7 100644 --- a/docs/quick_tutorial/authentication/development.ini +++ b/docs/quick_tutorial/authentication/development.ini @@ -7,4 +7,5 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/authorization/development.ini b/docs/quick_tutorial/authorization/development.ini index cbf694b2c..8a39b2fe7 100644 --- a/docs/quick_tutorial/authorization/development.ini +++ b/docs/quick_tutorial/authorization/development.ini @@ -7,4 +7,5 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 6145b5817..5da87d602 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -9,7 +9,8 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 # Begin logging configuration diff --git a/docs/quick_tutorial/debugtoolbar/development.ini b/docs/quick_tutorial/debugtoolbar/development.ini index c4b1b3c1d..52b2a3a41 100644 --- a/docs/quick_tutorial/debugtoolbar/development.ini +++ b/docs/quick_tutorial/debugtoolbar/development.ini @@ -5,4 +5,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/forms/development.ini b/docs/quick_tutorial/forms/development.ini index 7114a48bb..4d47e54a5 100644 --- a/docs/quick_tutorial/forms/development.ini +++ b/docs/quick_tutorial/forms/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 \ No newline at end of file +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/functional_testing/development.ini b/docs/quick_tutorial/functional_testing/development.ini index c4b1b3c1d..52b2a3a41 100644 --- a/docs/quick_tutorial/functional_testing/development.ini +++ b/docs/quick_tutorial/functional_testing/development.ini @@ -5,4 +5,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/ini/development.ini b/docs/quick_tutorial/ini/development.ini index 14dfcd36d..8853e2c2b 100644 --- a/docs/quick_tutorial/ini/development.ini +++ b/docs/quick_tutorial/ini/development.ini @@ -3,4 +3,5 @@ use = egg:tutorial [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/jinja2/development.ini b/docs/quick_tutorial/jinja2/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/jinja2/development.ini +++ b/docs/quick_tutorial/jinja2/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/json/development.ini b/docs/quick_tutorial/json/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/json/development.ini +++ b/docs/quick_tutorial/json/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/logging/development.ini b/docs/quick_tutorial/logging/development.ini index fa22c0c51..62e0c5123 100644 --- a/docs/quick_tutorial/logging/development.ini +++ b/docs/quick_tutorial/logging/development.ini @@ -6,7 +6,8 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 # Begin logging configuration diff --git a/docs/quick_tutorial/more_view_classes/development.ini b/docs/quick_tutorial/more_view_classes/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/more_view_classes/development.ini +++ b/docs/quick_tutorial/more_view_classes/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/request_response/development.ini b/docs/quick_tutorial/request_response/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/request_response/development.ini +++ b/docs/quick_tutorial/request_response/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/routing/development.ini b/docs/quick_tutorial/routing/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/routing/development.ini +++ b/docs/quick_tutorial/routing/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/scaffolds/development.ini b/docs/quick_tutorial/scaffolds/development.ini index a9ad1e60d..b31d06194 100644 --- a/docs/quick_tutorial/scaffolds/development.ini +++ b/docs/quick_tutorial/scaffolds/development.ini @@ -24,7 +24,8 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/quick_tutorial/scaffolds/production.ini b/docs/quick_tutorial/scaffolds/production.ini index 64f04dbec..1418e6bf6 100644 --- a/docs/quick_tutorial/scaffolds/production.ini +++ b/docs/quick_tutorial/scaffolds/production.ini @@ -18,7 +18,8 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/quick_tutorial/sessions/development.ini b/docs/quick_tutorial/sessions/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/sessions/development.ini +++ b/docs/quick_tutorial/sessions/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/static_assets/development.ini b/docs/quick_tutorial/static_assets/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/static_assets/development.ini +++ b/docs/quick_tutorial/static_assets/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/templating/development.ini b/docs/quick_tutorial/templating/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/templating/development.ini +++ b/docs/quick_tutorial/templating/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/unit_testing/development.ini b/docs/quick_tutorial/unit_testing/development.ini index c4b1b3c1d..52b2a3a41 100644 --- a/docs/quick_tutorial/unit_testing/development.ini +++ b/docs/quick_tutorial/unit_testing/development.ini @@ -5,4 +5,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/view_classes/development.ini b/docs/quick_tutorial/view_classes/development.ini index e2b176d9c..4d47e54a5 100644 --- a/docs/quick_tutorial/view_classes/development.ini +++ b/docs/quick_tutorial/view_classes/development.ini @@ -6,4 +6,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/quick_tutorial/views/development.ini b/docs/quick_tutorial/views/development.ini index c4b1b3c1d..52b2a3a41 100644 --- a/docs/quick_tutorial/views/development.ini +++ b/docs/quick_tutorial/views/development.ini @@ -5,4 +5,5 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index 3679f2dcd..6bf4b198e 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini index 41a5f9907..4e9892e7b 100644 --- a/docs/tutorials/wiki/src/authorization/production.ini +++ b/docs/tutorials/wiki/src/authorization/production.ini @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 3679f2dcd..6bf4b198e 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini index 41a5f9907..4e9892e7b 100644 --- a/docs/tutorials/wiki/src/basiclayout/production.ini +++ b/docs/tutorials/wiki/src/basiclayout/production.ini @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/development.ini b/docs/tutorials/wiki/src/installation/development.ini index 3679f2dcd..6bf4b198e 100644 --- a/docs/tutorials/wiki/src/installation/development.ini +++ b/docs/tutorials/wiki/src/installation/development.ini @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/production.ini b/docs/tutorials/wiki/src/installation/production.ini index 41a5f9907..4e9892e7b 100644 --- a/docs/tutorials/wiki/src/installation/production.ini +++ b/docs/tutorials/wiki/src/installation/production.ini @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 3679f2dcd..6bf4b198e 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini index 41a5f9907..4e9892e7b 100644 --- a/docs/tutorials/wiki/src/models/production.ini +++ b/docs/tutorials/wiki/src/models/production.ini @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini index 3679f2dcd..6bf4b198e 100644 --- a/docs/tutorials/wiki/src/tests/development.ini +++ b/docs/tutorials/wiki/src/tests/development.ini @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini index 41a5f9907..4e9892e7b 100644 --- a/docs/tutorials/wiki/src/tests/production.ini +++ b/docs/tutorials/wiki/src/tests/production.ini @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index 3679f2dcd..6bf4b198e 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini index 41a5f9907..4e9892e7b 100644 --- a/docs/tutorials/wiki/src/views/production.ini +++ b/docs/tutorials/wiki/src/views/production.ini @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index 89ee6388b..4a6c9325c 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -29,7 +29,8 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index 4a5023c67..a13a0ca19 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -18,7 +18,8 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 62a7edd48..4a6c9325c 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -29,7 +29,8 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index ac9672654..a13a0ca19 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -18,7 +18,8 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index c15f0a483..22b733e10 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -27,7 +27,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index 215cafbcd..d2ecfe22a 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -16,7 +16,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index c15f0a483..22b733e10 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -27,7 +27,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index 215cafbcd..d2ecfe22a 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -16,7 +16,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index c15f0a483..22b733e10 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -27,7 +27,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index 215cafbcd..d2ecfe22a 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -16,7 +16,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 89ee6388b..4a6c9325c 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -29,7 +29,8 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index 4a5023c67..a13a0ca19 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -18,7 +18,8 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index c15f0a483..22b733e10 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -27,7 +27,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index 215cafbcd..d2ecfe22a 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -16,7 +16,8 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index fd16826cb..f8ee290be 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -26,7 +26,8 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index d6a7c5a7b..4d9f835d4 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -16,7 +16,8 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index 18b2d7a2a..ae9460b11 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -24,7 +24,8 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/production.ini_tmpl b/pyramid/scaffolds/starter/production.ini_tmpl index a55b4d2e0..b2681c71d 100644 --- a/pyramid/scaffolds/starter/production.ini_tmpl +++ b/pyramid/scaffolds/starter/production.ini_tmpl @@ -18,7 +18,8 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index 3f5c3710b..a44b61686 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -29,7 +29,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +host = 127.0.0.1 +port = 6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index 05be225ed..522ff7651 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -24,7 +24,8 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 ### # logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl index d9fd3dd33..4d3a80286 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl @@ -11,7 +11,8 @@ pyramid.includes = pyramid_debugtoolbar [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 # Begin logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl index 5406fca80..931cfa510 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl @@ -10,7 +10,8 @@ pyramid.default_locale_name = en [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +host = 0.0.0.0 +port = 6543 # Begin logging configuration -- cgit v1.2.3 From b4abcd1f596297eb083e855d5e9a158d9e108c81 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 7 Dec 2016 09:43:22 +0100 Subject: Hashing helpers now deal in unicode. Fixed wording. Added link to bcrypt and a footnote from wiki2 example. --- docs/tutorials/wiki/authorization.rst | 16 ++++++++++++---- .../wiki/src/authorization/tutorial/security.py | 6 ++++-- docs/tutorials/wiki/src/tests/tutorial/security.py | 6 ++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 699e34355..523acc53b 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -43,7 +43,7 @@ Add dependencies ~~~~~~~~~~~~~~~~ Just like in :ref:`wiki_defining_views` we need a new dependency. -We need to add the ``bcrypt`` package, to our tutorial package's +We need to add the ``bcrypt`` [1]_ package, to our tutorial package's ``setup.py`` file by assigning this dependency to the ``requires`` parameter in the ``setup()`` function. @@ -81,15 +81,15 @@ request)`` returns ``None``. We will use ``groupfinder()`` as an :term:`authentication policy` "callback" that will provide the :term:`principal` or principals for a user. -There are two helper methods that will help us later when loging-in users. +There are two helper methods that will help us later to authenticate users. The first is ``hash_password`` which takes a raw password and transforms it using -bcrypt into an irreversible representation, a process known as "hashing". The +bcrypt_ into an irreversible representation, a process known as "hashing". The second method, ``check_password``, will allow us to compare the hashed value of the submitted password against the hashed value of the password stored in the user's record. If the two hashed values match, then the submitted password is valid, and we can authenticate the user. -We hash passwords so that it is impossible to decrypt them and use them to +We hash passwords so that it is impossible to decrypt and use them to authenticate in the application. If we stored passwords foolishly in clear text, then anyone with access to the database could retrieve any password to authenticate as any user. @@ -403,3 +403,11 @@ following URLs, checking that the result is as expected: the login form with the ``editor`` credentials), we'll see a Logout link in the upper right hand corner. When we click it, we're logged out, and redirected back to the front page. + + +.. _bcrypt: https://pypi.python.org/pypi/bcrypt + +.. [1] We are using the bcrypt_ package from PyPI to hash our passwords + securely. There are other one-way hash algorithms for passwords if + bcrypt is an issue on your system. Just make sure that it's an + algorithm approved for storing passwords versus a generic one-way hash. diff --git a/docs/tutorials/wiki/src/authorization/tutorial/security.py b/docs/tutorials/wiki/src/authorization/tutorial/security.py index 4115c780c..cbb3acd5d 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/security.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/security.py @@ -2,11 +2,13 @@ import bcrypt def hash_password(pw): - return bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt()) + hashed_pw = bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt()) + # return unicode instead of bytes because databases handle it better + return hashed_pw.decode('utf-8') def check_password(expected_hash, pw): if expected_hash is not None: - return bcrypt.checkpw(pw.encode('utf-8'), expected_hash) + return bcrypt.checkpw(pw.encode('utf-8'), expected_hash.encode('utf-8')) return False USERS = {'editor': hash_password('editor'), diff --git a/docs/tutorials/wiki/src/tests/tutorial/security.py b/docs/tutorials/wiki/src/tests/tutorial/security.py index 4115c780c..cbb3acd5d 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/security.py +++ b/docs/tutorials/wiki/src/tests/tutorial/security.py @@ -2,11 +2,13 @@ import bcrypt def hash_password(pw): - return bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt()) + hashed_pw = bcrypt.hashpw(pw.encode('utf-8'), bcrypt.gensalt()) + # return unicode instead of bytes because databases handle it better + return hashed_pw.decode('utf-8') def check_password(expected_hash, pw): if expected_hash is not None: - return bcrypt.checkpw(pw.encode('utf-8'), expected_hash) + return bcrypt.checkpw(pw.encode('utf-8'), expected_hash.encode('utf-8')) return False USERS = {'editor': hash_password('editor'), -- cgit v1.2.3 From 07e802fa7d6a63a69b31514923f85d6e76dd33e8 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 6 Dec 2016 10:43:22 +0100 Subject: Changed 'host' and 'port' configuration to a new 'listen' style that is now supported by waitress server. --- docs/narr/MyProject/development.ini | 3 +-- docs/narr/MyProject/production.ini | 3 +-- docs/narr/project.rst | 11 +++++------ docs/narr/startup.rst | 4 ++-- docs/quick_tour/package/development.ini | 3 +-- docs/quick_tour/sqla_demo/development.ini | 3 +-- docs/quick_tour/sqla_demo/production.ini | 3 +-- docs/quick_tutorial/authentication/development.ini | 3 +-- docs/quick_tutorial/authorization/development.ini | 3 +-- docs/quick_tutorial/databases/development.ini | 3 +-- docs/quick_tutorial/debugtoolbar/development.ini | 3 +-- docs/quick_tutorial/forms/development.ini | 3 +-- docs/quick_tutorial/functional_testing/development.ini | 3 +-- docs/quick_tutorial/ini/development.ini | 3 +-- docs/quick_tutorial/jinja2/development.ini | 3 +-- docs/quick_tutorial/json/development.ini | 3 +-- docs/quick_tutorial/logging/development.ini | 3 +-- docs/quick_tutorial/more_view_classes/development.ini | 3 +-- docs/quick_tutorial/request_response/development.ini | 3 +-- docs/quick_tutorial/retail_forms/development.ini | 3 +-- docs/quick_tutorial/routing/development.ini | 3 +-- docs/quick_tutorial/scaffolds/development.ini | 3 +-- docs/quick_tutorial/scaffolds/production.ini | 3 +-- docs/quick_tutorial/sessions/development.ini | 3 +-- docs/quick_tutorial/static_assets/development.ini | 3 +-- docs/quick_tutorial/templating/development.ini | 3 +-- docs/quick_tutorial/unit_testing/development.ini | 3 +-- docs/quick_tutorial/view_classes/development.ini | 3 +-- docs/quick_tutorial/views/development.ini | 3 +-- docs/tutorials/wiki/src/authorization/development.ini | 3 +-- docs/tutorials/wiki/src/authorization/production.ini | 3 +-- docs/tutorials/wiki/src/basiclayout/development.ini | 3 +-- docs/tutorials/wiki/src/basiclayout/production.ini | 3 +-- docs/tutorials/wiki/src/installation/development.ini | 3 +-- docs/tutorials/wiki/src/installation/production.ini | 3 +-- docs/tutorials/wiki/src/models/development.ini | 3 +-- docs/tutorials/wiki/src/models/production.ini | 3 +-- docs/tutorials/wiki/src/tests/development.ini | 3 +-- docs/tutorials/wiki/src/tests/production.ini | 3 +-- docs/tutorials/wiki/src/views/development.ini | 3 +-- docs/tutorials/wiki/src/views/production.ini | 3 +-- docs/tutorials/wiki2/src/authentication/development.ini | 3 +-- docs/tutorials/wiki2/src/authentication/production.ini | 3 +-- docs/tutorials/wiki2/src/authorization/development.ini | 3 +-- docs/tutorials/wiki2/src/authorization/production.ini | 3 +-- docs/tutorials/wiki2/src/basiclayout/development.ini | 3 +-- docs/tutorials/wiki2/src/basiclayout/production.ini | 3 +-- docs/tutorials/wiki2/src/installation/development.ini | 3 +-- docs/tutorials/wiki2/src/installation/production.ini | 3 +-- docs/tutorials/wiki2/src/models/development.ini | 3 +-- docs/tutorials/wiki2/src/models/production.ini | 3 +-- docs/tutorials/wiki2/src/tests/development.ini | 3 +-- docs/tutorials/wiki2/src/tests/production.ini | 3 +-- docs/tutorials/wiki2/src/views/development.ini | 3 +-- docs/tutorials/wiki2/src/views/production.ini | 3 +-- pyramid/scaffolds/alchemy/development.ini_tmpl | 3 +-- pyramid/scaffolds/alchemy/production.ini_tmpl | 3 +-- pyramid/scaffolds/starter/development.ini_tmpl | 3 +-- pyramid/scaffolds/starter/production.ini_tmpl | 3 +-- pyramid/scaffolds/zodb/development.ini_tmpl | 3 +-- pyramid/scaffolds/zodb/production.ini_tmpl | 3 +-- .../test_scaffolds/fixture_scaffold/development.ini_tmpl | 3 +-- .../tests/test_scaffolds/fixture_scaffold/production.ini_tmpl | 3 +-- 63 files changed, 68 insertions(+), 130 deletions(-) diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 94fece8ce..42c514794 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -24,8 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 1174b1cc7..3114b9d4d 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -18,8 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 6c42881f4..ec26b880e 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -295,16 +295,15 @@ Here's sample output from a run of ``pserve`` on UNIX: Access is restricted such that only a browser running on the same machine as Pyramid will be able to access your Pyramid application. However, if you want to open access to other machines on the same network, then edit the -``development.ini`` file, and replace the ``host`` value in the -``[server:main]`` section, changing it from ``127.0.0.1`` to ``0.0.0.0``. For +``development.ini`` file, and replace the ``listen`` value in the +``[server:main]`` section, changing it from ``127.0.0.1:6543`` to ``0.0.0.0:6543``. For example: .. code-block:: ini [server:main] use = egg:waitress#main - host = 0.0.0.0 - port = 6543 + listen = 0.0.0.0:6543 Now when you use ``pserve`` to start the application, it will respond to requests on *all* IP addresses possessed by your system, not just requests to @@ -320,8 +319,8 @@ browser by visiting ``http://192.168.1.50:6543/``. You can change the port on which the server runs on by changing the same portion of the ``development.ini`` file. For example, you can change the -``port = 6543`` line in the ``development.ini`` file's ``[server:main]`` -section to ``port = 8080`` to run the server on port 8080 instead of port 6543. +``listen = 127.0.0.1:6543`` line in the ``development.ini`` file's ``[server:main]`` +section to ``listen = 127:0.0.1:8080`` to run the server on port 8080 instead of port 6543. You can shut down a server started this way by pressing ``Ctrl-C`` (or ``Ctrl-Break`` on Windows). diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 3e168eaea..b71cff57d 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -130,8 +130,8 @@ Here's a high-level time-ordered overview of what happens when you press #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the Waitress server (``use = - egg:waitress#main``), and it will listen on all interfaces (``host = - 127.0.0.1``), on port number 6543 (``port = 6543``). The server code itself + egg:waitress#main``), and it will listen on all interfaces (``listen = + 127.0.0.1:6543``), on port number 6543. The server code itself is what prints ``serving on http://127.0.0.1:6543``. The server serves the application, and the application is running, waiting to receive requests. diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini index 20f9817a9..05571183d 100644 --- a/docs/quick_tour/package/development.ini +++ b/docs/quick_tour/package/development.ini @@ -25,8 +25,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini index 0db0950a0..a14402769 100644 --- a/docs/quick_tour/sqla_demo/development.ini +++ b/docs/quick_tour/sqla_demo/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini index 38f3b6318..e0bfd8ea0 100644 --- a/docs/quick_tour/sqla_demo/production.ini +++ b/docs/quick_tour/sqla_demo/production.ini @@ -18,8 +18,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/quick_tutorial/authentication/development.ini b/docs/quick_tutorial/authentication/development.ini index 8a39b2fe7..cbf694b2c 100644 --- a/docs/quick_tutorial/authentication/development.ini +++ b/docs/quick_tutorial/authentication/development.ini @@ -7,5 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/authorization/development.ini b/docs/quick_tutorial/authorization/development.ini index 8a39b2fe7..cbf694b2c 100644 --- a/docs/quick_tutorial/authorization/development.ini +++ b/docs/quick_tutorial/authorization/development.ini @@ -7,5 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 5da87d602..6145b5817 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -9,8 +9,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration diff --git a/docs/quick_tutorial/debugtoolbar/development.ini b/docs/quick_tutorial/debugtoolbar/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/debugtoolbar/development.ini +++ b/docs/quick_tutorial/debugtoolbar/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/forms/development.ini b/docs/quick_tutorial/forms/development.ini index 4d47e54a5..7114a48bb 100644 --- a/docs/quick_tutorial/forms/development.ini +++ b/docs/quick_tutorial/forms/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 \ No newline at end of file diff --git a/docs/quick_tutorial/functional_testing/development.ini b/docs/quick_tutorial/functional_testing/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/functional_testing/development.ini +++ b/docs/quick_tutorial/functional_testing/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/ini/development.ini b/docs/quick_tutorial/ini/development.ini index 8853e2c2b..14dfcd36d 100644 --- a/docs/quick_tutorial/ini/development.ini +++ b/docs/quick_tutorial/ini/development.ini @@ -3,5 +3,4 @@ use = egg:tutorial [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/jinja2/development.ini b/docs/quick_tutorial/jinja2/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/jinja2/development.ini +++ b/docs/quick_tutorial/jinja2/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/json/development.ini b/docs/quick_tutorial/json/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/json/development.ini +++ b/docs/quick_tutorial/json/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/logging/development.ini b/docs/quick_tutorial/logging/development.ini index 62e0c5123..fa22c0c51 100644 --- a/docs/quick_tutorial/logging/development.ini +++ b/docs/quick_tutorial/logging/development.ini @@ -6,8 +6,7 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration diff --git a/docs/quick_tutorial/more_view_classes/development.ini b/docs/quick_tutorial/more_view_classes/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/more_view_classes/development.ini +++ b/docs/quick_tutorial/more_view_classes/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/request_response/development.ini b/docs/quick_tutorial/request_response/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/request_response/development.ini +++ b/docs/quick_tutorial/request_response/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index 4d47e54a5..7114a48bb 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 \ No newline at end of file diff --git a/docs/quick_tutorial/routing/development.ini b/docs/quick_tutorial/routing/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/routing/development.ini +++ b/docs/quick_tutorial/routing/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/scaffolds/development.ini b/docs/quick_tutorial/scaffolds/development.ini index b31d06194..a9ad1e60d 100644 --- a/docs/quick_tutorial/scaffolds/development.ini +++ b/docs/quick_tutorial/scaffolds/development.ini @@ -24,8 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/quick_tutorial/scaffolds/production.ini b/docs/quick_tutorial/scaffolds/production.ini index 1418e6bf6..64f04dbec 100644 --- a/docs/quick_tutorial/scaffolds/production.ini +++ b/docs/quick_tutorial/scaffolds/production.ini @@ -18,8 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/quick_tutorial/sessions/development.ini b/docs/quick_tutorial/sessions/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/sessions/development.ini +++ b/docs/quick_tutorial/sessions/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/static_assets/development.ini b/docs/quick_tutorial/static_assets/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/static_assets/development.ini +++ b/docs/quick_tutorial/static_assets/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/templating/development.ini b/docs/quick_tutorial/templating/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/templating/development.ini +++ b/docs/quick_tutorial/templating/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/unit_testing/development.ini b/docs/quick_tutorial/unit_testing/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/unit_testing/development.ini +++ b/docs/quick_tutorial/unit_testing/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/view_classes/development.ini b/docs/quick_tutorial/view_classes/development.ini index 4d47e54a5..e2b176d9c 100644 --- a/docs/quick_tutorial/view_classes/development.ini +++ b/docs/quick_tutorial/view_classes/development.ini @@ -6,5 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/views/development.ini b/docs/quick_tutorial/views/development.ini index 52b2a3a41..c4b1b3c1d 100644 --- a/docs/quick_tutorial/views/development.ini +++ b/docs/quick_tutorial/views/development.ini @@ -5,5 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/authorization/production.ini +++ b/docs/tutorials/wiki/src/authorization/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/basiclayout/production.ini +++ b/docs/tutorials/wiki/src/basiclayout/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/development.ini b/docs/tutorials/wiki/src/installation/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/installation/development.ini +++ b/docs/tutorials/wiki/src/installation/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/production.ini b/docs/tutorials/wiki/src/installation/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/installation/production.ini +++ b/docs/tutorials/wiki/src/installation/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/models/production.ini +++ b/docs/tutorials/wiki/src/models/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/tests/development.ini +++ b/docs/tutorials/wiki/src/tests/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/tests/production.ini +++ b/docs/tutorials/wiki/src/tests/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index 6bf4b198e..3679f2dcd 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini index 4e9892e7b..41a5f9907 100644 --- a/docs/tutorials/wiki/src/views/production.ini +++ b/docs/tutorials/wiki/src/views/production.ini @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index 4a6c9325c..89ee6388b 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -29,8 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index a13a0ca19..4a5023c67 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -18,8 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 4a6c9325c..62a7edd48 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -29,8 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index a13a0ca19..ac9672654 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -18,8 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 4a6c9325c..89ee6388b 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -29,8 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index a13a0ca19..4a5023c67 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -18,8 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index 22b733e10..c15f0a483 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -27,8 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +list = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index d2ecfe22a..215cafbcd 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +list = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index f8ee290be..fd16826cb 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -26,8 +26,7 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index 4d9f835d4..d6a7c5a7b 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -16,8 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index ae9460b11..18b2d7a2a 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -24,8 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/production.ini_tmpl b/pyramid/scaffolds/starter/production.ini_tmpl index b2681c71d..a55b4d2e0 100644 --- a/pyramid/scaffolds/starter/production.ini_tmpl +++ b/pyramid/scaffolds/starter/production.ini_tmpl @@ -18,8 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index a44b61686..3f5c3710b 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -29,8 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 127.0.0.1 -port = 6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index 522ff7651..05be225ed 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -24,8 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl index 4d3a80286..d9fd3dd33 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl @@ -11,8 +11,7 @@ pyramid.includes = pyramid_debugtoolbar [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl index 931cfa510..5406fca80 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl @@ -10,8 +10,7 @@ pyramid.default_locale_name = en [server:main] use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 +listen = 0.0.0.0:6543 # Begin logging configuration -- cgit v1.2.3 From 3588e811df0efe16642fee427a2988af9f4e4b6e Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 7 Dec 2016 10:39:41 +0100 Subject: fixed 'list' to 'listen' --- CHANGES.txt | 3 +++ CONTRIBUTORS.txt | 2 ++ docs/quick_tutorial/forms/development.ini | 2 +- docs/quick_tutorial/retail_forms/development.ini | 2 +- docs/tutorials/wiki2/src/authentication/development.ini | 2 +- docs/tutorials/wiki2/src/authentication/production.ini | 2 +- docs/tutorials/wiki2/src/basiclayout/development.ini | 2 +- docs/tutorials/wiki2/src/basiclayout/production.ini | 2 +- docs/tutorials/wiki2/src/installation/development.ini | 2 +- docs/tutorials/wiki2/src/installation/production.ini | 2 +- docs/tutorials/wiki2/src/models/development.ini | 2 +- docs/tutorials/wiki2/src/models/production.ini | 2 +- docs/tutorials/wiki2/src/tests/development.ini | 2 +- docs/tutorials/wiki2/src/tests/production.ini | 2 +- docs/tutorials/wiki2/src/views/development.ini | 2 +- docs/tutorials/wiki2/src/views/production.ini | 2 +- 16 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 65a1f15cd..65df2c7c5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -39,6 +39,9 @@ Backward Incompatibilities (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. See https://github.com/Pylons/pyramid/pull/2823 +- Scaffolds, documentation and tutorials now use ``listen`` option instead + of ``host`` and ``port`` to configure Waitress server. + Features -------- diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b4e30e085..90da9e074 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -288,3 +288,5 @@ Contributors - Moriyoshi Koizumi, 2016/11/20 - Mikko Ohtamaa, 2016/12/6 + +- Martin Frlin, 2016/12/7 diff --git a/docs/quick_tutorial/forms/development.ini b/docs/quick_tutorial/forms/development.ini index 7114a48bb..e2b176d9c 100644 --- a/docs/quick_tutorial/forms/development.ini +++ b/docs/quick_tutorial/forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 \ No newline at end of file +listen = 0.0.0.0:6543 diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index 7114a48bb..e2b176d9c 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 \ No newline at end of file +listen = 0.0.0.0:6543 diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index 89ee6388b..62a7edd48 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -29,7 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index 4a5023c67..ac9672654 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -18,7 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index c15f0a483..c30a31988 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index 215cafbcd..86d2db46f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index c15f0a483..c30a31988 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index 215cafbcd..86d2db46f 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index c15f0a483..c30a31988 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index 215cafbcd..86d2db46f 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 89ee6388b..62a7edd48 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -29,7 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index 4a5023c67..ac9672654 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -18,7 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +listen = 0.0.0.0:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index c15f0a483..c30a31988 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 127.0.0.1:6543 +listen = 127.0.0.1:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index 215cafbcd..86d2db46f 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -list = 0.0.0.0:6543 +listen = 0.0.0.0:6543 ### # logging configuration -- cgit v1.2.3 From fad00d3201d9debd8abc146355a82d9adb6d823e Mon Sep 17 00:00:00 2001 From: Nejc Zupan Date: Wed, 7 Dec 2016 14:38:32 +0100 Subject: bring wiki2 test coverage up to 100%, refs #2451 --- .../src/tests/tutorial/scripts/initializedb.py | 1 + .../src/tests/tutorial/tests/test_functional.py | 12 ++++ .../wiki2/src/tests/tutorial/tests/test_initdb.py | 20 +++++++ .../src/tests/tutorial/tests/test_security.py | 21 +++++++ .../src/tests/tutorial/tests/test_user_model.py | 67 ++++++++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py create mode 100644 docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py diff --git a/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py index f3c0a6fef..c860ef8cf 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/scripts/initializedb.py @@ -28,6 +28,7 @@ def usage(argv): def main(argv=sys.argv): if len(argv) < 2: usage(argv) + return config_uri = argv[1] options = parse_vars(argv[2:]) setup_logging(config_uri) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py index 715768b2e..0250e71c9 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py @@ -11,6 +11,9 @@ class FunctionalTests(unittest.TestCase): basic_wrong_login = ( '/login?login=basic&password=incorrect' '&next=FrontPage&form.submitted=Login') + basic_login_no_next = ( + '/login?login=basic&password=basic' + '&form.submitted=Login') editor_login = ( '/login?login=editor&password=editor' '&next=FrontPage&form.submitted=Login') @@ -68,6 +71,10 @@ class FunctionalTests(unittest.TestCase): res = self.testapp.get(self.basic_login, status=302) self.assertEqual(res.location, 'http://localhost/FrontPage') + def test_successful_log_in_no_next(self): + res = self.testapp.get(self.basic_login_no_next, status=302) + self.assertEqual(res.location, 'http://localhost/') + def test_failed_log_in(self): res = self.testapp.get(self.basic_wrong_login, status=200) self.assertTrue(b'login' in res.body) @@ -120,3 +127,8 @@ class FunctionalTests(unittest.TestCase): self.testapp.get(self.editor_login, status=302) res = self.testapp.get('/FrontPage', status=200) self.assertTrue(b'FrontPage' in res.body) + + def test_redirect_to_edit_for_existing_page(self): + self.testapp.get(self.editor_login, status=302) + res = self.testapp.get('/add_page/FrontPage', status=302) + self.assertTrue(b'FrontPage' in res.body) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py new file mode 100644 index 000000000..97511d5e8 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py @@ -0,0 +1,20 @@ +import mock +import unittest + + +class TestInitializeDB(unittest.TestCase): + + @mock.patch('tutorial.scripts.initializedb.sys') + def test_usage(self, mocked_sys): + from ..scripts.initializedb import main + main(argv=['foo']) + mocked_sys.exit.assert_called_with(1) + + @mock.patch('tutorial.scripts.initializedb.get_tm_session') + @mock.patch('tutorial.scripts.initializedb.sys') + def test_run(self, mocked_sys, mocked_session): + from ..scripts.initializedb import main + main(argv=['foo', 'development.ini']) + mocked_session.assert_called_once() + + diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py new file mode 100644 index 000000000..4c3b72946 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py @@ -0,0 +1,21 @@ +import mock +import unittest + + +class TestMyAuthenticationPolicy(unittest.TestCase): + + def test_no_user(self): + request = mock.Mock() + request.user = None + + from ..security import MyAuthenticationPolicy + policy = MyAuthenticationPolicy(None) + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_user(self): + request = mock.Mock() + request.user.id = 'foo' + + from ..security import MyAuthenticationPolicy + policy = MyAuthenticationPolicy(None) + self.assertEqual(policy.authenticated_userid(request), 'foo') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py new file mode 100644 index 000000000..9490ac990 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py @@ -0,0 +1,67 @@ +import unittest +import transaction + +from pyramid import testing + + +class BaseTest(unittest.TestCase): + + def setUp(self): + from ..models import get_tm_session + self.config = testing.setUp(settings={ + 'sqlalchemy.url': 'sqlite:///:memory:' + }) + self.config.include('..models') + self.config.include('..routes') + + session_factory = self.config.registry['dbsession_factory'] + self.session = get_tm_session(session_factory, transaction.manager) + + self.init_database() + + def init_database(self): + from ..models.meta import Base + session_factory = self.config.registry['dbsession_factory'] + engine = session_factory.kw['bind'] + Base.metadata.create_all(engine) + + def tearDown(self): + testing.tearDown() + transaction.abort() + + def makeUser(self, name, role): + from ..models import User + return User(name=name, role=role) + + +class TestSetPassword(BaseTest): + + def test_password_hash_saved(self): + user = self.makeUser(name='foo', role='bar') + self.assertFalse(user.password_hash) + + user.set_password('secret') + self.assertTrue(user.password_hash) + + +class TestCheckPassword(BaseTest): + + def test_password_hash_not_set(self): + user = self.makeUser(name='foo', role='bar') + self.assertFalse(user.password_hash) + + self.assertFalse(user.check_password('secret')) + + def test_correct_password(self): + user = self.makeUser(name='foo', role='bar') + user.set_password('secret') + self.assertTrue(user.password_hash) + + self.assertTrue(user.check_password('secret')) + + def test_incorrect_password(self): + user = self.makeUser(name='foo', role='bar') + user.set_password('secret') + self.assertTrue(user.password_hash) + + self.assertFalse(user.check_password('incorrect')) -- cgit v1.2.3 From cfbc73dc042d924503527add9b32c48aa3ba29bd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Dec 2016 03:25:24 -0800 Subject: update typographical conventions per @bertjwregeer --- docs/typographical-conventions.rst | 89 -------------------------------------- 1 file changed, 89 deletions(-) diff --git a/docs/typographical-conventions.rst b/docs/typographical-conventions.rst index 5c7efea31..19894775b 100644 --- a/docs/typographical-conventions.rst +++ b/docs/typographical-conventions.rst @@ -28,32 +28,6 @@ A glossary defines terms used throughout the documentation. References to glossa Note it is hyperlinked, and when clicked it will take the user to the term in the Glossary and highlight the term. -.. _typographical-conventions-headings: - -Headings --------- - -Sections, sub-sections, and sub-sub-sections within a web page or chapter are denoted with headings at various levels. The immediately preceding heading "Headings" is a section heading. Sub-section and sub-sub-section headings are shown as follows. - -Heading Level 2 -^^^^^^^^^^^^^^^ - -sub-section - -Heading Level 3 -""""""""""""""" - -sub-sub-section - - -.. _typographical-conventions-paragraphs: - -Paragraphs ----------- - -A paragraph of text looks exactly like this paragraph. - - .. _typographical-conventions-links: Links @@ -202,53 +176,6 @@ Inline code is displayed as follows, where the inline code is 'pip install -e ". Install requirements for building documentation: ``pip install -e ".[docs]"`` -.. _typographical-conventions-lists: - -Lists ------ - -Bulleted lists display as follows. - -* This is an item in a bulleted list. -* This is another item in a bulleted list. - -Numbered lists display as follows. - -#. This is an item in a numbered list. -#. This is another item in a numbered list. - -Nested lists display as follows. - -#. This is a list item in the parent list. -#. This is another list item in the parent list. - - #. This is a list item in the child list. - #. This is another list item in the child list. - -#. This is one more list item in the parent list. - - -.. _typographical-conventions-tables: - -Tables ------- - -Tables display as follows. - -===== ===== -col 1 col 2 -===== ===== -1 Second column of row 1. -2 Second column of row 2. - Second line of paragraph. -3 * Second column of row 3. - - * Second item in bullet - list (row 3, column 2). -\ Row 4; column 1 will be empty. -===== ===== - - .. _typographical-conventions-feature-versioning: Feature versioning @@ -350,22 +277,6 @@ Todo items designated tasks that require further work. This is a todo item. -.. _typographical-conventions-italics: - -Italics -------- - -This *word* is italicized. - - -.. _typographical-conventions-strong: - -Strong ------- - -This **word** is in bold text. - - .. _typographical-conventions-cross-references: Cross-references -- cgit v1.2.3 From 11d637f45e90c011ce15f7e016e909f0f300c705 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Dec 2016 03:50:59 -0800 Subject: add fixes for Sphinx 1.5 --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 0e3f03068..12dd27722 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -196,10 +196,10 @@ latex_documents = [ # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -latex_use_parts = True +latex_toplevel_sectioning = "section" # If false, no module index is generated. -latex_use_modindex = False +latex_domain_indices = False ## Say, for a moment that you have a twoside document that needs a 3cm ## inner margin to allow for binding and at least two centimetres the -- cgit v1.2.3 From 3adaf31276f9c671ec469dee7dd115723f1eec3b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Dec 2016 23:06:26 -0800 Subject: minor grammar and style fixes for wiki/authorization --- docs/tutorials/wiki/authorization.rst | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 523acc53b..67af83b25 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -18,7 +18,7 @@ require permission, instead of a default "403 Forbidden" page. We will implement the access control with the following steps: -* Add password hashing dependencies +* Add password hashing dependencies. * Add users and groups (``security.py``, a new module). * Add an :term:`ACL` (``models.py``). * Add an :term:`authentication policy` and an :term:`authorization policy` @@ -39,13 +39,11 @@ Then we will add the login and logout feature: Access control -------------- + Add dependencies ~~~~~~~~~~~~~~~~ -Just like in :ref:`wiki_defining_views` we need a new dependency. -We need to add the ``bcrypt`` [1]_ package, to our tutorial package's -``setup.py`` file by assigning this dependency to the ``requires`` parameter -in the ``setup()`` function. +Just like in :ref:`wiki_defining_views`, we need a new dependency. We need to add the `bcrypt `_ package, to our tutorial package's ``setup.py`` file by assigning this dependency to the ``requires`` parameter in the ``setup()`` function. Open ``setup.py`` and edit it to look like the following: @@ -58,11 +56,15 @@ Only the highlighted line needs to be added. Do not forget to run ``pip install -e .`` just like in :ref:`wiki-running-pip-install`. +.. note:: + + We are using the ``bcrypt`` package from PyPI to hash our passwords securely. There are other one-way hash algorithms for passwords if bcrypt is an issue on your system. Just make sure that it's an algorithm approved for storing passwords versus a generic one-way hash. + + Add users and groups ~~~~~~~~~~~~~~~~~~~~ -Create a new ``tutorial/security.py`` module with the -following content: +Create a new ``tutorial/security.py`` module with the following content: .. literalinclude:: src/authorization/tutorial/security.py :linenos: @@ -83,7 +85,7 @@ request)`` returns ``None``. We will use ``groupfinder()`` as an There are two helper methods that will help us later to authenticate users. The first is ``hash_password`` which takes a raw password and transforms it using -bcrypt_ into an irreversible representation, a process known as "hashing". The +bcrypt into an irreversible representation, a process known as "hashing". The second method, ``check_password``, will allow us to compare the hashed value of the submitted password against the hashed value of the password stored in the user's record. If the two hashed values match, then the submitted @@ -403,11 +405,3 @@ following URLs, checking that the result is as expected: the login form with the ``editor`` credentials), we'll see a Logout link in the upper right hand corner. When we click it, we're logged out, and redirected back to the front page. - - -.. _bcrypt: https://pypi.python.org/pypi/bcrypt - -.. [1] We are using the bcrypt_ package from PyPI to hash our passwords - securely. There are other one-way hash algorithms for passwords if - bcrypt is an issue on your system. Just make sure that it's an - algorithm approved for storing passwords versus a generic one-way hash. -- cgit v1.2.3 From fb17a37442224961e4bd3d797945d130221acfb9 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 9 Dec 2016 12:46:33 +0100 Subject: Added configuration for ipv6 in .ini files. --- docs/narr/MyProject/development.ini | 2 +- docs/narr/MyProject/production.ini | 2 +- docs/narr/project.rst | 17 ++++++++++------- docs/narr/startup.rst | 6 ++++-- docs/quick_tour/package/development.ini | 2 +- docs/quick_tour/sqla_demo/development.ini | 2 +- docs/quick_tour/sqla_demo/production.ini | 2 +- docs/quick_tutorial/authentication/development.ini | 2 +- docs/quick_tutorial/authorization/development.ini | 2 +- docs/quick_tutorial/databases/development.ini | 2 +- docs/quick_tutorial/debugtoolbar/development.ini | 2 +- docs/quick_tutorial/forms/development.ini | 2 +- docs/quick_tutorial/functional_testing/development.ini | 2 +- docs/quick_tutorial/ini/development.ini | 2 +- docs/quick_tutorial/jinja2/development.ini | 2 +- docs/quick_tutorial/json/development.ini | 2 +- docs/quick_tutorial/logging/development.ini | 2 +- docs/quick_tutorial/more_view_classes/development.ini | 2 +- docs/quick_tutorial/request_response/development.ini | 2 +- docs/quick_tutorial/retail_forms/development.ini | 2 +- docs/quick_tutorial/routing/development.ini | 2 +- docs/quick_tutorial/scaffolds/development.ini | 2 +- docs/quick_tutorial/scaffolds/production.ini | 2 +- docs/quick_tutorial/sessions/development.ini | 2 +- docs/quick_tutorial/static_assets/development.ini | 2 +- docs/quick_tutorial/templating/development.ini | 2 +- docs/quick_tutorial/unit_testing/development.ini | 2 +- docs/quick_tutorial/view_classes/development.ini | 2 +- docs/quick_tutorial/views/development.ini | 2 +- docs/tutorials/wiki/src/authorization/development.ini | 2 +- docs/tutorials/wiki/src/authorization/production.ini | 2 +- docs/tutorials/wiki/src/basiclayout/development.ini | 2 +- docs/tutorials/wiki/src/basiclayout/production.ini | 2 +- docs/tutorials/wiki/src/installation/development.ini | 2 +- docs/tutorials/wiki/src/installation/production.ini | 2 +- docs/tutorials/wiki/src/models/development.ini | 2 +- docs/tutorials/wiki/src/models/production.ini | 2 +- docs/tutorials/wiki/src/tests/development.ini | 2 +- docs/tutorials/wiki/src/tests/production.ini | 2 +- docs/tutorials/wiki/src/views/development.ini | 2 +- docs/tutorials/wiki/src/views/production.ini | 2 +- docs/tutorials/wiki2/src/authentication/development.ini | 2 +- docs/tutorials/wiki2/src/authentication/production.ini | 2 +- docs/tutorials/wiki2/src/authorization/development.ini | 2 +- docs/tutorials/wiki2/src/authorization/production.ini | 2 +- docs/tutorials/wiki2/src/basiclayout/development.ini | 2 +- docs/tutorials/wiki2/src/basiclayout/production.ini | 2 +- docs/tutorials/wiki2/src/installation/development.ini | 2 +- docs/tutorials/wiki2/src/installation/production.ini | 2 +- docs/tutorials/wiki2/src/models/development.ini | 2 +- docs/tutorials/wiki2/src/models/production.ini | 2 +- docs/tutorials/wiki2/src/tests/development.ini | 2 +- docs/tutorials/wiki2/src/tests/production.ini | 2 +- docs/tutorials/wiki2/src/views/development.ini | 2 +- docs/tutorials/wiki2/src/views/production.ini | 2 +- pyramid/scaffolds/alchemy/development.ini_tmpl | 2 +- pyramid/scaffolds/alchemy/production.ini_tmpl | 2 +- pyramid/scaffolds/starter/development.ini_tmpl | 2 +- pyramid/scaffolds/starter/production.ini_tmpl | 2 +- pyramid/scaffolds/zodb/development.ini_tmpl | 2 +- pyramid/scaffolds/zodb/production.ini_tmpl | 2 +- .../fixture_scaffold/development.ini_tmpl | 2 +- .../test_scaffolds/fixture_scaffold/production.ini_tmpl | 2 +- 63 files changed, 75 insertions(+), 70 deletions(-) diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 42c514794..3a83dcfac 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -24,7 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 3114b9d4d..c48ca6d9b 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -18,7 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ec26b880e..e2e0f6411 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -290,20 +290,22 @@ Here's sample output from a run of ``pserve`` on UNIX: $ $VENV/bin/pserve development.ini Starting server in PID 16208. - serving on http://127.0.0.1:6543 + Serving on http://127.0.0.1:6543 + Serving on http://[::1]:6543 + Access is restricted such that only a browser running on the same machine as Pyramid will be able to access your Pyramid application. However, if you want to open access to other machines on the same network, then edit the ``development.ini`` file, and replace the ``listen`` value in the -``[server:main]`` section, changing it from ``127.0.0.1:6543`` to ``0.0.0.0:6543``. For -example: +``[server:main]`` section, changing it from ``127.0.0.1:6543 [::1]:6543`` to ``*:6543`` +(this is equivalent to ``0.0.0.0:6543 [::]:6543``). For example: .. code-block:: ini [server:main] use = egg:waitress#main - listen = 0.0.0.0:6543 + listen = *:6543 Now when you use ``pserve`` to start the application, it will respond to requests on *all* IP addresses possessed by your system, not just requests to @@ -315,12 +317,13 @@ the case, if you use a browser running on the same system as Pyramid, it will be able to access the application via ``http://127.0.0.1:6543/`` as well as via ``http://192.168.1.50:6543/``. However, *other people* on other computers on the same network will also be able to visit your Pyramid application in their -browser by visiting ``http://192.168.1.50:6543/``. +browser by visiting ``http://192.168.1.50:6543/``. Same holds true if you use +ipv6. ``[::]`` means the same as ``0.0.0.0`` but for ipv6 protocol. You can change the port on which the server runs on by changing the same portion of the ``development.ini`` file. For example, you can change the -``listen = 127.0.0.1:6543`` line in the ``development.ini`` file's ``[server:main]`` -section to ``listen = 127:0.0.1:8080`` to run the server on port 8080 instead of port 6543. +``listen = 127.0.0.1:6543 [::1]:6543`` line in the ``development.ini`` file's ``[server:main]`` +section to ``listen = 127:0.0.1:8080 [::1]:8080`` to run the server on port 8080 instead of port 6543. You can shut down a server started this way by pressing ``Ctrl-C`` (or ``Ctrl-Break`` on Windows). diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index b71cff57d..691a56da6 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -10,7 +10,8 @@ you'll see something much like this show up on the console: $ $VENV/bin/pserve development.ini Starting server in PID 16305. - serving on http://127.0.0.1:6543 + Serving on http://127.0.0.1:6543 + Serving on http://[::1]:6543 This chapter explains what happens between the time you press the "Return" key on your keyboard after typing ``pserve development.ini`` and the time the line @@ -131,7 +132,8 @@ Here's a high-level time-ordered overview of what happens when you press #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the Waitress server (``use = egg:waitress#main``), and it will listen on all interfaces (``listen = - 127.0.0.1:6543``), on port number 6543. The server code itself + 127.0.0.1:6543 [::1]:6543``, means that it will listen on ipv4 and ipv6), + on port number 6543. The server code itself is what prints ``serving on http://127.0.0.1:6543``. The server serves the application, and the application is running, waiting to receive requests. diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini index 05571183d..d00368686 100644 --- a/docs/quick_tour/package/development.ini +++ b/docs/quick_tour/package/development.ini @@ -25,7 +25,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini index a14402769..918c26cfa 100644 --- a/docs/quick_tour/sqla_demo/development.ini +++ b/docs/quick_tour/sqla_demo/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini index e0bfd8ea0..f4e535d46 100644 --- a/docs/quick_tour/sqla_demo/production.ini +++ b/docs/quick_tour/sqla_demo/production.ini @@ -18,7 +18,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/quick_tutorial/authentication/development.ini b/docs/quick_tutorial/authentication/development.ini index cbf694b2c..7665b90a4 100644 --- a/docs/quick_tutorial/authentication/development.ini +++ b/docs/quick_tutorial/authentication/development.ini @@ -7,4 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/authorization/development.ini b/docs/quick_tutorial/authorization/development.ini index cbf694b2c..7665b90a4 100644 --- a/docs/quick_tutorial/authorization/development.ini +++ b/docs/quick_tutorial/authorization/development.ini @@ -7,4 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index 6145b5817..f6e903d37 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -9,7 +9,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 # Begin logging configuration diff --git a/docs/quick_tutorial/debugtoolbar/development.ini b/docs/quick_tutorial/debugtoolbar/development.ini index c4b1b3c1d..e84d29665 100644 --- a/docs/quick_tutorial/debugtoolbar/development.ini +++ b/docs/quick_tutorial/debugtoolbar/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/forms/development.ini b/docs/quick_tutorial/forms/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/forms/development.ini +++ b/docs/quick_tutorial/forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/functional_testing/development.ini b/docs/quick_tutorial/functional_testing/development.ini index c4b1b3c1d..e84d29665 100644 --- a/docs/quick_tutorial/functional_testing/development.ini +++ b/docs/quick_tutorial/functional_testing/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/ini/development.ini b/docs/quick_tutorial/ini/development.ini index 14dfcd36d..4f0991fad 100644 --- a/docs/quick_tutorial/ini/development.ini +++ b/docs/quick_tutorial/ini/development.ini @@ -3,4 +3,4 @@ use = egg:tutorial [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/jinja2/development.ini b/docs/quick_tutorial/jinja2/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/jinja2/development.ini +++ b/docs/quick_tutorial/jinja2/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/json/development.ini b/docs/quick_tutorial/json/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/json/development.ini +++ b/docs/quick_tutorial/json/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/logging/development.ini b/docs/quick_tutorial/logging/development.ini index fa22c0c51..5e8e65a7c 100644 --- a/docs/quick_tutorial/logging/development.ini +++ b/docs/quick_tutorial/logging/development.ini @@ -6,7 +6,7 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 # Begin logging configuration diff --git a/docs/quick_tutorial/more_view_classes/development.ini b/docs/quick_tutorial/more_view_classes/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/more_view_classes/development.ini +++ b/docs/quick_tutorial/more_view_classes/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/request_response/development.ini b/docs/quick_tutorial/request_response/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/request_response/development.ini +++ b/docs/quick_tutorial/request_response/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/routing/development.ini b/docs/quick_tutorial/routing/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/routing/development.ini +++ b/docs/quick_tutorial/routing/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/scaffolds/development.ini b/docs/quick_tutorial/scaffolds/development.ini index a9ad1e60d..0f562d0e1 100644 --- a/docs/quick_tutorial/scaffolds/development.ini +++ b/docs/quick_tutorial/scaffolds/development.ini @@ -24,7 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/quick_tutorial/scaffolds/production.ini b/docs/quick_tutorial/scaffolds/production.ini index 64f04dbec..bf0446a47 100644 --- a/docs/quick_tutorial/scaffolds/production.ini +++ b/docs/quick_tutorial/scaffolds/production.ini @@ -18,7 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/quick_tutorial/sessions/development.ini b/docs/quick_tutorial/sessions/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/sessions/development.ini +++ b/docs/quick_tutorial/sessions/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/static_assets/development.ini b/docs/quick_tutorial/static_assets/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/static_assets/development.ini +++ b/docs/quick_tutorial/static_assets/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/templating/development.ini b/docs/quick_tutorial/templating/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/templating/development.ini +++ b/docs/quick_tutorial/templating/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/unit_testing/development.ini b/docs/quick_tutorial/unit_testing/development.ini index c4b1b3c1d..e84d29665 100644 --- a/docs/quick_tutorial/unit_testing/development.ini +++ b/docs/quick_tutorial/unit_testing/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/view_classes/development.ini b/docs/quick_tutorial/view_classes/development.ini index e2b176d9c..d5436148d 100644 --- a/docs/quick_tutorial/view_classes/development.ini +++ b/docs/quick_tutorial/view_classes/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/quick_tutorial/views/development.ini b/docs/quick_tutorial/views/development.ini index c4b1b3c1d..e84d29665 100644 --- a/docs/quick_tutorial/views/development.ini +++ b/docs/quick_tutorial/views/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index 3679f2dcd..78542a1d5 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini index 41a5f9907..0c6aa152b 100644 --- a/docs/tutorials/wiki/src/authorization/production.ini +++ b/docs/tutorials/wiki/src/authorization/production.ini @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 3679f2dcd..78542a1d5 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini index 41a5f9907..0c6aa152b 100644 --- a/docs/tutorials/wiki/src/basiclayout/production.ini +++ b/docs/tutorials/wiki/src/basiclayout/production.ini @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/development.ini b/docs/tutorials/wiki/src/installation/development.ini index 3679f2dcd..78542a1d5 100644 --- a/docs/tutorials/wiki/src/installation/development.ini +++ b/docs/tutorials/wiki/src/installation/development.ini @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/installation/production.ini b/docs/tutorials/wiki/src/installation/production.ini index 41a5f9907..0c6aa152b 100644 --- a/docs/tutorials/wiki/src/installation/production.ini +++ b/docs/tutorials/wiki/src/installation/production.ini @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 3679f2dcd..78542a1d5 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini index 41a5f9907..0c6aa152b 100644 --- a/docs/tutorials/wiki/src/models/production.ini +++ b/docs/tutorials/wiki/src/models/production.ini @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini index 3679f2dcd..78542a1d5 100644 --- a/docs/tutorials/wiki/src/tests/development.ini +++ b/docs/tutorials/wiki/src/tests/development.ini @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini index 41a5f9907..0c6aa152b 100644 --- a/docs/tutorials/wiki/src/tests/production.ini +++ b/docs/tutorials/wiki/src/tests/production.ini @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index 3679f2dcd..78542a1d5 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini index 41a5f9907..0c6aa152b 100644 --- a/docs/tutorials/wiki/src/views/production.ini +++ b/docs/tutorials/wiki/src/views/production.ini @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index 62a7edd48..a767a0e6f 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -29,7 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index ac9672654..f27dc09d4 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -18,7 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 62a7edd48..a767a0e6f 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -29,7 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index ac9672654..f27dc09d4 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -18,7 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index c30a31988..252398692 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index 86d2db46f..5f1fae07c 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index c30a31988..252398692 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index 86d2db46f..5f1fae07c 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index c30a31988..252398692 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index 86d2db46f..5f1fae07c 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 62a7edd48..a767a0e6f 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -29,7 +29,7 @@ auth.secret = seekrit [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index ac9672654..f27dc09d4 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -18,7 +18,7 @@ auth.secret = real-seekrit [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index c30a31988..252398692 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index 86d2db46f..5f1fae07c 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index fd16826cb..64ac5ab6c 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -26,7 +26,7 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index d6a7c5a7b..afc1c8f0a 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -16,7 +16,7 @@ sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index 18b2d7a2a..de58ea63e 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -24,7 +24,7 @@ pyramid.includes = [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration diff --git a/pyramid/scaffolds/starter/production.ini_tmpl b/pyramid/scaffolds/starter/production.ini_tmpl index a55b4d2e0..8f0ae66ed 100644 --- a/pyramid/scaffolds/starter/production.ini_tmpl +++ b/pyramid/scaffolds/starter/production.ini_tmpl @@ -18,7 +18,7 @@ pyramid.default_locale_name = en [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index 3f5c3710b..852c42fc6 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 127.0.0.1:6543 +listen = [::1]:6543 ### # logging configuration diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index 05be225ed..dbfc634f8 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -24,7 +24,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = 0.0.0.0:6543 +listen = *:6543 ### # logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl index d9fd3dd33..01c504f99 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl @@ -11,7 +11,7 @@ pyramid.includes = pyramid_debugtoolbar [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 # Begin logging configuration diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl index 5406fca80..becd3aa76 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl @@ -10,7 +10,7 @@ pyramid.default_locale_name = en [server:main] use = egg:pyramid#wsgiref -listen = 0.0.0.0:6543 +listen = *:6543 # Begin logging configuration -- cgit v1.2.3 From 7c777964bd2991e2940be2c3be63263b9d4ee2d8 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 9 Dec 2016 12:56:44 +0100 Subject: fixing missing ipv4 --- pyramid/scaffolds/zodb/development.ini_tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index 852c42fc6..a155590f8 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -29,7 +29,7 @@ zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 [server:main] use = egg:waitress#main -listen = [::1]:6543 +listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -- cgit v1.2.3 From 3c5731a1cac958e05093df56263d52433fc683a9 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 9 Dec 2016 14:21:23 +0100 Subject: grammar fixes --- docs/narr/project.rst | 4 ++-- docs/narr/startup.rst | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index e2e0f6411..9b0d54ec7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -317,8 +317,8 @@ the case, if you use a browser running on the same system as Pyramid, it will be able to access the application via ``http://127.0.0.1:6543/`` as well as via ``http://192.168.1.50:6543/``. However, *other people* on other computers on the same network will also be able to visit your Pyramid application in their -browser by visiting ``http://192.168.1.50:6543/``. Same holds true if you use -ipv6. ``[::]`` means the same as ``0.0.0.0`` but for ipv6 protocol. +browser by visiting ``http://192.168.1.50:6543/``. The same holds true if you use +IPv6. ``[::]`` means the same as ``0.0.0.0`` but for IPv6 protocol. You can change the port on which the server runs on by changing the same portion of the ``development.ini`` file. For example, you can change the diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 691a56da6..1be8037a3 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -131,11 +131,10 @@ Here's a high-level time-ordered overview of what happens when you press #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the Waitress server (``use = - egg:waitress#main``), and it will listen on all interfaces (``listen = - 127.0.0.1:6543 [::1]:6543``, means that it will listen on ipv4 and ipv6), - on port number 6543. The server code itself - is what prints ``serving on http://127.0.0.1:6543``. The server serves the - application, and the application is running, waiting to receive requests. + egg:waitress#main``), and it will listen on all interfaces on port 6543 + for both IPv4 and IPv6 (``listen = 127.0.0.1:6543 [::1]:6543``). The server + code itself is what prints ``serving on http://127.0.0.1:6543``. The server + serves the application, and the application is running, waiting to receive requests. .. seealso:: Logging configuration is described in the :ref:`logging_chapter` chapter. -- cgit v1.2.3 From 40ab35b67d2b563b096d99941b0ddb0aedd47524 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Fri, 9 Dec 2016 17:34:15 +0200 Subject: Fix typo --- docs/whatsnew-1.7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/whatsnew-1.7.rst b/docs/whatsnew-1.7.rst index 398b12f01..c5f611f04 100644 --- a/docs/whatsnew-1.7.rst +++ b/docs/whatsnew-1.7.rst @@ -126,7 +126,7 @@ Feature Additions - The :attr:`pyramid.tweens.EXCVIEW` tween will now re-raise the original exception if no exception view could be found to handle it. This allows - the exception to be handled upstream by another tween or middelware. + the exception to be handled upstream by another tween or middleware. See https://github.com/Pylons/pyramid/pull/2567 Deprecations -- cgit v1.2.3 From 80865ce4b2dee27d0be3868219fc447940ab1858 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 9 Dec 2016 22:16:49 -0700 Subject: Use has_body so we don't unravel app_iter This allows streaming responses. Closes #2625 --- pyramid/httpexceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index 054917dfa..a22b088c6 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -246,7 +246,7 @@ ${body}''') 'title': self.title} def prepare(self, environ): - if not self.body and not self.empty_body: + if not self.has_body and not self.empty_body: html_comment = '' comment = self.comment or '' accept_value = environ.get('HTTP_ACCEPT', '') -- cgit v1.2.3 From 2ae320a4390940014dd049d2fc5f8312a31e2961 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 9 Dec 2016 22:18:21 -0700 Subject: Pin to a newer version of WebOb v1.7.0 has property Response.has_body --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a6dbc2824..383991d73 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ except IOError: install_requires = [ 'setuptools', - 'WebOb >= 1.3.1', # request.domain and CookieProfile + 'WebOb >= 1.7.0rc2', # Response.has_body 'repoze.lru >= 0.4', # py3 compat 'zope.interface >= 3.8.0', # has zope.interface.registry 'zope.deprecation >= 3.5.0', # py3 compat -- cgit v1.2.3 From 2d45def603f038a8533eb9790640982012c0be30 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 9 Dec 2016 23:41:25 -0600 Subject: add changelog for #2863 --- CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 9daddff48..f3883b557 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -119,6 +119,12 @@ Features See https://github.com/Pylons/pyramid/pull/2805 +- Allow streaming responses to be made from subclasses of + ``pyramid.httpexceptions.HTTPException``. Previously the response would + be unrolled while testing for a body, making it impossible to stream + a response. + See https://github.com/Pylons/pyramid/pull/2863 + Bug Fixes --------- -- cgit v1.2.3 From bff312df8c36ac3ef5389a89c7459b282f944f77 Mon Sep 17 00:00:00 2001 From: Matthew Wilkes Date: Thu, 8 Dec 2016 15:00:29 +0100 Subject: Fix bug where plural rules would not be loaded for the default 'messages' domain. --- CHANGES.txt | 5 +++++ pyramid/i18n.py | 12 +++++++++++- pyramid/tests/test_i18n.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 65a1f15cd..2dc80c005 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -149,6 +149,11 @@ Bug Fixes from previous orders have executed. See https://github.com/Pylons/pyramid/pull/2757 +- Fix bug in i18n where the default domain would always use the Germanic plural + style, even if a different plural function is defined in the relevant messages + file. + See https://github.com/Pylons/pyramid/pull/2102 + Deprecations ------------ diff --git a/pyramid/i18n.py b/pyramid/i18n.py index 79209d342..1d11adfe3 100644 --- a/pyramid/i18n.py +++ b/pyramid/i18n.py @@ -22,6 +22,7 @@ from pyramid.threadlocal import get_current_registry TranslationString = TranslationString # PyFlakes TranslationStringFactory = TranslationStringFactory # PyFlakes +DEFAULT_PLURAL = lambda n: int(n != 1) class Localizer(object): """ @@ -233,7 +234,13 @@ class Translations(gettext.GNUTranslations, object): # GNUTranslations._parse (called as a side effect if fileobj is # passed to GNUTranslations.__init__) with a "real" self.plural for # this domain; see https://github.com/Pylons/pyramid/issues/235 - self.plural = lambda n: int(n != 1) + # It is only overridden the first time a new message file is found + # for a given domain, so all message files must have matching plural + # rules if they are in the same domain. We keep track of if we have + # overridden so we can special case the default domain, which is always + # instantiated before a message file is read. + # See also https://github.com/Pylons/pyramid/pull/2102 + self.plural = DEFAULT_PLURAL gettext.GNUTranslations.__init__(self, fp=fileobj) self.files = list(filter(None, [getattr(fileobj, 'name', None)])) self.domain = domain @@ -285,6 +292,9 @@ class Translations(gettext.GNUTranslations, object): :rtype: `Translations` """ domain = getattr(translations, 'domain', self.DEFAULT_DOMAIN) + if domain == self.DEFAULT_DOMAIN and self.plural is DEFAULT_PLURAL: + self.plural = translations.plural + if merge and domain == self.domain: return self.merge(translations) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 67b2ac356..d72d0d480 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -357,6 +357,36 @@ class TestTranslations(unittest.TestCase): inst.add(inst2) self.assertEqual(inst._catalog['a'], 'b') + def test_add_default_domain_replaces_plural_first_time(self): + # Create three empty message catalogs in the default domain + inst = self._getTargetClass()(None, domain='messages') + inst2 = self._getTargetClass()(None, domain='messages') + inst3 = self._getTargetClass()(None, domain='messages') + inst._catalog = {} + inst2._catalog = {} + inst3._catalog = {} + + # The default plural scheme is the germanic one + self.assertEqual(inst.plural(0), 1) + self.assertEqual(inst.plural(1), 0) + self.assertEqual(inst.plural(2), 1) + + # inst2 represents a message file that declares french plurals + inst2.plural = lambda n: n > 1 + inst.add(inst2) + # that plural rule should now apply to inst + self.assertEqual(inst.plural(0), 0) + self.assertEqual(inst.plural(1), 0) + self.assertEqual(inst.plural(2), 1) + + # We load a second message file with different plural rules + inst3.plural = lambda n: n > 0 + inst.add(inst3) + # It doesn't override the previously loaded rule + self.assertEqual(inst.plural(0), 0) + self.assertEqual(inst.plural(1), 0) + self.assertEqual(inst.plural(2), 1) + def test_dgettext(self): t = self._makeOne() self.assertEqual(t.dgettext('messages', 'foo'), 'Voh') -- cgit v1.2.3 From 6421f4c7559205e125a1c7218f711d6f6ecaf85c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 12 Dec 2016 11:13:08 -0600 Subject: reference the correct PR for #2859 --- CHANGES.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 0a810a0d6..8a6713783 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -160,9 +160,8 @@ Bug Fixes See https://github.com/Pylons/pyramid/pull/2757 - Fix bug in i18n where the default domain would always use the Germanic plural - style, even if a different plural function is defined in the relevant messages - file. - See https://github.com/Pylons/pyramid/pull/2102 + style, even if a different plural function is defined in the relevant + messages file. See https://github.com/Pylons/pyramid/pull/2859 Deprecations ------------ -- cgit v1.2.3 From b7b18463b80b9f16d603264c3b1b661061f492e6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 12:42:00 -0800 Subject: revert commits for ZODB scaffold changes --- pyramid/scaffolds/zodb/+package+/__init__.py | 2 +- .../zodb/+package+/templates/layout.jinja2_tmpl | 66 --------------------- .../+package+/templates/mytemplate.jinja2_tmpl | 7 --- .../zodb/+package+/templates/mytemplate.pt_tmpl | 67 ++++++++++++++++++++++ pyramid/scaffolds/zodb/+package+/views.py_tmpl | 2 +- pyramid/scaffolds/zodb/MANIFEST.in_tmpl | 2 +- pyramid/scaffolds/zodb/setup.py_tmpl | 2 +- 7 files changed, 71 insertions(+), 77 deletions(-) delete mode 100644 pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl delete mode 100644 pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl create mode 100644 pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl diff --git a/pyramid/scaffolds/zodb/+package+/__init__.py b/pyramid/scaffolds/zodb/+package+/__init__.py index 0ca5198b6..f2a86df47 100644 --- a/pyramid/scaffolds/zodb/+package+/__init__.py +++ b/pyramid/scaffolds/zodb/+package+/__init__.py @@ -12,7 +12,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=root_factory, settings=settings) - config.include('pyramid_jinja2') + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl b/pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl deleted file mode 100644 index a0b3f22f4..000000000 --- a/pyramid/scaffolds/zodb/+package+/templates/layout.jinja2_tmpl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - ZODB Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
-
-
-
- -
-
- {% block content %} -

No content

- {% endblock content %} -
-
-
- -
-
- -
-
-
- - - - - - - - diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl deleted file mode 100644 index bb075e91d..000000000 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.jinja2_tmpl +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "layout.jinja2" %} -{% block content %} -
-

Pyramid ZODB scaffold

-

Welcome to \{\{project\}\}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

-
-{% endblock content %} diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl new file mode 100644 index 000000000..e109ab829 --- /dev/null +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl @@ -0,0 +1,67 @@ + + + + + + + + + + + ZODB Scaffold for The Pyramid Web Framework + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+

Pyramid ZODB scaffold

+

Welcome to ${project}, an application generated by
the Pyramid Web Framework {{pyramid_version}}.

+
+
+
+
+ +
+
+ +
+
+
+ + + + + + + + diff --git a/pyramid/scaffolds/zodb/+package+/views.py_tmpl b/pyramid/scaffolds/zodb/+package+/views.py_tmpl index 0b176b365..1e8a9b65a 100644 --- a/pyramid/scaffolds/zodb/+package+/views.py_tmpl +++ b/pyramid/scaffolds/zodb/+package+/views.py_tmpl @@ -2,6 +2,6 @@ from pyramid.view import view_config from .models import MyModel -@view_config(context=MyModel, renderer='templates/mytemplate.jinja2') +@view_config(context=MyModel, renderer='templates/mytemplate.pt') def my_view(request): return {'project': '{{project}}'} diff --git a/pyramid/scaffolds/zodb/MANIFEST.in_tmpl b/pyramid/scaffolds/zodb/MANIFEST.in_tmpl index 4d1c86b44..0ff6eb7a0 100644 --- a/pyramid/scaffolds/zodb/MANIFEST.in_tmpl +++ b/pyramid/scaffolds/zodb/MANIFEST.in_tmpl @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 +recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/pyramid/scaffolds/zodb/setup.py_tmpl b/pyramid/scaffolds/zodb/setup.py_tmpl index a503d60ab..19771d756 100644 --- a/pyramid/scaffolds/zodb/setup.py_tmpl +++ b/pyramid/scaffolds/zodb/setup.py_tmpl @@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - 'pyramid_jinja2', + 'pyramid_chameleon', 'pyramid_debugtoolbar', 'pyramid_tm', 'pyramid_zodbconn', -- cgit v1.2.3 From 760cf2c1c6b0e5e098528d9229809a46c0a9d24d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 12:46:50 -0800 Subject: resolve conflict in CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index dcca62d48..93e526830 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -285,4 +285,8 @@ Contributors - Keith Yang, 2016/07/22 -- Hannah Krager, 2016/10/22 \ No newline at end of file +- Hannah Krager, 2016/10/22 + +- Moriyoshi Koizumi, 2016/11/20 + +- Mikko Ohtamaa, 2016/12/6 -- cgit v1.2.3 From 4393f8b8e54e636b5655e0a8d2477e0b15820f68 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 13:12:02 -0800 Subject: capitalize Pylons --- pyramid/scripts/pcreate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 52f8fea5e..825d8741b 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -27,7 +27,7 @@ Render Pyramid scaffolding to an output directory. Note: As of Pyramid 1.8, this command is deprecated. Use a specific cookiecutter instead: -https://github.com/pylons/?query=cookiecutter +https://github.com/Pylons/?query=cookiecutter """ usage = "usage: %prog [options] -s output_directory" parser = optparse.OptionParser(usage, description=description) -- cgit v1.2.3 From fd89d18d887576ca7d818f069b6bfad524c3e3ea Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 13:30:29 -0800 Subject: fix query string --- pyramid/scripts/pcreate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 595fd8d77..b3e3b65fa 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -27,7 +27,7 @@ Render Pyramid scaffolding to an output directory. Note: As of Pyramid 1.8, this command is deprecated. Use a specific cookiecutter instead: -https://github.com/Pylons/?query=cookiecutter +https://github.com/Pylons/?q=cookiecutter """ usage = "usage: %prog [options] -s output_directory" parser = optparse.OptionParser(usage, description=description) -- cgit v1.2.3 From b7f994c9d13e70b597f42bce49ca6389cd21e2b2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 12:13:30 -0800 Subject: convert pcreate and pdistreport to use argparse - add sphinxcontrib-autoprogram - attempt to render output of pcreate, but be unsuccessful --- docs/conf.py | 7 +++--- docs/pscripts/pcreate.rst | 5 ++-- pyramid/scaffolds/template.py | 8 +++--- pyramid/scripts/pcreate.py | 56 +++++++++++++++++++++--------------------- pyramid/scripts/pdistreport.py | 4 +-- setup.py | 2 +- 6 files changed, 40 insertions(+), 42 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 12dd27722..5496452bd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -51,11 +51,10 @@ book = os.environ.get('BOOK') extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.viewcode', 'repoze.sphinx.autointerface', - 'sphinxcontrib.programoutput', + 'sphinx.ext.viewcode', + 'sphinx.ext.intersphinx', + 'sphinxcontrib.autoprogram', # enable pylons_sphinx_latesturl when this branch is no longer "latest" # 'pylons_sphinx_latesturl', ] diff --git a/docs/pscripts/pcreate.rst b/docs/pscripts/pcreate.rst index b5ec3f4e2..7159395b7 100644 --- a/docs/pscripts/pcreate.rst +++ b/docs/pscripts/pcreate.rst @@ -6,8 +6,7 @@ ``pcreate`` ----------- -.. program-output:: pcreate --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.pcreate:PCreateCommand + :prog: pcreate.py .. seealso:: :ref:`creating_a_project` diff --git a/pyramid/scaffolds/template.py b/pyramid/scaffolds/template.py index d88f5b2a6..e5098e815 100644 --- a/pyramid/scaffolds/template.py +++ b/pyramid/scaffolds/template.py @@ -81,7 +81,7 @@ class Template(object): template_dir = self.template_dir() if not self.exists(output_dir): self.out("Creating directory %s" % output_dir) - if not command.options.simulate: + if not command.args.simulate: # Don't let copydir create this top-level directory, # since copydir will svn add it sometimes: self.makedirs(output_dir) @@ -90,9 +90,9 @@ class Template(object): output_dir, vars, verbosity=command.verbosity, - simulate=command.options.simulate, - interactive=command.options.interactive, - overwrite=command.options.overwrite, + simulate=command.args.simulate, + interactive=command.args.interactive, + overwrite=command.args.overwrite, indent=1, template_renderer=self.render_template, ) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index b3e3b65fa..ba4fcc8ae 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -2,7 +2,7 @@ # (http://pythonpaste.org) Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license.php -import optparse +import argparse import os import os.path import pkg_resources @@ -22,79 +22,79 @@ def main(argv=sys.argv, quiet=False): class PCreateCommand(object): verbosity = 1 # required - description = """\ + parser = argparse.ArgumentParser(description="""\ Render Pyramid scaffolding to an output directory. Note: As of Pyramid 1.8, this command is deprecated. Use a specific cookiecutter instead: https://github.com/Pylons/?q=cookiecutter -""" - usage = "usage: %prog [options] -s output_directory" - parser = optparse.OptionParser(usage, description=description) - parser.add_option('-s', '--scaffold', +""") + parser.add_argument('-s', '--scaffold', dest='scaffold_name', action='append', help=("Add a scaffold to the create process " "(multiple -s args accepted)")) - parser.add_option('-t', '--template', + parser.add_argument('-t', '--template', dest='scaffold_name', action='append', help=('A backwards compatibility alias for ' '-s/--scaffold. Add a scaffold to the ' 'create process (multiple -t args accepted)')) - parser.add_option('-l', '--list', + parser.add_argument('-l', '--list', dest='list', action='store_true', help="List all available scaffold names") - parser.add_option('--list-templates', + parser.add_argument('--list-templates', dest='list', action='store_true', help=("A backwards compatibility alias for -l/--list. " "List all available scaffold names.")) - parser.add_option('--package-name', + parser.add_argument('--package-name', dest='package_name', action='store', - type='string', help='Package name to use. The name provided is assumed ' 'to be a valid Python package name, and will not ' 'be validated. By default the package name is ' 'derived from the value of output_directory.') - parser.add_option('--simulate', + parser.add_argument('--simulate', dest='simulate', action='store_true', help='Simulate but do no work') - parser.add_option('--overwrite', + parser.add_argument('--overwrite', dest='overwrite', action='store_true', help='Always overwrite') - parser.add_option('--interactive', + parser.add_argument('--interactive', dest='interactive', action='store_true', help='When a file would be overwritten, interrogate ' '(this is the default, but you may specify it to ' 'override --overwrite)') - parser.add_option('--ignore-conflicting-name', + parser.add_argument('--ignore-conflicting-name', dest='force_bad_name', action='store_true', default=False, help='Do create a project even if the chosen name ' 'is the name of an already existing / importable ' 'package.') + parser.add_argument('output_directory', + help='The directory where the project will be ' + 'created.') pyramid_dist = pkg_resources.get_distribution("pyramid") def __init__(self, argv, quiet=False): self.quiet = quiet - self.options, self.args = self.parser.parse_args(argv[1:]) - if not self.options.interactive and not self.options.overwrite: - self.options.interactive = True + self.args = self.parser.parse_args() + if not self.args.interactive and not self.args.overwrite: + self.args.interactive = True self.scaffolds = self.all_scaffolds() def run(self): self._warn_pcreate_deprecated() - if self.options.list: + if self.args.list: return self.show_scaffolds() - if not self.options.scaffold_name and not self.args: + if not self.args.scaffold_name and not self.args: if not self.quiet: # pragma: no cover self.parser.print_help() self.out('') @@ -108,18 +108,18 @@ https://github.com/Pylons/?q=cookiecutter @property def output_path(self): - return os.path.abspath(os.path.normpath(self.args[0])) + return os.path.abspath(os.path.normpath(self.args.output_directory)) @property def project_vars(self): output_dir = self.output_path project_name = os.path.basename(os.path.split(output_dir)[1]) - if self.options.package_name is None: + if self.args.package_name is None: pkg_name = _bad_chars_re.sub( '', project_name.lower().replace('-', '_')) safe_name = pkg_resources.safe_name(project_name) else: - pkg_name = self.options.package_name + pkg_name = self.args.package_name safe_name = pkg_name egg_name = pkg_resources.to_filename(safe_name) @@ -152,7 +152,7 @@ https://github.com/Pylons/?q=cookiecutter def render_scaffolds(self): props = self.project_vars output_dir = self.output_path - for scaffold_name in self.options.scaffold_name: + for scaffold_name in self.args.scaffold_name: for scaffold in self.scaffolds: if scaffold.name == scaffold_name: scaffold.run(self, output_dir, props) @@ -189,7 +189,7 @@ https://github.com/Pylons/?q=cookiecutter print(msg) def validate_input(self): - if not self.options.scaffold_name: + if not self.args.scaffold_name: self.out('You must provide at least one scaffold name: -s ') self.out('') self.show_scaffolds() @@ -198,14 +198,14 @@ https://github.com/Pylons/?q=cookiecutter self.out('You must provide a project name') return False available = [x.name for x in self.scaffolds] - diff = set(self.options.scaffold_name).difference(available) + diff = set(self.args.scaffold_name).difference(available) if diff: self.out('Unavailable scaffolds: %s' % ", ".join(sorted(diff))) return False pkg_name = self.project_vars['package'] - if pkg_name == 'site' and not self.options.force_bad_name: + if pkg_name == 'site' and not self.args.force_bad_name: self.out('The package name "site" has a special meaning in ' 'Python. Are you sure you want to use it as your ' 'project\'s name?') @@ -221,7 +221,7 @@ https://github.com/Pylons/?q=cookiecutter if not pkg_exists: return True - if self.options.force_bad_name: + if self.args.force_bad_name: return True self.out('A package named "{0}" already exists, are you sure you want ' 'to use it as your project\'s name?'.format(pkg_name)) diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index 61098dc27..a504c9545 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -1,7 +1,7 @@ import sys import platform import pkg_resources -import optparse +import argparse from operator import itemgetter def out(*args): # pragma: no cover @@ -15,7 +15,7 @@ def main(argv=sys.argv, pkg_resources=pkg_resources, platform=platform.platform, # all args except argv are for unit testing purposes only description = "Show Python distribution versions and locations in use" usage = "usage: %prog" - parser = optparse.OptionParser(usage, description=description) + parser = argparse.ArgumentParser(usage, description=description) parser.parse_args(argv[1:]) packages = [] for distribution in pkg_resources.working_set: diff --git a/setup.py b/setup.py index 383991d73..63e82e707 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ docs_extras = [ 'repoze.sphinx.autointerface', 'pylons_sphinx_latesturl', 'pylons-sphinx-themes', - 'sphinxcontrib-programoutput', + 'sphinxcontrib-autoprogram', ] testing_extras = tests_require + [ -- cgit v1.2.3 From bde0ef17af0461799f04ace144526a06c6215776 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 12:49:28 -0800 Subject: fix autoprogram argument - restore argv - use standard Python syntax for string formatting --- docs/pscripts/pcreate.rst | 2 +- pyramid/scripts/pcreate.py | 2 +- pyramid/scripts/pdistreport.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pscripts/pcreate.rst b/docs/pscripts/pcreate.rst index 7159395b7..648491600 100644 --- a/docs/pscripts/pcreate.rst +++ b/docs/pscripts/pcreate.rst @@ -6,7 +6,7 @@ ``pcreate`` ----------- -.. autoprogram:: pyramid.scripts.pcreate:PCreateCommand +.. autoprogram:: pyramid.scripts.pcreate:PCreateCommand.parser :prog: pcreate.py .. seealso:: :ref:`creating_a_project` diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index ba4fcc8ae..027a52c06 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -85,7 +85,7 @@ https://github.com/Pylons/?q=cookiecutter def __init__(self, argv, quiet=False): self.quiet = quiet - self.args = self.parser.parse_args() + self.args = self.parser.parse_args(argv) if not self.args.interactive and not self.args.overwrite: self.args.interactive = True self.scaffolds = self.all_scaffolds() diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index a504c9545..c090d3311 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -14,7 +14,7 @@ def main(argv=sys.argv, pkg_resources=pkg_resources, platform=platform.platform, out=out): # all args except argv are for unit testing purposes only description = "Show Python distribution versions and locations in use" - usage = "usage: %prog" + usage = "usage: %(prog)s" parser = argparse.ArgumentParser(usage, description=description) parser.parse_args(argv[1:]) packages = [] -- cgit v1.2.3 From 3fb84e950bd6f65dd298b08c86723b388c3b62f8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 13:09:39 -0800 Subject: make usage parseable by argparse - PEP8 --- pyramid/scripts/pcreate.py | 80 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 027a52c06..49e5fbdf4 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -12,6 +12,7 @@ from pyramid.compat import input_ _bad_chars_re = re.compile('[^a-zA-Z0-9_]') + def main(argv=sys.argv, quiet=False): command = PCreateCommand(argv, quiet) try: @@ -30,53 +31,54 @@ cookiecutter instead: https://github.com/Pylons/?q=cookiecutter """) parser.add_argument('-s', '--scaffold', - dest='scaffold_name', - action='append', - help=("Add a scaffold to the create process " - "(multiple -s args accepted)")) + dest='scaffold_name', + action='append', + help=("Add a scaffold to the create process " + "(multiple -s args accepted)")) parser.add_argument('-t', '--template', - dest='scaffold_name', - action='append', - help=('A backwards compatibility alias for ' - '-s/--scaffold. Add a scaffold to the ' - 'create process (multiple -t args accepted)')) + dest='scaffold_name', + action='append', + help=('A backwards compatibility alias for ' + '-s/--scaffold. Add a scaffold to the ' + 'create process (multiple -t args accepted)')) parser.add_argument('-l', '--list', - dest='list', - action='store_true', - help="List all available scaffold names") + dest='list', + action='store_true', + help="List all available scaffold names") parser.add_argument('--list-templates', - dest='list', - action='store_true', - help=("A backwards compatibility alias for -l/--list. " - "List all available scaffold names.")) + dest='list', + action='store_true', + help=("A backwards compatibility alias for -l/--list. " + "List all available scaffold names.")) parser.add_argument('--package-name', - dest='package_name', - action='store', - help='Package name to use. The name provided is assumed ' - 'to be a valid Python package name, and will not ' - 'be validated. By default the package name is ' - 'derived from the value of output_directory.') + dest='package_name', + action='store', + help='Package name to use. The name provided is ' + 'assumed to be a valid Python package name, and ' + 'will not be validated. By default the package ' + 'name is derived from the value of ' + 'output_directory.') parser.add_argument('--simulate', - dest='simulate', - action='store_true', - help='Simulate but do no work') + dest='simulate', + action='store_true', + help='Simulate but do no work') parser.add_argument('--overwrite', - dest='overwrite', - action='store_true', - help='Always overwrite') + dest='overwrite', + action='store_true', + help='Always overwrite') parser.add_argument('--interactive', - dest='interactive', - action='store_true', - help='When a file would be overwritten, interrogate ' - '(this is the default, but you may specify it to ' - 'override --overwrite)') + dest='interactive', + action='store_true', + help='When a file would be overwritten, interrogate ' + '(this is the default, but you may specify it to ' + 'override --overwrite)') parser.add_argument('--ignore-conflicting-name', - dest='force_bad_name', - action='store_true', - default=False, - help='Do create a project even if the chosen name ' - 'is the name of an already existing / importable ' - 'package.') + dest='force_bad_name', + action='store_true', + default=False, + help='Do create a project even if the chosen name ' + 'is the name of an already existing / importable ' + 'package.') parser.add_argument('output_directory', help='The directory where the project will be ' 'created.') -- cgit v1.2.3 From f33a50c69bbb7790f612eebeb005e1137b5c252a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 19:48:00 -0800 Subject: make usage parseable by argparse --- pyramid/scripts/pdistreport.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index c090d3311..64837a36c 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -13,9 +13,9 @@ def out(*args): # pragma: no cover def main(argv=sys.argv, pkg_resources=pkg_resources, platform=platform.platform, out=out): # all args except argv are for unit testing purposes only - description = "Show Python distribution versions and locations in use" - usage = "usage: %(prog)s" - parser = argparse.ArgumentParser(usage, description=description) + parser = argparse.ArgumentParser( + usage="%(prog)s", + description="Show Python distribution versions and locations in use") parser.parse_args(argv[1:]) packages = [] for distribution in pkg_resources.working_set: -- cgit v1.2.3 From b2f3ed007ef27d24690f40c2ad8415fab9400e98 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 20:01:36 -0800 Subject: still fumbling around with autoprogram, not successful --- docs/pscripts/pdistreport.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/pscripts/pdistreport.rst b/docs/pscripts/pdistreport.rst index 1c53fb6e9..3bcd96b00 100644 --- a/docs/pscripts/pdistreport.rst +++ b/docs/pscripts/pdistreport.rst @@ -6,8 +6,7 @@ ``pdistreport`` --------------- -.. program-output:: pdistreport --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.pdistreport:parser + :prog: pdistreport.py .. seealso:: :ref:`showing_distributions` -- cgit v1.2.3 From cae3840bc43f54ae55d1e2c97da90cecdf49a95e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 20:03:45 -0800 Subject: drop '.py' from :prog: argument --- docs/pscripts/pcreate.rst | 2 +- docs/pscripts/pdistreport.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pscripts/pcreate.rst b/docs/pscripts/pcreate.rst index 648491600..476b3d577 100644 --- a/docs/pscripts/pcreate.rst +++ b/docs/pscripts/pcreate.rst @@ -7,6 +7,6 @@ ----------- .. autoprogram:: pyramid.scripts.pcreate:PCreateCommand.parser - :prog: pcreate.py + :prog: pcreate .. seealso:: :ref:`creating_a_project` diff --git a/docs/pscripts/pdistreport.rst b/docs/pscripts/pdistreport.rst index 3bcd96b00..8eebaf8cb 100644 --- a/docs/pscripts/pdistreport.rst +++ b/docs/pscripts/pdistreport.rst @@ -7,6 +7,6 @@ --------------- .. autoprogram:: pyramid.scripts.pdistreport:parser - :prog: pdistreport.py + :prog: pdistreport .. seealso:: :ref:`showing_distributions` -- cgit v1.2.3 From 0c208dd7bf66a41a056514025fa42be8fc428513 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 22:13:03 -0800 Subject: move parser outside of main into own function get_parser(), and call it from pdistreport.rst --- docs/pscripts/pdistreport.rst | 2 +- pyramid/scripts/pdistreport.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/pscripts/pdistreport.rst b/docs/pscripts/pdistreport.rst index 8eebaf8cb..f88ea7fe1 100644 --- a/docs/pscripts/pdistreport.rst +++ b/docs/pscripts/pdistreport.rst @@ -6,7 +6,7 @@ ``pdistreport`` --------------- -.. autoprogram:: pyramid.scripts.pdistreport:parser +.. autoprogram:: pyramid.scripts.pdistreport:get_parser() :prog: pdistreport .. seealso:: :ref:`showing_distributions` diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index 64837a36c..6622b4bd8 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -10,12 +10,16 @@ def out(*args): # pragma: no cover sys.stdout.write(' ') sys.stdout.write('\n') +def get_parser(): + _parser = argparse.ArgumentParser( + usage="%(prog)s", + description="Show Python distribution versions and locations in use") + return _parser + def main(argv=sys.argv, pkg_resources=pkg_resources, platform=platform.platform, out=out): # all args except argv are for unit testing purposes only - parser = argparse.ArgumentParser( - usage="%(prog)s", - description="Show Python distribution versions and locations in use") + parser = get_parser() parser.parse_args(argv[1:]) packages = [] for distribution in pkg_resources.working_set: -- cgit v1.2.3 From e5b871d5afa0cb2772780013636ee2b830c1fdf1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 22:19:08 -0800 Subject: remove duplicitous headings --- docs/pscripts/pcreate.rst | 3 --- docs/pscripts/pdistreport.rst | 3 --- 2 files changed, 6 deletions(-) diff --git a/docs/pscripts/pcreate.rst b/docs/pscripts/pcreate.rst index 476b3d577..0f23583ba 100644 --- a/docs/pscripts/pcreate.rst +++ b/docs/pscripts/pcreate.rst @@ -3,9 +3,6 @@ .. _pcreate_script: -``pcreate`` ------------ - .. autoprogram:: pyramid.scripts.pcreate:PCreateCommand.parser :prog: pcreate diff --git a/docs/pscripts/pdistreport.rst b/docs/pscripts/pdistreport.rst index f88ea7fe1..200218ad0 100644 --- a/docs/pscripts/pdistreport.rst +++ b/docs/pscripts/pdistreport.rst @@ -3,9 +3,6 @@ .. _pdistreport_script: -``pdistreport`` ---------------- - .. autoprogram:: pyramid.scripts.pdistreport:get_parser() :prog: pdistreport -- cgit v1.2.3 From 1efb3110d91a14a758366da6c5a489fc8b1c0def Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 22:57:06 -0800 Subject: rename local --- pyramid/scripts/pdistreport.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index 6622b4bd8..e80ea20b6 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -11,10 +11,10 @@ def out(*args): # pragma: no cover sys.stdout.write('\n') def get_parser(): - _parser = argparse.ArgumentParser( + parser = argparse.ArgumentParser( usage="%(prog)s", description="Show Python distribution versions and locations in use") - return _parser + return parser def main(argv=sys.argv, pkg_resources=pkg_resources, platform=platform.platform, out=out): -- cgit v1.2.3 From 6b229c9ef28556942845ac429e10e498fb5dea5f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 23:56:21 -0800 Subject: indent 4 spaces --- docs/pscripts/pcreate.rst | 4 ++-- docs/pscripts/pdistreport.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/pscripts/pcreate.rst b/docs/pscripts/pcreate.rst index 0f23583ba..c48a70acd 100644 --- a/docs/pscripts/pcreate.rst +++ b/docs/pscripts/pcreate.rst @@ -1,9 +1,9 @@ .. index:: - single: pcreate; --help + single: pcreate; --help .. _pcreate_script: .. autoprogram:: pyramid.scripts.pcreate:PCreateCommand.parser - :prog: pcreate + :prog: pcreate .. seealso:: :ref:`creating_a_project` diff --git a/docs/pscripts/pdistreport.rst b/docs/pscripts/pdistreport.rst index 200218ad0..b3c9dffd8 100644 --- a/docs/pscripts/pdistreport.rst +++ b/docs/pscripts/pdistreport.rst @@ -1,9 +1,9 @@ .. index:: - single: pdistreport; --help + single: pdistreport; --help .. _pdistreport_script: .. autoprogram:: pyramid.scripts.pdistreport:get_parser() - :prog: pdistreport + :prog: pdistreport .. seealso:: :ref:`showing_distributions` -- cgit v1.2.3 From 9a22d66e011f93135fa12c1ab1738b7f1ee90312 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 27 Nov 2016 23:57:22 -0800 Subject: use argparse in prequest; use autoprogram --- docs/pscripts/prequest.rst | 10 +++------- pyramid/scripts/prequest.py | 47 +++++++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/docs/pscripts/prequest.rst b/docs/pscripts/prequest.rst index a15827767..64ed01739 100644 --- a/docs/pscripts/prequest.rst +++ b/docs/pscripts/prequest.rst @@ -1,13 +1,9 @@ .. index:: - single: prequest; --help + single: prequest; --help .. _prequest_script: -``prequest`` ------------- - -.. program-output:: prequest --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.prequest:PRequestCommand.parser + :prog: prequest .. seealso:: :ref:`invoking_a_request` diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 14a132bdb..880eae5b0 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -1,5 +1,5 @@ import base64 -import optparse +import argparse import sys import textwrap @@ -45,58 +45,63 @@ class PRequestCommand(object): the request's WSGI environment, so your application can distinguish these calls from normal requests. """ - usage = "usage: %prog config_uri path_info [args/options]" - parser = optparse.OptionParser( - usage=usage, + parser = argparse.ArgumentParser( + usage="%(prog)s config_uri path_info [args/options]", description=textwrap.dedent(description) ) - parser.add_option( + parser.add_argument( '-n', '--app-name', dest='app_name', metavar='NAME', help=( "Load the named application from the config file (default 'main')" ), - type="string", ) - parser.add_option( + parser.add_argument( '--header', dest='headers', metavar='NAME:VALUE', - type='string', action='append', help=( "Header to add to request (you can use this option multiple times)" ), ) - parser.add_option( + parser.add_argument( '-d', '--display-headers', dest='display_headers', action='store_true', help='Display status and headers before the response body' ) - parser.add_option( + parser.add_argument( '-m', '--method', dest='method', choices=['GET', 'HEAD', 'POST', 'PUT', 'PATCH','DELETE', 'PROPFIND', 'OPTIONS'], - type='choice', help='Request method type (GET, POST, PUT, PATCH, DELETE, ' 'PROPFIND, OPTIONS)', ) - parser.add_option( + parser.add_argument( '-l', '--login', dest='login', - type='string', help='HTTP basic auth username:password pair', ) + parser.add_argument( + 'config_uri', + help='The URI to the configuration file.', + ) + + parser.add_argument( + 'path_info', + help='The path of the request.', + ) + get_app = staticmethod(get_app) stdin = sys.stdin def __init__(self, argv, quiet=False): self.quiet = quiet - self.options, self.args = self.parser.parse_args(argv[1:]) + self.args = self.parser.parse_args(argv[1:]) def out(self, msg): # pragma: no cover if not self.quiet: @@ -125,12 +130,12 @@ class PRequestCommand(object): path = url_unquote(path) headers = {} - if self.options.login: - enc = base64.b64encode(self.options.login.encode('ascii')) + if self.args.login: + enc = base64.b64encode(self.args.login.encode('ascii')) headers['Authorization'] = 'Basic ' + enc.decode('ascii') - if self.options.headers: - for item in self.options.headers: + if self.args.headers: + for item in self.args.headers: if ':' not in item: self.out( "Bad --header=%s option, value must be in the form " @@ -139,10 +144,10 @@ class PRequestCommand(object): name, value = item.split(':', 1) headers[name] = value.strip() - app = self.get_app(app_spec, self.options.app_name, + app = self.get_app(app_spec, self.args.app_name, options=parse_vars(self.args[2:])) - request_method = (self.options.method or 'GET').upper() + request_method = (self.args.method or 'GET').upper() environ = { 'REQUEST_METHOD': request_method, @@ -177,7 +182,7 @@ class PRequestCommand(object): request = Request.blank(path, environ=environ) response = request.get_response(app) - if self.options.display_headers: + if self.args.display_headers: self.out(response.status) for name, value in response.headerlist: self.out('%s: %s' % (name, value)) -- cgit v1.2.3 From 83ebd45272bee27a56aaf9a6494382da1499c12d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 01:48:38 -0800 Subject: use argparse in prequest; use autoprogram --- docs/pscripts/proutes.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/pscripts/proutes.rst b/docs/pscripts/proutes.rst index 09ed013e1..ee7c209e3 100644 --- a/docs/pscripts/proutes.rst +++ b/docs/pscripts/proutes.rst @@ -3,11 +3,7 @@ .. _proutes_script: -``proutes`` ------------ - -.. program-output:: proutes --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.proutes:PRoutesCommand.parser + :prog: proutes .. seealso:: :ref:`displaying_application_routes` -- cgit v1.2.3 From 616f40a660d1f095241a7c46ff3d68e69b07c900 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 01:55:43 -0800 Subject: use argparse in proutes; use autoprogram --- pyramid/scripts/proutes.py | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index f75810c06..640cd20a3 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -1,5 +1,5 @@ import fnmatch -import optparse +import argparse import sys import textwrap import re @@ -249,22 +249,31 @@ class PRoutesCommand(object): stdout = sys.stdout usage = '%prog config_uri' ConfigParser = configparser.ConfigParser # testing - parser = optparse.OptionParser( + parser = argparse.ArgumentParser( usage, description=textwrap.dedent(description) ) - parser.add_option('-g', '--glob', - action='store', type='string', dest='glob', - default='', help='Display routes matching glob pattern') - - parser.add_option('-f', '--format', - action='store', type='string', dest='format', - default='', help=('Choose which columns to display, this ' - 'will override the format key in the ' - '[proutes] ini section')) + parser.add_argument('-g', '--glob', + action='store', + dest='glob', + default='', + help='Display routes matching glob pattern') + + parser.add_argument('-f', '--format', + action='store', + dest='format', + default='', + help=('Choose which columns to display, this will ' + 'override the format key in the [proutes] ini ' + 'section')) + + parser.add_argument( + 'config_uri', + help='The URI to the configuration file.', + ) def __init__(self, argv, quiet=False): - self.options, self.args = self.parser.parse_args(argv[1:]) + self.args = self.parser.parse_args(argv[1:]) self.quiet = quiet self.available_formats = [ 'name', 'pattern', 'view', 'method' @@ -323,8 +332,8 @@ class PRoutesCommand(object): self.proutes_file_config(config_uri) - if self.options.format: - columns = self.options.format.split(',') + if self.args.format: + columns = self.args.format.split(',') self.column_format = [x.strip() for x in columns] is_valid = self.validate_formats(self.column_format) @@ -361,9 +370,9 @@ class PRoutesCommand(object): route_data = get_route_data(route, registry) for name, pattern, view, method in route_data: - if self.options.glob: - match = (fnmatch.fnmatch(name, self.options.glob) or - fnmatch.fnmatch(pattern, self.options.glob)) + if self.args.glob: + match = (fnmatch.fnmatch(name, self.args.glob) or + fnmatch.fnmatch(pattern, self.args.glob)) if not match: continue -- cgit v1.2.3 From 506d3c7fd5cd6cf3bd0c46f06f85c9cdf6795d18 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 01:56:15 -0800 Subject: add line feed to avoid Sphinx error --- pyramid/scripts/prequest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 880eae5b0..021b83f6c 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -45,6 +45,7 @@ class PRequestCommand(object): the request's WSGI environment, so your application can distinguish these calls from normal requests. """ + parser = argparse.ArgumentParser( usage="%(prog)s config_uri path_info [args/options]", description=textwrap.dedent(description) -- cgit v1.2.3 From 894534b26edcd1701dcf2c5f93377bf0d86dc51a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 01:58:46 -0800 Subject: fix quote mismatch --- pyramid/scripts/prequest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 021b83f6c..9e807896d 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -39,7 +39,7 @@ class PRequestCommand(object): If the path is relative (doesn't begin with "/") it is interpreted as relative to "/". The path passed to this script should be URL-quoted. - The path can be succeeded with a query string (e.g. `/path?a=1&=b2'). + The path can be succeeded with a query string (e.g. '/path?a=1&=b2'). The variable "environ['paste.command_request']" will be set to "True" in the request's WSGI environment, so your application can distinguish these -- cgit v1.2.3 From 6e14f62f24dcff03ebc6d27c0c756db449082cfd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 02:05:21 -0800 Subject: use argparse and autoprogram for pserve --- docs/pscripts/pserve.rst | 8 ++----- pyramid/scripts/pserve.py | 55 +++++++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/docs/pscripts/pserve.rst b/docs/pscripts/pserve.rst index d33d4a484..991976aea 100644 --- a/docs/pscripts/pserve.rst +++ b/docs/pscripts/pserve.rst @@ -3,11 +3,7 @@ .. _pserve_script: -``pserve`` ----------- - -.. program-output:: pserve --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.pserve:PServeCommand.parser + :prog: pserve .. seealso:: :ref:`running_the_project_application` diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index b8776d44f..f3515804d 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -8,7 +8,7 @@ # Code taken also from QP: http://www.mems-exchange.org/software/qp/ From # lib/site.py -import optparse +import argparse import os import re import sys @@ -41,7 +41,6 @@ def main(argv=sys.argv, quiet=False): class PServeCommand(object): - usage = '%prog config_uri [var=value]' description = """\ This command serves a web application that uses a PasteDeploy configuration file for the server and application. @@ -51,54 +50,58 @@ class PServeCommand(object): """ default_verbosity = 1 - parser = optparse.OptionParser( - usage, + parser = argparse.ArgumentParser( + usage="%(prog)s config_uri [var=value]", description=textwrap.dedent(description) ) - parser.add_option( + parser.add_argument( '-n', '--app-name', dest='app_name', metavar='NAME', help="Load the named application (default main)") - parser.add_option( + parser.add_argument( '-s', '--server', dest='server', metavar='SERVER_TYPE', help="Use the named server.") - parser.add_option( + parser.add_argument( '--server-name', dest='server_name', metavar='SECTION_NAME', help=("Use the named server as defined in the configuration file " "(default: main)")) - parser.add_option( + parser.add_argument( '--reload', dest='reload', action='store_true', help="Use auto-restart file monitor") - parser.add_option( + parser.add_argument( '--reload-interval', dest='reload_interval', default=1, help=("Seconds between checking files (low number can cause " "significant CPU usage)")) - parser.add_option( + parser.add_argument( '-b', '--browser', dest='browser', action='store_true', help="Open a web browser to server url") - parser.add_option( + parser.add_argument( '-v', '--verbose', default=default_verbosity, dest='verbose', action='count', help="Set verbose level (default " + str(default_verbosity) + ")") - parser.add_option( + parser.add_argument( '-q', '--quiet', action='store_const', const=0, dest='verbose', help="Suppress verbose output") + parser.add_argument( + 'config_uri', + help='The URI to the configuration file.', + ) ConfigParser = configparser.ConfigParser # testing loadapp = staticmethod(loadapp) # testing @@ -107,13 +110,13 @@ class PServeCommand(object): _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) def __init__(self, argv, quiet=False): - self.options, self.args = self.parser.parse_args(argv[1:]) + self.args = self.parser.parse_args(argv[1:]) if quiet: - self.options.verbose = 0 + self.args.verbose = 0 self.watch_files = [] def out(self, msg): # pragma: no cover - if self.options.verbose > 0: + if self.args.verbose > 0: print(msg) def get_options(self): @@ -153,7 +156,7 @@ class PServeCommand(object): app_spec = self.args[0] vars = self.get_options() - app_name = self.options.app_name + app_name = self.args.app_name base = os.getcwd() if not self._scheme_re.search(app_spec): @@ -161,16 +164,16 @@ class PServeCommand(object): app_spec = 'config:' + app_spec else: config_path = None - server_name = self.options.server_name - if self.options.server: + server_name = self.args.server_name + if self.args.server: server_spec = 'egg:pyramid' assert server_name is None - server_name = self.options.server + server_name = self.args.server else: server_spec = app_spec # do not open the browser on each reload so check hupper first - if self.options.browser and not hupper.is_active(): + if self.args.browser and not hupper.is_active(): def open_browser(): context = loadcontext( SERVER, app_spec, name=server_name, relative_to=base, @@ -182,13 +185,13 @@ class PServeCommand(object): t.setDaemon(True) t.start() - if self.options.reload and not hupper.is_active(): - if self.options.verbose > 1: + if self.args.reload and not hupper.is_active(): + if self.args.verbose > 1: self.out('Running reloading file monitor') hupper.start_reloader( 'pyramid.scripts.pserve.main', - reload_interval=int(self.options.reload_interval), - verbose=self.options.verbose, + reload_interval=int(self.args.reload_interval), + verbose=self.args.verbose, ) return 0 @@ -207,7 +210,7 @@ class PServeCommand(object): app = self.loadapp( app_spec, name=app_name, relative_to=base, global_conf=vars) - if self.options.verbose > 0: + if self.args.verbose > 0: if hasattr(os, 'getpid'): msg = 'Starting server in PID %i.' % os.getpid() else: @@ -217,7 +220,7 @@ class PServeCommand(object): try: server(app) except (SystemExit, KeyboardInterrupt) as e: - if self.options.verbose > 1: + if self.args.verbose > 1: raise if str(e): msg = ' ' + str(e) -- cgit v1.2.3 From 5ad647c869c90a6a64fb557d6a28b0d09d7e7354 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 02:10:59 -0800 Subject: use argparse and autoprogram for pshell --- docs/pscripts/pshell.rst | 8 ++------ pyramid/scripts/pshell.py | 50 ++++++++++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/docs/pscripts/pshell.rst b/docs/pscripts/pshell.rst index cfd84d4f8..4e2ce74cb 100644 --- a/docs/pscripts/pshell.rst +++ b/docs/pscripts/pshell.rst @@ -3,11 +3,7 @@ .. _pshell_script: -``pshell`` ----------- - -.. program-output:: pshell --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.pshell:PShellCommand.parser + :prog: pshell .. seealso:: :ref:`interactive_shell` diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index 56b1a15fa..7e00eeaac 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -1,5 +1,5 @@ from code import interact -import optparse +import argparse import os import sys import textwrap @@ -28,7 +28,6 @@ def python_shell_runner(env, help, interact=interact): class PShellCommand(object): - usage = '%prog config_uri' description = """\ Open an interactive shell with a Pyramid app loaded. This command accepts one positional argument named "config_uri" which specifies the @@ -45,26 +44,29 @@ class PShellCommand(object): bootstrap = (bootstrap,) # for testing pkg_resources = pkg_resources # for testing - parser = optparse.OptionParser( - usage, + parser = argparse.ArgumentParser( + usage="%(prog)s config_uri", description=textwrap.dedent(description) ) - parser.add_option('-p', '--python-shell', - action='store', type='string', dest='python_shell', - default='', - help=('Select the shell to use. A list of possible ' - 'shells is available using the --list-shells ' - 'option.')) - parser.add_option('-l', '--list-shells', - dest='list', - action='store_true', - help='List all available shells.') - parser.add_option('--setup', - dest='setup', - help=("A callable that will be passed the environment " - "before it is made available to the shell. This " - "option will override the 'setup' key in the " - "[pshell] ini section.")) + parser.add_argument('-p', '--python-shell', + action='store', + dest='python_shell', + default='', + help=('Select the shell to use. A list of possible ' + 'shells is available using the --list-shells ' + 'option.')) + parser.add_argument('-l', '--list-shells', + dest='list', + action='store_true', + help='List all available shells.') + parser.add_argument('--setup', + dest='setup', + help=("A callable that will be passed the environment " + "before it is made available to the shell. This " + "option will override the 'setup' key in the " + "[pshell] ini section.")) + parser.add_argument('config_uri', + help='The URI to the configuration file.') ConfigParser = configparser.ConfigParser # testing default_runner = python_shell_runner # testing @@ -77,7 +79,7 @@ class PShellCommand(object): def __init__(self, argv, quiet=False): self.quiet = quiet - self.options, self.args = self.parser.parse_args(argv[1:]) + self.args = self.parser.parse_args(argv[1:]) def pshell_file_config(self, filename): config = self.ConfigParser() @@ -132,8 +134,8 @@ class PShellCommand(object): 'Default root factory used to create `root`.') # override use_script with command-line options - if self.options.setup: - self.setup = self.options.setup + if self.args.setup: + self.setup = self.args.setup if self.setup: # store the env before muddling it with the script @@ -214,7 +216,7 @@ class PShellCommand(object): shells = self.find_all_shells() shell = None - user_shell = self.options.python_shell.lower() + user_shell = self.args.python_shell.lower() if not user_shell: preferred_shells = self.preferred_shells -- cgit v1.2.3 From 7dd4214cccdc417d78a78391cf387ff62489beb0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 02:15:11 -0800 Subject: use argparse and autoprogram for ptweens --- docs/pscripts/ptweens.rst | 8 ++------ pyramid/scripts/ptweens.py | 12 +++++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/pscripts/ptweens.rst b/docs/pscripts/ptweens.rst index 02e23e49a..f586e1467 100644 --- a/docs/pscripts/ptweens.rst +++ b/docs/pscripts/ptweens.rst @@ -3,11 +3,7 @@ .. _ptweens_script: -``ptweens`` ------------ - -.. program-output:: ptweens --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.ptweens:PTweensCommand.parser + :prog: ptweens .. seealso:: :ref:`displaying_tweens` diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index a7aa009da..3f8c9871e 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -1,4 +1,4 @@ -import optparse +import argparse import sys import textwrap @@ -14,7 +14,6 @@ def main(argv=sys.argv, quiet=False): return command.run() class PTweensCommand(object): - usage = '%prog config_uri' description = """\ Print all implicit and explicit tween objects used by a Pyramid application. The handler output includes whether the system is using an @@ -28,17 +27,20 @@ class PTweensCommand(object): will be assumed. Example: "ptweens myapp.ini#main". """ - parser = optparse.OptionParser( - usage, + parser = argparse.ArgumentParser( + usage="%(prog)s config_uri", description=textwrap.dedent(description), ) + parser.add_argument('config_uri', + help='The URI to the configuration file.') + stdout = sys.stdout bootstrap = (bootstrap,) # testing def __init__(self, argv, quiet=False): self.quiet = quiet - self.options, self.args = self.parser.parse_args(argv[1:]) + self.args = self.parser.parse_args(argv[1:]) def _get_tweens(self, registry): from pyramid.config import Configurator -- cgit v1.2.3 From 812bc62a37205353de1d1719b82718dd0699bf1a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 02:17:45 -0800 Subject: use argparse and autoprogram for ptviews --- docs/pscripts/pviews.rst | 8 ++------ pyramid/scripts/pviews.py | 12 +++++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/pscripts/pviews.rst b/docs/pscripts/pviews.rst index b4de5c054..da4660779 100644 --- a/docs/pscripts/pviews.rst +++ b/docs/pscripts/pviews.rst @@ -3,11 +3,7 @@ .. _pviews_script: -``pviews`` ----------- - -.. program-output:: pviews --help - :prompt: - :shell: +.. autoprogram:: pyramid.scripts.pviews:PViewsCommand.parser + :prog: pviews .. seealso:: :ref:`displaying_matching_views` diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index 9018eddb4..81150a801 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -1,4 +1,4 @@ -import optparse +import argparse import sys import textwrap @@ -13,7 +13,6 @@ def main(argv=sys.argv, quiet=False): return command.run() class PViewsCommand(object): - usage = '%prog config_uri url' description = """\ Print, for a given URL, the views that might match. Underneath each potentially matching route, list the predicates required. Underneath @@ -28,16 +27,19 @@ class PViewsCommand(object): """ stdout = sys.stdout - parser = optparse.OptionParser( - usage, + parser = argparse.ArgumentParser( + usage="%(prog)s config_uri url", description=textwrap.dedent(description) ) + parser.add_argument('config_uri', + help='The URI to the configuration file.') + bootstrap = (bootstrap,) # testing def __init__(self, argv, quiet=False): self.quiet = quiet - self.options, self.args = self.parser.parse_args(argv[1:]) + self.args = self.parser.parse_args(argv[1:]) def out(self, msg): # pragma: no cover if not self.quiet: -- cgit v1.2.3 From c47bfc66d61a692d9790ae1f8cf79599a7e2bbb5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 28 Nov 2016 16:32:15 -0800 Subject: restore slice of argv --- pyramid/scripts/pcreate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 49e5fbdf4..671233337 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -87,7 +87,7 @@ https://github.com/Pylons/?q=cookiecutter def __init__(self, argv, quiet=False): self.quiet = quiet - self.args = self.parser.parse_args(argv) + self.args = self.parser.parse_args(argv[1:]) if not self.args.interactive and not self.args.overwrite: self.args.interactive = True self.scaffolds = self.all_scaffolds() -- cgit v1.2.3 From 8d6301820dd4f13d2ab0424764d6969a8508b2a8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Dec 2016 23:14:05 -0800 Subject: make output_directory optional for argparse --- pyramid/scripts/pcreate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 671233337..278727308 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -80,6 +80,8 @@ https://github.com/Pylons/?q=cookiecutter 'is the name of an already existing / importable ' 'package.') parser.add_argument('output_directory', + nargs = '?', + default = None, help='The directory where the project will be ' 'created.') -- cgit v1.2.3 From 4996dbe000774b8d6fe015dd5d29b9bd9bfc827d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Dec 2016 23:15:17 -0800 Subject: add new test in attempt to catch status code and stderr --- pyramid/tests/test_scripts/test_pcreate.py | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py index 0286614ce..d6e6814fa 100644 --- a/pyramid/tests/test_scripts/test_pcreate.py +++ b/pyramid/tests/test_scripts/test_pcreate.py @@ -1,6 +1,32 @@ +from contextlib import contextmanager import unittest +@contextmanager +def patch_argparser(parser): + result = {} + old_exit = parser.exit + old_error = parser.error + try: + def dummy_exit(status=0, message=None): + result['status'] = status + result['message'] = message + raise ArgumentParserExit + + def dummy_error(message): + result['message'] = message + + parser.exit = dummy_exit + parser.error = dummy_error + yield result + finally: + parser.exit = old_exit + parser.error = old_error + +class ArgumentParserExit(Exception): + pass + + class TestPCreateCommand(unittest.TestCase): def setUp(self): from pyramid.compat import NativeIO @@ -49,6 +75,19 @@ class TestPCreateCommand(unittest.TestCase): self.assertTrue(out.count( 'You must provide at least one scaffold name')) + def test_test_no_project_name(self): + cmd = self._makeOne('-s', 'dummy') + with patch_argparser(cmd.parser) as result: + try: + cmd.run() + except ArgumentParserExit: + self.assertEqual(result['status'], 2) + self.assertTrue(result['message'].startswith( + 'usage: pcreate [-h] [-s SCAFFOLD_NAME] [-t SCAFFOLD_NAME] [-l]' + )) + else: # pragma: no cover + raise AssertionError + def test_no_project_name(self): cmd = self._makeOne('-s', 'dummy') result = cmd.run() -- cgit v1.2.3 From 74bed06995593b967afb626c6b3754861afb35b8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Dec 2016 23:49:31 -0800 Subject: tear out irrelevant test code, fix pcreate validation to test for output_directory --- pyramid/scripts/pcreate.py | 2 +- pyramid/tests/test_scripts/test_pcreate.py | 39 ------------------------------ 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 278727308..076b727a2 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -198,7 +198,7 @@ https://github.com/Pylons/?q=cookiecutter self.out('') self.show_scaffolds() return False - if not self.args: + if not self.args.output_directory: self.out('You must provide a project name') return False available = [x.name for x in self.scaffolds] diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py index d6e6814fa..0286614ce 100644 --- a/pyramid/tests/test_scripts/test_pcreate.py +++ b/pyramid/tests/test_scripts/test_pcreate.py @@ -1,32 +1,6 @@ -from contextlib import contextmanager import unittest -@contextmanager -def patch_argparser(parser): - result = {} - old_exit = parser.exit - old_error = parser.error - try: - def dummy_exit(status=0, message=None): - result['status'] = status - result['message'] = message - raise ArgumentParserExit - - def dummy_error(message): - result['message'] = message - - parser.exit = dummy_exit - parser.error = dummy_error - yield result - finally: - parser.exit = old_exit - parser.error = old_error - -class ArgumentParserExit(Exception): - pass - - class TestPCreateCommand(unittest.TestCase): def setUp(self): from pyramid.compat import NativeIO @@ -75,19 +49,6 @@ class TestPCreateCommand(unittest.TestCase): self.assertTrue(out.count( 'You must provide at least one scaffold name')) - def test_test_no_project_name(self): - cmd = self._makeOne('-s', 'dummy') - with patch_argparser(cmd.parser) as result: - try: - cmd.run() - except ArgumentParserExit: - self.assertEqual(result['status'], 2) - self.assertTrue(result['message'].startswith( - 'usage: pcreate [-h] [-s SCAFFOLD_NAME] [-t SCAFFOLD_NAME] [-l]' - )) - else: # pragma: no cover - raise AssertionError - def test_no_project_name(self): cmd = self._makeOne('-s', 'dummy') result = cmd.run() -- cgit v1.2.3 From 6293d331046c78e27a0065d39a5277040391dd2d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 6 Dec 2016 00:14:00 -0800 Subject: use ArgumentParser's default usage, specify prog argument --- pyramid/scripts/pdistreport.py | 2 +- pyramid/scripts/prequest.py | 2 +- pyramid/scripts/proutes.py | 5 ++--- pyramid/scripts/pshell.py | 2 +- pyramid/scripts/ptweens.py | 2 +- pyramid/scripts/pviews.py | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index e80ea20b6..e5928bde4 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -12,7 +12,7 @@ def out(*args): # pragma: no cover def get_parser(): parser = argparse.ArgumentParser( - usage="%(prog)s", + prog="pdistreport", description="Show Python distribution versions and locations in use") return parser diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 9e807896d..84e84e1c8 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -47,7 +47,7 @@ class PRequestCommand(object): """ parser = argparse.ArgumentParser( - usage="%(prog)s config_uri path_info [args/options]", + prog="prequest", description=textwrap.dedent(description) ) parser.add_argument( diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index 640cd20a3..e745e19fd 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -247,10 +247,9 @@ class PRoutesCommand(object): """ bootstrap = (bootstrap,) stdout = sys.stdout - usage = '%prog config_uri' - ConfigParser = configparser.ConfigParser # testing + ConfigParser = configparser.ConfigParser # testing parser = argparse.ArgumentParser( - usage, + prog="proutes", description=textwrap.dedent(description) ) parser.add_argument('-g', '--glob', diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index 7e00eeaac..4289f10c4 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -45,7 +45,7 @@ class PShellCommand(object): pkg_resources = pkg_resources # for testing parser = argparse.ArgumentParser( - usage="%(prog)s config_uri", + prog="pshell", description=textwrap.dedent(description) ) parser.add_argument('-p', '--python-shell', diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index 3f8c9871e..ed91757ab 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -28,7 +28,7 @@ class PTweensCommand(object): """ parser = argparse.ArgumentParser( - usage="%(prog)s config_uri", + prog="ptweens", description=textwrap.dedent(description), ) diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index 81150a801..e93d90a53 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -28,7 +28,7 @@ class PViewsCommand(object): stdout = sys.stdout parser = argparse.ArgumentParser( - usage="%(prog)s config_uri url", + prog="pviews", description=textwrap.dedent(description) ) -- cgit v1.2.3 From 31be0f5f72acf412486c66f2d423bbbec30091d5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 6 Dec 2016 00:43:00 -0800 Subject: make prequest tests pass --- pyramid/scripts/prequest.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 84e84e1c8..e4595a9cd 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -89,11 +89,15 @@ class PRequestCommand(object): parser.add_argument( 'config_uri', + nargs='?', + default=None, help='The URI to the configuration file.', ) parser.add_argument( 'path_info', + nargs='?', + default=None, help='The path of the request.', ) @@ -112,11 +116,11 @@ class PRequestCommand(object): setup_logging(app_spec) def run(self): - if not len(self.args) >= 2: + if not self.args.config_uri and not self.args.path_info: self.out('You must provide at least two arguments') return 2 - app_spec = self.args[0] - path = self.args[1] + app_spec = self.args.config_uri + path = self.args.path_info self.configure_logging(app_spec) @@ -146,7 +150,7 @@ class PRequestCommand(object): headers[name] = value.strip() app = self.get_app(app_spec, self.args.app_name, - options=parse_vars(self.args[2:])) + options=self.args) request_method = (self.args.method or 'GET').upper() -- cgit v1.2.3 From 307ee47697125ee34c615b44c57a9d84dd24d732 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 6 Dec 2016 02:39:17 -0800 Subject: update remaining pscripts to use nargs --- pyramid/scripts/proutes.py | 2 ++ pyramid/scripts/pshell.py | 2 ++ pyramid/scripts/ptweens.py | 2 ++ pyramid/scripts/pviews.py | 2 ++ 4 files changed, 8 insertions(+) diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index e745e19fd..a957b622a 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -268,6 +268,8 @@ class PRoutesCommand(object): parser.add_argument( 'config_uri', + nargs='?', + default=None, help='The URI to the configuration file.', ) diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index 4289f10c4..a7fa121cf 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -66,6 +66,8 @@ class PShellCommand(object): "option will override the 'setup' key in the " "[pshell] ini section.")) parser.add_argument('config_uri', + nargs='?', + default=None, help='The URI to the configuration file.') ConfigParser = configparser.ConfigParser # testing diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index ed91757ab..4c1555473 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -33,6 +33,8 @@ class PTweensCommand(object): ) parser.add_argument('config_uri', + nargs='?', + default=None, help='The URI to the configuration file.') stdout = sys.stdout diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index e93d90a53..7776077a8 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -33,6 +33,8 @@ class PViewsCommand(object): ) parser.add_argument('config_uri', + nargs='?', + default=None, help='The URI to the configuration file.') bootstrap = (bootstrap,) # testing -- cgit v1.2.3 From a4f18f93ecaf1fcd0bfb78aba7c6faf99762d253 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Dec 2016 20:31:45 -0800 Subject: update proutes with argparse-ish stuff --- pyramid/scripts/proutes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index a957b622a..696bdd953 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -326,8 +326,8 @@ class PRoutesCommand(object): self.out('requires a config file argument') return 2 - config_uri = self.args[0] - env = self.bootstrap[0](config_uri, options=parse_vars(self.args[1:])) + config_uri = self.args.config_uri + env = self.bootstrap[0](config_uri, options=vars(self.args)) registry = env['registry'] mapper = self._get_mapper(registry) -- cgit v1.2.3 From 83fb105cd8a5c0fff4aa8da35ee43c48c7b0424e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Dec 2016 20:49:16 -0800 Subject: test for the attribute config_uri --- pyramid/scripts/proutes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index 696bdd953..92ec48ed1 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -322,7 +322,7 @@ class PRoutesCommand(object): return config.get_routes_mapper() def run(self, quiet=False): - if not self.args: + if not self.args.config_uri: self.out('requires a config file argument') return 2 -- cgit v1.2.3 From e96b2b5d5b9ebab33cd6eb84ef498dbaf4da18cb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Dec 2016 22:26:54 -0800 Subject: add an argument `config_args` to be parsed and passed into bootstrap's options --- pyramid/scripts/proutes.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index 92ec48ed1..cf3ae5e9c 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -273,6 +273,14 @@ class PRoutesCommand(object): help='The URI to the configuration file.', ) + parser.add_argument( + 'config_args', + nargs='*', + default=(), + help='Arbitrary options to override those in the [app:main] section ' + 'of the configuration file.', + ) + def __init__(self, argv, quiet=False): self.args = self.parser.parse_args(argv[1:]) self.quiet = quiet @@ -327,7 +335,7 @@ class PRoutesCommand(object): return 2 config_uri = self.args.config_uri - env = self.bootstrap[0](config_uri, options=vars(self.args)) + env = self.bootstrap[0](config_uri, options=parse_vars(self.args.config_args)) registry = env['registry'] mapper = self._get_mapper(registry) -- cgit v1.2.3 From 0be0f1028ff8f996147ab275a403d6b99e43b932 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Dec 2016 23:10:02 -0800 Subject: fix proutes tests --- pyramid/tests/test_scripts/test_proutes.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pyramid/tests/test_scripts/test_proutes.py b/pyramid/tests/test_scripts/test_proutes.py index aeaa57060..e0a5be93a 100644 --- a/pyramid/tests/test_scripts/test_proutes.py +++ b/pyramid/tests/test_scripts/test_proutes.py @@ -20,7 +20,7 @@ class TestPRoutesCommand(unittest.TestCase): def _makeOne(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_uri = ('/foo/bar/myapp.ini#myapp',) return cmd @@ -38,7 +38,8 @@ class TestPRoutesCommand(unittest.TestCase): def test_good_args(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args = ('/foo/bar/myapp.ini#myapp', 'a=1') + cmd.args.config_uri = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_args = ('a=1',) route = dummy.DummyRoute('a', '/a') mapper = dummy.DummyMapper(route) cmd._get_mapper = lambda *arg: mapper @@ -52,7 +53,8 @@ class TestPRoutesCommand(unittest.TestCase): def test_bad_args(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args = ('/foo/bar/myapp.ini#myapp', 'a') + cmd.args.config_uri = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_args = ('a',) route = dummy.DummyRoute('a', '/a') mapper = dummy.DummyMapper(route) cmd._get_mapper = lambda *arg: mapper @@ -586,7 +588,7 @@ class TestPRoutesCommand(unittest.TestCase): ) command = self._makeOne() - command.options.glob = '*foo*' + command.args.glob = '*foo*' L = [] command.out = L.append @@ -618,8 +620,8 @@ class TestPRoutesCommand(unittest.TestCase): ) command = self._makeOne() - command.options.glob = '*foo*' - command.options.format = 'method,name' + command.args.glob = '*foo*' + command.args.format = 'method,name' L = [] command.out = L.append command.bootstrap = (dummy.DummyBootstrap(registry=config.registry),) @@ -648,8 +650,8 @@ class TestPRoutesCommand(unittest.TestCase): ) command = self._makeOne() - command.options.glob = '*foo*' - command.options.format = 'predicates,name,pattern' + command.args.glob = '*foo*' + command.args.format = 'predicates,name,pattern' L = [] command.out = L.append command.bootstrap = (dummy.DummyBootstrap(registry=config.registry),) -- cgit v1.2.3 From 9de2cd1d05ff62e3f75930559c2d83553df45d80 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 05:08:32 -0800 Subject: fix pserve to allow 4 of 5 tests to pass --- pyramid/scripts/pserve.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index f3515804d..50f4ac1d2 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -100,8 +100,18 @@ class PServeCommand(object): help="Suppress verbose output") parser.add_argument( 'config_uri', + nargs='?', + default=None, help='The URI to the configuration file.', ) + parser.add_argument( + 'config_args', + nargs='*', + default=(), + help='Arbitrary options to override those in the [app:main] section ' + 'of the configuration file.', + ) + ConfigParser = configparser.ConfigParser # testing loadapp = staticmethod(loadapp) # testing @@ -120,7 +130,7 @@ class PServeCommand(object): print(msg) def get_options(self): - restvars = self.args[1:] + restvars = self.args.config_args return parse_vars(restvars) def pserve_file_config(self, filename, global_conf=None): @@ -150,10 +160,10 @@ class PServeCommand(object): self.watch_files.append(os.path.abspath(file)) def run(self): # pragma: no cover - if not self.args: + if not self.args.config_uri: self.out('You must give a config file') return 2 - app_spec = self.args[0] + app_spec = self.args.config_uri vars = self.get_options() app_name = self.args.app_name -- cgit v1.2.3 From 3b72e86a4dc05086fb06b89f108d4e8129ec7d7c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 15:28:51 -0800 Subject: refactor get_options to get_config_args --- pyramid/scripts/pserve.py | 4 ++-- pyramid/tests/test_scripts/test_pserve.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 50f4ac1d2..6581c1b7a 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -129,7 +129,7 @@ class PServeCommand(object): if self.args.verbose > 0: print(msg) - def get_options(self): + def get_config_args(self): restvars = self.args.config_args return parse_vars(restvars) @@ -165,7 +165,7 @@ class PServeCommand(object): return 2 app_spec = self.args.config_uri - vars = self.get_options() + vars = self.get_config_args() app_name = self.args.app_name base = os.getcwd() diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index 18f7c8c2f..9934fc441 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -36,10 +36,10 @@ class TestPServeCommand(unittest.TestCase): self.assertEqual(result, 2) self.assertEqual(self.out_.getvalue(), 'You must give a config file') - def test_get_options_no_command(self): + def test_config_args_no_command(self): inst = self._makeOne() inst.args = ['foo', 'a=1', 'b=2'] - result = inst.get_options() + result = inst.get_config_args() self.assertEqual(result, {'a': '1', 'b': '2'}) def test_parse_vars_good(self): -- cgit v1.2.3 From 7ff9e9a3229a709f357a88d39763e34d9fb62206 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 15:46:52 -0800 Subject: get final pserve test to pass - ping @mmerickel or @bertjwregeer for review. I'm uncertain about what was the original test's intent, and whether this test still tests what was originally intended. --- pyramid/tests/test_scripts/test_pserve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index 9934fc441..f19985b35 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -38,7 +38,7 @@ class TestPServeCommand(unittest.TestCase): def test_config_args_no_command(self): inst = self._makeOne() - inst.args = ['foo', 'a=1', 'b=2'] + inst.args.config_args = ['a=1', 'b=2'] result = inst.get_config_args() self.assertEqual(result, {'a': '1', 'b': '2'}) -- cgit v1.2.3 From be51e57ac1f423579dc7426f93e957e3bf8ef450 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 17:04:22 -0800 Subject: test for self.args.output_directory instead of just self.args --- pyramid/scripts/pcreate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 076b727a2..b3181c2b3 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -98,7 +98,7 @@ https://github.com/Pylons/?q=cookiecutter self._warn_pcreate_deprecated() if self.args.list: return self.show_scaffolds() - if not self.args.scaffold_name and not self.args: + if not self.args.scaffold_name and not self.args.output_directory: if not self.quiet: # pragma: no cover self.parser.print_help() self.out('') -- cgit v1.2.3 From 5320e7e0d4b465a7c38004652c3ccf4c5b4e79c7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 17:11:30 -0800 Subject: add config_args option, fix nonsense options parameter --- pyramid/scripts/prequest.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index e4595a9cd..2025ecccc 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -101,6 +101,14 @@ class PRequestCommand(object): help='The path of the request.', ) + parser.add_argument( + 'config_args', + nargs='*', + default=(), + help='Arbitrary options to override those in the [app:main] section ' + 'of the configuration file.', + ) + get_app = staticmethod(get_app) stdin = sys.stdin @@ -150,7 +158,7 @@ class PRequestCommand(object): headers[name] = value.strip() app = self.get_app(app_spec, self.args.app_name, - options=self.args) + options=self.args.config_args) request_method = (self.args.method or 'GET').upper() -- cgit v1.2.3 From 898014c2e3b3fcebe5c5e7040ff3ca1409422873 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 17:11:49 -0800 Subject: use default usage --- pyramid/scripts/pserve.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 6581c1b7a..3816e7c75 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -51,7 +51,6 @@ class PServeCommand(object): default_verbosity = 1 parser = argparse.ArgumentParser( - usage="%(prog)s config_uri [var=value]", description=textwrap.dedent(description) ) parser.add_argument( -- cgit v1.2.3 From 1fc1b819f9364c0d64fc4e60c514141a58d641da Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 18:06:59 -0800 Subject: test for self.args.list and self.args.config_uri --- pyramid/scripts/pshell.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index a7fa121cf..9268c6e10 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -110,12 +110,12 @@ class PShellCommand(object): print(msg) def run(self, shell=None): - if self.options.list: + if self.args.list: return self.show_shells() - if not self.args: + if not self.args.config_uri: self.out('Requires a config file argument') return 2 - config_uri = self.args[0] + config_uri = self.args.config_uri config_file = config_uri.split('#', 1)[0] setup_logging(config_file) self.pshell_file_config(config_file) -- cgit v1.2.3 From d631aff9fd4a144cb9fce265b644aa3affbb6188 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 18:14:13 -0800 Subject: remove prog argument --- pyramid/scripts/pdistreport.py | 1 - pyramid/scripts/prequest.py | 1 - pyramid/scripts/proutes.py | 3 +-- pyramid/scripts/pshell.py | 1 - pyramid/scripts/ptweens.py | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/pyramid/scripts/pdistreport.py b/pyramid/scripts/pdistreport.py index e5928bde4..1952e5d39 100644 --- a/pyramid/scripts/pdistreport.py +++ b/pyramid/scripts/pdistreport.py @@ -12,7 +12,6 @@ def out(*args): # pragma: no cover def get_parser(): parser = argparse.ArgumentParser( - prog="pdistreport", description="Show Python distribution versions and locations in use") return parser diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 2025ecccc..1da54b8c0 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -47,7 +47,6 @@ class PRequestCommand(object): """ parser = argparse.ArgumentParser( - prog="prequest", description=textwrap.dedent(description) ) parser.add_argument( diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index cf3ae5e9c..26c112cde 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -249,9 +249,8 @@ class PRoutesCommand(object): stdout = sys.stdout ConfigParser = configparser.ConfigParser # testing parser = argparse.ArgumentParser( - prog="proutes", description=textwrap.dedent(description) - ) + ) parser.add_argument('-g', '--glob', action='store', dest='glob', diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index 9268c6e10..08aae6980 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -45,7 +45,6 @@ class PShellCommand(object): pkg_resources = pkg_resources # for testing parser = argparse.ArgumentParser( - prog="pshell", description=textwrap.dedent(description) ) parser.add_argument('-p', '--python-shell', diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index 4c1555473..7f0101323 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -28,7 +28,6 @@ class PTweensCommand(object): """ parser = argparse.ArgumentParser( - prog="ptweens", description=textwrap.dedent(description), ) -- cgit v1.2.3 From a8667577659a2622973dc80d177ac143fd161587 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 18:56:58 -0800 Subject: refactor config_args to config_vars --- pyramid/scripts/prequest.py | 4 ++-- pyramid/scripts/proutes.py | 4 ++-- pyramid/scripts/pserve.py | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 1da54b8c0..714aedf10 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -101,7 +101,7 @@ class PRequestCommand(object): ) parser.add_argument( - 'config_args', + 'config_vars', nargs='*', default=(), help='Arbitrary options to override those in the [app:main] section ' @@ -157,7 +157,7 @@ class PRequestCommand(object): headers[name] = value.strip() app = self.get_app(app_spec, self.args.app_name, - options=self.args.config_args) + options=self.args.config_vars) request_method = (self.args.method or 'GET').upper() diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index 26c112cde..df8e51e39 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -273,7 +273,7 @@ class PRoutesCommand(object): ) parser.add_argument( - 'config_args', + 'config_vars', nargs='*', default=(), help='Arbitrary options to override those in the [app:main] section ' @@ -334,7 +334,7 @@ class PRoutesCommand(object): return 2 config_uri = self.args.config_uri - env = self.bootstrap[0](config_uri, options=parse_vars(self.args.config_args)) + env = self.bootstrap[0](config_uri, options=parse_vars(self.args.config_vars)) registry = env['registry'] mapper = self._get_mapper(registry) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 3816e7c75..51cdd235a 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -104,7 +104,7 @@ class PServeCommand(object): help='The URI to the configuration file.', ) parser.add_argument( - 'config_args', + 'config_vars', nargs='*', default=(), help='Arbitrary options to override those in the [app:main] section ' @@ -128,8 +128,8 @@ class PServeCommand(object): if self.args.verbose > 0: print(msg) - def get_config_args(self): - restvars = self.args.config_args + def get_config_vars(self): + restvars = self.args.config_vars return parse_vars(restvars) def pserve_file_config(self, filename, global_conf=None): @@ -164,7 +164,7 @@ class PServeCommand(object): return 2 app_spec = self.args.config_uri - vars = self.get_config_args() + vars = self.get_config_vars() app_name = self.args.app_name base = os.getcwd() -- cgit v1.2.3 From b5faf2f17baddbc08bf43da2d244f6970ce9b012 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 19:05:39 -0800 Subject: update help for pserve config_vars --- pyramid/scripts/pserve.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 51cdd235a..845933c27 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -107,9 +107,10 @@ class PServeCommand(object): 'config_vars', nargs='*', default=(), - help='Arbitrary options to override those in the [app:main] section ' - 'of the configuration file.', - ) + help="Variables required by the config file. For example, " + "`http_port=%%(http_port)s` would expect `http_port=8080` to be " + "passed here.", + ) ConfigParser = configparser.ConfigParser # testing -- cgit v1.2.3 From a63b0f56e02f8b59cb4c36f1b1facf8dd48766af Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Dec 2016 19:23:45 -0800 Subject: - change from tuple to string - refactor config_args to config_vars --- pyramid/tests/test_scripts/test_proutes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/tests/test_scripts/test_proutes.py b/pyramid/tests/test_scripts/test_proutes.py index e0a5be93a..3c51ea6b4 100644 --- a/pyramid/tests/test_scripts/test_proutes.py +++ b/pyramid/tests/test_scripts/test_proutes.py @@ -20,7 +20,7 @@ class TestPRoutesCommand(unittest.TestCase): def _makeOne(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args.config_uri = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' return cmd @@ -53,8 +53,8 @@ class TestPRoutesCommand(unittest.TestCase): def test_bad_args(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args.config_uri = ('/foo/bar/myapp.ini#myapp',) - cmd.args.config_args = ('a',) + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' + cmd.args.config_vars = ('a',) route = dummy.DummyRoute('a', '/a') mapper = dummy.DummyMapper(route) cmd._get_mapper = lambda *arg: mapper -- cgit v1.2.3 From 67f0c2f626036f404c46982ba0ac58ea513f0e10 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 00:39:53 -0800 Subject: restore parse_vars --- pyramid/scripts/prequest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 714aedf10..f0ac0dfa9 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -157,7 +157,7 @@ class PRequestCommand(object): headers[name] = value.strip() app = self.get_app(app_spec, self.args.app_name, - options=self.args.config_vars) + options=parse_vars(self.args.config_vars)) request_method = (self.args.method or 'GET').upper() -- cgit v1.2.3 From 81e59a914c151d65cdd45d5f6f8c53b889aa77b8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 00:40:43 -0800 Subject: remove prog argument --- pyramid/scripts/pviews.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index 7776077a8..4c511a102 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -28,7 +28,6 @@ class PViewsCommand(object): stdout = sys.stdout parser = argparse.ArgumentParser( - prog="pviews", description=textwrap.dedent(description) ) -- cgit v1.2.3 From aa1ce33153eaa0c44ddfe5e0be173cbbd915c477 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 00:42:04 -0800 Subject: change config to tuple from string --- pyramid/tests/test_scripts/test_proutes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/tests/test_scripts/test_proutes.py b/pyramid/tests/test_scripts/test_proutes.py index 3c51ea6b4..74293a112 100644 --- a/pyramid/tests/test_scripts/test_proutes.py +++ b/pyramid/tests/test_scripts/test_proutes.py @@ -38,7 +38,7 @@ class TestPRoutesCommand(unittest.TestCase): def test_good_args(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args.config_uri = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' cmd.args.config_args = ('a=1',) route = dummy.DummyRoute('a', '/a') mapper = dummy.DummyMapper(route) -- cgit v1.2.3 From 931cbd9df499dc9c82c30081757a1d315cf89083 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 00:43:54 -0800 Subject: one more refactor of config_args to config_vars; bring back 'foo' as an arg --- pyramid/tests/test_scripts/test_pserve.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index f19985b35..5f6d6ee57 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -38,8 +38,8 @@ class TestPServeCommand(unittest.TestCase): def test_config_args_no_command(self): inst = self._makeOne() - inst.args.config_args = ['a=1', 'b=2'] - result = inst.get_config_args() + inst.args.config_args = ['foo', 'a=1', 'b=2'] + result = inst.get_config_vars() self.assertEqual(result, {'a': '1', 'b': '2'}) def test_parse_vars_good(self): -- cgit v1.2.3 From 2b7d128b9c5f1587f22c651ae44f71c331b22827 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 00:47:56 -0800 Subject: one more refactor of config_args to config_vars --- pyramid/tests/test_scripts/test_pserve.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index 5f6d6ee57..4eb85edf9 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -36,9 +36,9 @@ class TestPServeCommand(unittest.TestCase): self.assertEqual(result, 2) self.assertEqual(self.out_.getvalue(), 'You must give a config file') - def test_config_args_no_command(self): + def test_config_vars_no_command(self): inst = self._makeOne() - inst.args.config_args = ['foo', 'a=1', 'b=2'] + inst.args.config_vars = ['foo', 'a=1', 'b=2'] result = inst.get_config_vars() self.assertEqual(result, {'a': '1', 'b': '2'}) -- cgit v1.2.3 From 74b2368db37f360bf1021ab8b1d35961944597b5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 00:55:53 -0800 Subject: brain function temporarily restored, split config_vars into _vars and _uri - herpderp --- pyramid/tests/test_scripts/test_pserve.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py index 4eb85edf9..18b0c84b6 100644 --- a/pyramid/tests/test_scripts/test_pserve.py +++ b/pyramid/tests/test_scripts/test_pserve.py @@ -38,7 +38,8 @@ class TestPServeCommand(unittest.TestCase): def test_config_vars_no_command(self): inst = self._makeOne() - inst.args.config_vars = ['foo', 'a=1', 'b=2'] + inst.args.config_uri = 'foo' + inst.args.config_vars = ['a=1', 'b=2'] result = inst.get_config_vars() self.assertEqual(result, {'a': '1', 'b': '2'}) -- cgit v1.2.3 From 0a3a208cb1bbe21c8e350f83a47bade71cdb8f4f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 03:06:35 -0800 Subject: add missing period --- pyramid/scripts/pshell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index 08aae6980..7fa2f04a1 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -33,7 +33,7 @@ class PShellCommand(object): accepts one positional argument named "config_uri" which specifies the PasteDeploy config file to use for the interactive shell. The format is "inifile#name". If the name is left off, the Pyramid default application - will be assumed. Example: "pshell myapp.ini#main" + will be assumed. Example: "pshell myapp.ini#main". If you do not point the loader directly at the section of the ini file containing your Pyramid application, the command will attempt to -- cgit v1.2.3 From 53937c4083a06479050400f96b4eae2f0795c064 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 03:17:38 -0800 Subject: change command.options to command.args --- pyramid/tests/test_scripts/test_pshell.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pshell.py b/pyramid/tests/test_scripts/test_pshell.py index f98ded6d3..45d21015b 100644 --- a/pyramid/tests/test_scripts/test_pshell.py +++ b/pyramid/tests/test_scripts/test_pshell.py @@ -71,7 +71,7 @@ class TestPShellCommand(unittest.TestCase): self._makeEntryPoints(command, {}) command.default_runner = shell - command.options.python_shell = 'unknown_python_shell' + command.args.python_shell = 'unknown_python_shell' result = command.run() self.assertEqual(result, 1) self.assertEqual( @@ -95,7 +95,7 @@ class TestPShellCommand(unittest.TestCase): } ) - command.options.python_shell = 'ipython' + command.args.python_shell = 'ipython' command.run() self.assertTrue(self.config_factory.parser) @@ -140,7 +140,7 @@ class TestPShellCommand(unittest.TestCase): shell = command.make_shell() self.assertEqual(shell, dshell) - command.options.python_shell = 'ipython' + command.args.python_shell = 'ipython' self.assertRaises(ValueError, command.make_shell) self._makeEntryPoints( @@ -152,15 +152,15 @@ class TestPShellCommand(unittest.TestCase): } ) - command.options.python_shell = 'ipython' + command.args.python_shell = 'ipython' shell = command.make_shell() self.assertEqual(shell, ipshell) - command.options.python_shell = 'bpython' + command.args.python_shell = 'bpython' shell = command.make_shell() self.assertEqual(shell, bpshell) - command.options.python_shell = 'python' + command.args.python_shell = 'python' shell = command.make_shell() self.assertEqual(shell, dshell) @@ -291,7 +291,7 @@ class TestPShellCommand(unittest.TestCase): model = dummy.Dummy() self.config_factory.items = [('setup', 'abc'), ('m', model)] - command.options.setup = setup + command.args.setup = setup shell = dummy.DummyShell() command.run(shell) self.assertTrue(self.config_factory.parser) @@ -365,7 +365,7 @@ class TestPShellCommand(unittest.TestCase): } ) - command.options.list = True + command.args.list = True result = command.run() self.assertEqual(result, 0) self.assertEqual(out_calls, [ -- cgit v1.2.3 From ba93133ee29ecacad04770af7dffc39f2b2d3aff Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 04:02:01 -0800 Subject: update ptweens with config_vars argument - replace self.args with self.args.config_uri --- pyramid/scripts/ptweens.py | 14 +++++++++++--- pyramid/tests/test_scripts/test_ptweens.py | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index 7f0101323..348f2b372 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -36,6 +36,14 @@ class PTweensCommand(object): default=None, help='The URI to the configuration file.') + parser.add_argument( + 'config_vars', + nargs='*', + default=(), + help='Arbitrary options to override those in the [app:main] section ' + 'of the configuration file.', + ) + stdout = sys.stdout bootstrap = (bootstrap,) # testing @@ -62,11 +70,11 @@ class PTweensCommand(object): self.out(fmt % ('-', MAIN)) def run(self): - if not self.args: + if not self.args.config_uri: self.out('Requires a config file argument') return 2 - config_uri = self.args[0] - env = self.bootstrap[0](config_uri, options=parse_vars(self.args[1:])) + config_uri = self.args.config_uri + env = self.bootstrap[0](config_uri, options=parse_vars(self.args.config_vars)) registry = env['registry'] tweens = self._get_tweens(registry) if tweens is not None: diff --git a/pyramid/tests/test_scripts/test_ptweens.py b/pyramid/tests/test_scripts/test_ptweens.py index f39f84b68..f63069fed 100644 --- a/pyramid/tests/test_scripts/test_ptweens.py +++ b/pyramid/tests/test_scripts/test_ptweens.py @@ -9,7 +9,7 @@ class TestPTweensCommand(unittest.TestCase): def _makeOne(self): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(),) - cmd.args = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' return cmd def test_command_no_tweens(self): -- cgit v1.2.3 From 5b40cd38daf5c1a58810a0bff364be0043bc46ba Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 04:15:53 -0800 Subject: update pviews with url, config_vars arguments - fix run(self) method - use correct self.args.config_url and .url in tests --- pyramid/scripts/pviews.py | 22 ++++++++++++++---- pyramid/tests/test_scripts/test_pviews.py | 38 ++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index 4c511a102..c109f884a 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -36,6 +36,20 @@ class PViewsCommand(object): default=None, help='The URI to the configuration file.') + parser.add_argument('url', + nargs='?', + default=None, + help='The path info portion of the URL.') + parser.add_argument( + 'config_vars', + nargs='*', + default=(), + help="Variables required by the config file. For example, " + "`http_port=%%(http_port)s` would expect `http_port=8080` to be " + "passed here.", + ) + + bootstrap = (bootstrap,) # testing def __init__(self, argv, quiet=False): @@ -233,16 +247,16 @@ class PViewsCommand(object): self.out("%sview predicates (%s)" % (indent, predicate_text)) def run(self): - if len(self.args) < 2: + if not self.args.config_uri and not self.args.url: self.out('Command requires a config file arg and a url arg') return 2 - config_uri = self.args[0] - url = self.args[1] + config_uri = self.args.config_uri + url = self.args.url if not url.startswith('/'): url = '/%s' % url request = Request.blank(url) - env = self.bootstrap[0](config_uri, options=parse_vars(self.args[2:]), + env = self.bootstrap[0](config_uri, options=parse_vars(self.args.config_vars), request=request) view = self._find_view(request) self.out('') diff --git a/pyramid/tests/test_scripts/test_pviews.py b/pyramid/tests/test_scripts/test_pviews.py index b162144a7..a67a8c4d6 100644 --- a/pyramid/tests/test_scripts/test_pviews.py +++ b/pyramid/tests/test_scripts/test_pviews.py @@ -9,7 +9,7 @@ class TestPViewsCommand(unittest.TestCase): def _makeOne(self, registry=None): cmd = self._getTargetClass()([]) cmd.bootstrap = (dummy.DummyBootstrap(registry=registry),) - cmd.args = ('/foo/bar/myapp.ini#myapp',) + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' return cmd def _makeRequest(self, url, registry): @@ -242,7 +242,8 @@ class TestPViewsCommand(unittest.TestCase): L = [] command.out = L.append command._find_view = lambda arg1: None - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -255,7 +256,8 @@ class TestPViewsCommand(unittest.TestCase): L = [] command.out = L.append command._find_view = lambda arg1: None - command.args = ('/foo/bar/myapp.ini#myapp', 'a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -269,7 +271,8 @@ class TestPViewsCommand(unittest.TestCase): command.out = L.append view = dummy.DummyView(context='context', view_name='a') command._find_view = lambda arg1: view - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -287,7 +290,8 @@ class TestPViewsCommand(unittest.TestCase): def view(): pass view.__request_attrs__ = {'context': 'context', 'view_name': 'a'} command._find_view = lambda arg1: view - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -305,7 +309,8 @@ class TestPViewsCommand(unittest.TestCase): view = dummy.DummyView(context='context', view_name='a') view.__permission__ = 'test' command._find_view = lambda arg1: view - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -326,7 +331,8 @@ class TestPViewsCommand(unittest.TestCase): view = dummy.DummyView(context='context', view_name='a') view.__predicates__ = [predicate] command._find_view = lambda arg1: view - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -346,7 +352,8 @@ class TestPViewsCommand(unittest.TestCase): view = dummy.DummyView(context='context', view_name='a', matched_route=route, subpath='') command._find_view = lambda arg1: view - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -374,7 +381,8 @@ class TestPViewsCommand(unittest.TestCase): multiview2 = dummy.DummyMultiView(multiview1, context='context', view_name='a') command._find_view = lambda arg1: multiview2 - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -397,7 +405,8 @@ class TestPViewsCommand(unittest.TestCase): view = dummy.DummyView(context='context', view_name='a', matched_route=route, subpath='') command._find_view = lambda arg1: view - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -423,7 +432,8 @@ class TestPViewsCommand(unittest.TestCase): view.__view_attr__ = 'call' multiview = dummy.DummyMultiView(view, context='context', view_name='a') command._find_view = lambda arg1: multiview - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -444,7 +454,8 @@ class TestPViewsCommand(unittest.TestCase): view.__permission__ = 'test' multiview = dummy.DummyMultiView(view, context='context', view_name='a') command._find_view = lambda arg1: multiview - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') @@ -468,7 +479,8 @@ class TestPViewsCommand(unittest.TestCase): view.__predicates__ = [predicate] multiview = dummy.DummyMultiView(view, context='context', view_name='a') command._find_view = lambda arg1: multiview - command.args = ('/foo/bar/myapp.ini#myapp', '/a') + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') -- cgit v1.2.3 From 3c431019de4899e6a71cc5650ec52df65d56b2d7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 04:35:04 -0800 Subject: update pshell with config_vars argument --- pyramid/scripts/pshell.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index 7fa2f04a1..d8abf6619 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -68,6 +68,14 @@ class PShellCommand(object): nargs='?', default=None, help='The URI to the configuration file.') + parser.add_argument( + 'config_vars', + nargs='*', + default=(), + help="Variables required by the config file. For example, " + "`http_port=%%(http_port)s` would expect `http_port=8080` to be " + "passed here.", + ) ConfigParser = configparser.ConfigParser # testing default_runner = python_shell_runner # testing @@ -120,7 +128,8 @@ class PShellCommand(object): self.pshell_file_config(config_file) # bootstrap the environ - env = self.bootstrap[0](config_uri, options=parse_vars(self.args[1:])) + env = self.bootstrap[0](config_uri, + options=parse_vars(self.args.config_vars)) # remove the closer from the env self.closer = env.pop('closer') -- cgit v1.2.3 From 2d9c134245614026ec9528e5a9e78ba1d923f64b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 22:37:47 -0800 Subject: add an Args class, following pattern for OPtions; pshell tests now pass --- pyramid/tests/test_scripts/test_pshell.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyramid/tests/test_scripts/test_pshell.py b/pyramid/tests/test_scripts/test_pshell.py index 45d21015b..303964b2b 100644 --- a/pyramid/tests/test_scripts/test_pshell.py +++ b/pyramid/tests/test_scripts/test_pshell.py @@ -19,8 +19,10 @@ class TestPShellCommand(unittest.TestCase): self.config_factory = dummy.DummyConfigParserFactory() cmd.ConfigParser = self.config_factory if patch_args: - self.args = ('/foo/bar/myapp.ini#myapp',) - cmd.args = self.args + class Args(object): pass + self.args = Args() + self.args.config_uri = '/foo/bar/myapp.ini#myapp' + cmd.args.config_uri = self.args.config_uri if patch_options: class Options(object): pass self.options = Options() -- cgit v1.2.3 From 2fcfda1392b99cc403c99328b1b197432c3ea145 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 22:57:42 -0800 Subject: change options to args for test_template. This now aligns with pcreate, which the test uses --- pyramid/tests/test_scaffolds/test_template.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/tests/test_scaffolds/test_template.py b/pyramid/tests/test_scaffolds/test_template.py index 2e961c516..98f2daf73 100644 --- a/pyramid/tests/test_scaffolds/test_template.py +++ b/pyramid/tests/test_scaffolds/test_template.py @@ -143,13 +143,13 @@ class DummyCopydir(object): self.vars = vars self.kw = kw -class DummyOptions(object): +class DummyArgs(object): simulate = False overwrite = False interactive = False class DummyCommand(object): - options = DummyOptions() + args = DummyArgs() verbosity = 1 -- cgit v1.2.3 From 0183e44b667fa03fbb437398778fefc7d09d142d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 23:03:32 -0800 Subject: PEP8 --- pyramid/scripts/pcreate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index b3181c2b3..790fac230 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -80,8 +80,8 @@ https://github.com/Pylons/?q=cookiecutter 'is the name of an already existing / importable ' 'package.') parser.add_argument('output_directory', - nargs = '?', - default = None, + nargs='?', + default=None, help='The directory where the project will be ' 'created.') -- cgit v1.2.3 From 79f067b570cd8e23ee09a5b1de4b2fb3ec589a00 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 23:07:52 -0800 Subject: add sphinx.ext.todo, support for todo items --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 5496452bd..b9d2958b0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,6 +55,7 @@ extensions = [ 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx', 'sphinxcontrib.autoprogram', + 'sphinx.ext.todo', # enable pylons_sphinx_latesturl when this branch is no longer "latest" # 'pylons_sphinx_latesturl', ] -- cgit v1.2.3 From 8529b334e96078bac6c626da764db8f8e111ad72 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Dec 2016 23:14:20 -0800 Subject: fix test that caused coverage to drop one line --- pyramid/tests/test_scripts/test_pviews.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/tests/test_scripts/test_pviews.py b/pyramid/tests/test_scripts/test_pviews.py index a67a8c4d6..7bdab5804 100644 --- a/pyramid/tests/test_scripts/test_pviews.py +++ b/pyramid/tests/test_scripts/test_pviews.py @@ -257,7 +257,7 @@ class TestPViewsCommand(unittest.TestCase): command.out = L.append command._find_view = lambda arg1: None command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' + command.args.url = 'a' result = command.run() self.assertEqual(result, 0) self.assertEqual(L[1], 'URL = /a') -- cgit v1.2.3 From 8dfa640a52d57b630843a65b3b84bc13a8a1ed87 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 14 Dec 2016 00:21:22 -0600 Subject: fix holdover from chameleon in starter layout --- pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl b/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl index 360855602..6f0cfd2fa 100644 --- a/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl +++ b/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl @@ -6,7 +6,7 @@ - + Starter Scaffold for The Pyramid Web Framework -- cgit v1.2.3 From 50e8f0eb4d7a406b7041d0e01a2e1a15a0908ac0 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 14 Dec 2016 00:26:35 -0600 Subject: changelog for #2853 --- CHANGES.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 8c50e4d63..575038f0a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -39,9 +39,6 @@ Backward Incompatibilities (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. See https://github.com/Pylons/pyramid/pull/2823 -- Scaffolds, documentation and tutorials now use ``listen`` option instead - of ``host`` and ``port`` to configure Waitress server. - Features -------- @@ -132,6 +129,10 @@ Features a response. See https://github.com/Pylons/pyramid/pull/2863 +- Update starter, alchemy and zodb scaffolds to support IPv6 by using the + new ``listen`` directives in waitress. + See https://github.com/Pylons/pyramid/pull/2853 + Bug Fixes --------- -- cgit v1.2.3 From 258f8482549a75a627e5b80790ca7f7f84308684 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 23:31:48 -0800 Subject: fix faulty logic in prequest and pviews --- pyramid/scripts/prequest.py | 2 +- pyramid/scripts/pviews.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index f0ac0dfa9..1136dd409 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -123,7 +123,7 @@ class PRequestCommand(object): setup_logging(app_spec) def run(self): - if not self.args.config_uri and not self.args.path_info: + if not self.args.config_uri or not self.args.path_info: self.out('You must provide at least two arguments') return 2 app_spec = self.args.config_uri diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index c109f884a..64408bdad 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -247,7 +247,7 @@ class PViewsCommand(object): self.out("%sview predicates (%s)" % (indent, predicate_text)) def run(self): - if not self.args.config_uri and not self.args.url: + if not self.args.config_uri or not self.args.url: self.out('Command requires a config file arg and a url arg') return 2 config_uri = self.args.config_uri -- cgit v1.2.3 From f5ae217a444b9ba3598038d55204df35cb624a42 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 23:47:46 -0800 Subject: move deprecation warning further down in the logic to avoid it from being emitted for invalid commands --- pyramid/scripts/pcreate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 790fac230..d1200da42 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -95,7 +95,6 @@ https://github.com/Pylons/?q=cookiecutter self.scaffolds = self.all_scaffolds() def run(self): - self._warn_pcreate_deprecated() if self.args.list: return self.show_scaffolds() if not self.args.scaffold_name and not self.args.output_directory: @@ -107,6 +106,7 @@ https://github.com/Pylons/?q=cookiecutter if not self.validate_input(): return 2 + self._warn_pcreate_deprecated() return self.render_scaffolds() -- cgit v1.2.3 From 91db73661dfc4deccb68698a95004f2871aafcf1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Dec 2016 23:55:15 -0800 Subject: PEP8 --- pyramid/scripts/pcreate.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index d1200da42..75e3b1fdc 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -17,12 +17,12 @@ def main(argv=sys.argv, quiet=False): command = PCreateCommand(argv, quiet) try: return command.run() - except KeyboardInterrupt: # pragma: no cover + except KeyboardInterrupt: # pragma: no cover return 1 class PCreateCommand(object): - verbosity = 1 # required + verbosity = 1 # required parser = argparse.ArgumentParser(description="""\ Render Pyramid scaffolding to an output directory. @@ -98,7 +98,7 @@ https://github.com/Pylons/?q=cookiecutter if self.args.list: return self.show_scaffolds() if not self.args.scaffold_name and not self.args.output_directory: - if not self.quiet: # pragma: no cover + if not self.quiet: # pragma: no cover self.parser.print_help() self.out('') self.show_scaffolds() @@ -130,7 +130,7 @@ https://github.com/Pylons/?q=cookiecutter # get pyramid package version pyramid_version = self.pyramid_dist.version - ## map pyramid package version of the documentation branch ## + # map pyramid package version of the documentation branch ## # if version ends with 'dev' then docs version is 'master' if self.pyramid_dist.version[-3:] == 'dev': pyramid_docs_branch = 'master' @@ -152,7 +152,6 @@ https://github.com/Pylons/?q=cookiecutter 'pyramid_docs_branch': pyramid_docs_branch, } - def render_scaffolds(self): props = self.project_vars output_dir = self.output_path @@ -183,18 +182,19 @@ https://github.com/Pylons/?q=cookiecutter scaffold_class = entry.load() scaffold = scaffold_class(entry.name) scaffolds.append(scaffold) - except Exception as e: # pragma: no cover + except Exception as e: # pragma: no cover self.out('Warning: could not load entry point %s (%s: %s)' % ( entry.name, e.__class__.__name__, e)) return scaffolds - def out(self, msg): # pragma: no cover + def out(self, msg): # pragma: no cover if not self.quiet: print(msg) def validate_input(self): if not self.args.scaffold_name: - self.out('You must provide at least one scaffold name: -s ') + self.out('You must provide at least one scaffold name: ' + '-s ') self.out('') self.show_scaffolds() return False @@ -213,13 +213,15 @@ https://github.com/Pylons/?q=cookiecutter self.out('The package name "site" has a special meaning in ' 'Python. Are you sure you want to use it as your ' 'project\'s name?') - return self.confirm_bad_name('Really use "{0}"?: '.format(pkg_name)) + return self.confirm_bad_name('Really use "{0}"?: '.format( + pkg_name)) # check if pkg_name can be imported (i.e. already exists in current # $PYTHON_PATH, if so - let the user confirm pkg_exists = True try: - __import__(pkg_name, globals(), locals(), [], 0) # use absolute imports + # use absolute imports + __import__(pkg_name, globals(), locals(), [], 0) except ImportError as error: pkg_exists = False if not pkg_exists: @@ -231,7 +233,7 @@ https://github.com/Pylons/?q=cookiecutter 'to use it as your project\'s name?'.format(pkg_name)) return self.confirm_bad_name('Really use "{0}"?: '.format(pkg_name)) - def confirm_bad_name(self, prompt): # pragma: no cover + def confirm_bad_name(self, prompt): # pragma: no cover answer = input_('{0} [y|N]: '.format(prompt)) return answer.strip().lower() == 'y' @@ -242,5 +244,5 @@ cookiecutter instead: https://github.com/pylons/?query=cookiecutter ''') -if __name__ == '__main__': # pragma: no cover +if __name__ == '__main__': # pragma: no cover sys.exit(main() or 0) -- cgit v1.2.3 From e8e84e4c9840955600366bdba1af8c9b31158840 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 14 Dec 2016 00:10:22 -0800 Subject: Use web URL for IRC (to be consistent with docs) --- pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl | 2 +- pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl | 2 +- pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl index 51e382654..b5cfdc94d 100644 --- a/pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl +++ b/pyramid/scaffolds/alchemy/+package+/templates/layout.jinja2_tmpl @@ -43,7 +43,7 @@
  • Generated by v{{pyramid_version}}
  • Docs
  • Github Project
  • -
  • IRC Channel
  • +
  • IRC Channel
  • Pylons Project
  • diff --git a/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl b/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl index 360855602..6491d6c0a 100644 --- a/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl +++ b/pyramid/scaffolds/starter/+package+/templates/layout.jinja2_tmpl @@ -43,7 +43,7 @@
  • Generated by v{{pyramid_version}}
  • Docs
  • Github Project
  • -
  • IRC Channel
  • +
  • IRC Channel
  • Pylons Project
  • diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl index e109ab829..72b480249 100644 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl @@ -44,7 +44,7 @@
  • Generated by v{{pyramid_version}}
  • Docs
  • Github Project
  • -
  • IRC Channel
  • +
  • IRC Channel
  • Pylons Project
  • -- cgit v1.2.3 From 5225f973bf1a1da783317fb79f637438ece3bb46 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 15 Dec 2016 00:28:24 -0600 Subject: alphabetize --- docs/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index b9d2958b0..46534ea15 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,13 +49,13 @@ book = os.environ.get('BOOK') # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ + 'repoze.sphinx.autointerface', 'sphinx.ext.autodoc', 'sphinx.ext.doctest', - 'repoze.sphinx.autointerface', - 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx', - 'sphinxcontrib.autoprogram', 'sphinx.ext.todo', + 'sphinx.ext.viewcode', + 'sphinxcontrib.autoprogram', # enable pylons_sphinx_latesturl when this branch is no longer "latest" # 'pylons_sphinx_latesturl', ] -- cgit v1.2.3 From 4c8eb258689df43fa7ded99e4e781712a9106752 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 15 Dec 2016 00:30:32 -0600 Subject: changelog for #2864 --- CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 575038f0a..08013f3ec 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -133,6 +133,10 @@ Features new ``listen`` directives in waitress. See https://github.com/Pylons/pyramid/pull/2853 +- All p* scripts now use argparse instead of optparse. This improves their + ``--help`` output as well as enabling nicer documentation of their options. + See https://github.com/Pylons/pyramid/pull/2864 + Bug Fixes --------- -- cgit v1.2.3 From 6721ffd7075ff5357e0c19dd20e123d068cddce4 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 15 Dec 2016 00:33:48 -0600 Subject: improve config_vars docs in some scripts to mirror pserve --- pyramid/scripts/prequest.py | 7 ++++--- pyramid/scripts/proutes.py | 7 ++++--- pyramid/scripts/ptweens.py | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index 1136dd409..aefb4e18d 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -104,9 +104,10 @@ class PRequestCommand(object): 'config_vars', nargs='*', default=(), - help='Arbitrary options to override those in the [app:main] section ' - 'of the configuration file.', - ) + help="Variables required by the config file. For example, " + "`http_port=%%(http_port)s` would expect `http_port=8080` to be " + "passed here.", + ) get_app = staticmethod(get_app) stdin = sys.stdin diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index df8e51e39..2a999e04f 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -276,9 +276,10 @@ class PRoutesCommand(object): 'config_vars', nargs='*', default=(), - help='Arbitrary options to override those in the [app:main] section ' - 'of the configuration file.', - ) + help="Variables required by the config file. For example, " + "`http_port=%%(http_port)s` would expect `http_port=8080` to be " + "passed here.", + ) def __init__(self, argv, quiet=False): self.args = self.parser.parse_args(argv[1:]) diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index 348f2b372..f278a0370 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -40,8 +40,9 @@ class PTweensCommand(object): 'config_vars', nargs='*', default=(), - help='Arbitrary options to override those in the [app:main] section ' - 'of the configuration file.', + help="Variables required by the config file. For example, " + "`http_port=%%(http_port)s` would expect `http_port=8080` to be " + "passed here.", ) stdout = sys.stdout -- cgit v1.2.3 From 1a7242be0fc543fd8a965cbc02022941cdadabcc Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Thu, 15 Dec 2016 00:32:40 -0700 Subject: Add CHANGES for #2822 --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 08013f3ec..8f6e5b37a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,9 @@ unreleased Backward Incompatibilities -------------------------- + - Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 + has been removed. See https://github.com/Pylons/pyramid/pull/2822 + - Following the Pyramid deprecation period (1.6 -> 1.8), daemon support for pserve has been removed. This includes removing the daemon commands (start, stop, restart, status) as well as the following -- cgit v1.2.3 From 1d78284a59718b02df1e05ee24f9ed2485f51cbb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 16 Dec 2016 00:15:46 -0600 Subject: move asset overrides to an earlier phase --- docs/narr/extconfig.rst | 1 + pyramid/config/assets.py | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index babfa0a98..4009ec1dc 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -260,6 +260,7 @@ Pre-defined Phases - :meth:`pyramid.config.Configurator.add_subscriber_predicate` - :meth:`pyramid.config.Configurator.add_view_predicate` - :meth:`pyramid.config.Configurator.add_view_deriver` +- :meth:`pyramid.config.Configurator.override_asset` - :meth:`pyramid.config.Configurator.set_authorization_policy` - :meth:`pyramid.config.Configurator.set_default_csrf_options` - :meth:`pyramid.config.Configurator.set_default_permission` diff --git a/pyramid/config/assets.py b/pyramid/config/assets.py index d05314384..6eafc1eb1 100644 --- a/pyramid/config/assets.py +++ b/pyramid/config/assets.py @@ -4,7 +4,10 @@ import sys from zope.interface import implementer -from pyramid.interfaces import IPackageOverrides +from pyramid.interfaces import ( + IPackageOverrides, + PHASE1_CONFIG, +) from pyramid.exceptions import ConfigurationError from pyramid.threadlocal import get_current_registry @@ -387,6 +390,7 @@ class AssetsConfiguratorMixin(object): ) intr['to_override'] = to_override intr['override_with'] = override_with - self.action(None, register, introspectables=(intr,)) + self.action(None, register, introspectables=(intr,), + order=PHASE1_CONFIG) override_resource = override_asset # bw compat -- cgit v1.2.3 From 0c1c5872915d79f14b1af8c7c3e597d5e83f30bb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 16 Dec 2016 00:17:11 -0600 Subject: defer translation_dir resolution to allow asset overrides to execute first fixes #2046 --- pyramid/config/__init__.py | 13 +++++----- pyramid/config/i18n.py | 45 ++++++++++++++++------------------ pyramid/tests/test_config/test_i18n.py | 14 ++++++++--- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index d4064dc78..242fbcf4e 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -451,9 +451,6 @@ class Configurator( return filename # absolute filename return '%s:%s' % (package, filename) - def _split_spec(self, path_or_spec): - return resolve_asset_spec(path_or_spec, self.package_name) - def _fix_registry(self): """ Fix up a ZCA component registry that is not a pyramid.registry.Registry by adding analogues of ``has_listeners``, @@ -651,7 +648,11 @@ class Configurator( of this error will be information about the source of the conflict, usually including file names and line numbers of the cause of the configuration conflicts.""" - self.action_state.execute_actions(introspector=self.introspector) + self.begin() + try: + self.action_state.execute_actions(introspector=self.introspector) + finally: + self.end() self.action_state = ActionState() # old actions have been processed def include(self, callable, route_prefix=None): @@ -992,11 +993,11 @@ class Configurator( # Push the registry onto the stack in case any code that depends on # the registry threadlocal APIs used in listeners subscribed to the # IApplicationCreated event. - self.manager.push({'registry': self.registry, 'request': None}) + self.begin() try: self.registry.notify(ApplicationCreated(app)) finally: - self.manager.pop() + self.end() return app diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 69af0f9bc..9387a693b 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -1,13 +1,10 @@ -import os -import sys - from pyramid.interfaces import ( ILocaleNegotiator, ITranslationDirectories, ) from pyramid.exceptions import ConfigurationError -from pyramid.path import package_path +from pyramid.path import AssetResolver from pyramid.util import action_method class I18NConfiguratorMixin(object): @@ -69,32 +66,32 @@ class I18NConfiguratorMixin(object): directories will be inserted into the beginning of the directory list in the order they're provided in the ``*specs`` list argument (items earlier in the list trump ones later in the list). + """ directories = [] introspectables = [] - - for spec in specs[::-1]: # reversed - package_name, filename = self._split_spec(spec) - if package_name is None: # absolute filename - directory = filename - else: - __import__(package_name) - package = sys.modules[package_name] - directory = os.path.join(package_path(package), filename) - - if not os.path.isdir(os.path.realpath(directory)): - raise ConfigurationError('"%s" is not a directory' % - directory) - intr = self.introspectable('translation directories', directory, - spec, 'translation directory') - intr['directory'] = directory - intr['spec'] = spec - introspectables.append(intr) - directories.append(directory) + resolver = AssetResolver(self.package_name) def register(): - for directory in directories: + # defer spec resolution until register to allow for asset + # overrides to take place in an earlier config phase + for spec in specs[::-1]: # reversed + # the trailing slash helps match asset overrides for folders + if not spec.endswith('/'): + spec += '/' + asset = resolver.resolve(spec) + directory = asset.abspath() + if not asset.isdir(): + raise ConfigurationError('"%s" is not a directory' % + directory) + intr = self.introspectable('translation directories', directory, + spec, 'translation directory') + intr['directory'] = directory + intr['spec'] = spec + introspectables.append(intr) + directories.append(directory) + for directory in directories: tdirs = self.registry.queryUtility(ITranslationDirectories) if tdirs is None: tdirs = [] diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py index 71c68af8a..ee8fcfd65 100644 --- a/pyramid/tests/test_config/test_i18n.py +++ b/pyramid/tests/test_config/test_i18n.py @@ -36,9 +36,8 @@ class TestI18NConfiguratorMixin(unittest.TestCase): def test_add_translation_dirs_missing_dir(self): from pyramid.exceptions import ConfigurationError config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_translation_dirs, - '/wont/exist/on/my/system') + config.add_translation_dirs('/wont/exist/on/my/system') + self.assertRaises(ConfigurationError, config.commit) def test_add_translation_dirs_no_specs(self): from pyramid.interfaces import ITranslationDirectories @@ -87,3 +86,12 @@ class TestI18NConfiguratorMixin(unittest.TestCase): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale]) + def test_add_translation_dirs_uses_override(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne() + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + config.commit() + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale2]) -- cgit v1.2.3 From 804eb0edf94d971acc7c2efccd019e24735a882e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 17 Dec 2016 14:31:21 -0600 Subject: cover more cases where the threadlocals are not setup --- pyramid/config/__init__.py | 34 ++++++++++++++++++----- pyramid/tests/test_config/test_i18n.py | 22 +++++++++++++-- pyramid/tests/test_config/test_init.py | 50 ++++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 12 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index 242fbcf4e..304d3a85e 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -603,11 +603,15 @@ class Configurator( if autocommit: # callables can depend on the side effects of resolving a # deferred discriminator - undefer(discriminator) - if callable is not None: - callable(*args, **kw) - for introspectable in introspectables: - introspectable.register(self.introspector, action_info) + self.begin() + try: + undefer(discriminator) + if callable is not None: + callable(*args, **kw) + for introspectable in introspectables: + introspectable.register(self.introspector, action_info) + finally: + self.end() else: action = extra @@ -886,14 +890,30 @@ class Configurator( absolute_resource_spec = absolute_asset_spec # b/w compat forever - def begin(self, request=None): + def begin(self, request=_marker): """ Indicate that application or test configuration has begun. This pushes a dictionary containing the :term:`application registry` implied by ``registry`` attribute of this configurator and the :term:`request` implied by the ``request`` argument onto the :term:`thread local` stack consulted by various :mod:`pyramid.threadlocal` API - functions.""" + functions. + + If ``request`` is not specified and the registry owned by the + configurator is already pushed as the current threadlocal registry + then this method will keep the current threadlocal request unchanged. + + .. versionchanged:: 1.8 + The current threadlocal request is propagated if the current + threadlocal registry remains unchanged. + + """ + if request is _marker: + current = self.manager.get() + if current['registry'] == self.registry: + request = current['request'] + else: + request = None self.manager.push({'registry':self.registry, 'request':request}) def end(self): diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py index ee8fcfd65..adfb6191c 100644 --- a/pyramid/tests/test_config/test_i18n.py +++ b/pyramid/tests/test_config/test_i18n.py @@ -86,7 +86,7 @@ class TestI18NConfiguratorMixin(unittest.TestCase): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale]) - def test_add_translation_dirs_uses_override(self): + def test_add_translation_dirs_uses_override_out_of_order(self): from pyramid.interfaces import ITranslationDirectories config = self._makeOne() config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') @@ -94,4 +94,22 @@ class TestI18NConfiguratorMixin(unittest.TestCase): 'pyramid.tests.pkgs.localeapp:locale2/') config.commit() self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale2]) + [locale2]) + + def test_add_translation_dirs_doesnt_use_override_w_autocommit(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale]) + + def test_add_translation_dirs_uses_override_w_autocommit(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale2]) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index 7078d7e26..0d5413d16 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -91,13 +91,54 @@ class ConfiguratorTests(unittest.TestCase): {'registry':config.registry, 'request':request}) self.assertEqual(manager.popped, False) + def test_begin_overrides_request(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + req = object() + # set it up for auto-propagation + pushed = {'registry': config.registry, 'request': None} + manager.pushed = pushed + config.manager = manager + config.begin(req) + self.assertTrue(manager.pushed is not pushed) + self.assertEqual(manager.pushed['request'], req) + self.assertEqual(manager.pushed['registry'], config.registry) + + def test_begin_propagates_request_for_same_registry(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + req = object() + pushed = {'registry': config.registry, 'request': req} + manager.pushed = pushed + config.manager = manager + config.begin() + self.assertTrue(manager.pushed is not pushed) + self.assertEqual(manager.pushed['request'], req) + self.assertEqual(manager.pushed['registry'], config.registry) + + def test_begin_does_not_propagate_request_for_diff_registry(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + req = object() + pushed = {'registry': object(), 'request': req} + manager.pushed = pushed + config.manager = manager + config.begin() + self.assertTrue(manager.pushed is not pushed) + self.assertEqual(manager.pushed['request'], None) + self.assertEqual(manager.pushed['registry'], config.registry) + def test_end(self): from pyramid.config import Configurator config = Configurator() manager = DummyThreadLocalManager() + pushed = manager.pushed config.manager = manager config.end() - self.assertEqual(manager.pushed, None) + self.assertEqual(manager.pushed, pushed) self.assertEqual(manager.popped, True) def test_ctor_with_package_registry(self): @@ -1940,10 +1981,13 @@ class DummyRequest: self.cookies = {} class DummyThreadLocalManager(object): - pushed = None - popped = False + def __init__(self): + self.pushed = {'registry': None, 'request': None} + self.popped = False def push(self, d): self.pushed = d + def get(self): + return self.pushed def pop(self): self.popped = True -- cgit v1.2.3 From 617f19c670cd18d00e96112ebe501b74072e456d Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Sun, 18 Dec 2016 13:42:28 +0200 Subject: Fix typo --- docs/tutorials/wiki/definingviews.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index 3859d2cad..2419eb801 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -395,5 +395,5 @@ each of the following URLs, checking that the result is as expected: - http://localhost:6543/add_page/SomePageName invokes the add view for a Page. - To generate an error, visit http://localhost:6543/add_page which will - generate an ``IndexErrorr: tuple index out of range`` error. You'll see an + generate an ``IndexError: tuple index out of range`` error. You'll see an interactive traceback facility provided by :term:`pyramid_debugtoolbar`. -- cgit v1.2.3 From 75a92c306f573728266728897c342710566cd543 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Dec 2016 01:05:26 -0600 Subject: first cut at whatsnew-1.8 --- CHANGES.txt | 54 +++++++-------- docs/whatsnew-1.8.rst | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 26 deletions(-) create mode 100644 docs/whatsnew-1.8.rst diff --git a/CHANGES.txt b/CHANGES.txt index 8f6e5b37a..c7d40a37a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,25 +4,25 @@ unreleased Backward Incompatibilities -------------------------- - - Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 - has been removed. See https://github.com/Pylons/pyramid/pull/2822 +- Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 + has been removed. See https://github.com/Pylons/pyramid/pull/2822 - - Following the Pyramid deprecation period (1.6 -> 1.8), - daemon support for pserve has been removed. This includes removing the - daemon commands (start, stop, restart, status) as well as the following - arguments: - --daemon --pid-file --log-file --monitor-restart --status --user --group - --stop-daemon +- Following the Pyramid deprecation period (1.6 -> 1.8), + daemon support for pserve has been removed. This includes removing the + daemon commands (start, stop, restart, status) as well as the following + arguments: ``--daemon``, ``--pid-file``, ``--log-file``, + ``--monitor-restart``, ``--status``, ``--user``, ``--group``, + ``--stop-daemon`` - To run your server as a daemon you should use a process manager instead of - pserve. + To run your server as a daemon you should use a process manager instead of + pserve. - See https://github.com/Pylons/pyramid/pull/2615 + See https://github.com/Pylons/pyramid/pull/2615 -- ``pcreate`` is now interactive by default. You will be prompted if - a file already exists with different content. Previously if there were - similar files it would silently skip them unless you specified - ``--interactive`` or ``--overwrite``. +- ``pcreate`` is now interactive by default. You will be prompted if a file + already exists with different content. Previously if there were similar + files it would silently skip them unless you specified ``--interactive`` + or ``--overwrite``. See https://github.com/Pylons/pyramid/pull/2775 - Removed undocumented argument ``cachebust_match`` from @@ -48,13 +48,13 @@ Features - Python 3.6 compatibility. https://github.com/Pylons/pyramid/issues/2835 -- pcreate learned about --package-name to allow you to create a new project in - an existing folder with a different package name than the project name. See - https://github.com/Pylons/pyramid/pull/2783 +- pcreate learned about ``--package-name`` to allow you to create a new project + in an existing folder with a different package name than the project name. + See https://github.com/Pylons/pyramid/pull/2783 -- The `_get_credentials` private method of `BasicAuthAuthenticationPolicy` - has been extracted into standalone function ``extract_http_basic_credentials` - in `pyramid.authentication` module, this function extracts HTTP Basic +- The ``_get_credentials`` private method of ``BasicAuthAuthenticationPolicy`` + has been extracted into standalone function ``extract_http_basic_credentials`` + in ``pyramid.authentication`` module, this function extracts HTTP Basic credentials from a ``request`` object, and returns them as a named tuple. See https://github.com/Pylons/pyramid/pull/2662 @@ -143,8 +143,8 @@ Features Bug Fixes --------- -- Fixed bug in `proutes` such that it now shows the correct view when a class - and `attr` is involved. +- Fixed bug in ``proutes`` such that it now shows the correct view when a + class and ``attr`` is involved. See: https://github.com/Pylons/pyramid/pull/2687 - Fix a ``FutureWarning`` in Python 3.5 when using ``re.split`` on the @@ -179,13 +179,15 @@ Deprecations Documentation Changes --------------------- + - Replace Typographical Conventions with an enhanced Style Guide. https://github.com/Pylons/pyramid/pull/2838 -- Add pyramid_nacl_session to session factories. - See https://github.com/Pylons/pyramid/issues/2791 +- Add `pyramid_nacl_session + `_ + to session factories. See https://github.com/Pylons/pyramid/issues/2791 -- Update HACKING.txt from stale branch that was never merged to master. +- Update ``HACKING.txt`` from stale branch that was never merged to master. See https://github.com/Pylons/pyramid/pull/2782 - Updated Windows installation instructions and related bits. diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst new file mode 100644 index 000000000..1a5938327 --- /dev/null +++ b/docs/whatsnew-1.8.rst @@ -0,0 +1,181 @@ +What's New in Pyramid 1.8 +========================= + +This article explains the new features in :app:`Pyramid` version 1.8 as +compared to its predecessor, :app:`Pyramid` 1.7. It also documents backwards +incompatibilities between the two versions and deprecations added to +:app:`Pyramid` 1.8, as well as software dependency changes and notable +documentation additions. + +Backwards Incompatibilities +--------------------------- + +- Following the Pyramid deprecation period (1.6 -> 1.8), + daemon support for pserve has been removed. This includes removing the + daemon commands (start, stop, restart, status) as well as the following + arguments: ``--daemon``, ``--pid-file``, ``--log-file``, + ``--monitor-restart``, ``--status``, ``--user``, ``--group``, + ``--stop-daemon`` + + To run your server as a daemon you should use a process manager instead of + pserve. + + See https://github.com/Pylons/pyramid/pull/2615 + +- Change static view to avoid setting the ``Content-Encoding`` response header + to an encoding guessed using Python's ``mimetypes`` module. This was causing + clients to decode the content of gzipped files when downloading them. The + client would end up with a ``foo.txt.gz`` file on disk that was already + decoded, thus should really be ``foo.txt``. Also, the ``Content-Encoding`` + should only have been used if the client itself broadcast support for the + encoding via ``Accept-Encoding`` request headers. + See https://github.com/Pylons/pyramid/pull/2810 + +- ``pcreate`` is now interactive by default. You will be prompted if a file + already exists with different content. Previously if there were similar + files it would silently skip them unless you specified ``--interactive`` + or ``--overwrite``. + See https://github.com/Pylons/pyramid/pull/2775 + +- Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 + has been removed. See https://github.com/Pylons/pyramid/pull/2822 + +- Settings are no longer accessible as attributes on the settings object + (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. + See https://github.com/Pylons/pyramid/pull/2823 + +- Removed undocumented argument ``cachebust_match`` from + ``pyramid.static.static_view``. This argument was shipped accidentally + in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 + +Feature Additions +----------------- + +- Python 3.6 compatibility. + https://github.com/Pylons/pyramid/issues/2835 + +- ``pcreate`` learned about --package-name to allow you to create a new project + in an existing folder with a different package name than the project name. + See https://github.com/Pylons/pyramid/pull/2783 + +- The ``_get_credentials`` private method of + :class:`pyramid.authentication.BasicAuthAuthenticationPolicy` + has been extracted into standalone function + :func:`pyramid.authentication.extract_http_basic_credentials`, this function + extracts HTTP Basic credentials from a ``request`` object, and returns them + as a named tuple. See https://github.com/Pylons/pyramid/pull/2662 + +- Pyramid 1.4 silently dropped a feature of the configurator that has been + restored. It's again possible for action discriminators to conflict across + different action orders. + See https://github.com/Pylons/pyramid/pull/2757 + +- :func:`pyramid.paster.bootstrap` and its sibling + :func:`pyramid.scripting.prepare` can now be used as context managers to + automatically invoke the ``closer`` and pop threadlocals off of the stack + to prevent memory leaks. See https://github.com/Pylons/pyramid/pull/2760 + +- Added :meth:`pyramid.config.Configurator.add_exception_view` and the + :func:`pyramid.view.exception_view_config` decorator. It is now possible + using these methods or via the new ``exception_only=True`` option to + :meth:`pyramid.config.Configurator.add_view` to add a view which will only + be matched when handling an exception. Previously, any exception views were + also registered for a traversal context that inherited from the exception + class which prevented any exception-only optimizations. + See https://github.com/Pylons/pyramid/pull/2660 + +- Added the ``exception_only`` boolean to + :class:`pyramid.interfaces.IViewDeriverInfo` which can be used by view + derivers to determine if they are wrapping a view which only handles + exceptions. This means that it is no longer necessary to perform request-time + checks for ``request.exception`` to determine if the view is handling an + exception - the pipeline can be optimized at config-time. + See https://github.com/Pylons/pyramid/pull/2660 + +- ``pserve`` should now work with ``gevent`` and other workers that need + to monkeypatch the process, assuming the server and / or the app do so + as soon as possible before importing the rest of pyramid. + See https://github.com/Pylons/pyramid/pull/2797 + +- Pyramid no longer copies the settings object passed to the + ``pyramid.config.Configurator(settings=)``. The original ``dict`` is kept. + See https://github.com/Pylons/pyramid/pull/2823 + +- The csrf trusted origins setting may now be a whitespace-separated list of + domains. Previously only a python list was allowed. Also, it can now be set + using the ``PYRAMID_CSRF_TRUSTED_ORIGINS`` environment variable similar to + other settings. See https://github.com/Pylons/pyramid/pull/2823 + +- ``pserve --reload`` now uses the + `hupper ` + library to monitor file changes. This comes with many improvements: + + - If the `watchdog `_ package is + installed then monitoring will be done using inotify instead of + cpu and disk-intensive polling. + + - The monitor is now a separate process that will not crash and starts up + before any of your code. + + - The monitor will not restart the process after a crash until a file is + saved. + + - The monitor works on windows. + + - You can now trigger a reload manually from a pyramid view or any other + code via ``hupper.get_reloader().trigger_reload()``. Kind of neat. + + - You can trigger a reload by issuing a ``SIGHUP`` to the monitor process. + + See https://github.com/Pylons/pyramid/pull/2805 + +- A new ``[pserve]`` section is supported in your config files with a + ``watch_files`` key that can configure ``pserve --reload`` to monitor custom + file paths. See https://github.com/Pylons/pyramid/pull/2827 + +- Allow streaming responses to be made from subclasses of + :class:`pyramid.httpexceptions.HTTPException`. Previously the response would + be unrolled while testing for a body, making it impossible to stream + a response. + See https://github.com/Pylons/pyramid/pull/2863 + +- Update starter, alchemy and zodb scaffolds to support IPv6 by using the + new ``listen`` directives in waitress. + See https://github.com/Pylons/pyramid/pull/2853 + +- All p* scripts now use argparse instead of optparse. This improves their + ``--help`` output as well as enabling nicer documentation of their options. + See https://github.com/Pylons/pyramid/pull/2864 + +Deprecations +------------ + + +Scaffolding Enhancements +------------------------ + + +Documentation Enhancements +-------------------------- + +- Replace Typographical Conventions with an enhanced Style Guide. + https://github.com/Pylons/pyramid/pull/2838 + +- Add `pyramid_nacl_session + `_ + to session factories. See https://github.com/Pylons/pyramid/issues/2791 + +- Update HACKING.txt from stale branch that was never merged to master. + See https://github.com/Pylons/pyramid/pull/2782 + +- Updated Windows installation instructions and related bits. + See https://github.com/Pylons/pyramid/issues/2661 + +- Fix an inconsistency in the documentation between view predicates and + route predicates and highlight the differences in their APIs. + See https://github.com/Pylons/pyramid/pull/2764 + +- Clarify a possible misuse of the ``headers`` kwarg to subclasses of + :class:`pyramid.httpexceptions.HTTPException` in which more appropriate + kwargs from the parent class :class:`pyramid.response.Response` should be + used instead. See https://github.com/Pylons/pyramid/pull/2750 -- cgit v1.2.3 From 9edad55a25c6508d10e6b553c71923a4af0acbd7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Dec 2016 10:33:50 -0600 Subject: link to whatsnew-1.8 --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index a783e8a70..a2bdca093 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -184,6 +184,7 @@ Change History .. toctree:: :maxdepth: 1 + whatsnew-1.8 whatsnew-1.7 whatsnew-1.6 whatsnew-1.5 -- cgit v1.2.3 From 8dbefbdc7a5ecb426d03aa1fbdbaa05eac0c07e2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 19 Dec 2016 20:48:09 -0800 Subject: Correct change log entry --- CHANGES.txt | 2 +- docs/whatsnew-1.8.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c7d40a37a..ac3989d35 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -180,7 +180,7 @@ Deprecations Documentation Changes --------------------- -- Replace Typographical Conventions with an enhanced Style Guide. +- Update Typographical Conventions and add a Style Guide. https://github.com/Pylons/pyramid/pull/2838 - Add `pyramid_nacl_session diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 1a5938327..20261e704 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -158,7 +158,7 @@ Scaffolding Enhancements Documentation Enhancements -------------------------- -- Replace Typographical Conventions with an enhanced Style Guide. +- Update Typographical Conventions and add a Style Guide. https://github.com/Pylons/pyramid/pull/2838 - Add `pyramid_nacl_session -- cgit v1.2.3 From 5f4649e9a3a1880c715ed88d19290a8d8c51152f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 16 Dec 2016 20:40:11 -0600 Subject: add changelog for #2873 --- CHANGES.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 8f6e5b37a..4befe2658 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -140,6 +140,29 @@ Features ``--help`` output as well as enabling nicer documentation of their options. See https://github.com/Pylons/pyramid/pull/2864 +- Any deferred configuration action registered via ``config.action`` may now + depend on threadlocal state, such as asset overrides, being active when + the action is executed. + See https://github.com/Pylons/pyramid/pull/2873 + +- Asset specifications for directories passed to + ``config.add_translation_dirs`` now support overriding the entire asset + specification, including the folder name. Previously only the package name + was supported and the folder would always need to have the same name. + See https://github.com/Pylons/pyramid/pull/2873 + +- ``config.begin()`` will propagate the current threadlocal request through + as long as the registry is the same. For example: + + .. code-block:: python + + request = Request.blank(...) + config.begin(request) # pushes a request + config.begin() # propagates the previous request through unchanged + assert get_current_request() is request + + See https://github.com/Pylons/pyramid/pull/2873 + Bug Fixes --------- @@ -174,6 +197,11 @@ Bug Fixes style, even if a different plural function is defined in the relevant messages file. See https://github.com/Pylons/pyramid/pull/2859 +- The ``config.override_asset`` method now occurs during + ``pyramid.config.PHASE1_CONFIG`` such that it is ordered to execute before + any calls to ``config.add_translation_dirs``. + See https://github.com/Pylons/pyramid/pull/2873 + Deprecations ------------ -- cgit v1.2.3 From 4584c749ac40ef45ddde011f1fc3de1608918e38 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 00:48:15 -0800 Subject: remove style-guide, defer to 1.9 --- docs/index.rst | 1 - docs/latexindex.rst | 2 +- docs/style-guide.rst | 1258 ------------------------------------ docs/typographical-conventions.rst | 2 +- 4 files changed, 2 insertions(+), 1261 deletions(-) delete mode 100644 docs/style-guide.rst diff --git a/docs/index.rst b/docs/index.rst index a2bdca093..60dcdcc9c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -221,7 +221,6 @@ Typographical Conventions and Style Guide :maxdepth: 1 typographical-conventions - style-guide Index and Glossary diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 83a139917..a1e70425a 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -15,7 +15,7 @@ Front Matter :maxdepth: 1 copyright - style-guide + typographical-conventions authorintro designdefense diff --git a/docs/style-guide.rst b/docs/style-guide.rst deleted file mode 100644 index bdca45a06..000000000 --- a/docs/style-guide.rst +++ /dev/null @@ -1,1258 +0,0 @@ -.. _style-guide: - -Style Guide -=========== - -.. meta:: - :description: This chapter describes how to edit, update, and build the Pyramid documentation. - :keywords: Pyramid, Style Guide - - -.. _style-guide-introduction: - -Introduction ------------- - -This chapter provides details of how to contribute updates to the documentation following style guidelines and conventions. We provide examples, including reStructuredText code and its rendered output for both visual and technical reference. - -For coding style guidelines, see `Coding Style `_. - - -.. _style-guide-contribute: - -How to update and contribute to documentation ---------------------------------------------- - -All projects under the Pylons Projects, including this one, follow the guidelines established at `How to Contribute `_ and `Coding Style and Standards `_. - -By building the documentation locally, you can preview the output before committing and pushing your changes to the repository. Follow the instructions for `Building documentation for a Pylons Project project `_. These instructions also include how to install packages required to build the documentation, and how to follow our recommended git workflow. - -When submitting a pull request for the first time in a project, sign `CONTRIBUTORS.txt `_ and commit it along with your pull request. - - -.. _style-guide-file-conventions: - -Location, referencing, and naming of files ------------------------------------------- - -* reStructuredText (reST) files must be located in ``docs/`` and its subdirectories. -* Image files must be located in ``docs/_static/``. -* reST directives must refer to files either relative to the source file or absolute from the top source directory. For example, in ``docs/narr/source.rst``, you could refer to a file in a different directory as either ``.. include:: ../diff-dir/diff-source.rst`` or ``.. include:: /diff-dir/diff-source.rst``. -* File names should be lower-cased and have words separated with either a hyphen "-" or an underscore "_". -* reST files must have an extension of ``.rst``. -* Image files may be any format but must have lower-cased file names and have standard file extensions that consist three letters (``.gif``, ``.jpg``, ``.png``, ``.svg``). ``.gif`` and ``.svg`` are not currently supported by PDF builders in Sphinx, but you can allow the Sphinx builder to automatically select the correct image format for the desired output by replacing the three-letter file extension with ``*``. For example: - - .. code-block:: rst - - .. image:: ../_static/pyramid_request_processing. - - will select the image ``pyramid_request_processing.svg`` for the HTML documentation builder, and ``pyramid_request_processing.png`` for the PDF builder. See the related `Stack Overflow post `_. - - -.. _style-guide-table-of-contents-tree: - -Table of contents tree ----------------------- - -To insert a table of contents (TOC), use the ``toctree`` directive. Entries listed under the ``toctree`` directive follow :ref:`location conventions `. A numeric ``maxdepth`` option may be given to indicate the depth of the tree; by default, all levels are included. - -.. code-block:: rst - - .. toctree:: - :maxdepth: 2 - - narr/introduction - narr/install - -The above code renders as follows. - -.. toctree:: - :maxdepth: 2 - - narr/introduction - narr/install - -Globbing can be used. - -.. code-block:: rst - - .. toctree:: - :maxdepth: 1 - :glob: - - pscripts/index - pscripts/* - -The above code renders as follows. - -.. toctree:: - :maxdepth: 1 - :glob: - - pscripts/index - pscripts/* - -To notify Sphinx of the document hierarchy, but not insert links into the document at the location of the directive, use the option ``hidden``. This makes sense when you want to insert these links yourself, in a different style, or in the HTML sidebar. - -.. code-block:: rst - - .. toctree:: - :hidden: - - quick_tour - - * :doc:`quick_tour` gives an overview of the major features in Pyramid, covering a little about a lot. - -The above code renders as follows. - -.. toctree:: - :hidden: - - quick_tour - -* :doc:`quick_tour` gives an overview of the major features in Pyramid, covering a little about a lot. - -.. seealso:: Sphinx documentation of :ref:`toctree-directive`. - - -.. _style-guide-glossary: - -Glossary --------- - -A glossary defines terms used throughout the documentation. - -The glossary file must be named ``glossary.rst``. Its content must begin with the directive ``glossary``. An optional ``sorted`` argument should be used to sort the terms alphabetically when rendered, making it easier for the user to find a given term. Without the argument ``sorted``, terms will appear in the order of the ``glossary`` source file. - -.. code-block:: rst - - .. glossary:: - :sorted: - - voom - Theoretically, the sound a parrot makes when four-thousand volts of electricity pass through it. - - pining - What the Norwegien Blue does when it misses its homeland, e.g., pining for the fjords. - -The above code renders as follows. - -.. glossary:: - :sorted: - - voom - Theoretically, the sound a parrot makes when four-thousand volts of electricity pass through it. - - pining - What the Norwegien Blue does when it misses its homeland, e.g., pining for the fjords. - -References to glossary terms use the ``term`` directive. - -.. code-block:: rst - - :term:`voom` - -The above code renders as follows. Note it is hyperlinked, and when clicked it will take the user to the term in the Glossary and highlight the term. - -:term:`voom` - - -.. _style-guide-section-structure: - -Section structure ------------------ - -Each section, or a subdirectory of reST files, such as a tutorial, must contain an ``index.rst`` file. ``index.rst`` must contain the following. - -* A section heading. This will be visible in the table of contents. -* A single paragraph describing this section. -* A Sphinx ``toctree`` directive, with a ``maxdepth`` of 2. Each ``.rst`` file in the folder should be linked to this ``toctree``. - - .. code-block:: rst - - .. toctree:: - :maxdepth: 2 - - chapter1 - chapter2 - chapter3 - - -.. _style-guide-page-structure: - -Page structure --------------- - -Each page should contain in order the following. - -#. The main heading. This will be visible in the table of contents. - - .. code-block:: rst - - ================ - The main heading - ================ - -#. Meta tag information. The "meta" directive is used to specify HTML metadata stored in HTML META tags. "Metadata" is data about data, in this case data about web pages. Metadata is used to describe and classify web pages in the World Wide Web, in a form that is easy for search engines to extract and collate. - - .. code-block:: rst - - .. meta:: - :description: This chapter describes how to edit, update, and build the Pyramid documentation. - :keywords: Pyramid, Style Guide - - The above code renders as follows. - - .. code-block:: xml - - - - -#. Introduction paragraph. - - .. code-block:: rst - - Introduction - ------------ - - This chapter is an introduction. - -#. Finally the content of the document page, consisting of reST elements such as headings, paragraphs, tables, and so on. - - -.. _style-guide-page-content: - -Page content ------------- - -Within a page, content should adhere to specific guidelines. - - -.. _style-guide-line-lengths: - -Line lengths -^^^^^^^^^^^^ - -Narrative documentation is not code, and should therefore not adhere to PEP8 or other line length conventions. When a translator sees only part of a sentence or paragraph, it makes it more difficult to translate the concept. Line lengths make ``diff`` more difficult. Text editors can soft wrap lines for display to avoid horizontal scrolling. We admit, we boofed it by using arbitrary 79-character line lengths in our own documentation, but we have seen the error of our ways and wish to correct this going forward. - - -.. _style-guide-trailing-white-space: - -Trailing white spaces -^^^^^^^^^^^^^^^^^^^^^ - -* No trailing white spaces. -* Always use a line feed or carriage return at the end of a file. - - -.. _style-guide-indentation: - -Indentation -^^^^^^^^^^^ - -* Indent using four spaces, except for :ref:`nested lists `. -* Do not use tabs to indent. - - -.. _style-guide-grammar-spelling-preferences: - -Grammar, spelling, and capitalization preferences -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Use any commercial or free professional style guide in general. Use a spell- and grammar-checker. The following table lists the preferred grammar, spelling, and capitalization of words and phrases for frequently used items in the documentation. - -========== ===== -Preferred Avoid -========== ===== -add-on addon -and so on etc. -GitHub Github, github -JavaScript Javascript, javascript -plug-in plugin -select check, tick (checkbox) -such as like -verify be sure -========== ===== - - -.. _style-guide-headings: - -Headings -^^^^^^^^ - -Capitalize only the first letter in a heading (sentence-case), unless other words are proper nouns or acronyms, e.g., "Pyramid" or "HTML". - -For consistent heading characters throughout the documentation, follow the guidelines stated in the `Python Developer's Guide `_. Specifically: - -* =, for sections -* -, for subsections -* ^, for subsubsections -* ", for paragraphs - -As individual files do not have so-called "parts" or "chapters", the headings would be underlined with characters as shown. - - .. code-block:: rst - - ================================== - The main heading or web page title - ================================== - - Heading Level 1 - --------------- - - Heading Level 2 - ^^^^^^^^^^^^^^^ - - Heading Level 3 - """"""""""""""" - -Note, we do not render heading levels here because doing so causes a loss in page structure. - - -.. _style-guide-paragraphs: - -Paragraphs -^^^^^^^^^^ - -A paragraph should be on one line. Paragraphs must be separated by two line feeds. - - -.. _style-guide-links: - -Links -^^^^^ - -Use inline links to keep the context or link label together with the URL. Do not use targets and links at the end of the page, because the separation makes it difficult to update and translate. Here is an example of inline links, our required method. - -.. code-block:: rst - - `TryPyramid `_ - -The above code renders as follows. - -`TryPyramid `_ - -.. seealso:: See also :ref:`style-guide-cross-references` for generating links throughout the entire documentation. - - -.. _style-guide-topic: - -Topic -^^^^^ - -A topic is similar to a block quote with a title, or a self-contained section with no subsections. Use the ``topic`` directive to indicate a self-contained idea that is separate from the flow of the document. Topics may occur anywhere a section or transition may occur. Body elements and topics may not contain nested topics. - -The directive's sole argument is interpreted as the topic title, and next line must be blank. All subsequent lines make up the topic body, interpreted as body elements. - - .. code-block:: rst - - .. topic:: Topic Title - - Subsequent indented lines comprise - the body of the topic, and are - interpreted as body elements. - -The above code renders as follows. - -.. topic:: Topic Title - - Subsequent indented lines comprise - the body of the topic, and are - interpreted as body elements. - -.. _style-guide-displaying-code: - -Displaying code -^^^^^^^^^^^^^^^ - -Code may be displayed in blocks or inline. You can include blocks of code from other source files. Blocks of code should use syntax highlighting, and may use line numbering or emphasis. - -.. seealso:: See also the Sphinx documentation for :ref:`code-examples`. - - -.. _style-guide-syntax-highlighting: - -Syntax highlighting -""""""""""""""""""" - -Sphinx does syntax highlighting of code blocks using the `Pygments `_ library. - -Do not use two colons "::" at the end of a line, followed by a blank line, then code. Always specify the language to be used for syntax highlighting by using a language argument in the ``code-block`` directive. Always indent the subsequent code. - -.. code-block:: rst - - .. code-block:: python - - if "foo" == "bar": - # This is Python code - pass - -XML: - -.. code-block:: rst - - .. code-block:: xml - - Some XML - -Unix shell commands are prefixed with a ``$`` character. (See :term:`venv` for the meaning of ``$VENV``.) - -.. code-block:: rst - - .. code-block:: bash - - $ $VENV/bin/pip install -e . - -Windows commands are prefixed with a drive letter with an optional directory name. (See :term:`venv` for the meaning of ``%VENV%``.) - -.. code-block:: rst - - .. code-block:: doscon - - c:\> %VENV%\Scripts\pcreate -s starter MyProject - -cfg: - -.. code-block:: rst - - .. code-block:: cfg - - [some-part] - # A random part in the buildout - recipe = collective.recipe.foo - option = value - -ini: - -.. code-block:: rst - - .. code-block:: ini - - [nosetests] - match=^test - where=pyramid - nocapture=1 - -Interactive Python: - -.. code-block:: rst - - .. code-block:: pycon - - >>> class Foo: - ... bar = 100 - ... - >>> f = Foo() - >>> f.bar - 100 - >>> f.bar / 0 - Traceback (most recent call last): - File "", line 1, in - ZeroDivisionError: integer division or modulo by zero - -If syntax highlighting is not enabled for your code block, you probably have a syntax error and Pygments will fail silently. - -View the `full list of lexers and associated short names `_. - - -.. _style-guide-parsed-literals: - -Parsed literals -""""""""""""""" - -Parsed literals are used to render, for example, a specific version number of the application in code blocks. Use the directive ``parsed-literal``. Note that syntax highlighting is not supported and code is rendered as plain text. - -.. code-block:: rst - - .. parsed-literal:: - - $ $VENV/bin/pip install "pyramid==\ |release|\ " - -The above code renders as follows. - -.. parsed-literal:: - - $ $VENV/bin/pip install "pyramid==\ |release|\ " - - -.. _style-guide-long-commands: - -Displaying long commands -"""""""""""""""""""""""" - -When a command that should be typed on one line is too long to fit on the displayed width of a page, the backslash character ``\`` is used to indicate that the subsequent printed line should be part of the command: - -.. code-block:: rst - - .. code-block:: bash - - $ $VENV/bin/py.test tutorial/tests.py --cov-report term-missing \ - --cov=tutorial -q - - -.. _style-guide-code-block-options: - -Code block options -"""""""""""""""""" - -To emphasize lines (give the appearance that a highlighting pen has been used on the code), use the ``emphasize-lines`` option. The argument passed to ``emphasize-lines`` must be a comma-separated list of either single or ranges of line numbers. - -.. code-block:: rst - - .. code-block:: python - :emphasize-lines: 1,3 - - if "foo" == "bar": - # This is Python code - pass - -The above code renders as follows. - -.. code-block:: python - :emphasize-lines: 1,3 - - if "foo" == "bar": - # This is Python code - pass - -To display a code block with line numbers, use the ``linenos`` option. - -.. code-block:: rst - - .. code-block:: python - :linenos: - - if "foo" == "bar": - # This is Python code - pass - -The above code renders as follows. - -.. code-block:: python - :linenos: - - if "foo" == "bar": - # This is Python code - pass - -Code blocks may be given a caption, which may serve as a filename or other description, using the ``caption`` option. They may also be given a ``name`` option, providing an implicit target name that can be referenced by using ``ref`` (see :ref:`style-guide-cross-referencing-arbitrary-locations`). - -.. code-block:: rst - - .. code-block:: python - :caption: sample.py - :name: sample-py - - if "foo" == "bar": - # This is Python code - pass - -The above code renders as follows. - -.. code-block:: python - :caption: sample.py - :name: sample-py - - if "foo" == "bar": - # This is Python code - pass - -To specify the starting number to use for line numbering, use the ``lineno-start`` directive. - -.. code-block:: rst - - .. code-block:: python - :lineno-start: 2 - - if "foo" == "bar": - # This is Python code - pass - -The above code renders as follows. As you can see, ``lineno-start`` is not altogether accurate. - -.. code-block:: python - :lineno-start: 2 - - if "foo" == "bar": - # This is Python code - pass - - -.. _style-guide-includes: - -Includes -"""""""" - -Longer displays of verbatim text may be included by storing the example text in an external file containing only plain text or code. The file may be included using the ``literalinclude`` directive. The file name follows the conventions of :ref:`style-guide-file-conventions`. - -.. code-block:: rst - - .. literalinclude:: narr/helloworld.py - :language: python - -The above code renders as follows. - -.. literalinclude:: narr/helloworld.py - :language: python - -Like code blocks, ``literalinclude`` supports the following options. - -* ``language`` to select a language for syntax highlighting -* ``linenos`` to switch on line numbers -* ``lineno-start`` to specify the starting number to use for line numbering -* ``emphasize-lines`` to emphasize particular lines - -.. code-block:: rst - - .. literalinclude:: narr/helloworld.py - :language: python - :linenos: - :lineno-start: 11 - :emphasize-lines: 1,6-7,9- - -The above code renders as follows. Note that ``lineno-start`` and ``emphasize-lines`` do not align. The former displays numbering starting from the *arbitrarily provided value*, whereas the latter emphasizes the line numbers of the *source file*. - -.. literalinclude:: narr/helloworld.py - :language: python - :linenos: - :lineno-start: 11 - :emphasize-lines: 1,6-7,9- - -``literalinclude`` also supports including only parts of a file. - -If the source code is a Python module, you can select a class, function, or method to include using the ``pyobject`` option. - -.. code-block:: rst - - .. literalinclude:: narr/helloworld.py - :language: python - :pyobject: hello_world - -The above code renders as follows. It returns the function ``hello_world`` in the source file. - -.. literalinclude:: narr/helloworld.py - :language: python - :pyobject: hello_world - -Another way to control which part of the file is included is to use the ``start-after`` and ``end-before`` options (or only one of them). If ``start-after`` is given as a string option, only lines that follow the first line containing that string are included. If ``end-before`` is given as a string option, only lines that precede the first lines containing that string are included. - -.. code-block:: rst - - .. literalinclude:: narr/helloworld.py - :language: python - :start-after: from pyramid.response import Response - :end-before: if __name__ == '__main__': - -The above code renders as follows. - -.. literalinclude:: narr/helloworld.py - :language: python - :start-after: from pyramid.response import Response - :end-before: if __name__ == '__main__': - -You can specify exactly which lines to include by giving a ``lines`` option. - -.. code-block:: rst - - .. literalinclude:: narr/helloworld.py - :language: python - :lines: 6-7 - -The above code renders as follows. - -.. literalinclude:: narr/helloworld.py - :language: python - :lines: 6-7 - -When specifying particular parts of a file to display, it can be useful to display exactly which lines are being presented. This can be done using the ``lineno-match`` option. - -.. code-block:: rst - - .. literalinclude:: narr/helloworld.py - :language: python - :lines: 6-7 - :lineno-match: - -The above code renders as follows. - -.. literalinclude:: narr/helloworld.py - :language: python - :lines: 6-7 - :lineno-match: - -Out of all the ways to include parts of a file, ``pyobject`` is the most preferred option because if you change your code and add or remove lines, you don't need to adjust line numbering, whereas with ``lines`` you would have to adjust. ``start-after`` and ``end-before`` are less desirable because they depend on source code not changing. Alternatively you can insert comments into your source code to act as the delimiters, but that just adds comments that have nothing to do with the functionality of your code. - -Above all with includes, if you use line numbering, it's much preferred to use ``lineno-match`` over ``linenos`` with ``lineno-start`` because it "just works" without thinking and with less markup. - - -.. _style-guide-inline-code: - -Inline code -""""""""""" - -Inline code is surrounded by double backtick marks. Literals, filenames, and function arguments are presented using this style. - -.. code-block:: rst - - Install requirements for building documentation: ``pip install -e ".[docs]"`` - -The above code renders as follows. - -Install requirements for building documentation: ``pip install -e ".[docs]"`` - - -.. _style-guide-rest-block-markup: - -reST block markup ------------------ - -This section contains miscellaneous reST block markup for items not already covered. - - -.. _style-guide-lists: - -Lists -^^^^^ - -Bulleted lists use an asterisk "``*``". - -.. code-block:: rst - - * This is an item in a bulleted list. - * This is another item in a bulleted list. - -The above code renders as follows. - -* This is an item in a bulleted list. -* This is another item in a bulleted list. - -Numbered lists should use a number sign followed by a period "``#.``" and will be numbered automatically. - -.. code-block:: rst - - #. This is an item in a numbered list. - #. This is another item in a numbered list. - -The above code renders as follows. - -#. This is an item in a numbered list. -#. This is another item in a numbered list. - -The appearance of nested lists can be created by separating the child lists from their parent list by blank lines, and indenting by two spaces. Note that Sphinx renders the reST markup not as nested HTML lists, but instead merely indents the children using ``
    ``. - -.. code-block:: rst - - #. This is a list item in the parent list. - #. This is another list item in the parent list. - - #. This is a list item in the child list. - #. This is another list item in the child list. - - #. This is one more list item in the parent list. - -The above code renders as follows. - -#. This is a list item in the parent list. -#. This is another list item in the parent list. - - #. This is a list item in the child list. - #. This is another list item in the child list. - -#. This is one more list item in the parent list. - - -.. _style-guide-tables: - -Tables -^^^^^^ - -Two forms of tables are supported, `simple `_ and `grid `_. - -Simple tables require less markup but have fewer features and some constraints compared to grid tables. The right-most column in simple tables is unbound to the length of the underline in the column header. - -.. code-block:: rst - - ===== ===== - col 1 col 2 - ===== ===== - 1 Second column of row 1. - 2 Second column of row 2. - Second line of paragraph. - 3 * Second column of row 3. - - * Second item in bullet - list (row 3, column 2). - \ Row 4; column 1 will be empty. - ===== ===== - -The above code renders as follows. - -===== ===== -col 1 col 2 -===== ===== -1 Second column of row 1. -2 Second column of row 2. - Second line of paragraph. -3 * Second column of row 3. - - * Second item in bullet - list (row 3, column 2). -\ Row 4; column 1 will be empty. -===== ===== - -Grid tables have much more cumbersome markup, although Emacs' table mode may lessen the tedium. - -.. code-block:: rst - - +------------------------+------------+----------+----------+ - | Header row, column 1 | Header 2 | Header 3 | Header 4 | - | (header rows optional) | | | | - +========================+============+==========+==========+ - | body row 1, column 1 | column 2 | column 3 | column 4 | - +------------------------+------------+----------+----------+ - | body row 2 | Cells may span columns. | - +------------------------+------------+---------------------+ - | body row 3 | Cells may | * Table cells | - +------------------------+ span rows. | * contain | - | body row 4 | | * body elements. | - +------------------------+------------+---------------------+ - -The above code renders as follows. - -+------------------------+------------+----------+----------+ -| Header row, column 1 | Header 2 | Header 3 | Header 4 | -| (header rows optional) | | | | -+========================+============+==========+==========+ -| body row 1, column 1 | column 2 | column 3 | column 4 | -+------------------------+------------+----------+----------+ -| body row 2 | Cells may span columns. | -+------------------------+------------+---------------------+ -| body row 3 | Cells may | * Table cells | -+------------------------+ span rows. | * contain | -| body row 4 | | * body elements. | -+------------------------+------------+---------------------+ - - -.. _style-guide-feature-versioning: - -Feature versioning -^^^^^^^^^^^^^^^^^^ - -Three directives designate the version in which something is added, changed, or deprecated in the project. - - -.. _style-guide-version-added: - -Version added -""""""""""""" - -To indicate the version in which a feature is added to a project, use the ``versionadded`` directive. If the feature is an entire module, then the directive should be placed at the top of the module section before any prose. - -The first argument is the version. An optional second argument must appear upon a subsequent line, without blank lines in between, and indented. - -.. code-block:: rst - - .. versionadded:: 1.1 - :func:`pyramid.paster.bootstrap` - -The above code renders as follows. - -.. versionadded:: 1.1 - :func:`pyramid.paster.bootstrap` - - -.. _style-guide-version-changed: - -Version changed -""""""""""""""" - -To indicate the version in which a feature is changed in a project, use the ``versionchanged`` directive. Its arguments are the same as ``versionadded``. - -.. code-block:: rst - - .. versionchanged:: 1.8 - Added the ability for ``bootstrap`` to cleanup automatically via the ``with`` statement. - -The above code renders as follows. - -.. versionchanged:: 1.8 - Added the ability for ``bootstrap`` to cleanup automatically via the ``with`` statement. - - -.. _style-guide-deprecated: - -Deprecated -"""""""""" - -Similar to ``versionchanged``, ``deprecated`` describes when the feature was deprecated. An explanation can also be given, for example, to inform the reader what should be used instead. - -.. code-block:: rst - - .. deprecated:: 1.7 - Use the ``require_csrf`` option or read :ref:`auto_csrf_checking` instead to have :class:`pyramid.exceptions.BadCSRFToken` exceptions raised. - -The above code renders as follows. - -.. deprecated:: 1.7 - Use the ``require_csrf`` option or read :ref:`auto_csrf_checking` instead to have :class:`pyramid.exceptions.BadCSRFToken` exceptions raised. - - -.. _style-guide-danger: - -Danger -^^^^^^ - -Danger represents critical information related to a topic or concept, and should recommend to the user "don't do this dangerous thing". - -.. code-block:: rst - - .. danger:: - - This is danger or an error. - -The above code renders as follows. - -.. danger:: - - This is danger or an error. - -.. todo:: - - The style for ``danger`` and ``error`` has not yet been created. - - -.. _style-guide-warnings: - -Warnings -^^^^^^^^ - -Warnings represent limitations and advice related to a topic or concept. - -.. code-block:: rst - - .. warning:: - - This is a warning. - -The above code renders as follows. - -.. warning:: - - This is a warning. - - -.. _style-guide-notes: - -Notes -^^^^^ - -Notes represent additional information related to a topic or concept. - -.. code-block:: rst - - .. note:: - - This is a note. - -The above code renders as follows. - -.. note:: - - This is a note. - - -.. _style-guide-see-also: - -See also -^^^^^^^^ - -"See also" messages refer to topics that are related to the current topic, but have a narrative tone to them instead of merely a link without explanation. "See also" is rendered in a block as well, so that it stands out for the reader's attention. - -.. code-block:: rst - - .. seealso:: - - See :ref:`Quick Tutorial section on Requirements `. - -The above code renders as follows. - -.. seealso:: - - See :ref:`Quick Tutorial section on Requirements `. - - -.. _style-guide-todo: - -Todo -^^^^ - -Todo items designated tasks that require further work. - -.. code-block:: rst - - .. todo:: - - This is a todo item. - -The above code renders as follows. - -.. todo:: - - This is a todo item. - -.. todo:: - - The todo style is not yet implemented and needs further work. - - -.. _style-guide-comments: - -Comments -^^^^^^^^ - -Comments of the documentation within the documentation may be generated with two periods ``..``. Comments are not rendered, but provide information to documentation authors. - -.. code-block:: rst - - .. This is an example comment. - - -.. _style-guide-rest-inline-markup: - -reST inline markup ------------------- - -This section contains miscellaneous reST inline markup for items not already covered. Within a block of content, inline markup is useful to apply styles and links to other files. - - -.. _style-guide-italics: - -Italics -^^^^^^^ - -.. code-block:: rst - - This *word* is italicized. - -The above code renders as follows. - -This *word* is italicized. - - -.. _style-guide-strong: - -Strong -^^^^^^ - -.. code-block:: rst - - This **word** is in bold text. - -The above code renders as follows. - -This **word** is in bold text. - -.. seealso:: - - See also the Sphinx documentation for the :ref:`rst-primer`. - - -.. _style-guide-cross-references: - -Cross-references -^^^^^^^^^^^^^^^^ - -To create cross-references to a document, arbitrary location, object, or other items, use variations of the following syntax. - -* ``:role:`target``` creates a link to the item named ``target`` of the type indicated by ``role``, with the link's text as the title of the target. ``target`` may need to be disambiguated between documentation sets linked through intersphinx, in which case the syntax would be ``deform:overview``. -* ``:role:`~target``` displays the link as only the last component of the target. -* ``:role:`title ``` creates a custom title, instead of the default title of the target. - - -.. _style-guide-cross-referencing-documents: - -Cross-referencing documents -""""""""""""""""""""""""""" - -To link to pages within this documentation: - -.. code-block:: rst - - :doc:`quick_tour` - -The above code renders as follows. - -:doc:`quick_tour` - - -.. _style-guide-cross-referencing-arbitrary-locations: - -Cross-referencing arbitrary locations -""""""""""""""""""""""""""""""""""""" - -To support cross-referencing to arbitrary locations in any document and between documentation sets via intersphinx, the standard reST labels are used. For this to work, label names must be unique throughout the entire documentation including externally linked intersphinx references. There are two ways in which you can refer to labels, if they are placed directly before a section title, a figure, or table with a caption, or at any other location. The following section has a label with the syntax ``.. _label_name:`` followed by the section title. - -.. code-block:: rst - - .. _i18n_chapter: - - Internationalization and Localization - ===================================== - -To generate a link to that section with its title, use the following syntax. - -.. code-block:: rst - - :ref:`i18n_chapter` - -The above code renders as follows. - -:ref:`i18n_chapter` - -The same syntax works figures and tables with captions. - -For labels that are not placed as mentioned, the link must be given an explicit title, such as ``:ref:`Link title ```. - -.. seealso:: See also the Sphinx documentation, :ref:`inline-markup`. - - -.. _style-guide-cross-referencing-python: - -Python modules, classes, methods, and functions -""""""""""""""""""""""""""""""""""""""""""""""" - -Python module names use the ``mod`` directive, with the module name as the argument. - -.. code-block:: rst - - :mod:`pyramid.config` - -The above code renders as follows. - -:mod:`pyramid.config` - -Python class names use the ``class`` directive, with the class name as the argument. - -.. code-block:: rst - - :class:`pyramid.config.Configurator` - -The above code renders as follows. - -:class:`pyramid.config.Configurator` - -Python method names use the ``meth`` directive, with the method name as the argument. - -.. code-block:: rst - - :meth:`pyramid.config.Configurator.add_view` - -The above code renders as follows. - -:meth:`pyramid.config.Configurator.add_view` - -Python function names use the ``func`` directive, with the function name as the argument. - -.. code-block:: rst - - :func:`pyramid.renderers.render_to_response` - -The above code renders as follows. - -:func:`pyramid.renderers.render_to_response` - -Note that you can use the ``~`` prefix to show only the last segment of a Python object's name. We prefer not to use the ``.`` prefix, even though it may seem to be a convenience to documentation authors, because Sphinx might generate an error if it cannot disambiguate the reference. - -.. code-block:: rst - - :func:`~pyramid.renderers.render_to_response` - -The above code renders as follows. - -:func:`~pyramid.renderers.render_to_response` - - -.. _style-guide-role-app-pyramid: - -The role ``:app:`Pyramid``` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -We use the special role ``app`` to refer to the application "Pyramid". - -.. code-block:: rst - - :app:`Pyramid` - -The above code renders as follows. - -:app:`Pyramid` - - -.. _style-guide-sphinx-extensions: - -Sphinx extensions ------------------ - -We use several Sphinx extensions to add features to our documentation. Extensions need to be enabled and configured in ``docs/conf.py`` before they can be used. - - -.. _style-guide-sphinx-extension-autodoc: - -:mod:`sphinx.ext.autodoc` -------------------------- - -API documentation uses the Sphinx extension :mod:`sphinx.ext.autodoc` to include documentation from docstrings. - -See the source of any documentation within the ``docs/api/`` directory for conventions and usage, as well as the Sphinx extension's :mod:`documentation `. - - -.. _style-guide-sphinx-extension-doctest: - -:mod:`sphinx.ext.doctest` -------------------------- - -:mod:`sphinx.ext.doctest` allows you to test code snippets in the documentation in a natural way. It works by collecting specially-marked up code blocks and running them as doctest tests. We have only a few tests in our Pyramid documentation which can be found in ``narr/sessions.rst`` and ``narr/hooks.rst``. - - -.. _style-guide-sphinx-extension-intersphinx: - -:mod:`sphinx.ext.intersphinx` ------------------------------ - -:mod:`sphinx.ext.intersphinx` generates links to the documentation of objects in other projects. - - -.. _style-guide-sphinx-extension-todo: - -:mod:`sphinx.ext.todo` ----------------------- - -:mod:`sphinx.ext.todo` adds support for todo items. - - -.. _style-guide-sphinx-extension-viewcode: - -:mod:`sphinx.ext.viewcode` --------------------------- - -:mod:`sphinx.ext.viewcode` looks at your Python object descriptions and tries to find the source files where the objects are contained. When found, a separate HTML page will be output for each module with a highlighted version of the source code, and a link will be added to all object descriptions that leads to the source code of the described object. A link back from the source to the description will also be inserted. - - -.. _style-guide-sphinx-extension-repoze-sphinx-autointerface: - -`repoze.sphinx.autointerface `_ ------------------------------------------------------------------------------------------ - -`repoze.sphinx.autointerface `_ auto-generates API docs from Zope interfaces. - - -.. _style-guide-script-documentation: - -Script documentation --------------------- - -We currently use `sphinxcontrib-programoutput `_ to generate program output of the p* scripts. It is no longer maintained and may cause future builds of the documentation to fail. - -.. todo:: - - See `issue #2804 `_ for further discussion. diff --git a/docs/typographical-conventions.rst b/docs/typographical-conventions.rst index 19894775b..58aaff332 100644 --- a/docs/typographical-conventions.rst +++ b/docs/typographical-conventions.rst @@ -13,7 +13,7 @@ Typographical Conventions Introduction ------------ -This chapter describes typographical conventions used in the Pyramid documentation. Documentation authors and contributors should review the :ref:`style-guide`. +This chapter describes typographical conventions used in the Pyramid documentation. .. _typographical-conventions-glossary: -- cgit v1.2.3 From beb4f1a1c771b295a41c65ba17b943a943f02911 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 03:08:17 -0800 Subject: Use cookiecutter instead of scaffold and pcreate - minor grammar and reST fixes --- docs/tutorials/wiki/authorization.rst | 49 +++---- docs/tutorials/wiki/background.rst | 2 +- docs/tutorials/wiki/basiclayout.rst | 28 ++-- docs/tutorials/wiki/definingmodels.rst | 6 +- docs/tutorials/wiki/definingviews.rst | 46 +++--- docs/tutorials/wiki/design.rst | 7 +- docs/tutorials/wiki/distributing.rst | 2 +- docs/tutorials/wiki/index.rst | 7 +- docs/tutorials/wiki/installation.rst | 249 +++++++++++++-------------------- docs/tutorials/wiki/tests.rst | 14 +- 10 files changed, 174 insertions(+), 236 deletions(-) diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 67af83b25..63f18d72f 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -26,7 +26,7 @@ We will implement the access control with the following steps: * Add :term:`permission` declarations to the ``edit_page`` and ``add_page`` views (``views.py``). -Then we will add the login and logout feature: +Then we will add the login and logout features: * Add ``login`` and ``logout`` views (``views.py``). * Add a login template (``login.pt``). @@ -73,7 +73,7 @@ Create a new ``tutorial/security.py`` module with the following content: The ``groupfinder`` function accepts a userid and a request and returns one of these values: -- If the userid exists in the system, it will return a sequence of group +- If ``userid`` exists in the system, it will return a sequence of group identifiers (or an empty sequence if the user isn't a member of any groups). - If the userid *does not* exist in the system, it will return ``None``. @@ -103,19 +103,18 @@ Add an ACL ~~~~~~~~~~ Open ``tutorial/models.py`` and add the following import -statement at the head: +statement near the top: .. literalinclude:: src/authorization/tutorial/models.py - :lines: 4-7 - :linenos: + :lines: 4-8 + :lineno-match: :language: python Add the following lines to the ``Wiki`` class: .. literalinclude:: src/authorization/tutorial/models.py :lines: 9-13 - :linenos: - :lineno-start: 9 + :lineno-match: :emphasize-lines: 4-5 :language: python @@ -124,10 +123,10 @@ permission is allowed, and :data:`~pyramid.security.Everyone`, a special :term:`principal` that is associated to all requests. Both are used in the :term:`ACE` entries that make up the ACL. -The ACL is a list that needs to be named `__acl__` and be an attribute of a +The ACL is a list that needs to be named ``__acl__`` and be an attribute of a class. We define an :term:`ACL` with two :term:`ACE` entries: the first entry -allows any user the `view` permission. The second entry allows the -``group:editors`` principal the `edit` permission. +allows any user the ``view`` permission. The second entry allows the +``group:editors`` principal the ``edit`` permission. The ``Wiki`` class that contains the ACL is the :term:`resource` constructor for the :term:`root` resource, which is a ``Wiki`` instance. The ACL is @@ -150,15 +149,14 @@ statements: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 1-8 :linenos: - :emphasize-lines: 4-5,8 + :emphasize-lines: 3-6,8 :language: python Now add those policies to the configuration: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 18-23 - :linenos: - :lineno-start: 18 + :lineno-match: :emphasize-lines: 1-3,5-6 :language: python @@ -181,12 +179,12 @@ Open ``tutorial/views.py`` and add a ``permission='edit'`` parameter to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 50-52 + :lines: 49-51 :emphasize-lines: 2-3 :language: python .. literalinclude:: src/authorization/tutorial/views.py - :lines: 70-72 + :lines: 68-70 :emphasize-lines: 2-3 :language: python @@ -234,8 +232,8 @@ Add the following import statements to the head of ``tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 6-17 - :emphasize-lines: 1-12 + :lines: 5-18 + :emphasize-lines: 1-14 :language: python All the highlighted lines need to be added or edited. @@ -248,9 +246,8 @@ cookie. Now add the ``login`` and ``logout`` views at the end of the file: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 82-116 - :linenos: - :lineno-start: 82 + :lines: 80- + :lineno-match: :language: python ``login()`` has two decorators: @@ -287,17 +284,17 @@ the return value of ``view_page()``, ``add_page()``, and ``edit_page()`` as follows: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 47-48 + :lines: 46-47 :emphasize-lines: 1-2 :language: python .. literalinclude:: src/authorization/tutorial/views.py - :lines: 67-68 + :lines: 65-66 :emphasize-lines: 1-2 :language: python .. literalinclude:: src/authorization/tutorial/views.py - :lines: 78-80 + :lines: 76-78 :emphasize-lines: 2-3 :language: python @@ -348,7 +345,7 @@ Our ``tutorial/views.py`` will look like this when we're done: .. literalinclude:: src/authorization/tutorial/views.py :linenos: - :emphasize-lines: 8,11-15,17,24,29,48,52,68,72,80,82-120 + :emphasize-lines: 8,11-15,17,24,29,47,51,66,70,78,80- :language: python Only the highlighted lines need to be added or edited. @@ -358,7 +355,7 @@ we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt :linenos: - :emphasize-lines: 36-38 + :emphasize-lines: 37-39 :language: html Only the highlighted lines need to be added or edited. @@ -368,7 +365,7 @@ we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt :linenos: - :emphasize-lines: 36-38 + :emphasize-lines: 37-39 :language: html Only the highlighted lines need to be added or edited. diff --git a/docs/tutorials/wiki/background.rst b/docs/tutorials/wiki/background.rst index 31dcd6b53..c583b375c 100644 --- a/docs/tutorials/wiki/background.rst +++ b/docs/tutorials/wiki/background.rst @@ -13,7 +13,7 @@ Python web framework experience. To code along with this tutorial, the developer will need a UNIX machine with development tools (Mac OS X with XCode, any Linux or BSD -variant, etc.) *or* a Windows system of any kind. +variant, and so on) *or* a Windows system of any kind. .. warning:: diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst index 20bfdf754..d00eab956 100644 --- a/docs/tutorials/wiki/basiclayout.rst +++ b/docs/tutorials/wiki/basiclayout.rst @@ -4,7 +4,7 @@ Basic Layout ============ -The starter files generated by the ``zodb`` scaffold are very basic, but +The starter files generated by the ``zodb`` cookiecutter are very basic, but they provide a good orientation for the high-level patterns common to most :term:`traversal`-based (and :term:`ZODB`-based) :app:`Pyramid` projects. @@ -44,7 +44,11 @@ Open ``tutorial/__init__.py``. It should already contain the following: #. *Line 15*. Include support for the :term:`Chameleon` template rendering bindings, allowing us to use the ``.pt`` templates. -#. *Line 16*. Register a "static view", which answers requests whose URL +#. *Line 16*. Include support for ``pyramid_tm``, allowing Pyramid requests to join the active transaction as provided by the `transaction `_ package. + +#. *Line 17*. Include support for ``pyramid_zodbconn``, providing integration between :term:`ZODB` and a Pyramid application. + +#. *Line 18*. Register a "static view", which answers requests whose URL paths start with ``/static``, using the :meth:`pyramid.config.Configurator.add_static_view` method. This statement registers a view that will serve up static assets, such as CSS @@ -54,19 +58,19 @@ Open ``tutorial/__init__.py``. It should already contain the following: will be ``/static``. The second argument of this tag is the "path", which is a relative :term:`asset specification`, so it finds the resources it should serve within the ``static`` directory inside the ``tutorial`` - package. Alternatively the scaffold could have used an *absolute* asset + package. Alternatively the cookiecutter could have used an *absolute* asset specification as the path (``tutorial:static``). -#. *Line 17*. Perform a :term:`scan`. A scan will find :term:`configuration +#. *Line 19*. Perform a :term:`scan`. A scan will find :term:`configuration decoration`, such as view configuration decorators (e.g., ``@view_config``) in the source code of the ``tutorial`` package and will take actions based on these decorators. We don't pass any arguments to :meth:`~pyramid.config.Configurator.scan`, which implies that the scan should take place in the current package (in this case, ``tutorial``). - The scaffold could have equivalently said ``config.scan('tutorial')``, but + The cookiecutter could have equivalently said ``config.scan('tutorial')``, but it chose to omit the package name argument. -#. *Line 18*. Use the +#. *Line 20*. Use the :meth:`pyramid.config.Configurator.make_wsgi_app` method to return a :term:`WSGI` application. @@ -79,7 +83,7 @@ hierarchically in a :term:`resource tree`. This tree is consulted by tree represents the site structure, but it *also* represents the :term:`domain model` of the application, because each resource is a node stored persistently in a :term:`ZODB` database. The ``models.py`` file is -where the ``zodb`` scaffold put the classes that implement our +where the ``zodb`` cookiecutter put the classes that implement our resource objects, each of which also happens to be a domain model object. Here is the source for ``models.py``: @@ -93,7 +97,7 @@ Here is the source for ``models.py``: because the class inherits from the :class:`persistent.mapping.PersistentMapping` class. The ``__parent__`` and ``__name__`` are important parts of the :term:`traversal` protocol. - By default, have these as ``None`` indicating that this is the + By default, set these to ``None`` to indicate that this is the :term:`root` object. #. *Lines 8-14*. ``appmaker`` is used to return the *application @@ -110,7 +114,7 @@ Here is the source for ``models.py``: Views With ``views.py`` ----------------------- -Our scaffold generated a default ``views.py`` on our behalf. It +Our cookiecutter generated a default ``views.py`` on our behalf. It contains a single view, which is used to render the page shown when you visit the URL ``http://localhost:6543/``. @@ -156,7 +160,7 @@ Let's try to understand the components in this module: #. *Lines 6-7*. We define a :term:`view callable` named ``my_view``, which we decorated in the step above. This view callable is a *function* we - write generated by the ``zodb`` scaffold that is given a + write generated by the ``zodb`` cookiecutter that is given a ``request`` and which returns a dictionary. The ``mytemplate.pt`` :term:`renderer` named by the asset specification in the step above will convert this dictionary to a :term:`response` on our behalf. @@ -168,8 +172,8 @@ Let's try to understand the components in this module: Configuration in ``development.ini`` ------------------------------------ -The ``development.ini`` (in the tutorial :term:`project` directory, as -opposed to the tutorial :term:`package` directory) looks like this: +The ``development.ini`` (in the ``tutorial`` :term:`project` directory, as +opposed to the ``tutorial`` :term:`package` directory) looks like this: .. literalinclude:: src/basiclayout/development.ini :language: ini diff --git a/docs/tutorials/wiki/definingmodels.rst b/docs/tutorials/wiki/definingmodels.rst index 73dce14d5..419fede62 100644 --- a/docs/tutorials/wiki/definingmodels.rst +++ b/docs/tutorials/wiki/definingmodels.rst @@ -4,7 +4,7 @@ Defining the Domain Model ========================= -The first change we'll make to our stock ``pcreate``-generated application will +The first change we'll make to our stock cookiecutter-generated application will be to define two :term:`resource` constructors, one representing a wiki page, and another representing the wiki as a mapping of wiki page names to page objects. We'll do this inside our ``models.py`` file. @@ -50,7 +50,9 @@ The first thing we want to do is remove the ``MyModel`` class from the generated ``models.py`` file. The ``MyModel`` class is only a sample and we're not going to use it. -Then, we'll add a ``Wiki`` class. We want it to inherit from the +Then we'll add an import at the top for the :class:`persistent.Persistent` class. We'll use this for a new ``Page`` class in a moment. + +Then we'll add a ``Wiki`` class. We want it to inherit from the :class:`persistent.mapping.PersistentMapping` class because it provides mapping behavior, and it makes sure that our Wiki page is stored as a "first-class" persistent object in our ZODB database. diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index 2419eb801..f6e080d09 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -4,7 +4,7 @@ Defining Views ============== -A :term:`view callable` in a :term:`traversal` -based :app:`Pyramid` +A :term:`view callable` in a :term:`traversal`-based :app:`Pyramid` application is typically a simple Python function that accepts two parameters: :term:`context` and :term:`request`. A view callable is assumed to return a :term:`response` object. @@ -16,7 +16,7 @@ assumed to return a :term:`response` object. this one-argument pattern used in other :app:`Pyramid` tutorials and applications. Either calling convention will work in any :app:`Pyramid` application; the calling conventions can be used - interchangeably as necessary. In :term:`traversal` based applications, + interchangeably as necessary. In :term:`traversal`-based applications, URLs are mapped to a context :term:`resource`, and since our :term:`resource tree` also represents our application's "domain model", we're often interested in the context because @@ -75,15 +75,15 @@ On Windows: .. code-block:: doscon - c:\pyramidtut> cd tutorial - c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . + c:\> cd tutorial + c:\tutorial> %VENV%\Scripts\pip install -e . Success executing this command will end with a line to the console something like: .. code-block:: text - Successfully installed docutils-0.12 tutorial-0.0 + Successfully installed docutils-0.13.1 tutorial Adding view functions in ``views.py`` @@ -99,11 +99,11 @@ like the following: We added some imports and created a regular expression to find "WikiWords". We got rid of the ``my_view`` view function and its decorator that was added -when we originally rendered the ``zodb`` scaffold. It was only an example and +when we originally rendered the ``zodb`` cookiecutter. It was only an example and isn't relevant to our application. Then we added four :term:`view callable` functions to our ``views.py`` -module: +module: * ``view_wiki()`` - Displays the wiki itself. It will answer on the root URL. * ``view_page()`` - Displays an individual page. @@ -127,8 +127,7 @@ Following is the code for the ``view_wiki`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 12-14 - :lineno-start: 12 - :linenos: + :lineno-match: :language: python .. note:: In our code, we use an *import* that is *relative* to our package @@ -166,8 +165,7 @@ Here is the code for the ``view_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 16-33 - :lineno-start: 16 - :linenos: + :lineno-match: :language: python The ``view_page`` function is configured to respond as the default view @@ -220,8 +218,7 @@ Here is the code for the ``add_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 35-50 - :lineno-start: 35 - :linenos: + :lineno-match: :language: python The ``add_page`` function is configured to respond when the context resource @@ -248,7 +245,7 @@ are found *after* the :term:`view name` in the URL segments given in the add view is invoked via, e.g., ``http://localhost:6543/add_page/SomeName``, the :term:`subpath` will be a tuple: ``('SomeName',)``. -The add view takes the zeroth element of the subpath (the wiki page name), +The add view takes the zero\ :sup:`th` element of the subpath (the wiki page name), and aliases it to the name attribute in order to know the name of the page we're trying to add. @@ -275,8 +272,7 @@ Here is the code for the ``edit_page`` view function and its decorator: .. literalinclude:: src/views/tutorial/views.py :lines: 52-60 - :lineno-start: 52 - :linenos: + :lineno-match: :language: python The ``edit_page`` function is configured to respond when the context is @@ -317,26 +313,26 @@ extension to be recognized as such. The ``view.pt`` template ------------------------ -Create ``tutorial/templates/view.pt`` and add the following -content: +Rename ``tutorial/templates/mytemplate.pt`` to ``tutorial/templates/view.pt`` and edit the emphasized lines to look like the following: .. literalinclude:: src/views/tutorial/templates/view.pt :linenos: :language: html + :emphasize-lines: 11-12,37-52 This template is used by ``view_page()`` for displaying a single wiki page. It includes: - A ``div`` element that is replaced with the ``content`` value provided by - the view (lines 36-38). ``content`` contains HTML, so the ``structure`` + the view (lines 37-39). ``content`` contains HTML, so the ``structure`` keyword is used to prevent escaping it (i.e., changing ">" to ">", etc.) - A link that points at the "edit" URL which invokes the ``edit_page`` view - for the page being viewed (lines 40-42). + for the page being viewed (lines 41-43). The ``edit.pt`` template ------------------------ -Create ``tutorial/templates/edit.pt`` and add the following content: +Copy ``tutorial/templates/view.pt`` to ``tutorial/templates/edit.pt`` and edit the emphasized lines to look like the following: .. literalinclude:: src/views/tutorial/templates/edit.pt :linenos: @@ -345,12 +341,12 @@ Create ``tutorial/templates/edit.pt`` and add the following content: This template is used by ``add_page()`` and ``edit_page()`` for adding and editing a wiki page. It displays a page containing a form that includes: -- A 10 row by 60 column ``textarea`` field named ``body`` that is filled - with any existing page data when it is rendered (line 45). -- A submit button that has the name ``form.submitted`` (line 48). +- A 10-row by 60-column ``textarea`` field named ``body`` that is filled + with any existing page data when it is rendered (line 46). +- A submit button that has the name ``form.submitted`` (line 49). The form POSTs back to the ``save_url`` argument supplied by the view (line -43). The view will use the ``body`` and ``form.submitted`` values. +44). The view will use the ``body`` and ``form.submitted`` values. .. note:: Our templates use a ``request`` object that none of our tutorial views return in their dictionary. ``request`` is one of several names that diff --git a/docs/tutorials/wiki/design.rst b/docs/tutorials/wiki/design.rst index f2a02176b..30d443bb8 100644 --- a/docs/tutorials/wiki/design.rst +++ b/docs/tutorials/wiki/design.rst @@ -43,11 +43,8 @@ editing, and viewing wiki pages, plus one view for the wiki front page. Two templates will be used, one for viewing, and one for both adding and editing wiki pages. -The default templating systems in :app:`Pyramid` are -:term:`Chameleon` and :term:`Mako`. Chameleon is a variant of -:term:`ZPT`, which is an XML-based templating language. Mako is a -non-XML-based templating language. Because we had to pick one, -we chose Chameleon for this tutorial. +As of version 1.5 :app:`Pyramid` no longer ships with templating systems. In this tutorial, we will use :term:`Chameleon`. Chameleon is a variant of :term:`ZPT`, which is an XML-based templating language. + Security -------- diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst index 386b880e6..8f1318ec0 100644 --- a/docs/tutorials/wiki/distributing.rst +++ b/docs/tutorials/wiki/distributing.rst @@ -20,7 +20,7 @@ On Windows: .. code-block:: doscon - c:\pyramidtut> %VENV%\Scripts\python setup.py sdist + c:\tutorial> %VENV%\Scripts\python setup.py sdist The output of such a command will be something like: diff --git a/docs/tutorials/wiki/index.rst b/docs/tutorials/wiki/index.rst index 7808c7623..7bd58656b 100644 --- a/docs/tutorials/wiki/index.rst +++ b/docs/tutorials/wiki/index.rst @@ -5,13 +5,12 @@ ZODB + Traversal Wiki Tutorial This tutorial introduces a :term:`ZODB` and :term:`traversal`-based :app:`Pyramid` application to a developer familiar with Python. It will be -most familiar to developers with previous :term:`Zope` experience. When the -is finished, the developer will have created a basic Wiki application with +most familiar to developers with previous :term:`Zope` experience. When +finished, the developer will have created a basic Wiki application with authentication. For cut and paste purposes, the source code for all stages of this -tutorial can be browsed on GitHub at `docs/tutorials/wiki/src -`_, +tutorial can be browsed on GitHub at `GitHub `_ for a specific branch or version under ``docs/tutorials/wiki/src``, which corresponds to the same location if you have Pyramid sources. .. toctree:: diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index ec79a4e9c..aa60e310c 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -15,159 +15,128 @@ install Pyramid**. Thereby you will satisfy the following requirements. * You've satisfied the :ref:`requirements-for-installing-packages`. -Create directory to contain the project ---------------------------------------- - -We need a workspace for our project files. - -On UNIX -^^^^^^^ - -.. code-block:: bash - - $ mkdir ~/pyramidtut +Install cookiecutter +-------------------- +We will use a :term:`cookiecutter` to create a Python package project from a Python package project template. See `Cookiecutter Installation `_ for instructions. -On Windows -^^^^^^^^^^ - -.. code-block:: doscon +.. note:: - c:\> mkdir pyramidtut + At the time of writing, the installation instructions for Cookiecutter suggest the optional use of ``sudo``, implying to install it in the system Python. We suggest that you install it in a virtual environment instead. -Create and use a virtual Python environment -------------------------------------------- +Generate a Pyramid project from a cookiecutter +---------------------------------------------- -Next let's create a virtual environment workspace for our project. We will use -the ``VENV`` environment variable instead of the absolute path of the virtual -environment. +We will create a Pyramid project in your home directory for UNIX or at the root for Windows. It is assumed you know the path to where you installed ``cookiecutter``. Issue the following commands and override the defaults in the prompts as follows. On UNIX ^^^^^^^ .. code-block:: bash - $ export VENV=~/pyramidtut - $ python3 -m venv $VENV + $ cd ~ + $ cookiecutter https://github.com/Pylons/pyramid-cookiecutter-zodb On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\> set VENV=c:\pyramidtut + c:\> cd \ + c:\> cookiecutter https://github.com/Pylons/pyramid-cookiecutter-zodb -Each version of Python uses different paths, so you will need to adjust the -path to the command for your Python version. +On all operating systems +^^^^^^^^^^^^^^^^^^^^^^^^ +If prompted for the first item, accept the default ``yes`` by hitting return. -Python 2.7: +#. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-zodb before. Is it + okay to delete and re-clone it? [yes]:`` +#. ``project_name [Pyramid Scaffold]: myproj`` +#. ``repo_name [scaffold]: tutorial`` -.. code-block:: doscon - - c:\> c:\Python27\Scripts\virtualenv %VENV% - -Python 3.6: - -.. code-block:: doscon - - c:\> c:\Python35\Scripts\python -m venv %VENV% - -Upgrade ``pip`` and ``setuptools`` in the virtual environment -------------------------------------------------------------- +Change directory into your newly created project +------------------------------------------------ On UNIX ^^^^^^^ .. code-block:: bash - $ $VENV/bin/pip install --upgrade pip setuptools + $ cd tutorial On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\> %VENV%\Scripts\pip install --upgrade pip setuptools + c:\> cd tutorial -Install Pyramid into the virtual Python environment ---------------------------------------------------- +Set and use a ``VENV`` environment variable +------------------------------------------- + +We will set the ``VENV`` environment variable to the absolute path of the virtual environment, and use it going forward. On UNIX ^^^^^^^ -.. parsed-literal:: +.. code-block:: bash - $ $VENV/bin/pip install "pyramid==\ |release|\ " + $ export VENV=~/tutorial On Windows ^^^^^^^^^^ -.. parsed-literal:: - - c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " +.. code-block:: doscon + c:\tutorial\> set VENV=c:\tutorial -Change directory to your virtual Python environment ---------------------------------------------------- -Change directory to the ``pyramidtut`` directory, which is both your workspace -and your virtual environment. +Create a virtual environment +---------------------------- On UNIX ^^^^^^^ .. code-block:: bash - $ cd pyramidtut + $ python3 -m venv $VENV On Windows ^^^^^^^^^^ -.. code-block:: doscon +Each version of Python uses different paths, so you will need to adjust the path to the command for your Python version. - c:\> cd pyramidtut +Python 2.7: +.. code-block:: doscon -.. _making_a_project: + c:\tutorial\> c:\Python27\Scripts\virtualenv %VENV% -Making a project ----------------- +Python 3.6: -Your next step is to create a project. For this tutorial, we will use -the :term:`scaffold` named ``zodb``, which generates an application -that uses :term:`ZODB` and :term:`traversal`. +.. code-block:: doscon -:app:`Pyramid` supplies a variety of scaffolds to generate sample projects. We -will use ``pcreate``, a script that comes with Pyramid, to create our project -using a scaffold. + c:\tutorial\> c:\Python36\Scripts\python -m venv %VENV% -By passing ``zodb`` into the ``pcreate`` command, the script creates the files -needed to use ZODB. By passing in our application name ``tutorial``, the script -inserts that application name into all the required files. -The below instructions assume your current working directory is "pyramidtut". +Upgrade packaging tools in the virtual environment +-------------------------------------------------- On UNIX ^^^^^^^ .. code-block:: bash - $ $VENV/bin/pcreate -s zodb tutorial + $ $VENV/bin/pip install --upgrade pip setuptools On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut> %VENV%\Scripts\pcreate -s zodb tutorial - -.. note:: If you are using Windows, the ``zodb`` scaffold may not deal - gracefully with installation into a location that contains spaces in the - path. If you experience startup problems, try putting both the virtual - environment and the project into directories that do not contain spaces in - their paths. + c:\tutorial\> %VENV%\Scripts\pip install --upgrade pip setuptools .. _installing_project_in_dev_mode_zodb: @@ -175,76 +144,51 @@ On Windows Installing the project in development mode ------------------------------------------ -In order to do development on the project easily, you must "register" the -project as a development egg in your workspace using the ``pip install -e .`` -command. In order to do so, change directory to the ``tutorial`` directory that -you created in :ref:`making_a_project`, and run the ``pip install -e .`` -command using the virtual environment Python interpreter. +In order to do development on the project easily, you must "register" the project as a development egg in your workspace. We will install testing requirements at the same time. We do so with the following command. On UNIX ^^^^^^^ .. code-block:: bash - $ cd tutorial - $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install -e ".[testing]" On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut> cd tutorial - c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . + c:\tutorial\> %VENV%\Scripts\pip install -e ".[testing]" -The console will show ``pip`` checking for packages and installing missing -packages. Success executing this command will show a line like the following: - -.. code-block:: bash +On all operating systems +^^^^^^^^^^^^^^^^^^^^^^^^ - Successfully installed BTrees-4.2.0 Chameleon-2.24 Mako-1.0.4 \ - MarkupSafe-0.23 Pygments-2.1.3 ZConfig-3.1.0 ZEO-4.2.0b1 ZODB-4.2.0 \ - ZODB3-3.11.0 mock-2.0.0 pbr-1.8.1 persistent-4.1.1 pyramid-chameleon-0.3 \ - pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 pyramid-tm-0.12.1 \ - pyramid-zodbconn-0.7 six-1.10.0 transaction-1.4.4 tutorial waitress-0.8.10 \ - zc.lockfile-1.1.0 zdaemon-4.1.0 zodbpickle-0.6.0 zodburi-2.0 +The console will show ``pip`` checking for packages and installing missing packages. Success executing this command will show a line like the following: +.. code-block:: bash -.. _install-testing-requirements-zodb: - -Install testing requirements ----------------------------- + Successfully installed BTrees-4.3.1 Chameleon-3.0 Mako-1.0.6 \ + MarkupSafe-0.23 PasteDeploy-1.5.2 Pygments-2.1.3 WebOb-1.6.3 \ + WebTest-2.0.23 ZConfig-3.1.0 ZEO-5.0.4 ZODB-5.1.1 ZODB3-3.11.0 \ + beautifulsoup4-4.5.1 coverage-4.2 mock-2.0.0 pbr-1.10.0 persistent-4.2.2 \ + py-1.4.31 pyramid-1.7.3 pyramid-chameleon-0.3 pyramid-debugtoolbar-3.0.5 \ + pyramid-mako-1.0.2 pyramid-tm-1.1.1 pyramid-zodbconn-0.7 pyramidtut \ + pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 transaction-2.0.3 \ + translationstring-1.3 venusian-1.0 waitress-1.0.1 zc.lockfile-1.2.1 \ + zdaemon-4.2.0 zodbpickle-0.6.0 zodburi-2.0 zope.deprecation-4.2.0 \ + zope.interface-4.3.3 -In order to run tests, we need to install the testing requirements. This is -done through our project's ``setup.py`` file, in the ``tests_require`` and -``extras_require`` stanzas, and by issuing the command below for your -operating system. +Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas. .. literalinclude:: src/installation/setup.py - :language: python - :linenos: - :lineno-start: 22 - :lines: 22-26 + :language: python + :lineno-match: + :lines: 22-26 .. literalinclude:: src/installation/setup.py - :language: python - :linenos: - :lineno-start: 45 - :lines: 45-47 - -On UNIX -^^^^^^^ - -.. code-block:: bash - - $ $VENV/bin/pip install -e ".[testing]" - -On Windows -^^^^^^^^^^ - -.. code-block:: doscon - - c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e ".[testing]" + :language: python + :lineno-match: + :lines: 46-48 .. _running_tests: @@ -269,7 +213,7 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q + c:\tutorial\> %VENV%\Scripts\py.test -q For a successful test run, you should see output that ends like this: @@ -284,7 +228,7 @@ Expose test coverage information You can run the ``py.test`` command to see test coverage information. This runs the tests in the same way that ``py.test`` does, but provides additional -"coverage" information, exposing which lines of your project are covered by the +:term:`coverage` information, exposing which lines of your project are covered by the tests. We've already installed the ``pytest-cov`` package into our virtual @@ -302,41 +246,40 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov \ + c:\tutorial\> %VENV%\Scripts\py.test --cov \ --cov-report=term-missing If successful, you will see output something like this: .. code-block:: bash - ======================== test session starts ======================== - platform Python 3.6.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 - rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile: - plugins: cov-2.2.1 - collected 1 items + ======================== test session starts ======================== + platform Python 3.6.0, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + rootdir: /Users/stevepiercy/tutorial, inifile: + plugins: cov-2.4.0 + collected 1 items tutorial/tests.py . ------------------ coverage: platform Python 3.6.0 ------------------ Name Stmts Miss Cover Missing - ---------------------------------------------------- - tutorial/__init__.py 12 7 42% 7-8, 14-18 + ------------------------------------------------------- + tutorial/__init__.py 14 9 36% 7-8, 14-20 tutorial/models.py 10 6 40% 9-14 - tutorial/tests.py 12 0 100% tutorial/views.py 4 0 100% - ---------------------------------------------------- - TOTAL 38 13 66% + ------------------------------------------------------- + TOTAL 28 15 46% ===================== 1 passed in 0.31 seconds ====================== Our package doesn't quite have 100% test coverage. -.. _test_and_coverage_scaffold_defaults_zodb: +.. _test_and_coverage_cookiecutter_defaults_zodb: -Test and coverage scaffold defaults ------------------------------------ +Test and coverage cookiecutter defaults +--------------------------------------- -Scaffolds include configuration defaults for ``py.test`` and test coverage. +Cookiecutters include configuration defaults for ``py.test`` and test coverage. These configuration files are ``pytest.ini`` and ``.coveragerc``, located at the root of your package. Without these defaults, we would need to specify the path to the module on which we want to run tests and coverage. @@ -353,11 +296,10 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ - --cov-report=term-missing tutorial\tests.py -q + c:\tutorial\> %VENV%\Scripts\py.test --cov=tutorial tutorial\tests.py -q py.test follows :ref:`conventions for Python test discovery -`, and the configuration defaults from the scaffold +`, and the configuration defaults from the cookiecutter tell ``py.test`` where to find the module on which we want to run tests and coverage. @@ -385,7 +327,7 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload + c:\tutorial\> %VENV%\Scripts\pserve development.ini --reload .. note:: @@ -396,9 +338,10 @@ If successful, you will see something like this on your console: .. code-block:: text - Starting subprocess with file monitor - Starting server in PID 82349. - serving on http://127.0.0.1:6543 + Starting subprocess with file monitor + Starting server in PID 44078. + Serving on http://localhost:6543 + Serving on http://localhost:6543 This means the server is ready to accept requests. @@ -415,13 +358,13 @@ page. You can read more about the purpose of the icon at application while you develop. -Decisions the ``zodb`` scaffold has made for you ------------------------------------------------- +Decisions the ``zodb`` cookiecutter has made for you +---------------------------------------------------- -Creating a project using the ``zodb`` scaffold makes the following +Creating a project using the ``zodb`` cookiecutter makes the following assumptions: -- You are willing to use :term:`ZODB` as persistent storage. +- You are willing to use :term:`ZODB` for persistent storage. - You are willing to use :term:`traversal` to map URLs to code. diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index 85a023cc9..1503aaa0f 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -16,7 +16,7 @@ We write tests for the ``model`` classes and the ``appmaker``. Changing we'll write a test class for the ``appmaker``. To do so, we'll retain the ``tutorial.tests.ViewTests`` class that was -generated as part of the ``zodb`` scaffold. We'll add three test classes: one +generated as part of the ``zodb`` cookiecutter. We'll add three test classes: one for the ``Page`` model named ``PageModelTests``, one for the ``Wiki`` model named ``WikiModelTests``, and one for the appmaker named ``AppmakerTests``. @@ -24,8 +24,8 @@ Test the views ============== We'll modify our ``tests.py`` file, adding tests for each view function we -added previously. As a result, we'll *delete* the ``ViewTests`` class that -the ``zodb`` scaffold provided, and add four other test classes: +added previously. As a result, we'll delete the ``ViewTests`` class that +the ``zodb`` cookiecutter provided, and add four other test classes: ``ViewWikiTests``, ``ViewPageTests``, ``AddPageTests``, and ``EditPageTests``. These test the ``view_wiki``, ``view_page``, ``add_page``, and ``edit_page`` views. @@ -52,7 +52,7 @@ Running the tests ================= We can run these tests by using ``py.test`` similarly to how we did in -:ref:`running_tests`. Courtesy of the scaffold, our testing dependencies have +:ref:`running_tests`. Courtesy of the cookiecutter, our testing dependencies have already been satisfied and ``py.test`` and coverage have already been configured, so we can jump right to running tests. @@ -66,11 +66,11 @@ On Windows: .. code-block:: text - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q + c:\tutorial\> %VENV%\Scripts\py.test -q The expected result should look like the following: .. code-block:: text - ........................ - 24 passed in 2.46 seconds + ......................... + 25 passed in 6.87 seconds -- cgit v1.2.3 From e7b12f6111926cd3073cf1d6365c7a96ef3235b9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 03:13:42 -0800 Subject: update glossary --- docs/glossary.rst | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index 9b41b4359..35d35740d 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1000,6 +1000,10 @@ Glossary application and helps users to quickly get started writing larger applications. Scaffolds are usually used via the ``pcreate`` command. + .. deprecated:: 1.8 + + .. seealso:: See also :term:`cookiecutter`. + pyramid_exclog A package which logs Pyramid application exception (error) information to a standard Python logger. This add-on is most useful when @@ -1133,4 +1137,20 @@ Glossary Python Packaging Authority The `Python Packaging Authority (PyPA) `_ is a working group that maintains many of the relevant projects in Python - packaging. \ No newline at end of file + packaging. + + cookiecutter + A command-line utility that creates projects from :ref:`cookiecutters ` (project templates), e.g., creating a Python package project from a Python package project template. + + Pyramid cookiecutters include: + + * `pyramid-cookiecutter-alchemy `_ + * `pyramid-cookiecutter-starter `_ + * `pyramid-cookiecutter-zodb `_ + + .. versionadded:: 1.8 + + .. seealso:: See also :term:`scaffold`. + + coverage + A measurement of code coverage, usually expressed as a percentage of which lines of code have been executed over which lines are executable, typically run during test execution. -- cgit v1.2.3 From 5d9fd5fb7ca74ac33f2809c7e2949470d318b945 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 03:25:44 -0800 Subject: make distributing.rst's consistent, use pip install --- docs/tutorials/wiki/distributing.rst | 5 ++--- docs/tutorials/wiki2/distributing.rst | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst index 8f1318ec0..c1fc57e0c 100644 --- a/docs/tutorials/wiki/distributing.rst +++ b/docs/tutorials/wiki/distributing.rst @@ -6,9 +6,8 @@ Distributing Your Application Once your application works properly, you can create a "tarball" from it by using the ``setup.py sdist`` command. The following commands assume your -current working directory is the ``tutorial`` package we've created and that -the parent directory of the ``tutorial`` package is a virtual environment -representing a :app:`Pyramid` environment. +current working directory contains the ``tutorial`` package and the +``setup.py`` file. On UNIX: diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index f38a733f4..f4fdfcbbe 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -19,14 +19,14 @@ On Windows: .. code-block:: doscon - c:\pyramidtut> %VENV%\Scripts\python setup.py sdist + c:\tutorial> %VENV%\Scripts\python setup.py sdist The output of such a command will be something like: .. code-block:: text running sdist - # .. more output .. + # more output creating dist Creating tar archive removing 'tutorial-0.0' (and everything under it) @@ -34,7 +34,7 @@ The output of such a command will be something like: Note that this command creates a tarball in the "dist" subdirectory named ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them your cool new application. They should be able to install it by pointing the -``easy_install`` command directly at it. Or you can upload it to `PyPI +``pip install .`` command directly at it. Or you can upload it to `PyPI `_ and share it with the rest of the world, where -it can be downloaded via ``easy_install`` remotely like any other package -people download from PyPI. +it can be downloaded via ``pip install`` remotely like any other package people +download from PyPI. -- cgit v1.2.3 From 640ba7afd320e5eecada829ea8aa89fef6f5230e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 03:27:48 -0800 Subject: standardize windows prompt --- docs/tutorials/wiki/installation.rst | 18 +++++++++--------- docs/tutorials/wiki/tests.rst | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index aa60e310c..8b185a5c6 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -90,7 +90,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> set VENV=c:\tutorial + c:\tutorial> set VENV=c:\tutorial Create a virtual environment @@ -112,13 +112,13 @@ Python 2.7: .. code-block:: doscon - c:\tutorial\> c:\Python27\Scripts\virtualenv %VENV% + c:\tutorial> c:\Python27\Scripts\virtualenv %VENV% Python 3.6: .. code-block:: doscon - c:\tutorial\> c:\Python36\Scripts\python -m venv %VENV% + c:\tutorial> c:\Python36\Scripts\python -m venv %VENV% Upgrade packaging tools in the virtual environment @@ -136,7 +136,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> %VENV%\Scripts\pip install --upgrade pip setuptools + c:\tutorial> %VENV%\Scripts\pip install --upgrade pip setuptools .. _installing_project_in_dev_mode_zodb: @@ -158,7 +158,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> %VENV%\Scripts\pip install -e ".[testing]" + c:\tutorial> %VENV%\Scripts\pip install -e ".[testing]" On all operating systems ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -213,7 +213,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> %VENV%\Scripts\py.test -q + c:\tutorial> %VENV%\Scripts\py.test -q For a successful test run, you should see output that ends like this: @@ -246,7 +246,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> %VENV%\Scripts\py.test --cov \ + c:\tutorial> %VENV%\Scripts\py.test --cov \ --cov-report=term-missing If successful, you will see output something like this: @@ -296,7 +296,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> %VENV%\Scripts\py.test --cov=tutorial tutorial\tests.py -q + c:\tutorial> %VENV%\Scripts\py.test --cov=tutorial tutorial\tests.py -q py.test follows :ref:`conventions for Python test discovery `, and the configuration defaults from the cookiecutter @@ -327,7 +327,7 @@ On Windows .. code-block:: doscon - c:\tutorial\> %VENV%\Scripts\pserve development.ini --reload + c:\tutorial> %VENV%\Scripts\pserve development.ini --reload .. note:: diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index 1503aaa0f..6f0a305e4 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -66,7 +66,7 @@ On Windows: .. code-block:: text - c:\tutorial\> %VENV%\Scripts\py.test -q + c:\tutorial> %VENV%\Scripts\py.test -q The expected result should look like the following: -- cgit v1.2.3 From 81bf1454ad841b8250640f73d2186f2b8778dfac Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 03:55:45 -0800 Subject: wiki/src/installation updates --- docs/tutorials/wiki/src/installation/CHANGES.txt | 2 +- docs/tutorials/wiki/src/installation/README.txt | 27 ++++++++-- .../wiki/src/installation/development.ini | 7 +-- .../tutorials/wiki/src/installation/production.ini | 8 +-- docs/tutorials/wiki/src/installation/setup.py | 60 +++++++++++----------- .../wiki/src/installation/tutorial/__init__.py | 2 + .../installation/tutorial/templates/mytemplate.pt | 10 ++-- .../wiki/src/installation/tutorial/tests.py | 2 +- .../wiki/src/installation/tutorial/views.py | 2 +- 9 files changed, 66 insertions(+), 54 deletions(-) diff --git a/docs/tutorials/wiki/src/installation/CHANGES.txt b/docs/tutorials/wiki/src/installation/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki/src/installation/CHANGES.txt +++ b/docs/tutorials/wiki/src/installation/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki/src/installation/README.txt b/docs/tutorials/wiki/src/installation/README.txt index dcb3605b8..bd67221cc 100644 --- a/docs/tutorials/wiki/src/installation/README.txt +++ b/docs/tutorials/wiki/src/installation/README.txt @@ -1,12 +1,29 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/pserve development.ini +- Create a Python virtual environment. + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki/src/installation/development.ini b/docs/tutorials/wiki/src/installation/development.ini index 78542a1d5..82c8cf3a1 100644 --- a/docs/tutorials/wiki/src/installation/development.ini +++ b/docs/tutorials/wiki/src/installation/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,10 +13,7 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 # By default, the toolbar only appears for clients from IP addresses @@ -33,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/installation/production.ini b/docs/tutorials/wiki/src/installation/production.ini index 0c6aa152b..60b6fe253 100644 --- a/docs/tutorials/wiki/src/installation/production.ini +++ b/docs/tutorials/wiki/src/installation/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -11,11 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - pyramid_zodbconn -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 ### @@ -28,7 +24,7 @@ listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/installation/setup.py b/docs/tutorials/wiki/src/installation/setup.py index 46b395568..5d1e9c7b5 100644 --- a/docs/tutorials/wiki/src/installation/setup.py +++ b/docs/tutorials/wiki/src/installation/setup.py @@ -17,37 +17,39 @@ requires = [ 'transaction', 'ZODB3', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + }, +) diff --git a/docs/tutorials/wiki/src/installation/tutorial/__init__.py b/docs/tutorials/wiki/src/installation/tutorial/__init__.py index f2a86df47..728f7ac02 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/installation/tutorial/__init__.py @@ -13,6 +13,8 @@ def main(global_config, **settings): """ config = Configurator(root_factory=root_factory, settings=settings) config.include('pyramid_chameleon') + config.include('pyramid_tm') + config.include('pyramid_zodbconn') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt index f8cbe2e2c..3ac122711 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/installation/tutorial/templates/mytemplate.pt @@ -8,7 +8,7 @@ - ZODB Scaffold for The Pyramid Web Framework + Cookiecutter ZODB project for the Pyramid Web Framework @@ -33,18 +33,16 @@
    -

    Pyramid ZODB scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework 1.7.

    +

    Pyramid ZODB Project

    +

    Welcome to ${project}, a Pyramid application generated by
    Cookiecutter.

    diff --git a/docs/tutorials/wiki/src/installation/tutorial/tests.py b/docs/tutorials/wiki/src/installation/tutorial/tests.py index 40f3c47af..ca7a47279 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/tests.py +++ b/docs/tutorials/wiki/src/installation/tutorial/tests.py @@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase): from .views import my_view request = testing.DummyRequest() info = my_view(request) - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') diff --git a/docs/tutorials/wiki/src/installation/tutorial/views.py b/docs/tutorials/wiki/src/installation/tutorial/views.py index 628ce15ed..c1878bdd0 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/views.py +++ b/docs/tutorials/wiki/src/installation/tutorial/views.py @@ -4,4 +4,4 @@ from .models import MyModel @view_config(context=MyModel, renderer='templates/mytemplate.pt') def my_view(request): - return {'project': 'tutorial'} + return {'project': 'myproj'} -- cgit v1.2.3 From d5662c9f169575d868655068ae6f3b346b223af7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:07:09 -0800 Subject: alignment was off --- docs/tutorials/wiki/installation.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 8b185a5c6..2400f1b13 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -259,17 +259,17 @@ If successful, you will see output something like this: plugins: cov-2.4.0 collected 1 items - tutorial/tests.py . - ------------------ coverage: platform Python 3.6.0 ------------------ - Name Stmts Miss Cover Missing - ------------------------------------------------------- - tutorial/__init__.py 14 9 36% 7-8, 14-20 - tutorial/models.py 10 6 40% 9-14 - tutorial/views.py 4 0 100% - ------------------------------------------------------- - TOTAL 28 15 46% - - ===================== 1 passed in 0.31 seconds ====================== + tutorial/tests.py . + ------------------ coverage: platform Python 3.6.0 ------------------ + Name Stmts Miss Cover Missing + ------------------------------------------------------- + tutorial/__init__.py 14 9 36% 7-8, 14-20 + tutorial/models.py 10 6 40% 9-14 + tutorial/views.py 4 0 100% + ------------------------------------------------------- + TOTAL 28 15 46% + + ===================== 1 passed in 0.31 seconds ====================== Our package doesn't quite have 100% test coverage. -- cgit v1.2.3 From 184bb8dc828e2b4d0b9fc85b50d06bb773918f26 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:09:52 -0800 Subject: forgot to add some files to git --- docs/tutorials/wiki/src/installation/.coveragerc | 3 +++ docs/tutorials/wiki/src/installation/pytest.ini | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 docs/tutorials/wiki/src/installation/.coveragerc create mode 100644 docs/tutorials/wiki/src/installation/pytest.ini diff --git a/docs/tutorials/wiki/src/installation/.coveragerc b/docs/tutorials/wiki/src/installation/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki/src/installation/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/installation/pytest.ini b/docs/tutorials/wiki/src/installation/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki/src/installation/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py -- cgit v1.2.3 From 9e5dccb4d473b7e1fc38a2c8ff7e60dd88c2c64c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:11:21 -0800 Subject: wiki/src/basiclayout updats --- docs/tutorials/wiki/src/basiclayout/.coveragerc | 3 ++ docs/tutorials/wiki/src/basiclayout/CHANGES.txt | 2 +- docs/tutorials/wiki/src/basiclayout/README.txt | 27 ++++++++-- .../tutorials/wiki/src/basiclayout/development.ini | 7 +-- docs/tutorials/wiki/src/basiclayout/production.ini | 8 +-- docs/tutorials/wiki/src/basiclayout/pytest.ini | 3 ++ docs/tutorials/wiki/src/basiclayout/setup.py | 60 +++++++++++----------- .../wiki/src/basiclayout/tutorial/__init__.py | 2 + .../basiclayout/tutorial/templates/mytemplate.pt | 10 ++-- .../wiki/src/basiclayout/tutorial/tests.py | 2 +- .../wiki/src/basiclayout/tutorial/views.py | 2 +- 11 files changed, 72 insertions(+), 54 deletions(-) create mode 100644 docs/tutorials/wiki/src/basiclayout/.coveragerc create mode 100644 docs/tutorials/wiki/src/basiclayout/pytest.ini diff --git a/docs/tutorials/wiki/src/basiclayout/.coveragerc b/docs/tutorials/wiki/src/basiclayout/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/basiclayout/CHANGES.txt b/docs/tutorials/wiki/src/basiclayout/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki/src/basiclayout/CHANGES.txt +++ b/docs/tutorials/wiki/src/basiclayout/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki/src/basiclayout/README.txt b/docs/tutorials/wiki/src/basiclayout/README.txt index dcb3605b8..bd67221cc 100644 --- a/docs/tutorials/wiki/src/basiclayout/README.txt +++ b/docs/tutorials/wiki/src/basiclayout/README.txt @@ -1,12 +1,29 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/pserve development.ini +- Create a Python virtual environment. + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 78542a1d5..82c8cf3a1 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,10 +13,7 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 # By default, the toolbar only appears for clients from IP addresses @@ -33,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/basiclayout/production.ini b/docs/tutorials/wiki/src/basiclayout/production.ini index 0c6aa152b..60b6fe253 100644 --- a/docs/tutorials/wiki/src/basiclayout/production.ini +++ b/docs/tutorials/wiki/src/basiclayout/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -11,11 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - pyramid_zodbconn -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 ### @@ -28,7 +24,7 @@ listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/basiclayout/pytest.ini b/docs/tutorials/wiki/src/basiclayout/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py index 46b395568..5d1e9c7b5 100644 --- a/docs/tutorials/wiki/src/basiclayout/setup.py +++ b/docs/tutorials/wiki/src/basiclayout/setup.py @@ -17,37 +17,39 @@ requires = [ 'transaction', 'ZODB3', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + }, +) diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py index f2a86df47..728f7ac02 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/__init__.py @@ -13,6 +13,8 @@ def main(global_config, **settings): """ config = Configurator(root_factory=root_factory, settings=settings) config.include('pyramid_chameleon') + config.include('pyramid_tm') + config.include('pyramid_zodbconn') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt index f8cbe2e2c..3ac122711 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt @@ -8,7 +8,7 @@ - ZODB Scaffold for The Pyramid Web Framework + Cookiecutter ZODB project for the Pyramid Web Framework @@ -33,18 +33,16 @@
    -

    Pyramid ZODB scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework 1.7.

    +

    Pyramid ZODB Project

    +

    Welcome to ${project}, a Pyramid application generated by
    Cookiecutter.

    diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py index 40f3c47af..ca7a47279 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py @@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase): from .views import my_view request = testing.DummyRequest() info = my_view(request) - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/views.py b/docs/tutorials/wiki/src/basiclayout/tutorial/views.py index 628ce15ed..c1878bdd0 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/views.py +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/views.py @@ -4,4 +4,4 @@ from .models import MyModel @view_config(context=MyModel, renderer='templates/mytemplate.pt') def my_view(request): - return {'project': 'tutorial'} + return {'project': 'myproj'} -- cgit v1.2.3 From 0fb992d2eb0edeab67c4c57212244d6c6a6c515b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:21:00 -0800 Subject: wiki/src/models updates --- docs/tutorials/wiki/src/models/CHANGES.txt | 2 +- docs/tutorials/wiki/src/models/README.txt | 27 ++++++++-- docs/tutorials/wiki/src/models/development.ini | 7 +-- docs/tutorials/wiki/src/models/production.ini | 8 +-- docs/tutorials/wiki/src/models/setup.py | 60 +++++++++++----------- .../tutorials/wiki/src/models/tutorial/__init__.py | 2 + .../src/models/tutorial/templates/mytemplate.pt | 10 ++-- docs/tutorials/wiki/src/models/tutorial/tests.py | 2 +- docs/tutorials/wiki/src/models/tutorial/views.py | 2 +- 9 files changed, 66 insertions(+), 54 deletions(-) diff --git a/docs/tutorials/wiki/src/models/CHANGES.txt b/docs/tutorials/wiki/src/models/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki/src/models/CHANGES.txt +++ b/docs/tutorials/wiki/src/models/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki/src/models/README.txt b/docs/tutorials/wiki/src/models/README.txt index dcb3605b8..bd67221cc 100644 --- a/docs/tutorials/wiki/src/models/README.txt +++ b/docs/tutorials/wiki/src/models/README.txt @@ -1,12 +1,29 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/pserve development.ini +- Create a Python virtual environment. + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 78542a1d5..82c8cf3a1 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,10 +13,7 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 # By default, the toolbar only appears for clients from IP addresses @@ -33,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/models/production.ini b/docs/tutorials/wiki/src/models/production.ini index 0c6aa152b..60b6fe253 100644 --- a/docs/tutorials/wiki/src/models/production.ini +++ b/docs/tutorials/wiki/src/models/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -11,11 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - pyramid_zodbconn -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 ### @@ -28,7 +24,7 @@ listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py index 46b395568..5d1e9c7b5 100644 --- a/docs/tutorials/wiki/src/models/setup.py +++ b/docs/tutorials/wiki/src/models/setup.py @@ -17,37 +17,39 @@ requires = [ 'transaction', 'ZODB3', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + }, +) diff --git a/docs/tutorials/wiki/src/models/tutorial/__init__.py b/docs/tutorials/wiki/src/models/tutorial/__init__.py index f2a86df47..728f7ac02 100644 --- a/docs/tutorials/wiki/src/models/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/models/tutorial/__init__.py @@ -13,6 +13,8 @@ def main(global_config, **settings): """ config = Configurator(root_factory=root_factory, settings=settings) config.include('pyramid_chameleon') + config.include('pyramid_tm') + config.include('pyramid_zodbconn') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt index f8cbe2e2c..3ac122711 100644 --- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt @@ -8,7 +8,7 @@ - ZODB Scaffold for The Pyramid Web Framework + Cookiecutter ZODB project for the Pyramid Web Framework @@ -33,18 +33,16 @@
    -

    Pyramid ZODB scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework 1.7.

    +

    Pyramid ZODB Project

    +

    Welcome to ${project}, a Pyramid application generated by
    Cookiecutter.

    diff --git a/docs/tutorials/wiki/src/models/tutorial/tests.py b/docs/tutorials/wiki/src/models/tutorial/tests.py index 40f3c47af..ca7a47279 100644 --- a/docs/tutorials/wiki/src/models/tutorial/tests.py +++ b/docs/tutorials/wiki/src/models/tutorial/tests.py @@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase): from .views import my_view request = testing.DummyRequest() info = my_view(request) - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') diff --git a/docs/tutorials/wiki/src/models/tutorial/views.py b/docs/tutorials/wiki/src/models/tutorial/views.py index 628ce15ed..c1878bdd0 100644 --- a/docs/tutorials/wiki/src/models/tutorial/views.py +++ b/docs/tutorials/wiki/src/models/tutorial/views.py @@ -4,4 +4,4 @@ from .models import MyModel @view_config(context=MyModel, renderer='templates/mytemplate.pt') def my_view(request): - return {'project': 'tutorial'} + return {'project': 'myproj'} -- cgit v1.2.3 From 9d95c55f951e31fd42c10d40136cd72fc95f2159 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:21:30 -0800 Subject: wiki/src/models updates --- docs/tutorials/wiki/src/models/.coveragerc | 3 +++ docs/tutorials/wiki/src/models/pytest.ini | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 docs/tutorials/wiki/src/models/.coveragerc create mode 100644 docs/tutorials/wiki/src/models/pytest.ini diff --git a/docs/tutorials/wiki/src/models/.coveragerc b/docs/tutorials/wiki/src/models/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki/src/models/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/models/pytest.ini b/docs/tutorials/wiki/src/models/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki/src/models/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py -- cgit v1.2.3 From e03ea9265b809f783094799e67ae9e00e09085b1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:27:48 -0800 Subject: wiki/src/views updates --- docs/tutorials/wiki/src/views/.coveragerc | 3 + docs/tutorials/wiki/src/views/CHANGES.txt | 2 +- docs/tutorials/wiki/src/views/README.txt | 27 +++++++-- docs/tutorials/wiki/src/views/development.ini | 7 +-- docs/tutorials/wiki/src/views/production.ini | 8 +-- docs/tutorials/wiki/src/views/pytest.ini | 3 + docs/tutorials/wiki/src/views/setup.py | 60 +++++++++---------- docs/tutorials/wiki/src/views/tutorial/__init__.py | 2 + .../src/views/tutorial/templates/mytemplate.pt | 67 ---------------------- docs/tutorials/wiki/src/views/tutorial/tests.py | 2 +- docs/tutorials/wiki/src/views/tutorial/views.py | 2 +- 11 files changed, 68 insertions(+), 115 deletions(-) create mode 100644 docs/tutorials/wiki/src/views/.coveragerc create mode 100644 docs/tutorials/wiki/src/views/pytest.ini delete mode 100644 docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt diff --git a/docs/tutorials/wiki/src/views/.coveragerc b/docs/tutorials/wiki/src/views/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki/src/views/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/views/CHANGES.txt b/docs/tutorials/wiki/src/views/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki/src/views/CHANGES.txt +++ b/docs/tutorials/wiki/src/views/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki/src/views/README.txt b/docs/tutorials/wiki/src/views/README.txt index dcb3605b8..bd67221cc 100644 --- a/docs/tutorials/wiki/src/views/README.txt +++ b/docs/tutorials/wiki/src/views/README.txt @@ -1,12 +1,29 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/pserve development.ini +- Create a Python virtual environment. + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index 78542a1d5..82c8cf3a1 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,10 +13,7 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 # By default, the toolbar only appears for clients from IP addresses @@ -33,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/views/production.ini b/docs/tutorials/wiki/src/views/production.ini index 0c6aa152b..60b6fe253 100644 --- a/docs/tutorials/wiki/src/views/production.ini +++ b/docs/tutorials/wiki/src/views/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -11,11 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - pyramid_zodbconn -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 ### @@ -28,7 +24,7 @@ listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/views/pytest.ini b/docs/tutorials/wiki/src/views/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki/src/views/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py index beeed75c9..598ad8146 100644 --- a/docs/tutorials/wiki/src/views/setup.py +++ b/docs/tutorials/wiki/src/views/setup.py @@ -18,37 +18,39 @@ requires = [ 'ZODB3', 'waitress', 'docutils', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + }, +) diff --git a/docs/tutorials/wiki/src/views/tutorial/__init__.py b/docs/tutorials/wiki/src/views/tutorial/__init__.py index f2a86df47..728f7ac02 100644 --- a/docs/tutorials/wiki/src/views/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/views/tutorial/__init__.py @@ -13,6 +13,8 @@ def main(global_config, **settings): """ config = Configurator(root_factory=root_factory, settings=settings) config.include('pyramid_chameleon') + config.include('pyramid_tm') + config.include('pyramid_zodbconn') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt deleted file mode 100644 index f8cbe2e2c..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - ZODB Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    Pyramid ZODB scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework 1.7.

    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki/src/views/tutorial/tests.py b/docs/tutorials/wiki/src/views/tutorial/tests.py index 40f3c47af..ca7a47279 100644 --- a/docs/tutorials/wiki/src/views/tutorial/tests.py +++ b/docs/tutorials/wiki/src/views/tutorial/tests.py @@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase): from .views import my_view request = testing.DummyRequest() info = my_view(request) - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') diff --git a/docs/tutorials/wiki/src/views/tutorial/views.py b/docs/tutorials/wiki/src/views/tutorial/views.py index 61517c31d..5c8affa64 100644 --- a/docs/tutorials/wiki/src/views/tutorial/views.py +++ b/docs/tutorials/wiki/src/views/tutorial/views.py @@ -57,4 +57,4 @@ def edit_page(context, request): return HTTPFound(location = request.resource_url(context)) return dict(page=context, - save_url=request.resource_url(context, 'edit_page')) + save_url=request.resource_url(context, 'edit_page')) \ No newline at end of file -- cgit v1.2.3 From 0a2628a592599744b2a2ff8800f0e69c2db9e81b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:48:59 -0800 Subject: wiki/src/authorization updates --- docs/tutorials/wiki/src/authorization/.coveragerc | 3 + docs/tutorials/wiki/src/authorization/CHANGES.txt | 2 +- docs/tutorials/wiki/src/authorization/README.txt | 27 +++++++-- .../wiki/src/authorization/development.ini | 7 +-- .../wiki/src/authorization/production.ini | 8 +-- docs/tutorials/wiki/src/authorization/pytest.ini | 3 + docs/tutorials/wiki/src/authorization/setup.py | 60 +++++++++---------- .../wiki/src/authorization/tutorial/__init__.py | 2 + .../src/authorization/tutorial/templates/edit.pt | 1 + .../src/authorization/tutorial/templates/login.pt | 1 + .../authorization/tutorial/templates/mytemplate.pt | 67 ---------------------- .../src/authorization/tutorial/templates/view.pt | 1 + .../wiki/src/authorization/tutorial/tests.py | 2 +- .../wiki/src/authorization/tutorial/views.py | 2 - 14 files changed, 70 insertions(+), 116 deletions(-) create mode 100644 docs/tutorials/wiki/src/authorization/.coveragerc create mode 100644 docs/tutorials/wiki/src/authorization/pytest.ini delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt diff --git a/docs/tutorials/wiki/src/authorization/.coveragerc b/docs/tutorials/wiki/src/authorization/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/authorization/CHANGES.txt b/docs/tutorials/wiki/src/authorization/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki/src/authorization/CHANGES.txt +++ b/docs/tutorials/wiki/src/authorization/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki/src/authorization/README.txt b/docs/tutorials/wiki/src/authorization/README.txt index dcb3605b8..bd67221cc 100644 --- a/docs/tutorials/wiki/src/authorization/README.txt +++ b/docs/tutorials/wiki/src/authorization/README.txt @@ -1,12 +1,29 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/pserve development.ini +- Create a Python virtual environment. + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index 78542a1d5..82c8cf3a1 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,10 +13,7 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 # By default, the toolbar only appears for clients from IP addresses @@ -33,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/authorization/production.ini b/docs/tutorials/wiki/src/authorization/production.ini index 0c6aa152b..60b6fe253 100644 --- a/docs/tutorials/wiki/src/authorization/production.ini +++ b/docs/tutorials/wiki/src/authorization/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -11,11 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - pyramid_zodbconn -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 ### @@ -28,7 +24,7 @@ listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/authorization/pytest.ini b/docs/tutorials/wiki/src/authorization/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py index 68e3c0abd..4a9f041e3 100644 --- a/docs/tutorials/wiki/src/authorization/setup.py +++ b/docs/tutorials/wiki/src/authorization/setup.py @@ -19,37 +19,39 @@ requires = [ 'waitress', 'docutils', 'bcrypt', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + }, +) diff --git a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py index 39b94abd1..8af2ee5c0 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/__init__.py @@ -22,6 +22,8 @@ def main(global_config, **settings): config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) config.include('pyramid_chameleon') + config.include('pyramid_tm') + config.include('pyramid_zodbconn') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt index 823fa8972..19adc5932 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/edit.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt index 4a938e9bb..02f7038fe 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/login.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt deleted file mode 100644 index f8cbe2e2c..000000000 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - ZODB Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    Pyramid ZODB scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework 1.7.

    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt index fa35d758d..17a715b50 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/view.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/authorization/tutorial/tests.py b/docs/tutorials/wiki/src/authorization/tutorial/tests.py index 40f3c47af..ca7a47279 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/tests.py @@ -14,4 +14,4 @@ class ViewTests(unittest.TestCase): from .views import my_view request = testing.DummyRequest() info = my_view(request) - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py index e4560dfe1..ea2da01af 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py @@ -43,7 +43,6 @@ def view_page(context, request): content = publish_parts(context.data, writer_name='html')['html_body'] content = wikiwords.sub(check, content) edit_url = request.resource_url(context, 'edit_page') - return dict(page=context, content=content, edit_url=edit_url, logged_in=request.authenticated_userid) @@ -63,7 +62,6 @@ def add_page(context, request): page = Page('') page.__name__ = pagename page.__parent__ = context - return dict(page=page, save_url=save_url, logged_in=request.authenticated_userid) -- cgit v1.2.3 From b960f68382611c1e9ecd04a24e8c6a414d11d0b9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 04:59:46 -0800 Subject: readjust line numbers --- docs/tutorials/wiki/authorization.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 63f18d72f..d580e7816 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -232,7 +232,7 @@ Add the following import statements to the head of ``tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 5-18 + :lines: 6-17 :emphasize-lines: 1-14 :language: python @@ -311,7 +311,7 @@ Open ``tutorial/templates/edit.pt`` and indicated by the highlighted lines. .. literalinclude:: src/authorization/tutorial/templates/edit.pt - :lines: 34-38 + :lines: 35-39 :emphasize-lines: 3-5 :language: html -- cgit v1.2.3 From 90b803a669241fe39d7201633ba9dd539f401f12 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 05:04:55 -0800 Subject: wiki/src/views updates, PEP8 the dict --- docs/tutorials/wiki/src/views/tutorial/templates/view.pt | 1 + docs/tutorials/wiki/src/views/tutorial/views.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt index 93580658b..5caaef4af 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/view.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/views/tutorial/views.py b/docs/tutorials/wiki/src/views/tutorial/views.py index 5c8affa64..fd2b0edc1 100644 --- a/docs/tutorials/wiki/src/views/tutorial/views.py +++ b/docs/tutorials/wiki/src/views/tutorial/views.py @@ -24,13 +24,13 @@ def view_page(context, request): view_url = request.resource_url(page) return '%s' % (view_url, word) else: - add_url = request.application_url + '/add_page/' + word + add_url = request.application_url + '/add_page/' + word return '%s' % (add_url, word) content = publish_parts(context.data, writer_name='html')['html_body'] content = wikiwords.sub(check, content) edit_url = request.resource_url(context, 'edit_page') - return dict(page = context, content = content, edit_url = edit_url) + return dict(page=context, content=content, edit_url=edit_url) @view_config(name='add_page', context='.models.Wiki', renderer='templates/edit.pt') @@ -42,19 +42,19 @@ def add_page(context, request): page.__name__ = pagename page.__parent__ = context context[pagename] = page - return HTTPFound(location = request.resource_url(page)) + return HTTPFound(location=request.resource_url(page)) save_url = request.resource_url(context, 'add_page', pagename) page = Page('') page.__name__ = pagename page.__parent__ = context - return dict(page = page, save_url = save_url) + return dict(page=page, save_url=save_url) @view_config(name='edit_page', context='.models.Page', renderer='templates/edit.pt') def edit_page(context, request): if 'form.submitted' in request.params: context.data = request.params['body'] - return HTTPFound(location = request.resource_url(context)) + return HTTPFound(location=request.resource_url(context)) return dict(page=context, save_url=request.resource_url(context, 'edit_page')) \ No newline at end of file -- cgit v1.2.3 From d5f734ccb61f3df81575cdbbe4fc9fbf523b8746 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 05:14:42 -0800 Subject: wiki/src/tests updates, use correct lexers --- docs/tutorials/wiki/src/tests/.coveragerc | 3 ++ docs/tutorials/wiki/src/tests/CHANGES.txt | 2 +- docs/tutorials/wiki/src/tests/README.txt | 27 ++++++++-- docs/tutorials/wiki/src/tests/development.ini | 7 +-- docs/tutorials/wiki/src/tests/production.ini | 8 +-- docs/tutorials/wiki/src/tests/pytest.ini | 3 ++ docs/tutorials/wiki/src/tests/setup.py | 60 +++++++++++----------- docs/tutorials/wiki/src/tests/tutorial/__init__.py | 2 + .../wiki/src/tests/tutorial/templates/edit.pt | 1 + .../wiki/src/tests/tutorial/templates/login.pt | 1 + .../wiki/src/tests/tutorial/templates/view.pt | 1 + docs/tutorials/wiki/src/tests/tutorial/views.py | 2 - docs/tutorials/wiki/tests.rst | 4 +- 13 files changed, 71 insertions(+), 50 deletions(-) create mode 100644 docs/tutorials/wiki/src/tests/.coveragerc create mode 100644 docs/tutorials/wiki/src/tests/pytest.ini diff --git a/docs/tutorials/wiki/src/tests/.coveragerc b/docs/tutorials/wiki/src/tests/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki/src/tests/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/tests/CHANGES.txt b/docs/tutorials/wiki/src/tests/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki/src/tests/CHANGES.txt +++ b/docs/tutorials/wiki/src/tests/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki/src/tests/README.txt b/docs/tutorials/wiki/src/tests/README.txt index dcb3605b8..bd67221cc 100644 --- a/docs/tutorials/wiki/src/tests/README.txt +++ b/docs/tutorials/wiki/src/tests/README.txt @@ -1,12 +1,29 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/pserve development.ini +- Create a Python virtual environment. + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki/src/tests/development.ini b/docs/tutorials/wiki/src/tests/development.ini index 78542a1d5..82c8cf3a1 100644 --- a/docs/tutorials/wiki/src/tests/development.ini +++ b/docs/tutorials/wiki/src/tests/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,10 +13,7 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_zodbconn - pyramid_tm -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 # By default, the toolbar only appears for clients from IP addresses @@ -33,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/tests/production.ini b/docs/tutorials/wiki/src/tests/production.ini index 0c6aa152b..60b6fe253 100644 --- a/docs/tutorials/wiki/src/tests/production.ini +++ b/docs/tutorials/wiki/src/tests/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -11,11 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - pyramid_zodbconn -tm.attempts = 3 zodbconn.uri = file://%(here)s/Data.fs?connection_cache_size=20000 ### @@ -28,7 +24,7 @@ listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki/src/tests/pytest.ini b/docs/tutorials/wiki/src/tests/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki/src/tests/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py index 68e3c0abd..4a9f041e3 100644 --- a/docs/tutorials/wiki/src/tests/setup.py +++ b/docs/tutorials/wiki/src/tests/setup.py @@ -19,37 +19,39 @@ requires = [ 'waitress', 'docutils', 'bcrypt', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + }, +) diff --git a/docs/tutorials/wiki/src/tests/tutorial/__init__.py b/docs/tutorials/wiki/src/tests/tutorial/__init__.py index 39b94abd1..8af2ee5c0 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/__init__.py +++ b/docs/tutorials/wiki/src/tests/tutorial/__init__.py @@ -22,6 +22,8 @@ def main(global_config, **settings): config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) config.include('pyramid_chameleon') + config.include('pyramid_tm') + config.include('pyramid_zodbconn') config.add_static_view('static', 'static', cache_max_age=3600) config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt index 823fa8972..19adc5932 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/edit.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt index 4a938e9bb..02f7038fe 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/login.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt index fa35d758d..17a715b50 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/view.pt @@ -23,6 +23,7 @@ +
    diff --git a/docs/tutorials/wiki/src/tests/tutorial/views.py b/docs/tutorials/wiki/src/tests/tutorial/views.py index e4560dfe1..ea2da01af 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/views.py +++ b/docs/tutorials/wiki/src/tests/tutorial/views.py @@ -43,7 +43,6 @@ def view_page(context, request): content = publish_parts(context.data, writer_name='html')['html_body'] content = wikiwords.sub(check, content) edit_url = request.resource_url(context, 'edit_page') - return dict(page=context, content=content, edit_url=edit_url, logged_in=request.authenticated_userid) @@ -63,7 +62,6 @@ def add_page(context, request): page = Page('') page.__name__ = pagename page.__parent__ = context - return dict(page=page, save_url=save_url, logged_in=request.authenticated_userid) diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index 6f0a305e4..cd82c0118 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -58,13 +58,13 @@ configured, so we can jump right to running tests. On UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/py.test -q On Windows: -.. code-block:: text +.. code-block:: doscon c:\tutorial> %VENV%\Scripts\py.test -q -- cgit v1.2.3 From 38cf5b3d218cf1476c4553c229aebe15577b7f16 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 05:15:03 -0800 Subject: replace pcreate w/cc --- docs/tutorials/wiki/definingviews.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index f6e080d09..442d5ed18 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -36,7 +36,7 @@ Declaring Dependencies in Our ``setup.py`` File The view code in our application will depend on a package which is not a dependency of the original "tutorial" application. The original "tutorial" -application was generated by the ``pcreate`` command; it doesn't know +application was generated by the cookiecutter; it doesn't know about our custom application requirements. We need to add a dependency on the ``docutils`` package to our ``tutorial`` -- cgit v1.2.3 From acab34a20e9d017167f22f37a256e17758e9920e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 05:42:11 -0800 Subject: add cookiecutter to intersphinx --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 46534ea15..5eb18f15f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,6 +64,7 @@ extensions = [ intersphinx_mapping = { 'colander': ('http://docs.pylonsproject.org/projects/colander/en/latest', None), 'cookbook': ('http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/', None), + 'cookiecutter': ('https://cookiecutter.readthedocs.io/en/latest/', None), 'deform': ('http://docs.pylonsproject.org/projects/deform/en/latest', None), 'jinja2': ('http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/', None), 'pylonswebframework': ('http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/', None), -- cgit v1.2.3 From 1117bcd9a458e2f8664cabeef84209cf7b168e30 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 12:33:31 -0800 Subject: drop . from pip install command --- docs/tutorials/wiki/distributing.rst | 2 +- docs/tutorials/wiki2/distributing.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/wiki/distributing.rst b/docs/tutorials/wiki/distributing.rst index c1fc57e0c..fb0a552e0 100644 --- a/docs/tutorials/wiki/distributing.rst +++ b/docs/tutorials/wiki/distributing.rst @@ -34,7 +34,7 @@ The output of such a command will be something like: Note that this command creates a tarball in the "dist" subdirectory named ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them your cool new application. They should be able to install it by pointing the -``pip install .`` command directly at it. Or you can upload it to `PyPI +``pip install`` command directly at it. Or you can upload it to `PyPI `_ and share it with the rest of the world, where it can be downloaded via ``pip install`` remotely like any other package people download from PyPI. diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index f4fdfcbbe..7e2a08a58 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -34,7 +34,7 @@ The output of such a command will be something like: Note that this command creates a tarball in the "dist" subdirectory named ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them your cool new application. They should be able to install it by pointing the -``pip install .`` command directly at it. Or you can upload it to `PyPI +``pip install`` command directly at it. Or you can upload it to `PyPI `_ and share it with the rest of the world, where it can be downloaded via ``pip install`` remotely like any other package people download from PyPI. -- cgit v1.2.3 From ae6991bfc14db5d8577495e555a2dd8c9cd57e6f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 13:48:59 -0800 Subject: use correct package name --- docs/tutorials/wiki/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 2400f1b13..1368b5b2a 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -172,7 +172,7 @@ The console will show ``pip`` checking for packages and installing missing packa WebTest-2.0.23 ZConfig-3.1.0 ZEO-5.0.4 ZODB-5.1.1 ZODB3-3.11.0 \ beautifulsoup4-4.5.1 coverage-4.2 mock-2.0.0 pbr-1.10.0 persistent-4.2.2 \ py-1.4.31 pyramid-1.7.3 pyramid-chameleon-0.3 pyramid-debugtoolbar-3.0.5 \ - pyramid-mako-1.0.2 pyramid-tm-1.1.1 pyramid-zodbconn-0.7 pyramidtut \ + pyramid-mako-1.0.2 pyramid-tm-1.1.1 pyramid-zodbconn-0.7 tutorial \ pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 transaction-2.0.3 \ translationstring-1.3 venusian-1.0 waitress-1.0.1 zc.lockfile-1.2.1 \ zdaemon-4.2.0 zodbpickle-0.6.0 zodburi-2.0 zope.deprecation-4.2.0 \ -- cgit v1.2.3 From b29848f9d7b49715c1027c7361bb68e03707deae Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 13:50:10 -0800 Subject: wiki2/*.rst first cut from comparing across branches --- docs/tutorials/wiki2/authentication.rst | 2 +- docs/tutorials/wiki2/basiclayout.rst | 14 +- docs/tutorials/wiki2/definingmodels.rst | 143 +++++++------- docs/tutorials/wiki2/definingviews.rst | 12 +- docs/tutorials/wiki2/design.rst | 33 ++-- docs/tutorials/wiki2/distributing.rst | 2 +- docs/tutorials/wiki2/index.rst | 7 +- docs/tutorials/wiki2/installation.rst | 338 +++++++++++++------------------- docs/tutorials/wiki2/tests.rst | 4 +- 9 files changed, 236 insertions(+), 319 deletions(-) diff --git a/docs/tutorials/wiki2/authentication.rst b/docs/tutorials/wiki2/authentication.rst index 5447db861..ff59ce70b 100644 --- a/docs/tutorials/wiki2/authentication.rst +++ b/docs/tutorials/wiki2/authentication.rst @@ -92,7 +92,7 @@ Our authentication policy is expecting a new setting, ``auth.secret``. Open the file ``development.ini`` and add the highlighted line below: .. literalinclude:: src/authentication/development.ini - :lines: 18-20 + :lines: 17-19 :emphasize-lines: 3 :lineno-match: :language: ini diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index 98a14c644..233231f8d 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -4,7 +4,7 @@ Basic Layout ============ -The starter files generated by the ``alchemy`` scaffold are very basic, but +The starter files generated by the ``alchemy`` cookiecutter are very basic, but they provide a good orientation for the high-level patterns common to most :term:`URL dispatch`-based :app:`Pyramid` projects. @@ -29,7 +29,6 @@ code: .. literalinclude:: src/basiclayout/tutorial/__init__.py :end-before: main - :linenos: :lineno-match: :language: py @@ -38,7 +37,6 @@ the ``main`` function we've defined in our ``__init__.py``: .. literalinclude:: src/basiclayout/tutorial/__init__.py :pyobject: main - :linenos: :lineno-match: :language: py @@ -179,7 +177,7 @@ decorator in order to create a view configuration within our application. Without being processed by ``scan``, the decorator effectively does nothing. ``@view_config`` is inert without being detected via a :term:`scan`. -The sample ``my_view()`` created by the scaffold uses a ``try:`` and +The sample ``my_view()`` created by the cookiecutter uses a ``try:`` and ``except:`` clause to detect if there is a problem accessing the project database and provide an alternate error response. That response will include the text shown at the end of the file, which will be displayed in the browser @@ -191,7 +189,7 @@ Content models with the ``models`` package In an SQLAlchemy-based application, a *model* object is an object composed by querying the SQL database. The ``models`` package is where the ``alchemy`` -scaffold put the classes that implement our models. +cookiecutter put the classes that implement our models. First, open ``tutorial/models/meta.py``, which should already contain the following: @@ -222,7 +220,6 @@ application's database schema. .. literalinclude:: src/basiclayout/tutorial/models/meta.py :lines: 15-16 :lineno-match: - :linenos: :language: py Next open ``tutorial/models/mymodel.py``, which should already contain the @@ -239,7 +236,6 @@ we have defined one named ``MyModel`` in ``mymodel.py``: .. literalinclude:: src/basiclayout/tutorial/models/mymodel.py :pyobject: MyModel :lineno-match: - :linenos: :language: py Our example model does not require an ``__init__`` method because SQLAlchemy @@ -292,7 +288,6 @@ database engine using :func:`sqlalchemy.engine_from_config` from the .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: get_engine :lineno-match: - :linenos: :language: py The function ``get_session_factory`` accepts an :term:`SQLAlchemy` database @@ -303,7 +298,6 @@ used for creating sessions bound to the database engine. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: get_session_factory :lineno-match: - :linenos: :language: py The function ``get_tm_session`` registers a database session with a transaction @@ -314,7 +308,6 @@ unless an exception is raised, in which case the transaction will be aborted. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: get_tm_session :lineno-match: - :linenos: :language: py Finally, we define an ``includeme`` function, which is a hook for use with @@ -328,7 +321,6 @@ of an incoming request to our application. .. literalinclude:: src/basiclayout/tutorial/models/__init__.py :pyobject: includeme :lineno-match: - :linenos: :language: py That's about all there is to it regarding models, views, and initialization diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 9f7b82d1d..7d4a7baea 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -4,7 +4,7 @@ Defining the Domain Model ========================= -The first change we'll make to our stock ``pcreate``-generated application will +The first change we'll make to our stock cookiecutter-generated application will be to define a wiki page :term:`domain model`. .. note:: @@ -22,10 +22,10 @@ Declaring dependencies in our ``setup.py`` file The models code in our application will depend on a package which is not a dependency of the original "tutorial" application. The original "tutorial" -application was generated by the ``pcreate`` command; it doesn't know about our +application was generated by the cookiecutter; it doesn't know about our custom application requirements. -We need to add a dependency, the ``bcrypt`` package, to our ``tutorial`` +We need to add a dependency, the `bcrypt `_ package, to our ``tutorial`` package's ``setup.py`` file by assigning this dependency to the ``requires`` parameter in the ``setup()`` function. @@ -38,6 +38,10 @@ Open ``tutorial/setup.py`` and edit it to look like the following: Only the highlighted line needs to be added. +.. note:: + + We are using the ``bcrypt`` package from PyPI to hash our passwords securely. There are other one-way hash algorithms for passwords if bcrypt is an issue on your system. Just make sure that it's an algorithm approved for storing passwords versus a generic one-way hash. + Running ``pip install -e .`` ============================ @@ -53,31 +57,31 @@ On UNIX: .. code-block:: bash - $ cd tutorial - $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install -e . On Windows: .. code-block:: doscon - c:\pyramidtut> cd tutorial - c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . + c:\tutorial> %VENV%\Scripts\pip install -e . Success executing this command will end with a line to the console something -like this:: +like the following. - Successfully installed bcrypt-2.0.0 cffi-1.5.2 pycparser-2.14 tutorial-0.0 +.. code-block:: text + + Successfully installed bcrypt-3.1.2 cffi-1.9.1 pycparser-2.17 tutorial Remove ``mymodel.py`` ---------------------- +===================== Let's delete the file ``tutorial/models/mymodel.py``. The ``MyModel`` class is only a sample and we're not going to use it. Add ``user.py`` ---------------- +=============== Create a new file ``tutorial/models/user.py`` with the following contents: @@ -98,12 +102,12 @@ and ``role`` (all instances of :class:`sqlalchemy.schema.Column`). These will map to columns in the ``users`` table. The ``id`` attribute will be the primary key in the table. The ``name`` attribute will be a text column, each value of which needs to be unique within the column. The ``password_hash`` is a nullable -text attribute that will contain a securely hashed password [1]_. Finally, the +text attribute that will contain a securely hashed password. Finally, the ``role`` text attribute will hold the role of the user. There are two helper methods that will help us later when using the user objects. The first is ``set_password`` which will take a raw password and -transform it using bcrypt_ into an irreversible representation, a process known +transform it using ``bcrypt`` into an irreversible representation, a process known as "hashing". The second method, ``check_password``, will allow us to compare the hashed value of the submitted password against the hashed value of the password stored in the user's record in the database. If the two hashed values @@ -116,7 +120,7 @@ authenticate as any user. Add ``page.py`` ---------------- +=============== Create a new file ``tutorial/models/page.py`` with the following contents: @@ -138,7 +142,7 @@ guaranteed that an instance of ``page`` will have a corresponding Edit ``models/__init__.py`` ---------------------------- +=========================== Since we are using a package for our models, we also need to update our ``__init__.py`` file to ensure that the models are attached to the metadata. @@ -155,12 +159,16 @@ Here we align our imports with the names of the models, ``Page`` and ``User``. Edit ``scripts/initializedb.py`` --------------------------------- +================================ We haven't looked at the details of this file yet, but within the ``scripts`` directory of your ``tutorial`` package is a file named ``initializedb.py``. Code in this file is executed whenever we run the ``initialize_tutorial_db`` -command, as we did in the installation step of this tutorial [2]_. +command, as we did in the installation step of this tutorial. + +.. note:: + + The command is named ``initialize_tutorial_db`` because of the mapping defined in the ``[console_scripts]`` entry point of our project's ``setup.py`` file. Since we've changed our model, we need to make changes to our ``initializedb.py`` script. In particular, we'll replace our import of @@ -180,7 +188,7 @@ Only the highlighted lines need to be changed. Installing the project and re-initializing the database -------------------------------------------------------- +======================================================= Because our model has changed, and in order to reinitialize the database, we need to rerun the ``initialize_tutorial_db`` command to pick up the changes @@ -191,53 +199,53 @@ Success will look something like this: .. code-block:: bash - 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-05-22 04:12:09,226 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("users") - 2016-05-22 04:12:09,227 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:12:09,228 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("pages") - 2016-05-22 04:12:09,228 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:12:09,229 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] - CREATE TABLE users ( - id INTEGER NOT NULL, - name TEXT NOT NULL, - role TEXT NOT NULL, - password_hash TEXT, - CONSTRAINT pk_users PRIMARY KEY (id), - CONSTRAINT uq_users_name UNIQUE (name) - ) - - - 2016-05-22 04:12:09,229 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:12:09,230 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-05-22 04:12:09,230 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] - CREATE TABLE pages ( - id INTEGER NOT NULL, - name TEXT NOT NULL, - data TEXT NOT NULL, - creator_id INTEGER NOT NULL, - CONSTRAINT pk_pages PRIMARY KEY (id), - CONSTRAINT uq_pages_name UNIQUE (name), - CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id) - ) - - - 2016-05-22 04:12:09,231 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:12:09,231 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-05-22 04:12:09,782 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) - 2016-05-22 04:12:09,783 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) - 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('editor', 'editor', b'$2b$12$K/WLVKRl5fMAb6UM58ueTetXlE3rlc5cRK5zFPimK598scXBR/xWC') - 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) - 2016-05-22 04:12:09,784 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('basic', 'basic', b'$2b$12$JfwLyCJGv3t.RTSmIrh3B.FKXRT9FevkAqafWdK5oq7Hl4mgAQORe') - 2016-05-22 04:12:09,785 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) - 2016-05-22 04:12:09,785 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('FrontPage', 'This is the front page', 1) - 2016-05-22 04:12:09,786 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] () + 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2016-12-20 02:51:11,195 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] () + 2016-12-20 02:51:11,196 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] PRAGMA table_info("pages") + 2016-12-20 02:51:11,196 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-20 02:51:11,196 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] PRAGMA table_info("users") + 2016-12-20 02:51:11,197 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-20 02:51:11,197 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] + CREATE TABLE users ( + id INTEGER NOT NULL, + name TEXT NOT NULL, + role TEXT NOT NULL, + password_hash TEXT, + CONSTRAINT pk_users PRIMARY KEY (id), + CONSTRAINT uq_users_name UNIQUE (name) + ) + + + 2016-12-20 02:51:11,197 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-20 02:51:11,198 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT + 2016-12-20 02:51:11,199 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] + CREATE TABLE pages ( + id INTEGER NOT NULL, + name TEXT NOT NULL, + data TEXT NOT NULL, + creator_id INTEGER NOT NULL, + CONSTRAINT pk_pages PRIMARY KEY (id), + CONSTRAINT uq_pages_name UNIQUE (name), + CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id) + ) + + + 2016-12-20 02:51:11,199 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-20 02:51:11,200 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT + 2016-12-20 02:51:11,755 INFO [sqlalchemy.engine.base.Engine:679][MainThread] BEGIN (implicit) + 2016-12-20 02:51:11,755 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) + 2016-12-20 02:51:11,755 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('editor', 'editor', '$2b$12$ds7h2Zb7.l6TEFup5h8f4ekA9GRfEpE1yQGDRvT9PConw73kKuupG') + 2016-12-20 02:51:11,756 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) + 2016-12-20 02:51:11,756 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('basic', 'basic', '$2b$12$KgruXP5Vv7rikr6dGB3TF.flGXYpiE0Li9K583EVomjY.SYmQOsyi') + 2016-12-20 02:51:11,757 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) + 2016-12-20 02:51:11,757 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('FrontPage', 'This is the front page', 1) + 2016-12-20 02:51:11,757 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT View the application in a browser ---------------------------------- +================================= We can't. At this point, our system is in a "non-runnable" state; we'll need to change view-related files in the next chapter to be able to start the @@ -250,14 +258,3 @@ your console that ends with this exception: ImportError: cannot import name MyModel This will also happen if you attempt to run the tests. - -.. _bcrypt: https://pypi.python.org/pypi/bcrypt - -.. [1] We are using the bcrypt_ package from PyPI to hash our passwords - securely. There are other one-way hash algorithms for passwords if - bcrypt is an issue on your system. Just make sure that it's an - algorithm approved for storing passwords versus a generic one-way hash. - -.. [2] The command is named ``initialize_tutorial_db`` because of the mapping - defined in the ``[console_scripts]`` entry point of our project's - ``setup.py`` file. diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index 996bff88c..5d947a06f 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -42,7 +42,7 @@ installed, so re-run the ``$VENV/bin/pip install -e .`` command. Static assets -------------- +============= Our templates name static assets, including CSS and images. We don't need to create these files within our package's ``static`` directory because they @@ -133,7 +133,7 @@ The highlighted lines need to be added or edited. We added some imports, and created a regular expression to find "WikiWords". We got rid of the ``my_view`` view function and its decorator that was added -when we originally rendered the ``alchemy`` scaffold. It was only an example +when we originally rendered the ``alchemy`` cookiecutter. It was only an example and isn't relevant to our application. We also deleted the ``db_err_msg`` string. @@ -340,7 +340,7 @@ indicated by the emphasized lines: .. literalinclude:: src/views/tutorial/templates/layout.jinja2 :linenos: - :emphasize-lines: 11,35-36 + :emphasize-lines: 11,35-37 :language: html Since we're using a templating engine, we can factor common boilerplate out of @@ -350,7 +350,7 @@ template inheritance via blocks. - We have defined two placeholders in the layout template where a child template can override the content. These blocks are named ``subtitle`` (line 11) and ``content`` (line 36). -- Please refer to the Jinja2_ documentation for more information about template +- Please refer to the `Jinja2 documentation `_ for more information about template inheritance. @@ -436,7 +436,7 @@ There are several important things to note about this configuration: the view. Finally, we may delete the ``tutorial/templates/mytemplate.jinja2`` template -that was provided by the ``alchemy`` scaffold, as we have created our own +that was provided by the ``alchemy`` cookiecutter, as we have created our own templates for the wiki. .. note:: @@ -475,5 +475,3 @@ each of the following URLs, checking that the result is as expected: will generate a ``NoResultFound: No row was found for one()`` error. You'll see an interactive traceback facility provided by :term:`pyramid_debugtoolbar`. - -.. _jinja2: http://jinja.pocoo.org/ diff --git a/docs/tutorials/wiki2/design.rst b/docs/tutorials/wiki2/design.rst index 523a6e6d8..515aff276 100644 --- a/docs/tutorials/wiki2/design.rst +++ b/docs/tutorials/wiki2/design.rst @@ -23,22 +23,22 @@ We'll be using an SQLite database to hold our wiki data, and we'll be using Within the database, we will define two tables: -- The `users` table which will store the `id`, `name`, `password_hash` and - `role` of each wiki user. -- The `pages` table, whose elements will store the wiki pages. - There are four columns: `id`, `name`, `data` and `creator_id`. +- The ``users`` table which will store the ``id``, ``name``, ``password_hash`` and + ``role`` of each wiki user. +- The ``pages`` table, whose elements will store the wiki pages. + There are four columns: ``id``, ``name``, ``data`` and ``creator_id``. -There is a one-to-many relationship between `users` and `pages` tracking -the user who created each wiki page defined by the `creator_id` column on the -`pages` table. +There is a one-to-many relationship between ``users`` and ``pages`` tracking +the user who created each wiki page defined by the ``creator_id`` column on the +``pages`` table. -URLs like ``/PageName`` will try to find an element in the `pages` table that +URLs like ``/PageName`` will try to find an element in the ``pages`` table that has a corresponding name. To add a page to the wiki, a new row is created and the text is stored in -`data`. +``data``. -A page named ``FrontPage`` containing the text *This is the front page*, will +A page named ``FrontPage`` containing the text "This is the front page" will be created when the storage is initialized, and will be used as the wiki home page. @@ -61,12 +61,12 @@ We'll eventually be adding security to our application. To do this, we'll be using a very simple role-based security model. We'll assign a single role category to each user in our system. -`basic` - An authenticated user who can view content and create new pages. A `basic` +``basic`` + An authenticated user who can view content and create new pages. A ``basic`` user may also edit the pages they have created but not pages created by other users. -`editor` +``editor`` An authenticated user who can create and edit any content in the system. In order to accomplish this we'll need to define an authentication policy @@ -101,16 +101,12 @@ in the following table: +----------------------+-----------------------+-------------+----------------+------------+ | URL | Action | View | Template | Permission | -| | | | | | +======================+=======================+=============+================+============+ | / | Redirect to | view_wiki | | | | | /FrontPage | | | | +----------------------+-----------------------+-------------+----------------+------------+ | /PageName | Display existing | view_page | view.jinja2 | view | | | page [2]_ | [1]_ | | | -| | | | | | -| | | | | | -| | | | | | +----------------------+-----------------------+-------------+----------------+------------+ | /PageName/edit_page | Display edit form | edit_page | edit.jinja2 | edit | | | with existing | | | | @@ -149,14 +145,13 @@ in the following table: | | login form with | | | | | | "login failed" | | | | | | message. | | | | -| | | | | | +----------------------+-----------------------+-------------+----------------+------------+ | /logout | Redirect to | logout | | | | | /FrontPage | | | | +----------------------+-----------------------+-------------+----------------+------------+ .. [1] This is the default view for a Page context when there is no view name. -.. [2] Pyramid will return a default 404 Not Found page if the page *PageName* +.. [2] Pyramid will return a default 404 Not Found page if the page ``PageName`` does not exist yet. .. [3] ``pyramid.exceptions.Forbidden`` is reached when a user tries to invoke a view that is not authorized by the authorization policy. diff --git a/docs/tutorials/wiki2/distributing.rst b/docs/tutorials/wiki2/distributing.rst index 7e2a08a58..dd6b1b750 100644 --- a/docs/tutorials/wiki2/distributing.rst +++ b/docs/tutorials/wiki2/distributing.rst @@ -31,7 +31,7 @@ The output of such a command will be something like: Creating tar archive removing 'tutorial-0.0' (and everything under it) -Note that this command creates a tarball in the "dist" subdirectory named +Note that this command creates a tarball in the ``dist`` subdirectory named ``tutorial-0.0.tar.gz``. You can send this file to your friends to show them your cool new application. They should be able to install it by pointing the ``pip install`` command directly at it. Or you can upload it to `PyPI diff --git a/docs/tutorials/wiki2/index.rst b/docs/tutorials/wiki2/index.rst index 18e9f552e..740a7f014 100644 --- a/docs/tutorials/wiki2/index.rst +++ b/docs/tutorials/wiki2/index.rst @@ -4,13 +4,11 @@ SQLAlchemy + URL dispatch wiki tutorial ======================================= This tutorial introduces an :term:`SQLAlchemy` and :term:`URL dispatch`-based -:app:`Pyramid` application to a developer familiar with Python. When the -tutorial is finished, the developer will have created a basic wiki +:app:`Pyramid` application to a developer familiar with Python. When finished, the developer will have created a basic wiki application with authentication and authorization. For cut and paste purposes, the source code for all stages of this tutorial can -be browsed on GitHub at `docs/tutorials/wiki2/src -`_, +be browsed on `GitHub `_, which corresponds to the same location if you have Pyramid sources. .. toctree:: @@ -26,4 +24,3 @@ which corresponds to the same location if you have Pyramid sources. authorization tests distributing - diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index fa990fb01..f13c2d2da 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -15,178 +15,140 @@ install Pyramid**. Thereby you will satisfy the following requirements. * You've satisfied the :ref:`requirements-for-installing-packages`. -Create directory to contain the project ---------------------------------------- +Install SQLite3 and its development packages +-------------------------------------------- -We need a workspace for our project files. +If you used a package manager to install your Python or if you compiled your Python from source, then you must install SQLite3 and its development packages. If you downloaded your Python as an installer from https://www.python.org, then you already have it installed and can skip this step. -On UNIX -^^^^^^^ +If you need to install the SQLite3 packages, then, for example, using the Debian system and ``apt-get``, the command would be the following: .. code-block:: bash - $ mkdir ~/pyramidtut + $ sudo apt-get install libsqlite3-dev -On Windows -^^^^^^^^^^ -.. code-block:: doscon +Install cookiecutter +-------------------- +We will use a :term:`cookiecutter` to create a Python package project from a Python package project template. See `Cookiecutter Installation `_ for instructions. - c:\> mkdir pyramidtut +.. note:: + At the time of writing, the installation instructions for Cookiecutter suggest the optional use of ``sudo``, implying to install it in the system Python. We suggest that you install it in a virtual environment instead. -Create and use a virtual Python environment -------------------------------------------- -Next let's create a virtual environment workspace for our project. We will use -the ``VENV`` environment variable instead of the absolute path of the virtual -environment. +Generate a Pyramid project from a cookiecutter +---------------------------------------------- + +We will create a Pyramid project in your home directory for UNIX or at the root for Windows. It is assumed you know the path to where you installed ``cookiecutter``. Issue the following commands and override the defaults in the prompts as follows. On UNIX ^^^^^^^ .. code-block:: bash - $ export VENV=~/pyramidtut - $ python3 -m venv $VENV + $ cd ~ + $ cookiecutter https://github.com/Pylons/pyramid-cookiecutter-alchemy On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\> set VENV=c:\pyramidtut - -Each version of Python uses different paths, so you will need to adjust the -path to the command for your Python version. - -Python 2.7: - -.. code-block:: doscon - - c:\> c:\Python27\Scripts\virtualenv %VENV% - -Python 3.6: + c:\> cd \ + c:\> cookiecutter https://github.com/Pylons/pyramid-cookiecutter-alchemy -.. code-block:: doscon +On all operating systems +^^^^^^^^^^^^^^^^^^^^^^^^ +If prompted for the first item, accept the default ``yes`` by hitting return. - c:\> c:\Python35\Scripts\python -m venv %VENV% +#. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-alchemy before. Is it + okay to delete and re-clone it? [yes]:`` +#. ``project_name [Pyramid Scaffold]: myproj`` +#. ``repo_name [scaffold]: tutorial`` -Upgrade ``pip`` and ``setuptools`` in the virtual environment -------------------------------------------------------------- +Change directory into your newly created project +------------------------------------------------ On UNIX ^^^^^^^ .. code-block:: bash - $ $VENV/bin/pip install --upgrade pip setuptools + $ cd tutorial On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\> %VENV%\Scripts\pip install --upgrade pip setuptools + c:\> cd tutorial + +Set and use a ``VENV`` environment variable +------------------------------------------- -Install Pyramid into the virtual Python environment ---------------------------------------------------- +We will set the ``VENV`` environment variable to the absolute path of the virtual environment, and use it going forward. On UNIX ^^^^^^^ -.. parsed-literal:: +.. code-block:: bash - $ $VENV/bin/pip install "pyramid==\ |release|\ " + $ export VENV=~/tutorial On Windows ^^^^^^^^^^ -.. parsed-literal:: - - c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " - - -Install SQLite3 and its development packages --------------------------------------------- - -If you used a package manager to install your Python or if you compiled -your Python from source, then you must install SQLite3 and its -development packages. If you downloaded your Python as an installer -from https://www.python.org, then you already have it installed and can skip -this step. - -If you need to install the SQLite3 packages, then, for example, using -the Debian system and ``apt-get``, the command would be the following: - -.. code-block:: bash - - $ sudo apt-get install libsqlite3-dev +.. code-block:: doscon + c:\tutorial> set VENV=c:\tutorial -Change directory to your virtual Python environment ---------------------------------------------------- -Change directory to the ``pyramidtut`` directory, which is both your workspace -and your virtual environment. +Create a virtual environment +---------------------------- On UNIX ^^^^^^^ .. code-block:: bash - $ cd pyramidtut + $ python3 -m venv $VENV On Windows ^^^^^^^^^^ -.. code-block:: doscon +Each version of Python uses different paths, so you will need to adjust the path to the command for your Python version. - c:\> cd pyramidtut +Python 2.7: +.. code-block:: doscon -.. _sql_making_a_project: + c:\tutorial> c:\Python27\Scripts\virtualenv %VENV% -Making a project ----------------- +Python 3.6: -Your next step is to create a project. For this tutorial we will use -the :term:`scaffold` named ``alchemy`` which generates an application -that uses :term:`SQLAlchemy` and :term:`URL dispatch`. +.. code-block:: doscon -:app:`Pyramid` supplies a variety of scaffolds to generate sample projects. We -will use ``pcreate``, a script that comes with Pyramid, to create our project -using a scaffold. + c:\tutorial> c:\Python36\Scripts\python -m venv %VENV% -By passing ``alchemy`` into the ``pcreate`` command, the script creates the -files needed to use SQLAlchemy. By passing in our application name -``tutorial``, the script inserts that application name into all the required -files. For example, ``pcreate`` creates the ``initialize_tutorial_db`` in the -``pyramidtut/bin`` directory. -The below instructions assume your current working directory is "pyramidtut". +Upgrade packaging tools in the virtual environment +-------------------------------------------------- On UNIX ^^^^^^^ .. code-block:: bash - $ $VENV/bin/pcreate -s alchemy tutorial + $ $VENV/bin/pip install --upgrade pip setuptools On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut> %VENV%\Scripts\pcreate -s alchemy tutorial - -.. note:: If you are using Windows, the ``alchemy`` scaffold may not deal - gracefully with installation into a location that contains spaces in the - path. If you experience startup problems, try putting both the virtual - environment and the project into directories that do not contain spaces in - their paths. + c:\tutorial> %VENV%\Scripts\pip install --upgrade pip setuptools .. _installing_project_in_dev_mode: @@ -194,74 +156,49 @@ On Windows Installing the project in development mode ------------------------------------------ -In order to do development on the project easily, you must "register" the -project as a development egg in your workspace using the ``pip install -e .`` -command. In order to do so, change directory to the ``tutorial`` directory that -you created in :ref:`sql_making_a_project`, and run the ``pip install -e .`` -command using the virtual environment Python interpreter. +In order to do development on the project easily, you must "register" the project as a development egg in your workspace. We will install testing requirements at the same time. We do so with the following command. On UNIX ^^^^^^^ .. code-block:: bash - $ cd tutorial - $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install -e ".[testing]" On Windows ^^^^^^^^^^ .. code-block:: doscon - c:\pyramidtut> cd tutorial - c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e . + c:\tutorial> %VENV%\Scripts\pip install -e ".[testing]" -The console will show ``pip`` checking for packages and installing missing -packages. Success executing this command will show a line like the following: +On all operating systems +^^^^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: bash - - Successfully installed Chameleon-2.24 Mako-1.0.4 MarkupSafe-0.23 \ - Pygments-2.1.3 SQLAlchemy-1.0.12 pyramid-chameleon-0.3 \ - pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 pyramid-tm-0.12.1 \ - transaction-1.4.4 tutorial waitress-0.8.10 zope.sqlalchemy-0.7.6 +The console will show ``pip`` checking for packages and installing missing packages. Success executing this command will show a line like the following: +.. code-block:: bash -.. _install-testing-requirements: + Successfully installed Jinja2-2.8 Mako-1.0.6 MarkupSafe-0.23 \ + PasteDeploy-1.5.2 Pygments-2.1.3 SQLAlchemy-1.1.4 WebOb-1.6.3 \ + WebTest-2.0.24 beautifulsoup4-4.5.1 coverage-4.2 py-1.4.32 pyramid-1.7.3 \ + pyramid-debugtoolbar-3.0.5 pyramid-jinja2-2.7 pyramid-mako-1.0.2 \ + pyramid-tm-1.1.1 tutorial pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 \ + six-1.10.0 transaction-2.0.3 translationstring-1.3 venusian-1.0 \ + waitress-1.0.1 zope.deprecation-4.2.0 zope.interface-4.3.3 \ + zope.sqlalchemy-0.7.7 -Install testing requirements ----------------------------- - -In order to run tests, we need to install the testing requirements. This is -done through our project's ``setup.py`` file, in the ``tests_require`` and -``extras_require`` stanzas, and by issuing the command below for your -operating system. +Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas. .. literalinclude:: src/installation/setup.py :language: python - :linenos: - :lineno-start: 22 + :lineno-match: :lines: 22-26 .. literalinclude:: src/installation/setup.py :language: python - :linenos: - :lineno-start: 45 - :lines: 45-47 - -On UNIX -^^^^^^^ - -.. code-block:: bash - - $ $VENV/bin/pip install -e ".[testing]" - -On Windows -^^^^^^^^^^ - -.. code-block:: doscon - - c:\pyramidtut\tutorial> %VENV%\Scripts\pip install -e ".[testing]" + :lineno-match: + :lines: 46-48 .. _sql_running_tests: @@ -286,7 +223,7 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q + c:\tutorial> %VENV%\Scripts\py.test -q For a successful test run, you should see output that ends like this: @@ -301,7 +238,7 @@ Expose test coverage information You can run the ``py.test`` command to see test coverage information. This runs the tests in the same way that ``py.test`` does, but provides additional -"coverage" information, exposing which lines of your project are covered by the +:term:`coverage` information, exposing which lines of your project are covered by the tests. We've already installed the ``pytest-cov`` package into our virtual @@ -319,46 +256,45 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov \ - --cov-report=term-missing + c:\tutorial> %VENV%\Scripts\py.test --cov --cov-report=term-missing If successful, you will see output something like this: .. code-block:: bash - ======================== test session starts ======================== - platform Python 3.6.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 - rootdir: /Users/stevepiercy/projects/pyramidtut/tutorial, inifile: - plugins: cov-2.2.1 - collected 2 items - - tutorial/tests.py .. - ------------------ coverage: platform Python 3.6.0 ------------------ - Name Stmts Miss Cover Missing - ---------------------------------------------------------------- - tutorial/__init__.py 8 6 25% 7-12 - tutorial/models/__init__.py 22 0 100% - tutorial/models/meta.py 5 0 100% - tutorial/models/mymodel.py 8 0 100% - tutorial/routes.py 3 2 33% 2-3 - tutorial/scripts/__init__.py 0 0 100% - tutorial/scripts/initializedb.py 26 16 38% 22-25, 29-45 - tutorial/views/__init__.py 0 0 100% - tutorial/views/default.py 12 0 100% - tutorial/views/notfound.py 4 2 50% 6-7 - ---------------------------------------------------------------- - TOTAL 88 26 70% - ===================== 2 passed in 0.57 seconds ====================== + ======================== test session starts ======================== + platform Python 3.6.0, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + rootdir: /Users/stevepiercy/tutorial, inifile: + plugins: cov-2.4.0 + collected 2 items + + tutorial/tests.py .. + ------------------ coverage: platform Python 3.6.0 ------------------ + Name Stmts Miss Cover Missing + ---------------------------------------------------------------- + tutorial/__init__.py 8 6 25% 7-12 + tutorial/models/__init__.py 22 0 100% + tutorial/models/meta.py 5 0 100% + tutorial/models/mymodel.py 8 0 100% + tutorial/routes.py 3 2 33% 2-3 + tutorial/scripts/__init__.py 0 0 100% + tutorial/scripts/initializedb.py 26 16 38% 22-25, 29-45 + tutorial/views/__init__.py 0 0 100% + tutorial/views/default.py 12 0 100% + tutorial/views/notfound.py 4 2 50% 6-7 + ---------------------------------------------------------------- + TOTAL 88 26 70% + ===================== 2 passed in 0.57 seconds ====================== Our package doesn't quite have 100% test coverage. -.. _test_and_coverage_scaffold_defaults_sql: +.. _test_and_coverage_cookiecutter_defaults_sql: -Test and coverage scaffold defaults ------------------------------------ +Test and coverage cookiecutter defaults +--------------------------------------- -Scaffolds include configuration defaults for ``py.test`` and test coverage. +Cookiecutters include configuration defaults for ``py.test`` and test coverage. These configuration files are ``pytest.ini`` and ``.coveragerc``, located at the root of your package. Without these defaults, we would need to specify the path to the module on which we want to run tests and coverage. @@ -375,11 +311,10 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test --cov=tutorial \ - --cov-report=term-missing tutorial\tests.py -q + c:\tutorial> %VENV%\Scripts\py.test --cov=tutorial tutorial\tests.py -q py.test follows :ref:`conventions for Python test discovery -`, and the configuration defaults from the scaffold +`, and the configuration defaults from the cookiecutter tell ``py.test`` where to find the module on which we want to run tests and coverage. @@ -417,36 +352,36 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\initialize_tutorial_db development.ini + c:\tutorial> %VENV%\Scripts\initialize_tutorial_db development.ini The output to your console should be something like this: .. code-block:: bash - 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-05-22 04:03:28,888 INFO [sqlalchemy.engine.base.Engine:1192][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2016-05-22 04:03:28,889 INFO [sqlalchemy.engine.base.Engine:1193][MainThread] () - 2016-05-22 04:03:28,890 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] PRAGMA table_info("models") - 2016-05-22 04:03:28,890 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:03:28,892 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] - CREATE TABLE models ( - id INTEGER NOT NULL, - name TEXT, - value INTEGER, - CONSTRAINT pk_models PRIMARY KEY (id) - ) - - - 2016-05-22 04:03:28,892 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] CREATE UNIQUE INDEX my_index ON models (name) - 2016-05-22 04:03:28,893 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] () - 2016-05-22 04:03:28,894 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT - 2016-05-22 04:03:28,896 INFO [sqlalchemy.engine.base.Engine:646][MainThread] BEGIN (implicit) - 2016-05-22 04:03:28,897 INFO [sqlalchemy.engine.base.Engine:1097][MainThread] INSERT INTO models (name, value) VALUES (?, ?) - 2016-05-22 04:03:28,897 INFO [sqlalchemy.engine.base.Engine:1100][MainThread] ('one', 1) - 2016-05-22 04:03:28,898 INFO [sqlalchemy.engine.base.Engine:686][MainThread] COMMIT + 2016-12-18 21:30:08,675 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 + 2016-12-18 21:30:08,675 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] () + 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1235][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 + 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1236][MainThread] () + 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] PRAGMA table_info("models") + 2016-12-18 21:30:08,676 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-18 21:30:08,677 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] + CREATE TABLE models ( + id INTEGER NOT NULL, + name TEXT, + value INTEGER, + CONSTRAINT pk_models PRIMARY KEY (id) + ) + + + 2016-12-18 21:30:08,677 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-18 21:30:08,678 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT + 2016-12-18 21:30:08,679 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] CREATE UNIQUE INDEX my_index ON models (name) + 2016-12-18 21:30:08,679 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] () + 2016-12-18 21:30:08,679 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT + 2016-12-18 21:30:08,681 INFO [sqlalchemy.engine.base.Engine:679][MainThread] BEGIN (implicit) + 2016-12-18 21:30:08,682 INFO [sqlalchemy.engine.base.Engine:1140][MainThread] INSERT INTO models (name, value) VALUES (?, ?) + 2016-12-18 21:30:08,682 INFO [sqlalchemy.engine.base.Engine:1143][MainThread] ('one', 1) + 2016-12-18 21:30:08,682 INFO [sqlalchemy.engine.base.Engine:719][MainThread] COMMIT Success! You should now have a ``tutorial.sqlite`` file in your current working directory. This is an SQLite database with a single table defined in it @@ -472,7 +407,7 @@ On Windows .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\pserve development.ini --reload + c:\tutorial> %VENV%\Scripts\pserve development.ini --reload .. note:: @@ -483,9 +418,10 @@ If successful, you will see something like this on your console: .. code-block:: text - Starting subprocess with file monitor - Starting server in PID 82349. - serving on http://127.0.0.1:6543 + Starting subprocess with file monitor + Starting server in PID 44078. + Serving on http://localhost:6543 + Serving on http://localhost:6543 This means the server is ready to accept requests. @@ -502,13 +438,15 @@ page. You can read more about the purpose of the icon at application while you develop. -Decisions the ``alchemy`` scaffold has made for you ---------------------------------------------------- +Decisions the ``alchemy`` cookiecutter has made for you +------------------------------------------------------- -Creating a project using the ``alchemy`` scaffold makes the following +Creating a project using the ``alchemy`` cookiecutter makes the following assumptions: -- You are willing to use :term:`SQLAlchemy` as a database access tool. +- You are willing to use SQLite for persistent storage, although almost any SQL database could be used with SQLAlchemy. + +- You are willing to use :term:`SQLAlchemy` for a database access tool. - You are willing to use :term:`URL dispatch` to map URLs to code. diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index e923ff9cb..67c7e65e0 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -8,7 +8,7 @@ We will now add tests for the models and views as well as a few functional tests in a new ``tests`` subpackage. Tests ensure that an application works, and that it continues to work when changes are made in the future. -The file ``tests.py`` was generated as part of the ``alchemy`` scaffold, but it +The file ``tests.py`` was generated as part of the ``alchemy`` cookiecutter, but it is a common practice to put tests into a ``tests`` subpackage, especially as projects grow in size and complexity. Each module in the test subpackage should contain tests for its corresponding module in our application. Each @@ -89,7 +89,7 @@ On Windows: .. code-block:: doscon - c:\pyramidtut\tutorial> %VENV%\Scripts\py.test -q + c:\tutorial> %VENV%\Scripts\py.test -q The expected result should look like the following: -- cgit v1.2.3 From 2d5234732371d7fed3350b7f50eb2be41eb5920e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 14:25:38 -0800 Subject: sort packages alpha --- docs/tutorials/wiki/installation.rst | 10 +++++----- docs/tutorials/wiki2/installation.rst | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 1368b5b2a..b99196474 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -172,11 +172,11 @@ The console will show ``pip`` checking for packages and installing missing packa WebTest-2.0.23 ZConfig-3.1.0 ZEO-5.0.4 ZODB-5.1.1 ZODB3-3.11.0 \ beautifulsoup4-4.5.1 coverage-4.2 mock-2.0.0 pbr-1.10.0 persistent-4.2.2 \ py-1.4.31 pyramid-1.7.3 pyramid-chameleon-0.3 pyramid-debugtoolbar-3.0.5 \ - pyramid-mako-1.0.2 pyramid-tm-1.1.1 pyramid-zodbconn-0.7 tutorial \ - pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 transaction-2.0.3 \ - translationstring-1.3 venusian-1.0 waitress-1.0.1 zc.lockfile-1.2.1 \ - zdaemon-4.2.0 zodbpickle-0.6.0 zodburi-2.0 zope.deprecation-4.2.0 \ - zope.interface-4.3.3 + pyramid-mako-1.0.2 pyramid-tm-1.1.1 pyramid-zodbconn-0.7 pytest-3.0.5 \ + pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 transaction-2.0.3 \ + translationstring-1.3 tutorial venusian-1.0 waitress-1.0.1 \ + zc.lockfile-1.2.1 zdaemon-4.2.0 zodbpickle-0.6.0 zodburi-2.0 \ + zope.deprecation-4.2.0 zope.interface-4.3.3 Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas. diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index f13c2d2da..2142a0c0c 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -183,8 +183,8 @@ The console will show ``pip`` checking for packages and installing missing packa PasteDeploy-1.5.2 Pygments-2.1.3 SQLAlchemy-1.1.4 WebOb-1.6.3 \ WebTest-2.0.24 beautifulsoup4-4.5.1 coverage-4.2 py-1.4.32 pyramid-1.7.3 \ pyramid-debugtoolbar-3.0.5 pyramid-jinja2-2.7 pyramid-mako-1.0.2 \ - pyramid-tm-1.1.1 tutorial pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 \ - six-1.10.0 transaction-2.0.3 translationstring-1.3 venusian-1.0 \ + pyramid-tm-1.1.1 pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 \ + transaction-2.0.3 translationstring-1.3 tutorial venusian-1.0 \ waitress-1.0.1 zope.deprecation-4.2.0 zope.interface-4.3.3 \ zope.sqlalchemy-0.7.7 -- cgit v1.2.3 From 29394211eaeff1dff3cc6578761883f9fd0a1e8a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 14:31:26 -0800 Subject: wiki2/src/installation - update files --- docs/tutorials/wiki2/src/installation/.coveragerc | 3 + docs/tutorials/wiki2/src/installation/CHANGES.txt | 2 +- docs/tutorials/wiki2/src/installation/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/installation/README.txt | 31 +++++++++-- .../wiki2/src/installation/development.ini | 5 +- .../wiki2/src/installation/production.ini | 8 ++- docs/tutorials/wiki2/src/installation/pytest.ini | 3 + docs/tutorials/wiki2/src/installation/setup.py | 65 +++++++++++----------- .../src/installation/tutorial/models/__init__.py | 2 +- .../installation/tutorial/templates/layout.jinja2 | 8 +-- .../tutorial/templates/mytemplate.jinja2 | 4 +- .../wiki2/src/installation/tutorial/tests.py | 2 +- .../src/installation/tutorial/views/default.py | 2 +- 13 files changed, 83 insertions(+), 54 deletions(-) create mode 100644 docs/tutorials/wiki2/src/installation/.coveragerc create mode 100644 docs/tutorials/wiki2/src/installation/pytest.ini diff --git a/docs/tutorials/wiki2/src/installation/.coveragerc b/docs/tutorials/wiki2/src/installation/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/installation/CHANGES.txt b/docs/tutorials/wiki2/src/installation/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/installation/CHANGES.txt +++ b/docs/tutorials/wiki2/src/installation/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/installation/MANIFEST.in b/docs/tutorials/wiki2/src/installation/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/installation/MANIFEST.in +++ b/docs/tutorials/wiki2/src/installation/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/installation/README.txt b/docs/tutorials/wiki2/src/installation/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/installation/README.txt +++ b/docs/tutorials/wiki2/src/installation/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index 252398692..e9f6d8d3f 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -31,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index 5f1fae07c..c01ad9a7e 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -14,13 +14,17 @@ pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/installation/pytest.ini b/docs/tutorials/wiki2/src/installation/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/installation/setup.py b/docs/tutorials/wiki2/src/installation/setup.py index ede0a82ef..d3992a8f2 100644 --- a/docs/tutorials/wiki2/src/installation/setup.py +++ b/docs/tutorials/wiki2/src/installation/setup.py @@ -17,39 +17,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) diff --git a/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py index 3fc82cfba..5ca037787 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py @@ -5,7 +5,7 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .mymodel import MyModel # noqa +from .mymodel import MyModel # flake8: noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 index ab8c5ea3d..1f658c834 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ - Alchemy Scaffold for The Pyramid Web Framework + Cookiecutter Alchemy project for the Pyramid Web Framework @@ -29,7 +29,7 @@
    - +
    {% block content %} @@ -40,10 +40,8 @@
    diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 index 6b49869c4..359f55ffa 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %}
    -

    Pyramid Alchemy scaffold

    -

    Welcome to {{project}}, an application generated by
    the Pyramid Web Framework 1.7.

    +

    Pyramid Alchemy project

    +

    Welcome to myproj, a Pyramid application generated by
    Cookiecutter.

    {% endblock content %} diff --git a/docs/tutorials/wiki2/src/installation/tutorial/tests.py b/docs/tutorials/wiki2/src/installation/tutorial/tests.py index 99e95efd3..ce650ca7c 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/tests.py @@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest): from .views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') class TestMyViewFailureCondition(BaseTest): diff --git a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py index ad0c728d7..a404d4154 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py @@ -13,7 +13,7 @@ def my_view(request): one = query.filter(MyModel.name == 'one').first() except DBAPIError: return Response(db_err_msg, content_type='text/plain', status=500) - return {'one': one, 'project': 'tutorial'} + return {'one': one, 'project': 'myproj'} db_err_msg = """\ -- cgit v1.2.3 From 7e93ce88b677b7d61fdb121737e685a1d4adee7c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 14:35:13 -0800 Subject: wiki2/src/basiclayout - update files --- docs/tutorials/wiki2/src/basiclayout/.coveragerc | 3 + docs/tutorials/wiki2/src/basiclayout/CHANGES.txt | 2 +- docs/tutorials/wiki2/src/basiclayout/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/basiclayout/README.txt | 31 +++++++++-- .../wiki2/src/basiclayout/development.ini | 5 +- .../tutorials/wiki2/src/basiclayout/production.ini | 8 ++- docs/tutorials/wiki2/src/basiclayout/pytest.ini | 3 + docs/tutorials/wiki2/src/basiclayout/setup.py | 65 +++++++++++----------- .../src/basiclayout/tutorial/models/__init__.py | 2 +- .../basiclayout/tutorial/templates/layout.jinja2 | 8 +-- .../tutorial/templates/mytemplate.jinja2 | 4 +- .../wiki2/src/basiclayout/tutorial/tests.py | 2 +- .../src/basiclayout/tutorial/views/default.py | 2 +- 13 files changed, 83 insertions(+), 54 deletions(-) create mode 100644 docs/tutorials/wiki2/src/basiclayout/.coveragerc create mode 100644 docs/tutorials/wiki2/src/basiclayout/pytest.ini diff --git a/docs/tutorials/wiki2/src/basiclayout/.coveragerc b/docs/tutorials/wiki2/src/basiclayout/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt b/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt +++ b/docs/tutorials/wiki2/src/basiclayout/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in +++ b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/basiclayout/README.txt b/docs/tutorials/wiki2/src/basiclayout/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/basiclayout/README.txt +++ b/docs/tutorials/wiki2/src/basiclayout/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 252398692..e9f6d8d3f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -31,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index 5f1fae07c..c01ad9a7e 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -14,13 +14,17 @@ pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/basiclayout/pytest.ini b/docs/tutorials/wiki2/src/basiclayout/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index ede0a82ef..d3992a8f2 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -17,39 +17,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py index 3fc82cfba..5ca037787 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py @@ -5,7 +5,7 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .mymodel import MyModel # noqa +from .mymodel import MyModel # flake8: noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 index ab8c5ea3d..1f658c834 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ - Alchemy Scaffold for The Pyramid Web Framework + Cookiecutter Alchemy project for the Pyramid Web Framework @@ -29,7 +29,7 @@
    - +
    {% block content %} @@ -40,10 +40,8 @@
    diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 index 6b49869c4..359f55ffa 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %}
    -

    Pyramid Alchemy scaffold

    -

    Welcome to {{project}}, an application generated by
    the Pyramid Web Framework 1.7.

    +

    Pyramid Alchemy project

    +

    Welcome to myproj, a Pyramid application generated by
    Cookiecutter.

    {% endblock content %} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py index 99e95efd3..ce650ca7c 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py @@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest): from .views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') class TestMyViewFailureCondition(BaseTest): diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py index ad0c728d7..a404d4154 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py @@ -13,7 +13,7 @@ def my_view(request): one = query.filter(MyModel.name == 'one').first() except DBAPIError: return Response(db_err_msg, content_type='text/plain', status=500) - return {'one': one, 'project': 'tutorial'} + return {'one': one, 'project': 'myproj'} db_err_msg = """\ -- cgit v1.2.3 From 34a21b8b14adc93d26c35ae3e0c467874a36d01b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 14:55:03 -0800 Subject: wiki2/src/models - update files --- docs/tutorials/wiki2/src/models/.coveragerc | 3 + docs/tutorials/wiki2/src/models/CHANGES.txt | 2 +- docs/tutorials/wiki2/src/models/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/models/README.txt | 31 +++++++++-- docs/tutorials/wiki2/src/models/development.ini | 5 +- docs/tutorials/wiki2/src/models/production.ini | 8 ++- docs/tutorials/wiki2/src/models/pytest.ini | 3 + docs/tutorials/wiki2/src/models/setup.py | 65 +++++++++++----------- .../src/models/tutorial/templates/layout.jinja2 | 8 +-- .../models/tutorial/templates/mytemplate.jinja2 | 4 +- docs/tutorials/wiki2/src/models/tutorial/tests.py | 2 +- .../wiki2/src/models/tutorial/views/default.py | 2 +- 12 files changed, 82 insertions(+), 53 deletions(-) create mode 100644 docs/tutorials/wiki2/src/models/.coveragerc create mode 100644 docs/tutorials/wiki2/src/models/pytest.ini diff --git a/docs/tutorials/wiki2/src/models/.coveragerc b/docs/tutorials/wiki2/src/models/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/models/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/models/CHANGES.txt b/docs/tutorials/wiki2/src/models/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/models/CHANGES.txt +++ b/docs/tutorials/wiki2/src/models/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/models/MANIFEST.in b/docs/tutorials/wiki2/src/models/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/models/MANIFEST.in +++ b/docs/tutorials/wiki2/src/models/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/models/README.txt b/docs/tutorials/wiki2/src/models/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/models/README.txt +++ b/docs/tutorials/wiki2/src/models/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index 252398692..e9f6d8d3f 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -31,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index 5f1fae07c..c01ad9a7e 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -14,13 +14,17 @@ pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/models/pytest.ini b/docs/tutorials/wiki2/src/models/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py index 742a7c59c..faf76aa27 100644 --- a/docs/tutorials/wiki2/src/models/setup.py +++ b/docs/tutorials/wiki2/src/models/setup.py @@ -18,39 +18,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 index ab8c5ea3d..1f658c834 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ - Alchemy Scaffold for The Pyramid Web Framework + Cookiecutter Alchemy project for the Pyramid Web Framework @@ -29,7 +29,7 @@
    - +
    {% block content %} @@ -40,10 +40,8 @@
    diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 index 6b49869c4..359f55ffa 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %}
    -

    Pyramid Alchemy scaffold

    -

    Welcome to {{project}}, an application generated by
    the Pyramid Web Framework 1.7.

    +

    Pyramid Alchemy project

    +

    Welcome to myproj, a Pyramid application generated by
    Cookiecutter.

    {% endblock content %} diff --git a/docs/tutorials/wiki2/src/models/tutorial/tests.py b/docs/tutorials/wiki2/src/models/tutorial/tests.py index 99e95efd3..ce650ca7c 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/models/tutorial/tests.py @@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest): from .views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') class TestMyViewFailureCondition(BaseTest): diff --git a/docs/tutorials/wiki2/src/models/tutorial/views/default.py b/docs/tutorials/wiki2/src/models/tutorial/views/default.py index ad0c728d7..a404d4154 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/models/tutorial/views/default.py @@ -13,7 +13,7 @@ def my_view(request): one = query.filter(MyModel.name == 'one').first() except DBAPIError: return Response(db_err_msg, content_type='text/plain', status=500) - return {'one': one, 'project': 'tutorial'} + return {'one': one, 'project': 'myproj'} db_err_msg = """\ -- cgit v1.2.3 From 446fae40100bdc483a4311f6e316d75cc2ff37df Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 14:56:42 -0800 Subject: fix reST syntax --- docs/tutorials/wiki2/definingmodels.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 7d4a7baea..5cebb943c 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -40,7 +40,7 @@ Only the highlighted line needs to be added. .. note:: - We are using the ``bcrypt`` package from PyPI to hash our passwords securely. There are other one-way hash algorithms for passwords if bcrypt is an issue on your system. Just make sure that it's an algorithm approved for storing passwords versus a generic one-way hash. + We are using the ``bcrypt`` package from PyPI to hash our passwords securely. There are other one-way hash algorithms for passwords if ``bcrypt`` is an issue on your system. Just make sure that it's an algorithm approved for storing passwords versus a generic one-way hash. Running ``pip install -e .`` -- cgit v1.2.3 From bb5ba0ea7dfeff26ed0c7c37e80e512c7d3f3b3d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 17:50:23 -0800 Subject: wiki2/src/views update files, line number range --- docs/tutorials/wiki2/definingviews.rst | 2 +- docs/tutorials/wiki2/src/views/.coveragerc | 3 + docs/tutorials/wiki2/src/views/CHANGES.txt | 2 +- docs/tutorials/wiki2/src/views/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/views/README.txt | 31 +++++++++-- docs/tutorials/wiki2/src/views/development.ini | 5 +- docs/tutorials/wiki2/src/views/production.ini | 8 ++- docs/tutorials/wiki2/src/views/pytest.ini | 3 + docs/tutorials/wiki2/src/views/setup.py | 65 +++++++++++----------- .../src/views/tutorial/templates/layout.jinja2 | 2 +- docs/tutorials/wiki2/src/views/tutorial/tests.py | 2 +- 11 files changed, 78 insertions(+), 47 deletions(-) create mode 100644 docs/tutorials/wiki2/src/views/.coveragerc create mode 100644 docs/tutorials/wiki2/src/views/pytest.ini diff --git a/docs/tutorials/wiki2/definingviews.rst b/docs/tutorials/wiki2/definingviews.rst index 5d947a06f..3c343e155 100644 --- a/docs/tutorials/wiki2/definingviews.rst +++ b/docs/tutorials/wiki2/definingviews.rst @@ -375,7 +375,7 @@ This template is used by ``view_page()`` for displaying a single wiki page. view (line 6). ``content`` contains HTML, so the ``|safe`` filter is used to prevent escaping it (e.g., changing ">" to ">"). - We create a link that points at the "edit" URL, which when clicked invokes - the ``edit_page`` view for the requested page (line 9). + the ``edit_page`` view for the requested page (lines 8-10). The ``edit.jinja2`` template diff --git a/docs/tutorials/wiki2/src/views/.coveragerc b/docs/tutorials/wiki2/src/views/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/views/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/views/CHANGES.txt b/docs/tutorials/wiki2/src/views/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/views/CHANGES.txt +++ b/docs/tutorials/wiki2/src/views/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/views/MANIFEST.in b/docs/tutorials/wiki2/src/views/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/views/MANIFEST.in +++ b/docs/tutorials/wiki2/src/views/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/views/README.txt b/docs/tutorials/wiki2/src/views/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/views/README.txt +++ b/docs/tutorials/wiki2/src/views/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index 252398692..e9f6d8d3f 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -31,7 +30,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index 5f1fae07c..c01ad9a7e 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -14,13 +14,17 @@ pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/views/pytest.ini b/docs/tutorials/wiki2/src/views/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/views/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py index def3ce1f6..cc1aa421c 100644 --- a/docs/tutorials/wiki2/src/views/setup.py +++ b/docs/tutorials/wiki2/src/views/setup.py @@ -19,39 +19,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2 index 71785157f..7575de8a7 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/layout.jinja2 @@ -29,7 +29,7 @@
    - +
    diff --git a/docs/tutorials/wiki2/src/views/tutorial/tests.py b/docs/tutorials/wiki2/src/views/tutorial/tests.py index 99e95efd3..ce650ca7c 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/views/tutorial/tests.py @@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest): from .views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') class TestMyViewFailureCondition(BaseTest): -- cgit v1.2.3 From 4eb7f0b3ceee763d673535ae3365843096ebbc8a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 17:59:54 -0800 Subject: wiki2/src/authentication update files --- .../tutorials/wiki2/src/authentication/.coveragerc | 3 + .../tutorials/wiki2/src/authentication/CHANGES.txt | 2 +- .../tutorials/wiki2/src/authentication/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/authentication/README.txt | 31 +++++++++-- .../wiki2/src/authentication/development.ini | 5 +- .../wiki2/src/authentication/production.ini | 8 ++- docs/tutorials/wiki2/src/authentication/pytest.ini | 3 + docs/tutorials/wiki2/src/authentication/setup.py | 65 +++++++++++----------- 8 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authentication/.coveragerc create mode 100644 docs/tutorials/wiki2/src/authentication/pytest.ini diff --git a/docs/tutorials/wiki2/src/authentication/.coveragerc b/docs/tutorials/wiki2/src/authentication/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/authentication/CHANGES.txt b/docs/tutorials/wiki2/src/authentication/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/authentication/CHANGES.txt +++ b/docs/tutorials/wiki2/src/authentication/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/authentication/MANIFEST.in b/docs/tutorials/wiki2/src/authentication/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/authentication/MANIFEST.in +++ b/docs/tutorials/wiki2/src/authentication/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/authentication/README.txt b/docs/tutorials/wiki2/src/authentication/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/authentication/README.txt +++ b/docs/tutorials/wiki2/src/authentication/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index a767a0e6f..1e08d1bce 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -33,7 +32,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index f27dc09d4..05d60feec 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -16,13 +16,17 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite auth.secret = real-seekrit +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/authentication/pytest.ini b/docs/tutorials/wiki2/src/authentication/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/authentication/setup.py b/docs/tutorials/wiki2/src/authentication/setup.py index def3ce1f6..cc1aa421c 100644 --- a/docs/tutorials/wiki2/src/authentication/setup.py +++ b/docs/tutorials/wiki2/src/authentication/setup.py @@ -19,39 +19,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) -- cgit v1.2.3 From 266dea26ac6cabb66ee94e8dddc15c1c97e3bf2a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 18:03:12 -0800 Subject: wiki2/src/authentication update files --- docs/tutorials/wiki2/src/authentication/tutorial/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/tests.py b/docs/tutorials/wiki2/src/authentication/tutorial/tests.py index 99e95efd3..ce650ca7c 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/tests.py @@ -54,7 +54,7 @@ class TestMyViewSuccessCondition(BaseTest): from .views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'tutorial') + self.assertEqual(info['project'], 'myproj') class TestMyViewFailureCondition(BaseTest): -- cgit v1.2.3 From 7293d371a8bf257ad98a781f199a4cee34a94cab Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 18:06:28 -0800 Subject: wiki2/src/authorization update files --- docs/tutorials/wiki2/src/authorization/.coveragerc | 3 + docs/tutorials/wiki2/src/authorization/CHANGES.txt | 2 +- docs/tutorials/wiki2/src/authorization/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/authorization/README.txt | 31 +++++++++-- .../wiki2/src/authorization/development.ini | 5 +- .../wiki2/src/authorization/production.ini | 8 ++- docs/tutorials/wiki2/src/authorization/pytest.ini | 3 + docs/tutorials/wiki2/src/authorization/setup.py | 65 +++++++++++----------- 8 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authorization/.coveragerc create mode 100644 docs/tutorials/wiki2/src/authorization/pytest.ini diff --git a/docs/tutorials/wiki2/src/authorization/.coveragerc b/docs/tutorials/wiki2/src/authorization/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/authorization/CHANGES.txt b/docs/tutorials/wiki2/src/authorization/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/authorization/CHANGES.txt +++ b/docs/tutorials/wiki2/src/authorization/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/authorization/MANIFEST.in b/docs/tutorials/wiki2/src/authorization/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/authorization/MANIFEST.in +++ b/docs/tutorials/wiki2/src/authorization/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/authorization/README.txt +++ b/docs/tutorials/wiki2/src/authorization/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index a767a0e6f..1e08d1bce 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -33,7 +32,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index f27dc09d4..05d60feec 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -16,13 +16,17 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite auth.secret = real-seekrit +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/authorization/pytest.ini b/docs/tutorials/wiki2/src/authorization/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index def3ce1f6..cc1aa421c 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -19,39 +19,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) -- cgit v1.2.3 From f4bfa2df091b09ff73d5f97a8f0a13a6b0ef17e0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 23 Dec 2016 18:19:30 -0800 Subject: wiki2/src/tests update files --- docs/tutorials/wiki2/src/tests/.coveragerc | 3 ++ docs/tutorials/wiki2/src/tests/CHANGES.txt | 2 +- docs/tutorials/wiki2/src/tests/MANIFEST.in | 2 +- docs/tutorials/wiki2/src/tests/README.txt | 31 +++++++++--- docs/tutorials/wiki2/src/tests/development.ini | 5 +- docs/tutorials/wiki2/src/tests/production.ini | 8 +++- docs/tutorials/wiki2/src/tests/pytest.ini | 3 ++ docs/tutorials/wiki2/src/tests/setup.py | 65 ++++++++++++++------------ 8 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 docs/tutorials/wiki2/src/tests/.coveragerc create mode 100644 docs/tutorials/wiki2/src/tests/pytest.ini diff --git a/docs/tutorials/wiki2/src/tests/.coveragerc b/docs/tutorials/wiki2/src/tests/.coveragerc new file mode 100644 index 000000000..a1d87d03d --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = tutorial +omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/tests/CHANGES.txt b/docs/tutorials/wiki2/src/tests/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/tutorials/wiki2/src/tests/CHANGES.txt +++ b/docs/tutorials/wiki2/src/tests/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/tutorials/wiki2/src/tests/MANIFEST.in b/docs/tutorials/wiki2/src/tests/MANIFEST.in index 42cd299b5..05cc195d9 100644 --- a/docs/tutorials/wiki2/src/tests/MANIFEST.in +++ b/docs/tutorials/wiki2/src/tests/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/tutorials/wiki2/src/tests/README.txt b/docs/tutorials/wiki2/src/tests/README.txt index 5b0101e5f..8466fd7b5 100644 --- a/docs/tutorials/wiki2/src/tests/README.txt +++ b/docs/tutorials/wiki2/src/tests/README.txt @@ -1,14 +1,33 @@ -tutorial README -================== +myproj +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd myproj -- $VENV/bin/initialize_tutorial_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools wheel + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_tutorial_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index a767a0e6f..1e08d1bce 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite @@ -33,7 +32,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index f27dc09d4..05d60feec 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -16,13 +16,17 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite auth.secret = real-seekrit +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/tests/pytest.ini b/docs/tutorials/wiki2/src/tests/pytest.ini new file mode 100644 index 000000000..8b76bc410 --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = tutorial +python_files = *.py diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py index def3ce1f6..cc1aa421c 100644 --- a/docs/tutorials/wiki2/src/tests/setup.py +++ b/docs/tutorials/wiki2/src/tests/setup.py @@ -19,39 +19,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] tests_require = [ 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv + 'pytest', 'pytest-cov', - ] +] -setup(name='tutorial', - version='0.0', - description='tutorial', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = tutorial:main - [console_scripts] - initialize_tutorial_db = tutorial.scripts.initializedb:main - """, - ) +setup( + name='tutorial', + version='0.0', + description='myproj', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = tutorial:main', + ], + 'console_scripts': [ + 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + ], + }, +) -- cgit v1.2.3 From d2f0fe8e44fd81d99142b8174c665354a072b774 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 23 Dec 2016 22:37:50 -0600 Subject: add changelog for #2780 --- CHANGES.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index ac329f574..c6074f552 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -205,6 +205,24 @@ Bug Fixes Deprecations ------------ +- The ``pcreate`` script and related scaffolds have been deprecated in favor + of the popular + `cookiecutter `_ project. + + All of Pyramid's official scaffolds as well as the tutorials have been + ported to cookiecutters: + + - `pyramid-cookiecutter-starter + `_ + + - `pyramid-cookiecutter-alchemy + `_ + + - `pyramid-cookiecutter-zodb + `_ + + See https://github.com/Pylons/pyramid/pull/2780 + Documentation Changes --------------------- -- cgit v1.2.3 From e40c8ad52509b1559bca0312b1b19c29b23e210f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 23 Dec 2016 22:55:37 -0600 Subject: add changelogs for #2881 and #2883. --- CHANGES.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index c6074f552..d14078300 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -163,6 +163,14 @@ Features See https://github.com/Pylons/pyramid/pull/2873 +- The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and + ZODB + Traversal + Chameleon (``wiki``) tutorials have been updated to + utilize the new cookiecutters and drop support for the ``pcreate`` + scaffolds. + + See https://github.com/Pylons/pyramid/pull/2881 and + https://github.com/Pylons/pyramid/pull/2883. + Bug Fixes --------- -- cgit v1.2.3 From 6e037c6d7806ea895dc03bf56c9567474b33f4de Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 23 Dec 2016 22:57:11 -0600 Subject: update whatsnew --- CHANGES.txt | 16 ++++++++-------- docs/whatsnew-1.8.rst | 25 +++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d14078300..994aaec18 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -163,14 +163,6 @@ Features See https://github.com/Pylons/pyramid/pull/2873 -- The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and - ZODB + Traversal + Chameleon (``wiki``) tutorials have been updated to - utilize the new cookiecutters and drop support for the ``pcreate`` - scaffolds. - - See https://github.com/Pylons/pyramid/pull/2881 and - https://github.com/Pylons/pyramid/pull/2883. - Bug Fixes --------- @@ -255,3 +247,11 @@ Documentation Changes :class:`pyramid.httpexceptions.HTTPException` in which more appropriate kwargs from the parent class :class:`pyramid.response.Response` should be used instead. See https://github.com/Pylons/pyramid/pull/2750 + +- The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and + ZODB + Traversal + Chameleon (``wiki``) tutorials have been updated to + utilize the new cookiecutters and drop support for the ``pcreate`` + scaffolds. + + See https://github.com/Pylons/pyramid/pull/2881 and + https://github.com/Pylons/pyramid/pull/2883. diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 20261e704..88e2b4736 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -150,10 +150,23 @@ Feature Additions Deprecations ------------ +- The ``pcreate`` script and related scaffolds have been deprecated in favor + of the popular + `cookiecutter `_ project. -Scaffolding Enhancements ------------------------- + All of Pyramid's official scaffolds as well as the tutorials have been + ported to cookiecutters: + - `pyramid-cookiecutter-starter + `_ + + - `pyramid-cookiecutter-alchemy + `_ + + - `pyramid-cookiecutter-zodb + `_ + + See https://github.com/Pylons/pyramid/pull/2780 Documentation Enhancements -------------------------- @@ -179,3 +192,11 @@ Documentation Enhancements :class:`pyramid.httpexceptions.HTTPException` in which more appropriate kwargs from the parent class :class:`pyramid.response.Response` should be used instead. See https://github.com/Pylons/pyramid/pull/2750 + +- The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and + ZODB + Traversal + Chameleon (``wiki``) tutorials have been updated to + utilize the new cookiecutters and drop support for the ``pcreate`` + scaffolds. + + See https://github.com/Pylons/pyramid/pull/2881 and + https://github.com/Pylons/pyramid/pull/2883. -- cgit v1.2.3 From a0ebd777ad773c86f5bd5becfd77c2a0d61906d1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 02:38:07 -0800 Subject: quick_tour - first cut --- docs/quick_tour.rst | 46 +++++++++++++++++++++++---------------- docs/quick_tutorial/scaffolds.rst | 2 +- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 5dc7d8816..f9dbd2438 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -491,40 +491,48 @@ more to offer: :ref:`class_as_view`. -Quick project startup with scaffolds -==================================== +Quick project startup with cookiecutters +======================================== So far we have done all of our *Quick Tour* as a single Python file. No Python packages, no structure. Most Pyramid projects, though, aren't developed this way. -To ease the process of getting started, Pyramid provides *scaffolds* that -generate sample projects from templates in Pyramid and Pyramid add-ons. -Pyramid's ``pcreate`` command can list the available scaffolds: +To ease the process of getting started, the Pylons Project provides :term:`cookiecutter`\ s that generate sample Pyramid projects from project templates. In addition these cookiecutters will install Pyramid and its dependencies. + +First you'll need to install cookiecutter. .. code-block:: bash - $ $VENV/bin/pcreate --list - Available scaffolds: - alchemy: Pyramid project using SQLAlchemy, SQLite, URL dispatch, and Jinja2 - pyramid_jinja2_starter: Pyramid Jinja2 starter project - starter: Pyramid starter project using URL dispatch and Chameleon - zodb: Pyramid project using ZODB, traversal, and Chameleon + $ $VENV/bin/pip install cookiecutter -The ``pyramid_jinja2`` add-on gave us a scaffold that we can use. From the -parent directory of where we want our Python package to be generated, let's use -that scaffold to make our project: +In the directory where we want our sample Pyramid project to be generated, let's use the cookiecutter ``pyramid-cookiecutter-starter``, following the prompts of the command. .. code-block:: bash - $ $VENV/bin/pcreate --scaffold pyramid_jinja2_starter hello_world + $ $VENV/bin/cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter + +If prompted for the first item, accept the default ``yes`` by hitting return. -We next use the normal Python command to set up our package for development: +#. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before. Is it + okay to delete and re-clone it? [yes]:`` +#. ``project_name [Pyramid Scaffold]: myproject`` +#. ``repo_name [scaffold]: qtour`` + +We then run through the following commands .. code-block:: bash - $ cd hello_world - $ $VENV/bin/pip install -e . + # Change directory into your newly created project. + $ cd qtour + # Create a new virtual environment... + $ python3 -m venv env + # ...where we upgrade packaging tools... + $ env/bin/pip install --upgrade pip setuptools + # ...and into which we install our project and its testing requirements. + $ env/bin/pip install -e ".[testing]" + # Reset our environment variable to use the new virtual environment. + $ export VENV=~/env/qtour/env We are moving in the direction of a full-featured Pyramid project, with a proper setup for Python standards (packaging) and Pyramid configuration. This @@ -537,7 +545,7 @@ includes a new way of running your application: Let's look at ``pserve`` and configuration in more depth. .. seealso:: See also: - :ref:`Quick Tutorial Scaffolds `, + :ref:`Quick Tutorial Cookiecutters `, :ref:`project_narr`, and :doc:`../narr/scaffolding` diff --git a/docs/quick_tutorial/scaffolds.rst b/docs/quick_tutorial/scaffolds.rst index ad002f4fd..8712d64e9 100644 --- a/docs/quick_tutorial/scaffolds.rst +++ b/docs/quick_tutorial/scaffolds.rst @@ -1,4 +1,4 @@ -.. _qtut_scaffolds: +.. _qtut_cookiecutters: ============================================= Prelude: Quick Project Startup with Scaffolds -- cgit v1.2.3 From 49cd001b213ca74d0b39914eeed4c1eb4969d84d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 02:38:54 -0800 Subject: quick_tour - fix reference --- docs/quick_tour.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index f9dbd2438..a0c8a4737 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -545,7 +545,7 @@ includes a new way of running your application: Let's look at ``pserve`` and configuration in more depth. .. seealso:: See also: - :ref:`Quick Tutorial Cookiecutters `, + :ref:`Quick Tutorial Cookiecutters `, :ref:`project_narr`, and :doc:`../narr/scaffolding` -- cgit v1.2.3 From 3d3ee8b2404cd3f73157cc2f1c61e647fba77df4 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Sat, 24 Dec 2016 14:50:01 +0200 Subject: Fix link --- docs/whatsnew-1.8.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 88e2b4736..9185f1ae2 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -107,7 +107,7 @@ Feature Additions other settings. See https://github.com/Pylons/pyramid/pull/2823 - ``pserve --reload`` now uses the - `hupper ` + `hupper `_ library to monitor file changes. This comes with many improvements: - If the `watchdog `_ package is -- cgit v1.2.3 From 8553bd2f06405320d27129e8336d9655ae25e72c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 24 Dec 2016 13:53:20 -0600 Subject: update whatsnew --- docs/whatsnew-1.8.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 9185f1ae2..9f55ad60a 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -150,9 +150,18 @@ Feature Additions Deprecations ------------ -- The ``pcreate`` script and related scaffolds have been deprecated in favor - of the popular - `cookiecutter `_ project. +- The ``pcreate`` script and the core scaffolds (``starter``, ``alchemy`` and + ``zodb``) have been deprecated. + + They have been replaced with the decision to embrace the popular + `cookiecutter `_ project + as a best-of-breed project templating solution. + + ``pcreate`` was originally introduced when very few alternatives existed + that supported Python 3. Fortunately the situation has improved and + with possible tooling support for cookiecutters being discussed by major + IDEs, and the simplicity of the jinja2 syntax, it is exciting to embrace + the project moving forward! All of Pyramid's official scaffolds as well as the tutorials have been ported to cookiecutters: -- cgit v1.2.3 From df57ecafed8e3cf56a74e5f95b578f5dae400f55 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 12:41:49 -0800 Subject: improve display of help's description for p* scripts - Without ``formatter_class = argparse.RawDescriptionHelpFormatter``, whitespace is removed from the description, rendering it as a blob of text and less readable --- pyramid/scripts/pcreate.py | 7 +++++-- pyramid/scripts/prequest.py | 3 ++- pyramid/scripts/proutes.py | 3 ++- pyramid/scripts/pserve.py | 3 ++- pyramid/scripts/pshell.py | 3 ++- pyramid/scripts/ptweens.py | 1 + pyramid/scripts/pviews.py | 3 ++- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 75e3b1fdc..cfab88160 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -23,13 +23,16 @@ def main(argv=sys.argv, quiet=False): class PCreateCommand(object): verbosity = 1 # required - parser = argparse.ArgumentParser(description="""\ + parser = argparse.ArgumentParser( + description="""\ Render Pyramid scaffolding to an output directory. Note: As of Pyramid 1.8, this command is deprecated. Use a specific cookiecutter instead: https://github.com/Pylons/?q=cookiecutter -""") +""", + formatter_class = argparse.RawDescriptionHelpFormatter, + ) parser.add_argument('-s', '--scaffold', dest='scaffold_name', action='append', diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index aefb4e18d..b74948289 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -47,7 +47,8 @@ class PRequestCommand(object): """ parser = argparse.ArgumentParser( - description=textwrap.dedent(description) + description=textwrap.dedent(description), + formatter_class = argparse.RawDescriptionHelpFormatter, ) parser.add_argument( '-n', '--app-name', diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index 2a999e04f..cd731946d 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -249,7 +249,8 @@ class PRoutesCommand(object): stdout = sys.stdout ConfigParser = configparser.ConfigParser # testing parser = argparse.ArgumentParser( - description=textwrap.dedent(description) + description=textwrap.dedent(description), + formatter_class = argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-g', '--glob', action='store', diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 845933c27..1f66394da 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -51,7 +51,8 @@ class PServeCommand(object): default_verbosity = 1 parser = argparse.ArgumentParser( - description=textwrap.dedent(description) + description=textwrap.dedent(description), + formatter_class = argparse.RawDescriptionHelpFormatter, ) parser.add_argument( '-n', '--app-name', diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index d8abf6619..d4b2db0ff 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -45,7 +45,8 @@ class PShellCommand(object): pkg_resources = pkg_resources # for testing parser = argparse.ArgumentParser( - description=textwrap.dedent(description) + description=textwrap.dedent(description), + formatter_class = argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-p', '--python-shell', action='store', diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index f278a0370..076d44fa5 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -29,6 +29,7 @@ class PTweensCommand(object): """ parser = argparse.ArgumentParser( description=textwrap.dedent(description), + formatter_class = argparse.RawDescriptionHelpFormatter, ) parser.add_argument('config_uri', diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index 64408bdad..0d4c8e201 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -28,7 +28,8 @@ class PViewsCommand(object): stdout = sys.stdout parser = argparse.ArgumentParser( - description=textwrap.dedent(description) + description=textwrap.dedent(description), + formatter_class = argparse.RawDescriptionHelpFormatter, ) parser.add_argument('config_uri', -- cgit v1.2.3 From c9b2fa4d314e1d743a8e21c7b5ba85e1cb212e33 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 12:47:00 -0800 Subject: PEP8 --- pyramid/scripts/pcreate.py | 2 +- pyramid/scripts/prequest.py | 2 +- pyramid/scripts/proutes.py | 2 +- pyramid/scripts/pserve.py | 2 +- pyramid/scripts/pshell.py | 2 +- pyramid/scripts/ptweens.py | 2 +- pyramid/scripts/pviews.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index cfab88160..a6db520ce 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -31,7 +31,7 @@ Note: As of Pyramid 1.8, this command is deprecated. Use a specific cookiecutter instead: https://github.com/Pylons/?q=cookiecutter """, - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-s', '--scaffold', dest='scaffold_name', diff --git a/pyramid/scripts/prequest.py b/pyramid/scripts/prequest.py index b74948289..66feff624 100644 --- a/pyramid/scripts/prequest.py +++ b/pyramid/scripts/prequest.py @@ -48,7 +48,7 @@ class PRequestCommand(object): parser = argparse.ArgumentParser( description=textwrap.dedent(description), - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument( '-n', '--app-name', diff --git a/pyramid/scripts/proutes.py b/pyramid/scripts/proutes.py index cd731946d..80c8238a2 100644 --- a/pyramid/scripts/proutes.py +++ b/pyramid/scripts/proutes.py @@ -250,7 +250,7 @@ class PRoutesCommand(object): ConfigParser = configparser.ConfigParser # testing parser = argparse.ArgumentParser( description=textwrap.dedent(description), - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-g', '--glob', action='store', diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 1f66394da..e2d97f5ec 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -52,7 +52,7 @@ class PServeCommand(object): parser = argparse.ArgumentParser( description=textwrap.dedent(description), - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument( '-n', '--app-name', diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py index d4b2db0ff..83e640c32 100644 --- a/pyramid/scripts/pshell.py +++ b/pyramid/scripts/pshell.py @@ -46,7 +46,7 @@ class PShellCommand(object): parser = argparse.ArgumentParser( description=textwrap.dedent(description), - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('-p', '--python-shell', action='store', diff --git a/pyramid/scripts/ptweens.py b/pyramid/scripts/ptweens.py index 076d44fa5..5ca77e52a 100644 --- a/pyramid/scripts/ptweens.py +++ b/pyramid/scripts/ptweens.py @@ -29,7 +29,7 @@ class PTweensCommand(object): """ parser = argparse.ArgumentParser( description=textwrap.dedent(description), - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('config_uri', diff --git a/pyramid/scripts/pviews.py b/pyramid/scripts/pviews.py index 0d4c8e201..4d3312917 100644 --- a/pyramid/scripts/pviews.py +++ b/pyramid/scripts/pviews.py @@ -29,7 +29,7 @@ class PViewsCommand(object): parser = argparse.ArgumentParser( description=textwrap.dedent(description), - formatter_class = argparse.RawDescriptionHelpFormatter, + formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument('config_uri', -- cgit v1.2.3 From 5428bce2147e7f8cec503a3fb884b246e748b833 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 12:47:12 -0800 Subject: add changelog entry --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 994aaec18..fcb5cbcbe 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -255,3 +255,6 @@ Documentation Changes See https://github.com/Pylons/pyramid/pull/2881 and https://github.com/Pylons/pyramid/pull/2883. + +- Improve output of p* script output of description for help. + See https://github.com/Pylons/pyramid/pull/2886 \ No newline at end of file -- cgit v1.2.3 From 0d5820c1c8aa8f0d355a1a875c89bf1c0207bcdf Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 12:49:00 -0800 Subject: fix grammar of changelog entry --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index fcb5cbcbe..218b2e412 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -256,5 +256,5 @@ Documentation Changes See https://github.com/Pylons/pyramid/pull/2881 and https://github.com/Pylons/pyramid/pull/2883. -- Improve output of p* script output of description for help. +- Improve output of p* script descriptions for help. See https://github.com/Pylons/pyramid/pull/2886 \ No newline at end of file -- cgit v1.2.3 From 85b301a5355e7b9373d9381ee75fc6233915cea1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 12:55:24 -0800 Subject: remove Style Guide from changelog and whatsnew --- CHANGES.txt | 2 +- docs/whatsnew-1.8.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 218b2e412..959dc6a4f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -226,7 +226,7 @@ Deprecations Documentation Changes --------------------- -- Update Typographical Conventions and add a Style Guide. +- Update Typographical Conventions. https://github.com/Pylons/pyramid/pull/2838 - Add `pyramid_nacl_session diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 9f55ad60a..9ec3bb23c 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -180,7 +180,7 @@ Deprecations Documentation Enhancements -------------------------- -- Update Typographical Conventions and add a Style Guide. +- Update Typographical Conventions. https://github.com/Pylons/pyramid/pull/2838 - Add `pyramid_nacl_session -- cgit v1.2.3 From c22270f6bcbb8e43ac53140a2f30afe3059194db Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 24 Dec 2016 16:17:25 -0600 Subject: reorganize the whatsnew doc to look more like older versions (< 1.5) --- CHANGES.txt | 6 +-- docs/whatsnew-1.8.rst | 143 ++++++++++++++++++++++++++------------------------ 2 files changed, 76 insertions(+), 73 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 959dc6a4f..55e56ff1a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -48,9 +48,9 @@ Features - Python 3.6 compatibility. https://github.com/Pylons/pyramid/issues/2835 -- pcreate learned about ``--package-name`` to allow you to create a new project - in an existing folder with a different package name than the project name. - See https://github.com/Pylons/pyramid/pull/2783 +- ``pcreate`` learned about ``--package-name`` to allow you to create a new + project in an existing folder with a different package name than the project + name. See https://github.com/Pylons/pyramid/pull/2783 - The ``_get_credentials`` private method of ``BasicAuthAuthenticationPolicy`` has been extracted into standalone function ``extract_http_basic_credentials`` diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 9ec3bb23c..e666f0cd1 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -7,57 +7,47 @@ incompatibilities between the two versions and deprecations added to :app:`Pyramid` 1.8, as well as software dependency changes and notable documentation additions. -Backwards Incompatibilities ---------------------------- +Major Feature Additions +----------------------- -- Following the Pyramid deprecation period (1.6 -> 1.8), - daemon support for pserve has been removed. This includes removing the - daemon commands (start, stop, restart, status) as well as the following - arguments: ``--daemon``, ``--pid-file``, ``--log-file``, - ``--monitor-restart``, ``--status``, ``--user``, ``--group``, - ``--stop-daemon`` +- Added :meth:`pyramid.config.Configurator.add_exception_view` and the + :func:`pyramid.view.exception_view_config` decorator. It is now possible + using these methods or via the new ``exception_only=True`` option to + :meth:`pyramid.config.Configurator.add_view` to add a view which will only + be matched when handling an exception. Previously, any exception views were + also registered for a traversal context that inherited from the exception + class which prevented any exception-only optimizations. + See https://github.com/Pylons/pyramid/pull/2660 - To run your server as a daemon you should use a process manager instead of - pserve. +- ``pserve --reload`` now uses the + `hupper `_ + library to monitor file changes. This comes with many improvements: - See https://github.com/Pylons/pyramid/pull/2615 + - If the `watchdog `_ package is + installed then monitoring will be done using inotify instead of + cpu and disk-intensive polling. -- Change static view to avoid setting the ``Content-Encoding`` response header - to an encoding guessed using Python's ``mimetypes`` module. This was causing - clients to decode the content of gzipped files when downloading them. The - client would end up with a ``foo.txt.gz`` file on disk that was already - decoded, thus should really be ``foo.txt``. Also, the ``Content-Encoding`` - should only have been used if the client itself broadcast support for the - encoding via ``Accept-Encoding`` request headers. - See https://github.com/Pylons/pyramid/pull/2810 + - The monitor is now a separate process that will not crash and starts up + before any of your code. -- ``pcreate`` is now interactive by default. You will be prompted if a file - already exists with different content. Previously if there were similar - files it would silently skip them unless you specified ``--interactive`` - or ``--overwrite``. - See https://github.com/Pylons/pyramid/pull/2775 + - The monitor will not restart the process after a crash until a file is + saved. -- Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 - has been removed. See https://github.com/Pylons/pyramid/pull/2822 + - The monitor works on windows. -- Settings are no longer accessible as attributes on the settings object - (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. - See https://github.com/Pylons/pyramid/pull/2823 + - You can now trigger a reload manually from a pyramid view or any other + code via ``hupper.get_reloader().trigger_reload()``. Kind of neat. -- Removed undocumented argument ``cachebust_match`` from - ``pyramid.static.static_view``. This argument was shipped accidentally - in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 + - You can trigger a reload by issuing a ``SIGHUP`` to the monitor process. -Feature Additions ------------------ + See https://github.com/Pylons/pyramid/pull/2805 + +Minor Feature Additions +----------------------- - Python 3.6 compatibility. https://github.com/Pylons/pyramid/issues/2835 -- ``pcreate`` learned about --package-name to allow you to create a new project - in an existing folder with a different package name than the project name. - See https://github.com/Pylons/pyramid/pull/2783 - - The ``_get_credentials`` private method of :class:`pyramid.authentication.BasicAuthAuthenticationPolicy` has been extracted into standalone function @@ -75,15 +65,6 @@ Feature Additions automatically invoke the ``closer`` and pop threadlocals off of the stack to prevent memory leaks. See https://github.com/Pylons/pyramid/pull/2760 -- Added :meth:`pyramid.config.Configurator.add_exception_view` and the - :func:`pyramid.view.exception_view_config` decorator. It is now possible - using these methods or via the new ``exception_only=True`` option to - :meth:`pyramid.config.Configurator.add_view` to add a view which will only - be matched when handling an exception. Previously, any exception views were - also registered for a traversal context that inherited from the exception - class which prevented any exception-only optimizations. - See https://github.com/Pylons/pyramid/pull/2660 - - Added the ``exception_only`` boolean to :class:`pyramid.interfaces.IViewDeriverInfo` which can be used by view derivers to determine if they are wrapping a view which only handles @@ -106,29 +87,6 @@ Feature Additions using the ``PYRAMID_CSRF_TRUSTED_ORIGINS`` environment variable similar to other settings. See https://github.com/Pylons/pyramid/pull/2823 -- ``pserve --reload`` now uses the - `hupper `_ - library to monitor file changes. This comes with many improvements: - - - If the `watchdog `_ package is - installed then monitoring will be done using inotify instead of - cpu and disk-intensive polling. - - - The monitor is now a separate process that will not crash and starts up - before any of your code. - - - The monitor will not restart the process after a crash until a file is - saved. - - - The monitor works on windows. - - - You can now trigger a reload manually from a pyramid view or any other - code via ``hupper.get_reloader().trigger_reload()``. Kind of neat. - - - You can trigger a reload by issuing a ``SIGHUP`` to the monitor process. - - See https://github.com/Pylons/pyramid/pull/2805 - - A new ``[pserve]`` section is supported in your config files with a ``watch_files`` key that can configure ``pserve --reload`` to monitor custom file paths. See https://github.com/Pylons/pyramid/pull/2827 @@ -147,6 +105,51 @@ Feature Additions ``--help`` output as well as enabling nicer documentation of their options. See https://github.com/Pylons/pyramid/pull/2864 +Backwards Incompatibilities +--------------------------- + +- Following the Pyramid deprecation period (1.6 -> 1.8), + daemon support for pserve has been removed. This includes removing the + daemon commands (start, stop, restart, status) as well as the following + arguments: ``--daemon``, ``--pid-file``, ``--log-file``, + ``--monitor-restart``, ``--status``, ``--user``, ``--group``, + ``--stop-daemon`` + + To run your server as a daemon you should use a process manager instead of + pserve. + + See https://github.com/Pylons/pyramid/pull/2615 + +- Change static view to avoid setting the ``Content-Encoding`` response header + to an encoding guessed using Python's ``mimetypes`` module. This was causing + clients to decode the content of gzipped files when downloading them. The + client would end up with a ``foo.txt.gz`` file on disk that was already + decoded, thus should really be ``foo.txt``. Also, the ``Content-Encoding`` + should only have been used if the client itself broadcast support for the + encoding via ``Accept-Encoding`` request headers. + See https://github.com/Pylons/pyramid/pull/2810 + +- ``pcreate`` learned about ``--package-name`` to allow you to create a new + project in an existing folder with a different package name than the project + name. See https://github.com/Pylons/pyramid/pull/2783 + +- ``pcreate`` is now interactive by default. You will be prompted if a file + already exists with different content. Previously if there were similar + files it would silently skip them unless you specified ``--interactive`` + or ``--overwrite``. + See https://github.com/Pylons/pyramid/pull/2775 + +- Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 + has been removed. See https://github.com/Pylons/pyramid/pull/2822 + +- Settings are no longer accessible as attributes on the settings object + (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. + See https://github.com/Pylons/pyramid/pull/2823 + +- Removed undocumented argument ``cachebust_match`` from + ``pyramid.static.static_view``. This argument was shipped accidentally + in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 + Deprecations ------------ -- cgit v1.2.3 From af77a11004056797340136d7997c88cdd0106575 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 24 Dec 2016 16:29:12 -0600 Subject: expose the new exception view apis --- docs/api/config.rst | 1 + docs/api/view.rst | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/api/config.rst b/docs/api/config.rst index ab3ff0fe1..62f138b76 100644 --- a/docs/api/config.rst +++ b/docs/api/config.rst @@ -26,6 +26,7 @@ .. automethod:: add_view .. automethod:: add_notfound_view .. automethod:: add_forbidden_view + .. automethod:: add_exception_view :methodcategory:`Adding an Event Subscriber` diff --git a/docs/api/view.rst b/docs/api/view.rst index d8e429552..e41212012 100644 --- a/docs/api/view.rst +++ b/docs/api/view.rst @@ -23,4 +23,6 @@ .. autoclass:: forbidden_view_config :members: + .. autoclass:: exception_view_config + :members: -- cgit v1.2.3 From 2cd1eab15a3777cbc81c2d365f21a98c29c9ed86 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Dec 2016 20:41:08 -0800 Subject: use hello_world for project and repo names; grammar fixes --- docs/quick_tour.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index a0c8a4737..4c8dfc143 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -498,7 +498,7 @@ So far we have done all of our *Quick Tour* as a single Python file. No Python packages, no structure. Most Pyramid projects, though, aren't developed this way. -To ease the process of getting started, the Pylons Project provides :term:`cookiecutter`\ s that generate sample Pyramid projects from project templates. In addition these cookiecutters will install Pyramid and its dependencies. +To ease the process of getting started, the Pylons Project provides :term:`cookiecutter`\ s that generate sample Pyramid projects from project templates. These cookiecutters will install Pyramid and its dependencies as well. First you'll need to install cookiecutter. @@ -506,7 +506,7 @@ First you'll need to install cookiecutter. $ $VENV/bin/pip install cookiecutter -In the directory where we want our sample Pyramid project to be generated, let's use the cookiecutter ``pyramid-cookiecutter-starter``, following the prompts of the command. +Let's use the cookiecutter ``pyramid-cookiecutter-starter`` to create a starter Pyramid project in the current directory, entering values at the prompts as shown below for the following command. .. code-block:: bash @@ -516,23 +516,23 @@ If prompted for the first item, accept the default ``yes`` by hitting return. #. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before. Is it okay to delete and re-clone it? [yes]:`` -#. ``project_name [Pyramid Scaffold]: myproject`` -#. ``repo_name [scaffold]: qtour`` +#. ``project_name [Pyramid Scaffold]: hello_world`` +#. ``repo_name [scaffold]: hello_world`` We then run through the following commands .. code-block:: bash # Change directory into your newly created project. - $ cd qtour + $ cd hello_world # Create a new virtual environment... $ python3 -m venv env # ...where we upgrade packaging tools... $ env/bin/pip install --upgrade pip setuptools # ...and into which we install our project and its testing requirements. $ env/bin/pip install -e ".[testing]" - # Reset our environment variable to use the new virtual environment. - $ export VENV=~/env/qtour/env + # Reset our environment variable for a new virtual environment. + $ export VENV=~/env/hello_world/env We are moving in the direction of a full-featured Pyramid project, with a proper setup for Python standards (packaging) and Pyramid configuration. This @@ -552,7 +552,7 @@ Let's look at ``pserve`` and configuration in more depth. Application running with ``pserve`` =================================== -Prior to scaffolds, our project mixed a number of operational details into our +Prior to the cookiecutter, our project mixed a number of operational details into our code. Why should my main code care which HTTP server I want and what port number to run on? @@ -582,7 +582,7 @@ Configuration with ``.ini`` files Earlier in *Quick Tour* we first met Pyramid's configuration system. At that point we did all configuration in Python code. For example, the port number -chosen for our HTTP server was right there in Python code. Our scaffold has +chosen for our HTTP server was right there in Python code. Our cookiecutter has moved this decision and more into the ``development.ini`` file: .. literalinclude:: quick_tour/package/development.ini -- cgit v1.2.3 From 54d9ddcd335d45662ca2ec2839574085318e8704 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 02:17:19 -0800 Subject: quick_tour - Configuration with ``.ini`` files section cookiecutter updates - src files - update numbered list for new listen configuration for waitress - fix reference to app, not server - reorder numbered list to align with configuration order --- docs/quick_tour.rst | 10 +-- docs/quick_tour/package/.coveragerc | 3 + docs/quick_tour/package/CHANGES.txt | 2 +- docs/quick_tour/package/MANIFEST.in | 2 +- docs/quick_tour/package/README.txt | 27 ++++++- docs/quick_tour/package/development.ini | 5 +- docs/quick_tour/package/hello_world/__init__.py | 24 ++----- .../locale/de/LC_MESSAGES/hello_world.mo | Bin 460 -> 0 bytes .../locale/de/LC_MESSAGES/hello_world.po | 21 ------ .../locale/fr/LC_MESSAGES/hello_world.mo | Bin 461 -> 0 bytes .../locale/fr/LC_MESSAGES/hello_world.po | 21 ------ .../package/hello_world/locale/hello_world.pot | 21 ------ docs/quick_tour/package/hello_world/resources.py | 8 --- .../package/hello_world/static/favicon.ico | Bin 1406 -> 0 bytes .../package/hello_world/static/theme.css | 9 +-- .../package/hello_world/templates/layout.jinja2 | 64 +++++++++++++++++ .../hello_world/templates/mytemplate.jinja2 | 80 +++------------------ docs/quick_tour/package/hello_world/tests.py | 27 ++++--- docs/quick_tour/package/hello_world/views.py | 14 +--- docs/quick_tour/package/message-extraction.ini | 3 - docs/quick_tour/package/production.ini | 53 ++++++++++++++ docs/quick_tour/package/pytest.ini | 3 + docs/quick_tour/package/setup.cfg | 28 -------- docs/quick_tour/package/setup.py | 61 +++++++++------- 24 files changed, 230 insertions(+), 256 deletions(-) create mode 100644 docs/quick_tour/package/.coveragerc delete mode 100644 docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo delete mode 100644 docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po delete mode 100644 docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo delete mode 100644 docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po delete mode 100644 docs/quick_tour/package/hello_world/locale/hello_world.pot delete mode 100644 docs/quick_tour/package/hello_world/resources.py delete mode 100644 docs/quick_tour/package/hello_world/static/favicon.ico create mode 100644 docs/quick_tour/package/hello_world/templates/layout.jinja2 delete mode 100644 docs/quick_tour/package/message-extraction.ini create mode 100644 docs/quick_tour/package/production.ini create mode 100644 docs/quick_tour/package/pytest.ini delete mode 100644 docs/quick_tour/package/setup.cfg diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 4c8dfc143..a48ac4137 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -599,15 +599,15 @@ sections: We have a few decisions made for us in this configuration: -#. *Choice of web server:* ``use = egg:hello_world`` tells ``pserve`` to - use the ``waitress`` server. - -#. *Port number:* ``port = 6543`` tells ``waitress`` to listen on port 6543. - #. *WSGI app:* What package has our WSGI application in it? ``use = egg:hello_world`` in the app section tells the configuration what application to load. +#. *Choice of web server:* ``use = egg:waitress#main`` tells ``pserve`` to + use the ``waitress`` server. + +#. *Interfaces:* ``listen = 127.0.0.1:6543 [::1]:6543`` tells ``waitress`` to listen on all interfaces on port 6543 for both IPv4 and IPv6. + #. *Easier development by automatic template reloading:* In development mode, you shouldn't have to restart the server when editing a Jinja2 template. ``pyramid.reload_templates = true`` sets this policy, which might be diff --git a/docs/quick_tour/package/.coveragerc b/docs/quick_tour/package/.coveragerc new file mode 100644 index 000000000..128e26410 --- /dev/null +++ b/docs/quick_tour/package/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = hello_world +omit = hello_world/test* diff --git a/docs/quick_tour/package/CHANGES.txt b/docs/quick_tour/package/CHANGES.txt index ffa255da8..14b902fd1 100644 --- a/docs/quick_tour/package/CHANGES.txt +++ b/docs/quick_tour/package/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/quick_tour/package/MANIFEST.in b/docs/quick_tour/package/MANIFEST.in index 1d0352f7d..a75da6dad 100644 --- a/docs/quick_tour/package/MANIFEST.in +++ b/docs/quick_tour/package/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.jinja2 *.js *.html *.xml +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/quick_tour/package/README.txt b/docs/quick_tour/package/README.txt index 63aaf6fbd..fb7bde0a7 100644 --- a/docs/quick_tour/package/README.txt +++ b/docs/quick_tour/package/README.txt @@ -1,4 +1,29 @@ -hello_world README +hello_world +=============================== +Getting Started +--------------- +- Change directory into your newly created project. + cd hello_world + +- Create a Python virtual environment. + + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini index d00368686..1f19e373d 100644 --- a/docs/quick_tour/package/development.ini +++ b/docs/quick_tour/package/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.6-branch/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html ### [app:main] @@ -10,7 +10,6 @@ pyramid.reload_templates = true pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false -pyramid.debug_templates = true pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar @@ -29,7 +28,7 @@ listen = 127.0.0.1:6543 [::1]:6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.6-branch/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html ### [loggers] diff --git a/docs/quick_tour/package/hello_world/__init__.py b/docs/quick_tour/package/hello_world/__init__.py index 97f93d5a8..49dde36d4 100644 --- a/docs/quick_tour/package/hello_world/__init__.py +++ b/docs/quick_tour/package/hello_world/__init__.py @@ -1,26 +1,12 @@ from pyramid.config import Configurator -from hello_world.resources import get_root -from pyramid.session import SignedCookieSessionFactory def main(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. + """ This function returns a Pyramid WSGI application. """ - settings = dict(settings) - settings.setdefault('jinja2.i18n.domain', 'hello_world') - - my_session_factory = SignedCookieSessionFactory('itsaseekreet') - config = Configurator(root_factory=get_root, settings=settings, - session_factory=my_session_factory) - config.add_translation_dirs('locale/') + config = Configurator(settings=settings) config.include('pyramid_jinja2') - - config.add_static_view('static', 'static') - config.add_view('hello_world.views.my_view', - context='hello_world.resources.MyResource', - renderer="templates/mytemplate.jinja2") - + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() return config.make_wsgi_app() diff --git a/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo b/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo deleted file mode 100644 index 40bf0c271..000000000 Binary files a/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo and /dev/null differ diff --git a/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po b/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po deleted file mode 100644 index 0df243dba..000000000 --- a/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "Hallo!" diff --git a/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo b/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo deleted file mode 100644 index 4fc438bfe..000000000 Binary files a/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo and /dev/null differ diff --git a/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po b/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po deleted file mode 100644 index dc0aae5d7..000000000 --- a/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "Bonjour!" diff --git a/docs/quick_tour/package/hello_world/locale/hello_world.pot b/docs/quick_tour/package/hello_world/locale/hello_world.pot deleted file mode 100644 index 9c9460cb2..000000000 --- a/docs/quick_tour/package/hello_world/locale/hello_world.pot +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "" diff --git a/docs/quick_tour/package/hello_world/resources.py b/docs/quick_tour/package/hello_world/resources.py deleted file mode 100644 index e89c2f363..000000000 --- a/docs/quick_tour/package/hello_world/resources.py +++ /dev/null @@ -1,8 +0,0 @@ -class MyResource(object): - pass - -root = MyResource() - - -def get_root(request): - return root diff --git a/docs/quick_tour/package/hello_world/static/favicon.ico b/docs/quick_tour/package/hello_world/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/quick_tour/package/hello_world/static/favicon.ico and /dev/null differ diff --git a/docs/quick_tour/package/hello_world/static/theme.css b/docs/quick_tour/package/hello_world/static/theme.css index e3cf3f290..0f4b1a4d4 100644 --- a/docs/quick_tour/package/hello_world/static/theme.css +++ b/docs/quick_tour/package/hello_world/static/theme.css @@ -72,10 +72,12 @@ p { color: #f2b7bd; font-weight: 400; } -.starter-template .links ul li a { - color: #ffffff; +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; } -.starter-template .links ul li a:hover { +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; text-decoration: underline; } .starter-template .links ul li .icon-muted { @@ -150,4 +152,3 @@ p { margin-top: 20px; } } - diff --git a/docs/quick_tour/package/hello_world/templates/layout.jinja2 b/docs/quick_tour/package/hello_world/templates/layout.jinja2 new file mode 100644 index 000000000..916127267 --- /dev/null +++ b/docs/quick_tour/package/hello_world/templates/layout.jinja2 @@ -0,0 +1,64 @@ + + + + + + + + + + + Cookiecutter Starter project for the Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + {% block content %} +

    No content

    + {% endblock content %} +
    +
    + +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 b/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 index a6089aebc..cf2d7f996 100644 --- a/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 +++ b/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 @@ -1,72 +1,8 @@ - - - - - - - - - - - Starter Scaffold for Pyramid Jinja2 - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    - Pyramid - Jinja2 scaffold -

    -

    - {% trans %}Hello{% endtrans %} to {{project}}, an application generated by
    the Pyramid Web Framework 1.6.

    -

    Counter: {{ request.session.counter }}

    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - - - - - - - - +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Starter project

    +

    Welcome to hello_world, a Pyramid application generated by
    Cookiecutter.

    +
    +{% endblock content %} diff --git a/docs/quick_tour/package/hello_world/tests.py b/docs/quick_tour/package/hello_world/tests.py index ccec14f70..ee9745685 100644 --- a/docs/quick_tour/package/hello_world/tests.py +++ b/docs/quick_tour/package/hello_world/tests.py @@ -1,20 +1,29 @@ import unittest -from pyramid import testing -from pyramid.i18n import TranslationStringFactory -_ = TranslationStringFactory('hello_world') +from pyramid import testing class ViewTests(unittest.TestCase): - def setUp(self): - testing.setUp() - + self.config = testing.setUp() + def tearDown(self): testing.tearDown() def test_my_view(self): - from hello_world.views import my_view + from .views import my_view request = testing.DummyRequest() - response = my_view(request) - self.assertEqual(response['project'], 'hello_world') + info = my_view(request) + self.assertEqual(info['project'], 'hello_world') + + +class FunctionalTests(unittest.TestCase): + def setUp(self): + from hello_world import main + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/quick_tour/package/hello_world/views.py b/docs/quick_tour/package/hello_world/views.py index 9f7953c8e..67f78dad7 100644 --- a/docs/quick_tour/package/hello_world/views.py +++ b/docs/quick_tour/package/hello_world/views.py @@ -1,16 +1,6 @@ -from pyramid.i18n import TranslationStringFactory - -import logging -log = logging.getLogger(__name__) - -_ = TranslationStringFactory('hello_world') +from pyramid.view import view_config +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') def my_view(request): - log.debug('Some Message') - session = request.session - if 'counter' in session: - session['counter'] += 1 - else: - session['counter'] = 0 return {'project': 'hello_world'} diff --git a/docs/quick_tour/package/message-extraction.ini b/docs/quick_tour/package/message-extraction.ini deleted file mode 100644 index 0c3d54bc1..000000000 --- a/docs/quick_tour/package/message-extraction.ini +++ /dev/null @@ -1,3 +0,0 @@ -[python: **.py] -[jinja2: **.jinja2] -encoding = utf-8 diff --git a/docs/quick_tour/package/production.ini b/docs/quick_tour/package/production.ini new file mode 100644 index 000000000..9c12bc4ec --- /dev/null +++ b/docs/quick_tour/package/production.ini @@ -0,0 +1,53 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = *:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_hello_world] +level = WARN +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/package/pytest.ini b/docs/quick_tour/package/pytest.ini new file mode 100644 index 000000000..f707d54e4 --- /dev/null +++ b/docs/quick_tour/package/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = hello_world +python_files = *.py diff --git a/docs/quick_tour/package/setup.cfg b/docs/quick_tour/package/setup.cfg deleted file mode 100644 index 186e796fc..000000000 --- a/docs/quick_tour/package/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = hello_world -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = hello_world/locale -domain = hello_world -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = hello_world/locale/hello_world.pot -width = 80 -mapping_file = message-extraction.ini - -[init_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale - -[update_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale -previous = true diff --git a/docs/quick_tour/package/setup.py b/docs/quick_tour/package/setup.py index 61ed3c406..e32aecacd 100644 --- a/docs/quick_tour/package/setup.py +++ b/docs/quick_tour/package/setup.py @@ -15,30 +15,37 @@ requires = [ 'waitress', ] -setup(name='hello_world', - version='0.0', - description='hello_world', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require={ - 'testing': ['nose', 'coverage'], - }, - test_suite="hello_world", - entry_points="""\ - [paste.app_factory] - main = hello_world:main - """, - ) +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='hello_world', + version='0.0', + description='hello_world', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = hello_world:main', + ], + }, +) -- cgit v1.2.3 From 7857763be80aad2e60b95bfed73c641194fb380c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 02:18:51 -0800 Subject: quick_tour - Configuration with ``.ini`` files section cookiecutter updates - reorder numbered list to align with configuration order, this time for sure! --- docs/quick_tour.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index a48ac4137..ab25f68dc 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -603,16 +603,16 @@ We have a few decisions made for us in this configuration: ``use = egg:hello_world`` in the app section tells the configuration what application to load. -#. *Choice of web server:* ``use = egg:waitress#main`` tells ``pserve`` to - use the ``waitress`` server. - -#. *Interfaces:* ``listen = 127.0.0.1:6543 [::1]:6543`` tells ``waitress`` to listen on all interfaces on port 6543 for both IPv4 and IPv6. - #. *Easier development by automatic template reloading:* In development mode, you shouldn't have to restart the server when editing a Jinja2 template. ``pyramid.reload_templates = true`` sets this policy, which might be different in production. +#. *Choice of web server:* ``use = egg:waitress#main`` tells ``pserve`` to + use the ``waitress`` server. + +#. *Interfaces:* ``listen = 127.0.0.1:6543 [::1]:6543`` tells ``waitress`` to listen on all interfaces on port 6543 for both IPv4 and IPv6. + Additionally the ``development.ini`` generated by this scaffold wired up Python's standard logging. We'll now see in the console, for example, a log on every request that comes in, as well as traceback information. -- cgit v1.2.3 From af1e3221489954cd3001e81e4b94516a820c2f72 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 02:29:14 -0800 Subject: quick_tour - "Easier development with ``debugtoolbar``" updates for cookiecutter - adjust line numbers, grammar, pip command --- docs/quick_tour.rst | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index ab25f68dc..a02d2ab27 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -634,38 +634,35 @@ and earlier we showed ``--reload`` for application reloading. available in your browser. Adding it to your project illustrates several points about configuration. -The scaffold ``pyramid_jinja2_starter`` is already configured to include the +The cookiecutter ``pyramid-cookiecutter-starter`` already configured our package to include the add-on ``pyramid_debugtoolbar`` in its ``setup.py``: .. literalinclude:: quick_tour/package/setup.py :language: python - :linenos: - :lineno-start: 11 + :lineno-match: :lines: 11-16 + :emphasize-lines: 4 It was installed when you previously ran: .. code-block:: bash - $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install -e ".[testing]" The ``pyramid_debugtoolbar`` package is a Pyramid add-on, which means we need -to include its configuration into our web application. The ``pyramid_jinja2`` -add-on already took care of this for us in its ``__init__.py``: +to include its configuration into our web application. The cookiecutter already took care of this for us in its ``__init__.py``: .. literalinclude:: quick_tour/package/hello_world/__init__.py :language: python - :linenos: - :lineno-start: 16 - :lines: 19 + :lineno-match: + :lines: 8 And it uses the ``pyramid.includes`` facility in our ``development.ini``: .. literalinclude:: quick_tour/package/development.ini :language: ini - :linenos: - :lineno-start: 15 - :lines: 15-16 + :lineno-match: + :lines: 14-15 You'll now see a Pyramid logo on the right side of your browser window, which when clicked opens a new window that provides introspective access to debugging -- cgit v1.2.3 From 9483444d55f4dd9be8adc8c386b4af0d8af032a3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 02:47:16 -0800 Subject: quick_tour - "Unit tests and ``py.test``" updates for cookiecutter - use literal includes instead of inline code - document second test --- docs/quick_tour.rst | 76 ++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index a02d2ab27..fd35ba419 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -682,42 +682,23 @@ Yikes! We got this far and we haven't yet discussed tests. This is particularly egregious, as Pyramid has had a deep commitment to full test coverage since before its release. -Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module with -one unit test in it. It also configured ``setup.py`` with test requirements: +Our ``pyramid-cookiecutter-starter`` cookiecutter generated a ``tests.py`` module with +one unit test and one functional test in it. It also configured ``setup.py`` with test requirements: ``py.test`` as the test runner, ``WebTest`` for running view tests, and the ``pytest-cov`` tool which yells at us for code that isn't tested. The highlighted lines show this: -.. code-block:: python - :linenos: - :lineno-start: 11 - :emphasize-lines: 8-12 - - requires = [ - 'pyramid', - 'pyramid_jinja2', - 'pyramid_debugtoolbar', - 'waitress', - ] - - tests_require = [ - 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv - 'pytest-cov', - ] - -.. code-block:: python - :linenos: - :lineno-start: 34 - :emphasize-lines: 2-4 +.. literalinclude:: quick_tour/package/setup.py + :language: python + :lineno-match: + :lines: 18-22 - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, +.. literalinclude:: quick_tour/package/setup.py + :language: python + :lineno-match: + :lines: 42-44 -To install the test requirements, run ``$VENV/bin/pip install -e -".[testing]"``. We can now run all our tests: +We already installed the test requirements when we ran the command ``$VENV/bin/pip install -e ".[testing]"``. We can now run all our tests: .. code-block:: bash @@ -728,34 +709,33 @@ This yields the following output. .. code-block:: text =========================== test session starts =========================== - platform darwin -- Python 3.5.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 - rootdir: /Users/stevepiercy/projects/hack-on-pyramid/hello_world, inifile: - plugins: cov-2.2.1 - collected 1 items + platform darwin -- Python 3.6.0, pytest-3.0.5, py-1.4.32, pluggy-0.4.0 + rootdir: /Users/stevepiercy/hello_world, inifile: pytest.ini + plugins: cov-2.4.0 + collected 2 items + + hello_world/tests.py .. - hello_world/tests.py . ------------- coverage: platform darwin, python 3.6.0-final-0 ------------- - Name Stmts Miss Cover Missing - -------------------------------------------------------- - hello_world/__init__.py 11 8 27% 11-23 - hello_world/resources.py 5 1 80% 8 - hello_world/tests.py 14 0 100% - hello_world/views.py 4 0 100% - -------------------------------------------------------- - TOTAL 34 9 74% + Name Stmts Miss Cover Missing + ----------------------------------------------------------------------- + hello_world/__init__.py 8 0 100% + hello_world/views.py 3 0 100% + ----------------------------------------------------------------------- + TOTAL 11 0 100% + - ========================= 1 passed in 0.22 seconds ========================= + ========================= 2 passed in 1.37 seconds ========================= -Our unit test passed, although its coverage is incomplete. What did our test -look like? +Our tests passed, and its coverage is complete. What did our test look like? .. literalinclude:: quick_tour/package/hello_world/tests.py :language: python :linenos: Pyramid supplies helpers for test writing, which we use in the test setup and -teardown. Our one test imports the view, makes a dummy request, and sees if the -view returns what we expected. +teardown. Our first test imports the view, makes a dummy request, and sees if the +view returns what we expected. Our second test verifies that the response body from a request to the web root contains what we expected. .. seealso:: See also: :ref:`Quick Tutorial Unit Testing `, :ref:`Quick -- cgit v1.2.3 From c87565c5ff1a3422e651f369fe4b2f848a9010ed Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 03:07:50 -0800 Subject: quick_tour - "Logging" updates for cookiecutter - fix line numbering - add new src files that were never included --- docs/quick_tour.rst | 28 ++-- docs/quick_tour/logging/.coveragerc | 3 + docs/quick_tour/logging/CHANGES.txt | 4 + docs/quick_tour/logging/MANIFEST.in | 2 + docs/quick_tour/logging/README.txt | 29 ++++ docs/quick_tour/logging/development.ini | 59 ++++++++ docs/quick_tour/logging/hello_world/__init__.py | 12 ++ .../logging/hello_world/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../logging/hello_world/static/pyramid.png | Bin 0 -> 12901 bytes .../logging/hello_world/static/theme.css | 154 +++++++++++++++++++++ .../logging/hello_world/templates/layout.jinja2 | 64 +++++++++ .../hello_world/templates/mytemplate.jinja2 | 8 ++ docs/quick_tour/logging/hello_world/tests.py | 29 ++++ docs/quick_tour/logging/hello_world/views.py | 9 ++ docs/quick_tour/logging/production.ini | 53 +++++++ docs/quick_tour/logging/pytest.ini | 3 + docs/quick_tour/logging/setup.py | 51 +++++++ 17 files changed, 492 insertions(+), 16 deletions(-) create mode 100644 docs/quick_tour/logging/.coveragerc create mode 100644 docs/quick_tour/logging/CHANGES.txt create mode 100644 docs/quick_tour/logging/MANIFEST.in create mode 100644 docs/quick_tour/logging/README.txt create mode 100644 docs/quick_tour/logging/development.ini create mode 100644 docs/quick_tour/logging/hello_world/__init__.py create mode 100644 docs/quick_tour/logging/hello_world/static/pyramid-16x16.png create mode 100644 docs/quick_tour/logging/hello_world/static/pyramid.png create mode 100644 docs/quick_tour/logging/hello_world/static/theme.css create mode 100644 docs/quick_tour/logging/hello_world/templates/layout.jinja2 create mode 100644 docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 create mode 100644 docs/quick_tour/logging/hello_world/tests.py create mode 100644 docs/quick_tour/logging/hello_world/views.py create mode 100644 docs/quick_tour/logging/production.ini create mode 100644 docs/quick_tour/logging/pytest.ini create mode 100644 docs/quick_tour/logging/setup.py diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index fd35ba419..f5f722053 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -749,38 +749,34 @@ It's important to know what is going on inside our web application. In development we might need to collect some output. In production we might need to detect situations 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`` has a number of lines that configure the +Fortunately Pyramid uses the normal Python approach to logging. The ``development.ini`` file for your project 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). Maybe you would like to log messages in your code? In your Python module, -import and set up the logging: +import and set up the logging in your ``views.py``: -.. literalinclude:: quick_tour/package/hello_world/views.py +.. literalinclude:: quick_tour/logging/hello_world/views.py :language: python - :linenos: - :lineno-start: 3 + :lineno-match: :lines: 3-4 You can now, in your code, log messages: -.. literalinclude:: quick_tour/package/hello_world/views.py +.. literalinclude:: quick_tour/logging/hello_world/views.py :language: python - :linenos: - :lineno-start: 9 - :lines: 9-10 + :lineno-match: + :lines: 7-8 :emphasize-lines: 2 -This will log ``Some Message`` at a ``debug`` log level to the +This will log ``Some Message`` at a ``DEBUG`` log level to the application-configured logger in your ``development.ini``. What controls that? These emphasized sections in the configuration file: -.. literalinclude:: quick_tour/package/development.ini +.. literalinclude:: quick_tour/logging/development.ini :language: ini - :linenos: - :lineno-start: 36 - :lines: 36-52 + :lineno-match: + :lines: 34-50 :emphasize-lines: 1-2,14-17 Our application, a package named ``hello_world``, is set up as a logger and @@ -789,7 +785,7 @@ http://localhost:6543, your console will now show: .. code-block:: text - 2016-01-18 13:55:55,040 DEBUG [hello_world.views:10][waitress] Some Message + 2016-12-25 03:03:57,059 DEBUG [hello_world.views:8][waitress] Some Message .. seealso:: See also: :ref:`Quick Tutorial Logging ` and :ref:`logging_chapter`. diff --git a/docs/quick_tour/logging/.coveragerc b/docs/quick_tour/logging/.coveragerc new file mode 100644 index 000000000..128e26410 --- /dev/null +++ b/docs/quick_tour/logging/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = hello_world +omit = hello_world/test* diff --git a/docs/quick_tour/logging/CHANGES.txt b/docs/quick_tour/logging/CHANGES.txt new file mode 100644 index 000000000..14b902fd1 --- /dev/null +++ b/docs/quick_tour/logging/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version. diff --git a/docs/quick_tour/logging/MANIFEST.in b/docs/quick_tour/logging/MANIFEST.in new file mode 100644 index 000000000..a75da6dad --- /dev/null +++ b/docs/quick_tour/logging/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/quick_tour/logging/README.txt b/docs/quick_tour/logging/README.txt new file mode 100644 index 000000000..fb7bde0a7 --- /dev/null +++ b/docs/quick_tour/logging/README.txt @@ -0,0 +1,29 @@ +hello_world +=============================== + +Getting Started +--------------- + +- Change directory into your newly created project. + + cd hello_world + +- Create a Python virtual environment. + + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/quick_tour/logging/development.ini b/docs/quick_tour/logging/development.ini new file mode 100644 index 000000000..1f19e373d --- /dev/null +++ b/docs/quick_tour/logging/development.ini @@ -0,0 +1,59 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = 127.0.0.1:6543 [::1]:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/logging/hello_world/__init__.py b/docs/quick_tour/logging/hello_world/__init__.py new file mode 100644 index 000000000..49dde36d4 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/__init__.py @@ -0,0 +1,12 @@ +from pyramid.config import Configurator + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + config = Configurator(settings=settings) + config.include('pyramid_jinja2') + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/quick_tour/logging/hello_world/static/pyramid-16x16.png b/docs/quick_tour/logging/hello_world/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/quick_tour/logging/hello_world/static/pyramid-16x16.png differ diff --git a/docs/quick_tour/logging/hello_world/static/pyramid.png b/docs/quick_tour/logging/hello_world/static/pyramid.png new file mode 100644 index 000000000..4ab837be9 Binary files /dev/null and b/docs/quick_tour/logging/hello_world/static/pyramid.png differ diff --git a/docs/quick_tour/logging/hello_world/static/theme.css b/docs/quick_tour/logging/hello_world/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/quick_tour/logging/hello_world/templates/layout.jinja2 b/docs/quick_tour/logging/hello_world/templates/layout.jinja2 new file mode 100644 index 000000000..916127267 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/templates/layout.jinja2 @@ -0,0 +1,64 @@ + + + + + + + + + + + Cookiecutter Starter project for the Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + {% block content %} +

    No content

    + {% endblock content %} +
    +
    + +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 b/docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 new file mode 100644 index 000000000..cf2d7f996 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Starter project

    +

    Welcome to hello_world, a Pyramid application generated by
    Cookiecutter.

    +
    +{% endblock content %} diff --git a/docs/quick_tour/logging/hello_world/tests.py b/docs/quick_tour/logging/hello_world/tests.py new file mode 100644 index 000000000..ee9745685 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/tests.py @@ -0,0 +1,29 @@ +import unittest + +from pyramid import testing + + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], 'hello_world') + + +class FunctionalTests(unittest.TestCase): + def setUp(self): + from hello_world import main + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/quick_tour/logging/hello_world/views.py b/docs/quick_tour/logging/hello_world/views.py new file mode 100644 index 000000000..a648d6ba3 --- /dev/null +++ b/docs/quick_tour/logging/hello_world/views.py @@ -0,0 +1,9 @@ +from pyramid.view import view_config + +import logging +log = logging.getLogger(__name__) + +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') +def my_view(request): + log.debug('Some Message') + return {'project': 'hello_world'} diff --git a/docs/quick_tour/logging/production.ini b/docs/quick_tour/logging/production.ini new file mode 100644 index 000000000..9c12bc4ec --- /dev/null +++ b/docs/quick_tour/logging/production.ini @@ -0,0 +1,53 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = *:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_hello_world] +level = WARN +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/logging/pytest.ini b/docs/quick_tour/logging/pytest.ini new file mode 100644 index 000000000..f707d54e4 --- /dev/null +++ b/docs/quick_tour/logging/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = hello_world +python_files = *.py diff --git a/docs/quick_tour/logging/setup.py b/docs/quick_tour/logging/setup.py new file mode 100644 index 000000000..e32aecacd --- /dev/null +++ b/docs/quick_tour/logging/setup.py @@ -0,0 +1,51 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + +requires = [ + 'pyramid', + 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', +] + +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='hello_world', + version='0.0', + description='hello_world', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = hello_world:main', + ], + }, +) -- cgit v1.2.3 From 64009ac01e4a8a8526289d600cb3c60ca50257ef Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 03:24:10 -0800 Subject: quick_tour - "Sessions" updates for cookiecutter - add src files - adjust line numbers --- docs/quick_tour.rst | 34 ++--- docs/quick_tour/sessions/.coveragerc | 3 + docs/quick_tour/sessions/CHANGES.txt | 4 + docs/quick_tour/sessions/MANIFEST.in | 2 + docs/quick_tour/sessions/README.txt | 29 ++++ docs/quick_tour/sessions/development.ini | 59 ++++++++ docs/quick_tour/sessions/hello_world/__init__.py | 14 ++ .../sessions/hello_world/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../sessions/hello_world/static/pyramid.png | Bin 0 -> 12901 bytes .../sessions/hello_world/static/theme.css | 154 +++++++++++++++++++++ .../sessions/hello_world/templates/layout.jinja2 | 64 +++++++++ .../hello_world/templates/mytemplate.jinja2 | 9 ++ docs/quick_tour/sessions/hello_world/tests.py | 29 ++++ docs/quick_tour/sessions/hello_world/views.py | 14 ++ docs/quick_tour/sessions/production.ini | 53 +++++++ docs/quick_tour/sessions/pytest.ini | 3 + docs/quick_tour/sessions/setup.py | 51 +++++++ 17 files changed, 503 insertions(+), 19 deletions(-) create mode 100644 docs/quick_tour/sessions/.coveragerc create mode 100644 docs/quick_tour/sessions/CHANGES.txt create mode 100644 docs/quick_tour/sessions/MANIFEST.in create mode 100644 docs/quick_tour/sessions/README.txt create mode 100644 docs/quick_tour/sessions/development.ini create mode 100644 docs/quick_tour/sessions/hello_world/__init__.py create mode 100644 docs/quick_tour/sessions/hello_world/static/pyramid-16x16.png create mode 100644 docs/quick_tour/sessions/hello_world/static/pyramid.png create mode 100644 docs/quick_tour/sessions/hello_world/static/theme.css create mode 100644 docs/quick_tour/sessions/hello_world/templates/layout.jinja2 create mode 100644 docs/quick_tour/sessions/hello_world/templates/mytemplate.jinja2 create mode 100644 docs/quick_tour/sessions/hello_world/tests.py create mode 100644 docs/quick_tour/sessions/hello_world/views.py create mode 100644 docs/quick_tour/sessions/production.ini create mode 100644 docs/quick_tour/sessions/pytest.ini create mode 100644 docs/quick_tour/sessions/setup.py diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index f5f722053..97f91d609 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -803,11 +803,10 @@ your own custom sessioning engine. Let's take a look at the :doc:`built-in sessioning support <../narr/sessions>`. In our ``__init__.py`` we first import the kind of sessioning we want: -.. literalinclude:: quick_tour/package/hello_world/__init__.py +.. literalinclude:: quick_tour/sessions/hello_world/__init__.py :language: python - :linenos: - :lineno-start: 2 - :lines: 2-3 + :lineno-match: + :lines: 1-2 :emphasize-lines: 2 .. warning:: @@ -818,31 +817,28 @@ the kind of sessioning we want: Now make a "factory" and pass it to the :term:`configurator`'s ``session_factory`` argument: -.. literalinclude:: quick_tour/package/hello_world/__init__.py +.. literalinclude:: quick_tour/sessions/hello_world/__init__.py :language: python - :linenos: - :lineno-start: 13 - :lines: 13-17 - :emphasize-lines: 3-5 + :lineno-match: + :lines: 10-13 + :emphasize-lines: 2-3 Pyramid's :term:`request` object now has a ``session`` attribute that we can use in our view code in ``views.py``: -.. literalinclude:: quick_tour/package/hello_world/views.py +.. literalinclude:: quick_tour/sessions/hello_world/views.py :language: python - :linenos: - :lineno-start: 9 - :lines: 9-15 + :lineno-match: + :lines: 7- :emphasize-lines: 3-7 -We need to update our Jinja2 template to show counter increment in the session: +We need to update our Jinja2 template ``templates/mytemplate.jinja2`` to show counter increment in the session: -.. literalinclude:: quick_tour/package/hello_world/templates/mytemplate.jinja2 +.. literalinclude:: quick_tour/sessions/hello_world/templates/mytemplate.jinja2 :language: jinja - :linenos: - :lineno-start: 40 - :lines: 40-42 - :emphasize-lines: 3 + :lineno-match: + :lines: 4-8 + :emphasize-lines: 4 .. seealso:: See also: :ref:`Quick Tutorial Sessions `, :ref:`sessions_chapter`, diff --git a/docs/quick_tour/sessions/.coveragerc b/docs/quick_tour/sessions/.coveragerc new file mode 100644 index 000000000..128e26410 --- /dev/null +++ b/docs/quick_tour/sessions/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = hello_world +omit = hello_world/test* diff --git a/docs/quick_tour/sessions/CHANGES.txt b/docs/quick_tour/sessions/CHANGES.txt new file mode 100644 index 000000000..14b902fd1 --- /dev/null +++ b/docs/quick_tour/sessions/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version. diff --git a/docs/quick_tour/sessions/MANIFEST.in b/docs/quick_tour/sessions/MANIFEST.in new file mode 100644 index 000000000..a75da6dad --- /dev/null +++ b/docs/quick_tour/sessions/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/quick_tour/sessions/README.txt b/docs/quick_tour/sessions/README.txt new file mode 100644 index 000000000..fb7bde0a7 --- /dev/null +++ b/docs/quick_tour/sessions/README.txt @@ -0,0 +1,29 @@ +hello_world +=============================== + +Getting Started +--------------- + +- Change directory into your newly created project. + + cd hello_world + +- Create a Python virtual environment. + + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/quick_tour/sessions/development.ini b/docs/quick_tour/sessions/development.ini new file mode 100644 index 000000000..1f19e373d --- /dev/null +++ b/docs/quick_tour/sessions/development.ini @@ -0,0 +1,59 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = 127.0.0.1:6543 [::1]:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/sessions/hello_world/__init__.py b/docs/quick_tour/sessions/hello_world/__init__.py new file mode 100644 index 000000000..7cdc55ebe --- /dev/null +++ b/docs/quick_tour/sessions/hello_world/__init__.py @@ -0,0 +1,14 @@ +from pyramid.config import Configurator +from pyramid.session import SignedCookieSessionFactory + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + config = Configurator(settings=settings) + config.include('pyramid_jinja2') + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + my_session_factory = SignedCookieSessionFactory('itsaseekreet') + config.set_session_factory(my_session_factory) + config.scan() + return config.make_wsgi_app() diff --git a/docs/quick_tour/sessions/hello_world/static/pyramid-16x16.png b/docs/quick_tour/sessions/hello_world/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/quick_tour/sessions/hello_world/static/pyramid-16x16.png differ diff --git a/docs/quick_tour/sessions/hello_world/static/pyramid.png b/docs/quick_tour/sessions/hello_world/static/pyramid.png new file mode 100644 index 000000000..4ab837be9 Binary files /dev/null and b/docs/quick_tour/sessions/hello_world/static/pyramid.png differ diff --git a/docs/quick_tour/sessions/hello_world/static/theme.css b/docs/quick_tour/sessions/hello_world/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/quick_tour/sessions/hello_world/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/quick_tour/sessions/hello_world/templates/layout.jinja2 b/docs/quick_tour/sessions/hello_world/templates/layout.jinja2 new file mode 100644 index 000000000..916127267 --- /dev/null +++ b/docs/quick_tour/sessions/hello_world/templates/layout.jinja2 @@ -0,0 +1,64 @@ + + + + + + + + + + + Cookiecutter Starter project for the Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + {% block content %} +

    No content

    + {% endblock content %} +
    +
    + +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/quick_tour/sessions/hello_world/templates/mytemplate.jinja2 b/docs/quick_tour/sessions/hello_world/templates/mytemplate.jinja2 new file mode 100644 index 000000000..c7776144c --- /dev/null +++ b/docs/quick_tour/sessions/hello_world/templates/mytemplate.jinja2 @@ -0,0 +1,9 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Starter project

    +

    Welcome to hello_world, a Pyramid application generated by
    Cookiecutter.

    +

    Counter: {{ request.session.counter }}

    +
    +{% endblock content %} diff --git a/docs/quick_tour/sessions/hello_world/tests.py b/docs/quick_tour/sessions/hello_world/tests.py new file mode 100644 index 000000000..ee9745685 --- /dev/null +++ b/docs/quick_tour/sessions/hello_world/tests.py @@ -0,0 +1,29 @@ +import unittest + +from pyramid import testing + + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], 'hello_world') + + +class FunctionalTests(unittest.TestCase): + def setUp(self): + from hello_world import main + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/quick_tour/sessions/hello_world/views.py b/docs/quick_tour/sessions/hello_world/views.py new file mode 100644 index 000000000..9716f854e --- /dev/null +++ b/docs/quick_tour/sessions/hello_world/views.py @@ -0,0 +1,14 @@ +from pyramid.view import view_config + +import logging +log = logging.getLogger(__name__) + +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') +def my_view(request): + log.debug('Some Message') + session = request.session + if 'counter' in session: + session['counter'] += 1 + else: + session['counter'] = 0 + return {'project': 'hello_world'} diff --git a/docs/quick_tour/sessions/production.ini b/docs/quick_tour/sessions/production.ini new file mode 100644 index 000000000..9c12bc4ec --- /dev/null +++ b/docs/quick_tour/sessions/production.ini @@ -0,0 +1,53 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_world + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = *:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_hello_world] +level = WARN +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/sessions/pytest.ini b/docs/quick_tour/sessions/pytest.ini new file mode 100644 index 000000000..f707d54e4 --- /dev/null +++ b/docs/quick_tour/sessions/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = hello_world +python_files = *.py diff --git a/docs/quick_tour/sessions/setup.py b/docs/quick_tour/sessions/setup.py new file mode 100644 index 000000000..e32aecacd --- /dev/null +++ b/docs/quick_tour/sessions/setup.py @@ -0,0 +1,51 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + +requires = [ + 'pyramid', + 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', +] + +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='hello_world', + version='0.0', + description='hello_world', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = hello_world:main', + ], + }, +) -- cgit v1.2.3 From b488f7f72ff36526cf21798c91c7f09eaf1afa7a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 03:46:31 -0800 Subject: quick_tour - "Databases" updates for cookiecutter - add src files - adjust line numbers --- docs/quick_tour.rst | 41 +++++++++--- docs/quick_tour/sqla_demo/CHANGES.txt | 2 +- docs/quick_tour/sqla_demo/MANIFEST.in | 2 +- docs/quick_tour/sqla_demo/README.txt | 31 +++++++-- docs/quick_tour/sqla_demo/development.ini | 1 - docs/quick_tour/sqla_demo/production.ini | 6 +- docs/quick_tour/sqla_demo/setup.cfg | 27 -------- docs/quick_tour/sqla_demo/setup.py | 63 ++++++++++-------- docs/quick_tour/sqla_demo/sqla_demo/__init__.py | 5 +- .../sqla_demo/sqla_demo/models/__init__.py | 74 ++++++++++++++++++++-- docs/quick_tour/sqla_demo/sqla_demo/models/meta.py | 33 ---------- .../sqla_demo/sqla_demo/models/mymodel.py | 5 +- .../sqla_demo/sqla_demo/scripts/initializedb.py | 18 +++--- .../sqla_demo/sqla_demo/templates/layout.jinja2 | 8 +-- .../sqla_demo/templates/mytemplate.jinja2 | 4 +- docs/quick_tour/sqla_demo/sqla_demo/tests.py | 16 ++--- .../sqla_demo/sqla_demo/views/default.py | 6 +- 17 files changed, 197 insertions(+), 145 deletions(-) delete mode 100644 docs/quick_tour/sqla_demo/setup.cfg diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 97f91d609..68ff76b47 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -519,7 +519,7 @@ If prompted for the first item, accept the default ``yes`` by hitting return. #. ``project_name [Pyramid Scaffold]: hello_world`` #. ``repo_name [scaffold]: hello_world`` -We then run through the following commands +We then run through the following commands. .. code-block:: bash @@ -532,7 +532,7 @@ We then run through the following commands # ...and into which we install our project and its testing requirements. $ env/bin/pip install -e ".[testing]" # Reset our environment variable for a new virtual environment. - $ export VENV=~/env/hello_world/env + $ export VENV=~/hello_world/env We are moving in the direction of a full-featured Pyramid project, with a proper setup for Python standards (packaging) and Pyramid configuration. This @@ -854,13 +854,34 @@ databases frequently mean an "ORM" (object-relational mapper.) In Python, ORM usually leads to the mega-quality *SQLAlchemy*, a Python package that greatly eases working with databases. -Pyramid and SQLAlchemy are great friends. That friendship includes a scaffold! +Pyramid and SQLAlchemy are great friends. That friendship includes a cookiecutter! .. code-block:: bash - $ $VENV/bin/pcreate --scaffold alchemy sqla_demo - $ cd sqla_demo - $ $VENV/bin/pip install -e . + $ cd ~ + $ env/bin/cookiecutter https://github.com/Pylons/pyramid-cookiecutter-alchemy + +If prompted for the first item, accept the default ``yes`` by hitting return. + +#. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-alchemy before. Is it + okay to delete and re-clone it? [yes]:`` +#. ``project_name [Pyramid Scaffold]: sqla_demo`` +#. ``repo_name [scaffold]: sqla_demo`` + +We then run through the following commands as before. + +.. code-block:: bash + + # Change directory into your newly created project. + $ cd sqla_demo + # Create a new virtual environment... + $ python3 -m venv env + # ...where we upgrade packaging tools... + $ env/bin/pip install --upgrade pip setuptools + # ...and into which we install our project and its testing requirements. + $ env/bin/pip install -e ".[testing]" + # Reset our environment variable for a new virtual environment. + $ export VENV=~/sqla_demo/env We now have a working sample SQLAlchemy application with all dependencies installed. The sample project provides a console script to initialize a SQLite @@ -877,16 +898,16 @@ model: .. literalinclude:: quick_tour/sqla_demo/sqla_demo/models/mymodel.py :language: python - :start-after: Start Sphinx Include - :end-before: End Sphinx Include + :lineno-match: + :pyobject: MyModel View code, which mediates the logic between web requests and the rest of the system, can then easily get at the data thanks to SQLAlchemy: .. literalinclude:: quick_tour/sqla_demo/sqla_demo/views/default.py :language: python - :start-after: Start Sphinx Include - :end-before: End Sphinx Include + :lineno-match: + :lines: 13 .. seealso:: See also: :ref:`Quick Tutorial Databases `, `SQLAlchemy diff --git a/docs/quick_tour/sqla_demo/CHANGES.txt b/docs/quick_tour/sqla_demo/CHANGES.txt index 35a34f332..14b902fd1 100644 --- a/docs/quick_tour/sqla_demo/CHANGES.txt +++ b/docs/quick_tour/sqla_demo/CHANGES.txt @@ -1,4 +1,4 @@ 0.0 --- -- Initial version +- Initial version. diff --git a/docs/quick_tour/sqla_demo/MANIFEST.in b/docs/quick_tour/sqla_demo/MANIFEST.in index a432577e9..e079655f9 100644 --- a/docs/quick_tour/sqla_demo/MANIFEST.in +++ b/docs/quick_tour/sqla_demo/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/quick_tour/sqla_demo/README.txt b/docs/quick_tour/sqla_demo/README.txt index b6d4c7798..1659e47ab 100644 --- a/docs/quick_tour/sqla_demo/README.txt +++ b/docs/quick_tour/sqla_demo/README.txt @@ -1,14 +1,33 @@ -sqla_demo README -================== +sqla_demo +=============================== Getting Started --------------- -- cd +- Change directory into your newly created project. -- $VENV/bin/pip install -e . + cd sqla_demo -- $VENV/bin/initialize_sqla_demo_db development.ini +- Create a Python virtual environment. -- $VENV/bin/pserve development.ini + python3 -m venv env +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Configure the database. + + env/bin/initialize_sqla_demo_db development.ini + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini index 918c26cfa..17b57fd0d 100644 --- a/docs/quick_tour/sqla_demo/development.ini +++ b/docs/quick_tour/sqla_demo/development.ini @@ -13,7 +13,6 @@ pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini index f4e535d46..a85c354d3 100644 --- a/docs/quick_tour/sqla_demo/production.ini +++ b/docs/quick_tour/sqla_demo/production.ini @@ -11,11 +11,13 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main listen = *:6543 diff --git a/docs/quick_tour/sqla_demo/setup.cfg b/docs/quick_tour/sqla_demo/setup.cfg deleted file mode 100644 index 9f91cd122..000000000 --- a/docs/quick_tour/sqla_demo/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=sqla_demo -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = sqla_demo/locale -domain = sqla_demo -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = sqla_demo/locale/sqla_demo.pot -width = 80 - -[init_catalog] -domain = sqla_demo -input_file = sqla_demo/locale/sqla_demo.pot -output_dir = sqla_demo/locale - -[update_catalog] -domain = sqla_demo -input_file = sqla_demo/locale/sqla_demo.pot -output_dir = sqla_demo/locale -previous = true diff --git a/docs/quick_tour/sqla_demo/setup.py b/docs/quick_tour/sqla_demo/setup.py index 312a97c06..75c1403fb 100644 --- a/docs/quick_tour/sqla_demo/setup.py +++ b/docs/quick_tour/sqla_demo/setup.py @@ -17,31 +17,42 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - ] +] -setup(name='sqla_demo', - version='0.0', - description='sqla_demo', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='sqla_demo', + version='0.0', + description='sqla_demo', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = sqla_demo:main', + ], + 'console_scripts': [ + 'initialize_sqla_demo_db = sqla_demo.scripts.initializedb:main', ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='sqla_demo', - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = sqla_demo:main - [console_scripts] - initialize_sqla_demo_db = sqla_demo.scripts.initializedb:main - """, - ) + }, +) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py index 7994bbfa8..4dab44823 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py @@ -6,8 +6,7 @@ def main(global_config, **settings): """ config = Configurator(settings=settings) config.include('pyramid_jinja2') - config.include('.models.meta') - config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('home', '/') + config.include('.models') + config.include('.routes') config.scan() return config.make_wsgi_app() diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py index 76e0fd26b..339326758 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py @@ -1,7 +1,73 @@ +from sqlalchemy import engine_from_config +from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import configure_mappers -# import all models classes here for sqlalchemy mappers -# to pick up -from .mymodel import MyModel # noqa +import zope.sqlalchemy -# run configure mappers to ensure we avoid any race conditions +# import or define all models here to ensure they are attached to the +# Base.metadata prior to any initialization routines +from .mymodel import MyModel # flake8: noqa + +# run configure_mappers after defining all of the models to ensure +# all relationships can be setup configure_mappers() + + +def get_engine(settings, prefix='sqlalchemy.'): + return engine_from_config(settings, prefix) + + +def get_session_factory(engine): + factory = sessionmaker() + factory.configure(bind=engine) + return factory + + +def get_tm_session(session_factory, transaction_manager): + """ + Get a ``sqlalchemy.orm.Session`` instance backed by a transaction. + + This function will hook the session to the transaction manager which + will take care of committing any changes. + + - When using pyramid_tm it will automatically be committed or aborted + depending on whether an exception is raised. + + - When using scripts you should wrap the session in a manager yourself. + For example:: + + import transaction + + engine = get_engine(settings) + session_factory = get_session_factory(engine) + with transaction.manager: + dbsession = get_tm_session(session_factory, transaction.manager) + + """ + dbsession = session_factory() + zope.sqlalchemy.register( + dbsession, transaction_manager=transaction_manager) + return dbsession + + +def includeme(config): + """ + Initialize the model for a Pyramid app. + + Activate this setup using ``config.include('sqla_demo.models')``. + + """ + settings = config.get_settings() + + # use pyramid_tm to hook the transaction lifecycle to the request + config.include('pyramid_tm') + + session_factory = get_session_factory(get_engine(settings)) + config.registry['dbsession_factory'] = session_factory + + # make request.dbsession available for use in Pyramid + config.add_request_method( + # r.tm is the transaction manager used by pyramid_tm + lambda r: get_tm_session(session_factory, r.tm), + 'dbsession', + reify=True + ) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py b/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py index 03c50ae93..0682247b5 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py @@ -1,8 +1,5 @@ -from sqlalchemy import engine_from_config from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import sessionmaker from sqlalchemy.schema import MetaData -import zope.sqlalchemy # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more @@ -17,33 +14,3 @@ NAMING_CONVENTION = { metadata = MetaData(naming_convention=NAMING_CONVENTION) Base = declarative_base(metadata=metadata) - - -def includeme(config): - settings = config.get_settings() - dbmaker = get_dbmaker(get_engine(settings)) - - config.add_request_method( - lambda r: get_session(r.tm, dbmaker), - 'dbsession', - reify=True - ) - - config.include('pyramid_tm') - - -def get_session(transaction_manager, dbmaker): - dbsession = dbmaker() - zope.sqlalchemy.register(dbsession, - transaction_manager=transaction_manager) - return dbsession - - -def get_engine(settings, prefix='sqlalchemy.'): - return engine_from_config(settings, prefix) - - -def get_dbmaker(engine): - dbmaker = sessionmaker() - dbmaker.configure(bind=engine) - return dbmaker diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py b/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py index eb645bfe6..d65a01a42 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py @@ -1,4 +1,3 @@ -from .meta import Base from sqlalchemy import ( Column, Index, @@ -6,14 +5,14 @@ from sqlalchemy import ( Text, ) +from .meta import Base + -# Start Sphinx Include class MyModel(Base): __tablename__ = 'models' id = Column(Integer, primary_key=True) name = Column(Text) value = Column(Integer) - # End Sphinx Include Index('my_index', MyModel.name, unique=True, mysql_length=255) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py index f0d09729e..7307ecc5c 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py @@ -9,13 +9,13 @@ from pyramid.paster import ( from pyramid.scripts.common import parse_vars -from ..models.meta import ( - Base, - get_session, +from ..models.meta import Base +from ..models import ( get_engine, - get_dbmaker, + get_session_factory, + get_tm_session, ) -from ..models.mymodel import MyModel +from ..models import MyModel def usage(argv): @@ -34,12 +34,12 @@ def main(argv=sys.argv): settings = get_appsettings(config_uri, options=options) engine = get_engine(settings) - dbmaker = get_dbmaker(engine) - - dbsession = get_session(transaction.manager, dbmaker) - Base.metadata.create_all(engine) + session_factory = get_session_factory(engine) + with transaction.manager: + dbsession = get_tm_session(session_factory, transaction.manager) + model = MyModel(name='one', value=1) dbsession.add(model) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 index 76a098122..4607eb11f 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 @@ -8,7 +8,7 @@ - Alchemy Scaffold for The Pyramid Web Framework + Cookiecutter Alchemy project for the Pyramid Web Framework @@ -29,7 +29,7 @@
    - +
    {% block content %} @@ -40,10 +40,8 @@
    diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 index bb622bf5a..bd00845d5 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %}
    -

    Pyramid Alchemy scaffold

    -

    Welcome to {{project}}, an application generated by
    the Pyramid Web Framework 1.7.dev0.

    +

    Pyramid Alchemy project

    +

    Welcome to sqla_demo, a Pyramid application generated by
    Cookiecutter.

    {% endblock content %} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/tests.py b/docs/quick_tour/sqla_demo/sqla_demo/tests.py index b6b6fdf4d..6db538ffd 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/tests.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/tests.py @@ -13,19 +13,19 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models.meta') + self.config.include('.models') settings = self.config.get_settings() - from .models.meta import ( - get_session, + from .models import ( get_engine, - get_dbmaker, + get_session_factory, + get_tm_session, ) self.engine = get_engine(settings) - dbmaker = get_dbmaker(self.engine) + session_factory = get_session_factory(self.engine) - self.session = get_session(transaction.manager, dbmaker) + self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): from .models.meta import Base @@ -36,7 +36,7 @@ class BaseTest(unittest.TestCase): testing.tearDown() transaction.abort() - Base.metadata.create_all(self.engine) + Base.metadata.drop_all(self.engine) class TestMyViewSuccessCondition(BaseTest): @@ -45,7 +45,7 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models.mymodel import MyModel + from .models import MyModel model = MyModel(name='one', value=55) self.session.add(model) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views/default.py b/docs/quick_tour/sqla_demo/sqla_demo/views/default.py index e5e70cf9d..d4afb1b0b 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/views/default.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/views/default.py @@ -3,18 +3,16 @@ from pyramid.view import view_config from sqlalchemy.exc import DBAPIError -from ..models.mymodel import MyModel +from ..models import MyModel @view_config(route_name='home', renderer='../templates/mytemplate.jinja2') def my_view(request): try: query = request.dbsession.query(MyModel) - # Start Sphinx Include one = query.filter(MyModel.name == 'one').first() - # End Sphinx Include except DBAPIError: - return Response(db_err_msg, content_type='text/plain', status_int=500) + return Response(db_err_msg, content_type='text/plain', status=500) return {'one': one, 'project': 'sqla_demo'} -- cgit v1.2.3 From 5fadd8838d922ccbd084421af51715992bce12ee Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 03:47:10 -0800 Subject: quick_tour - "Databases" updates for cookiecutter - add ALL src files --- docs/quick_tour/sqla_demo/.coveragerc | 3 +++ docs/quick_tour/sqla_demo/pytest.ini | 3 +++ docs/quick_tour/sqla_demo/sqla_demo/routes.py | 3 +++ docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 | 8 ++++++++ docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py | 7 +++++++ 5 files changed, 24 insertions(+) create mode 100644 docs/quick_tour/sqla_demo/.coveragerc create mode 100644 docs/quick_tour/sqla_demo/pytest.ini create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/routes.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py diff --git a/docs/quick_tour/sqla_demo/.coveragerc b/docs/quick_tour/sqla_demo/.coveragerc new file mode 100644 index 000000000..918f8dea0 --- /dev/null +++ b/docs/quick_tour/sqla_demo/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = sqla_demo +omit = sqla_demo/test* diff --git a/docs/quick_tour/sqla_demo/pytest.ini b/docs/quick_tour/sqla_demo/pytest.ini new file mode 100644 index 000000000..2d7535841 --- /dev/null +++ b/docs/quick_tour/sqla_demo/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = sqla_demo +python_files = *.py diff --git a/docs/quick_tour/sqla_demo/sqla_demo/routes.py b/docs/quick_tour/sqla_demo/sqla_demo/routes.py new file mode 100644 index 000000000..25504ad4d --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/routes.py @@ -0,0 +1,3 @@ +def includeme(config): + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 new file mode 100644 index 000000000..1917f83c7 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Alchemy scaffold

    +

    404 Page Not Found

    +
    +{% endblock content %} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py b/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py new file mode 100644 index 000000000..69d6e2804 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py @@ -0,0 +1,7 @@ +from pyramid.view import notfound_view_config + + +@notfound_view_config(renderer='../templates/404.jinja2') +def notfound_view(request): + request.response.status = 404 + return {} -- cgit v1.2.3 From a0ad6ffc14ef8dfde70e487fb057433ff942b001 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 03:57:14 -0800 Subject: quick_tour - "Forms" update for recent Deform changes --- docs/quick_tour.rst | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 68ff76b47..186cab29e 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -966,14 +966,10 @@ Deform and Colander provide a very flexible combination for forms, widgets, schemas, and validation. Recent versions of Deform also include a :ref:`retail mode ` for gaining Deform features on custom forms. -Also the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform widgets -using attractive CSS from Twitter Bootstrap and more powerful widgets from -Chosen. +Deform uses attractive CSS from Twitter Bootstrap and more powerful select, checkbox, and date and time widgets. .. seealso:: See also: - :ref:`Quick Tutorial Forms `, :ref:`Deform `, - :ref:`Colander `, and `deform_bootstrap - `_. + :ref:`Quick Tutorial Forms `, :ref:`Deform `, and :ref:`Colander `. Conclusion ========== -- cgit v1.2.3 From caee6c5c6125013e638cd38db5916c67fd0e7f26 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 04:38:42 -0800 Subject: quick_tutorial/requirements - add prompt --- docs/quick_tutorial/requirements.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index 913e08a62..f95dac488 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -172,7 +172,7 @@ time of its release. .. code-block:: bash # Mac and Linux - $VENV/bin/pip install --upgrade pip setuptools + $ $VENV/bin/pip install --upgrade pip setuptools .. code-block:: doscon -- cgit v1.2.3 From 910b8a085085fae3d8b44bca6f037fc61d4b10d0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Dec 2016 04:46:25 -0800 Subject: quick_tutorial/tutorial_approach - Fix up the process description to reflect reality --- docs/quick_tutorial/tutorial_approach.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/quick_tutorial/tutorial_approach.rst b/docs/quick_tutorial/tutorial_approach.rst index 49a6bfd85..d944aaebd 100644 --- a/docs/quick_tutorial/tutorial_approach.rst +++ b/docs/quick_tutorial/tutorial_approach.rst @@ -10,18 +10,17 @@ Details, references, and deeper discussions are mentioned in "See also" notes. This "Getting Started" tutorial is broken into independent steps, starting with the smallest possible "single file WSGI app" example. Each of these steps introduce a topic and a very small set of concepts via working code. The steps -each correspond to a directory in this repo, where each step/topic/directory is +each correspond to a directory in this repository, where each step's directory is a Python package. -To successfully run each step: +To successfully run each step, you'll usually copy the current step's directory to a new directory, change your working directory to the new directory, then install your project: .. code-block:: bash - $ cd request_response + $ cd ..; cp -r package ini; cd ini $ $VENV/bin/pip install -e . -...and repeat for each step you would like to work on. In most cases we will -start with the results of an earlier step. +For a few steps, you won't copy the step's directory. Directory tree ============== @@ -43,5 +42,5 @@ below: Each of the first-level directories (e.g., ``request_response``) is a *Python project* (except as noted for the ``hello_world`` step). The ``tutorial`` -directory is a *Python package*. At the end of each step, we copy a previous +directory is a *Python package*. At the start of each step, we usually copy a previous directory into a new directory to use as a starting point. -- cgit v1.2.3 From 6c3f4f8d0598cb62e37aa278e9c2c3e4194f8831 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 25 Dec 2016 19:51:55 -0600 Subject: enable zope.component tests on py3 --- pyramid/tests/test_testing.py | 51 ++++++++++--------------------------------- setup.py | 5 +---- 2 files changed, 13 insertions(+), 43 deletions(-) diff --git a/pyramid/tests/test_testing.py b/pyramid/tests/test_testing.py index 113f7e5f4..0b4619de4 100644 --- a/pyramid/tests/test_testing.py +++ b/pyramid/tests/test_testing.py @@ -1,4 +1,5 @@ import unittest +from zope.component import getSiteManager class TestDummyRootFactory(unittest.TestCase): def _makeOne(self, environ): @@ -320,22 +321,11 @@ class Test_setUp(unittest.TestCase): def tearDown(self): from pyramid.threadlocal import manager manager.clear() - getSiteManager = self._getSM() - if getSiteManager is not None: - getSiteManager.reset() - - def _getSM(self): - try: - from zope.component import getSiteManager - except ImportError: # pragma: no cover - getSiteManager = None - return getSiteManager + getSiteManager.reset() def _assertSMHook(self, hook): - getSiteManager = self._getSM() - if getSiteManager is not None: - result = getSiteManager.sethook(None) - self.assertEqual(result, hook) + result = getSiteManager.sethook(None) + self.assertEqual(result, hook) def test_it_defaults(self): from pyramid.threadlocal import manager @@ -375,10 +365,8 @@ class Test_setUp(unittest.TestCase): from pyramid.registry import Registry registry = Registry() self._callFUT(registry=registry, hook_zca=False) - getSiteManager = self._getSM() - if getSiteManager is not None: - sm = getSiteManager() - self.assertFalse(sm is registry) + sm = getSiteManager() + self.assertFalse(sm is registry) def test_it_with_settings_passed_explicit_registry(self): from pyramid.registry import Registry @@ -403,27 +391,14 @@ class Test_tearDown(unittest.TestCase): def tearDown(self): from pyramid.threadlocal import manager manager.clear() - getSiteManager = self._getSM() - if getSiteManager is not None: - getSiteManager.reset() - - def _getSM(self): - try: - from zope.component import getSiteManager - except ImportError: # pragma: no cover - getSiteManager = None - return getSiteManager + getSiteManager.reset() def _assertSMHook(self, hook): - getSiteManager = self._getSM() - if getSiteManager is not None: - result = getSiteManager.sethook(None) - self.assertEqual(result, hook) + result = getSiteManager.sethook(None) + self.assertEqual(result, hook) def _setSMHook(self, hook): - getSiteManager = self._getSM() - if getSiteManager is not None: - getSiteManager.sethook(hook) + getSiteManager.sethook(hook) def test_defaults(self): from pyramid.threadlocal import manager @@ -438,10 +413,8 @@ class Test_tearDown(unittest.TestCase): self.assertNotEqual(current, old) self.assertEqual(registry.inited, 2) finally: - getSiteManager = self._getSM() - if getSiteManager is not None: - result = getSiteManager.sethook(None) - self.assertNotEqual(result, hook) + result = getSiteManager.sethook(None) + self.assertNotEqual(result, hook) def test_registry_cannot_be_inited(self): from pyramid.threadlocal import manager diff --git a/setup.py b/setup.py index 63e82e707..687ed5700 100644 --- a/setup.py +++ b/setup.py @@ -20,8 +20,6 @@ from setuptools import setup, find_packages py_version = sys.version_info[:2] -PY2 = py_version[0] == 2 - if (3, 0) <= py_version < (3, 4): warnings.warn( 'On Python 3, Pyramid only supports Python 3.4 or better', @@ -53,10 +51,9 @@ install_requires = [ tests_require = [ 'WebTest >= 1.3.1', # py3 compat + 'zope.component >= 4.0', # py3 compat ] -if PY2: - tests_require.append('zope.component>=3.11.0') docs_extras = [ 'Sphinx >= 1.3.5', -- cgit v1.2.3 From 73b851a2bac7cf32a1d1df594a04cdd631e3391a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 25 Dec 2016 19:48:28 -0600 Subject: prep 1.8a1 --- README.rst | 4 ++-- contributing.md | 4 ++-- setup.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 6ef75e899..7179fa8db 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,9 @@ Pyramid ======= -.. image:: https://travis-ci.org/Pylons/pyramid.png?branch=master +.. image:: https://travis-ci.org/Pylons/pyramid.png?branch=1.8-branch :target: https://travis-ci.org/Pylons/pyramid - :alt: Master Travis CI Status + :alt: 1.8-branch Travis CI Status .. image:: https://readthedocs.org/projects/pyramid/badge/?version=master :target: http://docs.pylonsproject.org/projects/pyramid/en/master/ diff --git a/contributing.md b/contributing.md index b5f17ae06..9deeee035 100644 --- a/contributing.md +++ b/contributing.md @@ -26,9 +26,9 @@ listed below. * [master](https://github.com/Pylons/pyramid/) - The branch on which further development takes place. The default branch on GitHub. -* [1.7-branch](https://github.com/Pylons/pyramid/tree/1.7-branch) - The branch +* [1.8-branch](https://github.com/Pylons/pyramid/tree/1.8-branch) - The branch classified as "stable" or "latest". -* [1.6-branch](https://github.com/Pylons/pyramid/tree/1.6-branch) - The oldest +* [1.7-branch](https://github.com/Pylons/pyramid/tree/1.7-branch) - The oldest actively maintained and stable branch. Older branches are not actively maintained. In general, two stable branches and diff --git a/setup.py b/setup.py index 687ed5700..2439e59bc 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ testing_extras = tests_require + [ ] setup(name='pyramid', - version='1.8.dev0', + version='1.8a1', description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ -- cgit v1.2.3 From fc163d411bd57b232f68ed6554aff3a3ef8f2339 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 25 Dec 2016 20:20:14 -0600 Subject: fix changelog date --- CHANGES.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 55e56ff1a..48c4e4fe2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ -unreleased -========== +1.8a1 (2016-12-25) +================== Backward Incompatibilities -------------------------- @@ -257,4 +257,4 @@ Documentation Changes https://github.com/Pylons/pyramid/pull/2883. - Improve output of p* script descriptions for help. - See https://github.com/Pylons/pyramid/pull/2886 \ No newline at end of file + See https://github.com/Pylons/pyramid/pull/2886 -- cgit v1.2.3 From b00c4e46cafbaefa32288480477005caabf88bc9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Dec 2016 23:09:42 -0800 Subject: quick_tutorial/tutorial_approach - Fix up the process description to reflect reality, and improve flow --- docs/quick_tutorial/tutorial_approach.rst | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/quick_tutorial/tutorial_approach.rst b/docs/quick_tutorial/tutorial_approach.rst index d944aaebd..8da9f71b3 100644 --- a/docs/quick_tutorial/tutorial_approach.rst +++ b/docs/quick_tutorial/tutorial_approach.rst @@ -7,24 +7,16 @@ Details, references, and deeper discussions are mentioned in "See also" notes. .. seealso:: This is an example "See also" note. -This "Getting Started" tutorial is broken into independent steps, starting with -the smallest possible "single file WSGI app" example. Each of these steps -introduce a topic and a very small set of concepts via working code. The steps -each correspond to a directory in this repository, where each step's directory is -a Python package. - -To successfully run each step, you'll usually copy the current step's directory to a new directory, change your working directory to the new directory, then install your project: - -.. code-block:: bash - - $ cd ..; cp -r package ini; cd ini - $ $VENV/bin/pip install -e . - -For a few steps, you won't copy the step's directory. Directory tree ============== +This "Getting Started" tutorial is broken into independent steps, starting with +the smallest possible "single file WSGI app" example. Each of these steps +introduces a topic and a very small set of concepts via working code. The steps +each correspond to a directory in our workspace, where each step's directory is +a Python package. + As we develop our tutorial, our directory tree will resemble the structure below: @@ -40,7 +32,15 @@ below: │── development.ini `── setup.py -Each of the first-level directories (e.g., ``request_response``) is a *Python +Each of the directories in our ``quick_tutorial`` workspace (e.g., ``request_response``) is a *Python project* (except as noted for the ``hello_world`` step). The ``tutorial`` -directory is a *Python package*. At the start of each step, we usually copy a previous -directory into a new directory to use as a starting point. +directory is a *Python package*. + +For most steps you will copy the previous step's directory to a new directory, and change your working directory to the new directory, then install your project: + +.. code-block:: bash + + $ cd ..; cp -r package ini; cd ini + $ $VENV/bin/pip install -e . + +For a few steps, you won't copy the previous step's directory, but you will still need to install your project with ``$VENV/bin/pip install -e .``. -- cgit v1.2.3 From 558f3e772a1416ebdd9cd8122c0aeac3f0b0d72c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Dec 2016 23:11:28 -0800 Subject: quick_tutorial/cookiecutters - renamed from scaffolds - rewrite for use of cookiecutters instead of scaffolds - update source files --- docs/quick_tutorial/cookiecutters.rst | 79 +++++ docs/quick_tutorial/cookiecutters/.coveragerc | 3 + docs/quick_tutorial/cookiecutters/CHANGES.txt | 4 + docs/quick_tutorial/cookiecutters/MANIFEST.in | 2 + docs/quick_tutorial/cookiecutters/README.txt | 29 ++ .../cookiecutters/cc_starter/__init__.py | 12 + .../cc_starter/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../cookiecutters/cc_starter/static/pyramid.png | Bin 0 -> 12901 bytes .../cookiecutters/cc_starter/static/theme.css | 154 +++++++++ .../cc_starter/templates/layout.jinja2 | 64 ++++ .../cc_starter/templates/mytemplate.jinja2 | 8 + .../cookiecutters/cc_starter/tests.py | 29 ++ .../cookiecutters/cc_starter/views.py | 6 + docs/quick_tutorial/cookiecutters/development.ini | 59 ++++ docs/quick_tutorial/cookiecutters/production.ini | 53 +++ docs/quick_tutorial/cookiecutters/pytest.ini | 3 + docs/quick_tutorial/cookiecutters/setup.py | 51 +++ docs/quick_tutorial/index.rst | 2 +- docs/quick_tutorial/scaffolds.rst | 87 ----- docs/quick_tutorial/scaffolds/CHANGES.txt | 4 - docs/quick_tutorial/scaffolds/MANIFEST.in | 2 - docs/quick_tutorial/scaffolds/README.txt | 1 - docs/quick_tutorial/scaffolds/development.ini | 59 ---- docs/quick_tutorial/scaffolds/production.ini | 53 --- .../quick_tutorial/scaffolds/scaffolds/__init__.py | 12 - .../scaffolds/scaffolds/static/favicon.ico | Bin 1406 -> 0 bytes .../scaffolds/scaffolds/static/footerbg.png | Bin 333 -> 0 bytes .../scaffolds/scaffolds/static/headerbg.png | Bin 203 -> 0 bytes .../scaffolds/scaffolds/static/ie6.css | 8 - .../scaffolds/scaffolds/static/middlebg.png | Bin 2797 -> 0 bytes .../scaffolds/scaffolds/static/pylons.css | 372 --------------------- .../scaffolds/scaffolds/static/pyramid-small.png | Bin 7044 -> 0 bytes .../scaffolds/scaffolds/static/pyramid.png | Bin 33055 -> 0 bytes .../scaffolds/scaffolds/static/transparent.gif | Bin 49 -> 0 bytes .../scaffolds/scaffolds/templates/mytemplate.pt | 73 ---- docs/quick_tutorial/scaffolds/scaffolds/tests.py | 17 - docs/quick_tutorial/scaffolds/scaffolds/views.py | 6 - docs/quick_tutorial/scaffolds/setup.py | 42 --- 38 files changed, 557 insertions(+), 737 deletions(-) create mode 100644 docs/quick_tutorial/cookiecutters.rst create mode 100644 docs/quick_tutorial/cookiecutters/.coveragerc create mode 100644 docs/quick_tutorial/cookiecutters/CHANGES.txt create mode 100644 docs/quick_tutorial/cookiecutters/MANIFEST.in create mode 100644 docs/quick_tutorial/cookiecutters/README.txt create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/__init__.py create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid-16x16.png create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid.png create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/static/theme.css create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/templates/layout.jinja2 create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/templates/mytemplate.jinja2 create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/tests.py create mode 100644 docs/quick_tutorial/cookiecutters/cc_starter/views.py create mode 100644 docs/quick_tutorial/cookiecutters/development.ini create mode 100644 docs/quick_tutorial/cookiecutters/production.ini create mode 100644 docs/quick_tutorial/cookiecutters/pytest.ini create mode 100644 docs/quick_tutorial/cookiecutters/setup.py delete mode 100644 docs/quick_tutorial/scaffolds.rst delete mode 100644 docs/quick_tutorial/scaffolds/CHANGES.txt delete mode 100644 docs/quick_tutorial/scaffolds/MANIFEST.in delete mode 100644 docs/quick_tutorial/scaffolds/README.txt delete mode 100644 docs/quick_tutorial/scaffolds/development.ini delete mode 100644 docs/quick_tutorial/scaffolds/production.ini delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/__init__.py delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/favicon.ico delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/footerbg.png delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/headerbg.png delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/ie6.css delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/middlebg.png delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/pylons.css delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/pyramid-small.png delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/pyramid.png delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/static/transparent.gif delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/templates/mytemplate.pt delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/tests.py delete mode 100644 docs/quick_tutorial/scaffolds/scaffolds/views.py delete mode 100644 docs/quick_tutorial/scaffolds/setup.py diff --git a/docs/quick_tutorial/cookiecutters.rst b/docs/quick_tutorial/cookiecutters.rst new file mode 100644 index 000000000..8e7048f78 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters.rst @@ -0,0 +1,79 @@ +.. _qtut_cookiecutters: + +================================================= +Prelude: Quick Project Startup with Cookiecutters +================================================= + +To ease the process of getting started on a project, the Pylons Project provides :term:`cookiecutter`\ s that generate sample :app:`Pyramid` projects from project templates. These cookiecutters will install :app:`Pyramid` and its dependencies as well. We will still cover many topics of web application development using :app:`Pyramid`, but it's good to know of this facility. This prelude will demonstrate how to get a working :app:`Pyramid` web application running via ``cookiecutter``. + + +Objectives +========== + +- Use a cookiecutter to make a new project. + +- Start up a :app:`Pyramid` application and visit it in a web browser. + + +Steps +===== + +#. Install cookiecutter into your virtual environment. + + .. code-block:: bash + + $VENV/bin/pip install cookiecutter + +#. Let's use the cookiecutter ``pyramid-cookiecutter-starter`` to create a starter :app:`Pyramid` project in the current directory, entering values at the prompts as shown below for the following command. + + .. code-block:: bash + + $ $VENV/bin/cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter + + If prompted for the first item, accept the default ``yes`` by hitting return. + + #. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before. Is it okay to delete and re-clone it? [yes]:`` + #. ``project_name [Pyramid Scaffold]: cc_starter`` + #. ``repo_name [scaffold]: cc_starter`` + +#. We then run through the following commands. + + .. code-block:: bash + + # Change directory into your newly created project. + $ cd cc_starter + # Create a new virtual environment... + $ python3 -m venv env + # ...where we upgrade packaging tools... + $ env/bin/pip install --upgrade pip setuptools + # ...and into which we install our project. + $ env/bin/pip install -e . + +#. Start up the application by pointing :app:`Pyramid`'s ``pserve`` command at the + project's (generated) configuration file: + + .. code-block:: bash + + $ env/bin/pserve development.ini --reload + + On start up, ``pserve`` logs some output: + + .. code-block:: text + + Starting subprocess with file monitor + Starting server in PID 73732. + Serving on http://localhost:6543 + Serving on http://localhost:6543 + +#. Open http://localhost:6543/ in your browser. + +Analysis +======== + +Rather than starting from scratch, a cookiecutter can make it easy to get a Python +project containing a working :app:`Pyramid` application. The Pylons Project provides `several cookiecutters `_. + +``pserve`` is :app:`Pyramid`'s application runner, separating operational details from +your code. When you install :app:`Pyramid`, a small command program called ``pserve`` +is written to your ``bin`` directory. This program is an executable Python +module. It is passed a configuration file (in this case, ``development.ini``). diff --git a/docs/quick_tutorial/cookiecutters/.coveragerc b/docs/quick_tutorial/cookiecutters/.coveragerc new file mode 100644 index 000000000..1bcbb8c3e --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = cc_starter +omit = cc_starter/test* diff --git a/docs/quick_tutorial/cookiecutters/CHANGES.txt b/docs/quick_tutorial/cookiecutters/CHANGES.txt new file mode 100644 index 000000000..14b902fd1 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version. diff --git a/docs/quick_tutorial/cookiecutters/MANIFEST.in b/docs/quick_tutorial/cookiecutters/MANIFEST.in new file mode 100644 index 000000000..79c7ec16c --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include cc_starter *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/quick_tutorial/cookiecutters/README.txt b/docs/quick_tutorial/cookiecutters/README.txt new file mode 100644 index 000000000..4b1f31bf3 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/README.txt @@ -0,0 +1,29 @@ +cc_starter +=============================== + +Getting Started +--------------- + +- Change directory into your newly created project. + + cd cc_starter + +- Create a Python virtual environment. + + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/__init__.py b/docs/quick_tutorial/cookiecutters/cc_starter/__init__.py new file mode 100644 index 000000000..49dde36d4 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/cc_starter/__init__.py @@ -0,0 +1,12 @@ +from pyramid.config import Configurator + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + config = Configurator(settings=settings) + config.include('pyramid_jinja2') + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid-16x16.png b/docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid-16x16.png differ diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid.png b/docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid.png new file mode 100644 index 000000000..4ab837be9 Binary files /dev/null and b/docs/quick_tutorial/cookiecutters/cc_starter/static/pyramid.png differ diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/static/theme.css b/docs/quick_tutorial/cookiecutters/cc_starter/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/cc_starter/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/templates/layout.jinja2 b/docs/quick_tutorial/cookiecutters/cc_starter/templates/layout.jinja2 new file mode 100644 index 000000000..20da74879 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/cc_starter/templates/layout.jinja2 @@ -0,0 +1,64 @@ + + + + + + + + + + + Cookiecutter Starter project for the Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + {% block content %} +

    No content

    + {% endblock content %} +
    +
    + +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/templates/mytemplate.jinja2 b/docs/quick_tutorial/cookiecutters/cc_starter/templates/mytemplate.jinja2 new file mode 100644 index 000000000..979ee5071 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/cc_starter/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Starter project

    +

    Welcome to cc_starter, a Pyramid application generated by
    Cookiecutter.

    +
    +{% endblock content %} diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/tests.py b/docs/quick_tutorial/cookiecutters/cc_starter/tests.py new file mode 100644 index 000000000..2f553bbb4 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/cc_starter/tests.py @@ -0,0 +1,29 @@ +import unittest + +from pyramid import testing + + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], 'cc_starter') + + +class FunctionalTests(unittest.TestCase): + def setUp(self): + from cc_starter import main + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/views.py b/docs/quick_tutorial/cookiecutters/cc_starter/views.py new file mode 100644 index 000000000..deedd53b8 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/cc_starter/views.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + + +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') +def my_view(request): + return {'project': 'cc_starter'} diff --git a/docs/quick_tutorial/cookiecutters/development.ini b/docs/quick_tutorial/cookiecutters/development.ini new file mode 100644 index 000000000..86b54b51d --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/development.ini @@ -0,0 +1,59 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:cc_starter + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = 127.0.0.1:6543 [::1]:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, cc_starter + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_cc_starter] +level = DEBUG +handlers = +qualname = cc_starter + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tutorial/cookiecutters/production.ini b/docs/quick_tutorial/cookiecutters/production.ini new file mode 100644 index 000000000..e24a065b1 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/production.ini @@ -0,0 +1,53 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:cc_starter + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = *:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, cc_starter + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_cc_starter] +level = WARN +handlers = +qualname = cc_starter + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/quick_tutorial/cookiecutters/pytest.ini b/docs/quick_tutorial/cookiecutters/pytest.ini new file mode 100644 index 000000000..a7bd797f0 --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = cc_starter +python_files = *.py diff --git a/docs/quick_tutorial/cookiecutters/setup.py b/docs/quick_tutorial/cookiecutters/setup.py new file mode 100644 index 000000000..e47cdf8ea --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/setup.py @@ -0,0 +1,51 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + +requires = [ + 'pyramid', + 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', +] + +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='cc_starter', + version='0.0', + description='cc_starter', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = cc_starter:main', + ], + }, +) diff --git a/docs/quick_tutorial/index.rst b/docs/quick_tutorial/index.rst index 29b4d8fb7..b5b7b3313 100644 --- a/docs/quick_tutorial/index.rst +++ b/docs/quick_tutorial/index.rst @@ -19,7 +19,7 @@ Contents requirements tutorial_approach - scaffolds + cookiecutters hello_world package ini diff --git a/docs/quick_tutorial/scaffolds.rst b/docs/quick_tutorial/scaffolds.rst deleted file mode 100644 index 8712d64e9..000000000 --- a/docs/quick_tutorial/scaffolds.rst +++ /dev/null @@ -1,87 +0,0 @@ -.. _qtut_cookiecutters: - -============================================= -Prelude: Quick Project Startup with Scaffolds -============================================= - -To ease the process of getting started, Pyramid provides *scaffolds* that -generate sample projects from templates in Pyramid and Pyramid add-ons. - - -Background -========== - -We're going to cover a lot in this tutorial, focusing on one topic at a time -and writing everything from scratch. As a warm up, though, it sure would be -nice to see some pixels on a screen. - -Like other web development frameworks, Pyramid provides a number of "scaffolds" -that generate working Python, template, and CSS code for sample applications. -In this step we'll use a built-in scaffold to let us preview a Pyramid -application, before starting from scratch on Step 1. - - -Objectives -========== - -- Use Pyramid's ``pcreate`` command to list scaffolds and make a new project. - -- Start up a Pyramid application and visit it in a web browser. - - -Steps -===== - -#. Pyramid's ``pcreate`` command can list the available scaffolds: - - .. code-block:: bash - - $ $VENV/bin/pcreate --list - Available scaffolds: - alchemy: Pyramid project using SQLAlchemy, SQLite, URL dispatch, and Jinja2 - starter: Pyramid starter project using URL dispatch and Chameleon - zodb: Pyramid project using ZODB, traversal, and Chameleon - -#. Tell ``pcreate`` to use the ``starter`` scaffold to make our project: - - .. code-block:: bash - - $ $VENV/bin/pcreate --scaffold starter scaffolds - -#. Install our project in editable mode for development in the current - directory: - - .. code-block:: bash - - $ cd scaffolds - $ $VENV/bin/pip install -e . - -#. Start up the application by pointing Pyramid's ``pserve`` command at the - project's (generated) configuration file: - - .. code-block:: bash - - $ $VENV/bin/pserve development.ini --reload - - On start up, ``pserve`` logs some output: - - .. code-block:: bash - - Starting subprocess with file monitor - Starting server in PID 72213. - Starting HTTP server on http://0.0.0.0:6543 - -#. Open http://localhost:6543/ in your browser. - -Analysis -======== - -Rather than starting from scratch, ``pcreate`` can make getting a Python -project containing a Pyramid application a quick matter. Pyramid ships with a -few scaffolds. But installing a Pyramid add-on can give you new scaffolds from -that add-on. - -``pserve`` is Pyramid's application runner, separating operational details from -your code. When you install Pyramid, a small command program called ``pserve`` -is written to your ``bin`` directory. This program is an executable Python -module. It is passed a configuration file (in this case, ``development.ini``). diff --git a/docs/quick_tutorial/scaffolds/CHANGES.txt b/docs/quick_tutorial/scaffolds/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/quick_tutorial/scaffolds/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/quick_tutorial/scaffolds/MANIFEST.in b/docs/quick_tutorial/scaffolds/MANIFEST.in deleted file mode 100644 index 91d3f763b..000000000 --- a/docs/quick_tutorial/scaffolds/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include scaffolds *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/quick_tutorial/scaffolds/README.txt b/docs/quick_tutorial/scaffolds/README.txt deleted file mode 100644 index 7776dd2d5..000000000 --- a/docs/quick_tutorial/scaffolds/README.txt +++ /dev/null @@ -1 +0,0 @@ -scaffolds README diff --git a/docs/quick_tutorial/scaffolds/development.ini b/docs/quick_tutorial/scaffolds/development.ini deleted file mode 100644 index 0f562d0e1..000000000 --- a/docs/quick_tutorial/scaffolds/development.ini +++ /dev/null @@ -1,59 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:scaffolds - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_debugtoolbar - -# By default, the toolbar only appears for clients from IP addresses -# '127.0.0.1' and '::1'. -# debugtoolbar.hosts = 127.0.0.1 ::1 - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -listen = *:6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, scaffolds - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_scaffolds] -level = DEBUG -handlers = -qualname = scaffolds - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/quick_tutorial/scaffolds/production.ini b/docs/quick_tutorial/scaffolds/production.ini deleted file mode 100644 index bf0446a47..000000000 --- a/docs/quick_tutorial/scaffolds/production.ini +++ /dev/null @@ -1,53 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:scaffolds - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -listen = *:6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, scaffolds - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_scaffolds] -level = WARN -handlers = -qualname = scaffolds - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/quick_tutorial/scaffolds/scaffolds/__init__.py b/docs/quick_tutorial/scaffolds/scaffolds/__init__.py deleted file mode 100644 index ad5ecbc6f..000000000 --- a/docs/quick_tutorial/scaffolds/scaffolds/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -from pyramid.config import Configurator - - -def main(global_config, **settings): - """ This function returns a Pyramid WSGI application. - """ - config = Configurator(settings=settings) - config.include('pyramid_chameleon') - config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('home', '/') - config.scan() - return config.make_wsgi_app() diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/favicon.ico b/docs/quick_tutorial/scaffolds/scaffolds/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/favicon.ico and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/footerbg.png b/docs/quick_tutorial/scaffolds/scaffolds/static/footerbg.png deleted file mode 100644 index 1fbc873da..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/footerbg.png and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/headerbg.png b/docs/quick_tutorial/scaffolds/scaffolds/static/headerbg.png deleted file mode 100644 index 0596f2020..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/headerbg.png and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/ie6.css b/docs/quick_tutorial/scaffolds/scaffolds/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/quick_tutorial/scaffolds/scaffolds/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} -#wrap{display:table;height:100%} diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/middlebg.png b/docs/quick_tutorial/scaffolds/scaffolds/static/middlebg.png deleted file mode 100644 index 2369cfb7d..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/middlebg.png and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/pylons.css b/docs/quick_tutorial/scaffolds/scaffolds/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/quick_tutorial/scaffolds/scaffolds/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -ul, menu, dir -{ - display: block; - list-style-type: disc; - margin: 1em 0; - padding-left: 40px; -} - -ol -{ - display: block; - list-style-type: decimal-leading-zero; - margin: 1em 0; - padding-left: 40px; -} - -li -{ - display: list-item; -} - -ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl -{ - margin-top: 0; - margin-bottom: 0; -} - -ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir -{ - list-style-type: circle; -} - -ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir -{ - list-style-type: square; -} - -.hidden -{ - display: none; -} - -p -{ - line-height: 1.5em; -} - -h1 -{ - font-size: 1.75em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h2 -{ - font-size: 1.5em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h3 -{ - font-size: 1.25em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h4 -{ - font-size: 1em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -html, body -{ - width: 100%; - height: 100%; -} - -body -{ - margin: 0; - padding: 0; - background-color: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 url(footerbg.png) repeat-x 0 top; - position: relative; - margin-top: -40px; - clear: both; -} - -.header, .footer -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.wrapper -{ - width: 100%; -} - -#top, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.top, .top-small, .middle, .bottom -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.top -{ - padding-top: 40px; -} - -.top-small -{ - padding-top: 10px; -} - -#middle -{ - width: 100%; - height: 100px; - background: url(middlebg.png) repeat-x; - border-top: 2px solid #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#left -{ - width: 350px; - float: left; - padding-right: 25px; -} - -#right -{ - width: 350px; - float: right; - padding-left: 25px; -} - -.align-left -{ - text-align: left; -} - -.align-right -{ - text-align: right; -} - -.align-center -{ - text-align: center; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -ul.links li -{ - list-style-type: none; - font-size: 14px; -} - -form -{ - border-style: none; -} - -fieldset -{ - border-style: none; -} - -input -{ - color: #222; - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 12px; - line-height: 16px; -} - -input[type=text], input[type=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/pyramid-small.png b/docs/quick_tutorial/scaffolds/scaffolds/static/pyramid-small.png deleted file mode 100644 index a5bc0ade7..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/pyramid-small.png and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/pyramid.png b/docs/quick_tutorial/scaffolds/scaffolds/static/pyramid.png deleted file mode 100644 index 347e05549..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/pyramid.png and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/static/transparent.gif b/docs/quick_tutorial/scaffolds/scaffolds/static/transparent.gif deleted file mode 100644 index 0341802e5..000000000 Binary files a/docs/quick_tutorial/scaffolds/scaffolds/static/transparent.gif and /dev/null differ diff --git a/docs/quick_tutorial/scaffolds/scaffolds/templates/mytemplate.pt b/docs/quick_tutorial/scaffolds/scaffolds/templates/mytemplate.pt deleted file mode 100644 index b43a174e3..000000000 --- a/docs/quick_tutorial/scaffolds/scaffolds/templates/mytemplate.pt +++ /dev/null @@ -1,73 +0,0 @@ - - - - The Pyramid Web Framework - - - - - - - - - - -
    -
    -
    -
    pyramid
    -
    -
    -
    -
    -

    - Welcome to ${project}, an application generated by
    - the Pyramid Web Framework. -

    -
    -
    -
    -
    -
    -

    Search documentation

    -
    - - -
    -
    - -
    -
    -
    - - diff --git a/docs/quick_tutorial/scaffolds/scaffolds/tests.py b/docs/quick_tutorial/scaffolds/scaffolds/tests.py deleted file mode 100644 index 4f906ffa9..000000000 --- a/docs/quick_tutorial/scaffolds/scaffolds/tests.py +++ /dev/null @@ -1,17 +0,0 @@ -import unittest - -from pyramid import testing - - -class ViewTests(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from .views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['project'], 'scaffolds') diff --git a/docs/quick_tutorial/scaffolds/scaffolds/views.py b/docs/quick_tutorial/scaffolds/scaffolds/views.py deleted file mode 100644 index db90d8364..000000000 --- a/docs/quick_tutorial/scaffolds/scaffolds/views.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config - - -@view_config(route_name='home', renderer='templates/mytemplate.pt') -def my_view(request): - return {'project': 'scaffolds'} diff --git a/docs/quick_tutorial/scaffolds/setup.py b/docs/quick_tutorial/scaffolds/setup.py deleted file mode 100644 index ec95946a5..000000000 --- a/docs/quick_tutorial/scaffolds/setup.py +++ /dev/null @@ -1,42 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(here, 'README.txt')) as f: - README = f.read() -with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() - -requires = [ - 'pyramid', - 'pyramid_chameleon', - 'pyramid_debugtoolbar', - 'waitress', - ] - -setup(name='scaffolds', - version='0.0', - description='scaffolds', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="scaffolds", - entry_points="""\ - [paste.app_factory] - main = scaffolds:main - """, - ) -- cgit v1.2.3 From 99d45a935a4fe6a9e9d1df364e74f536a418e105 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Dec 2016 23:16:49 -0800 Subject: quick_tutorial/hello_world - minor update for cd into current directory. - modernize "microframework" --- docs/quick_tutorial/hello_world.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quick_tutorial/hello_world.rst b/docs/quick_tutorial/hello_world.rst index 56dccde58..2f2515fcd 100644 --- a/docs/quick_tutorial/hello_world.rst +++ b/docs/quick_tutorial/hello_world.rst @@ -11,7 +11,7 @@ Python packages, no ``pip install -e .``, no other machinery. Background ========== -Microframeworks are all the rage these days. "Microframework" is a marketing +Microframeworks were all the rage, until the next shiny thing came along. "Microframework" is a marketing term, not a technical one. They have a low mental overhead: they do so little, the only things you have to worry about are *your things*. @@ -49,7 +49,7 @@ Steps .. code-block:: bash - $ mkdir hello_world; cd hello_world + $ cd ~/projects/quick_tutorial; mkdir hello_world; cd hello_world #. Copy the following into ``hello_world/app.py``: -- cgit v1.2.3 From 6261ae4fbf73cb9e72aea2b8f67c6b04e5c474a6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Dec 2016 23:59:14 -0800 Subject: narr/cookiecutters - add narr/scaffolding - update index - add link to narr/cookiecutters --- docs/index.rst | 1 + docs/narr/cookiecutters.rst | 20 ++++++++++++++++++++ docs/narr/scaffolding.rst | 4 ++++ 3 files changed, 25 insertions(+) create mode 100644 docs/narr/cookiecutters.rst diff --git a/docs/index.rst b/docs/index.rst index 60dcdcc9c..668347744 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -145,6 +145,7 @@ Narrative documentation in chapter form explaining how to use :app:`Pyramid`. narr/extending narr/advconfig narr/extconfig + narr/cookiecutters narr/scaffolding narr/upgrading narr/threadlocals diff --git a/docs/narr/cookiecutters.rst b/docs/narr/cookiecutters.rst new file mode 100644 index 000000000..bb4c61616 --- /dev/null +++ b/docs/narr/cookiecutters.rst @@ -0,0 +1,20 @@ +.. _cookiecutters: + +Pyramid cookiecutters +===================== + +.. versionadded:: 1.8 + +A :term:`cookiecutter` is a command-line utility that creates projects from :ref:`cookiecutters ` (project templates), e.g., creating a Python package project from a Python package project template. + +Pyramid cookiecutters have replaced the now deprecated Pyramid scaffolds, and should be used going forward. Pyramid cookiecutters released under the Pylons Project include: + +* `pyramid-cookiecutter-alchemy `_ +* `pyramid-cookiecutter-starter `_ +* `pyramid-cookiecutter-zodb `_ + +Development of cookiecutters is documented under `Learn the Basics of Cookiecutter by Creating a Cookiecutter `_. + +.. seealso:: See also `Cookiecutter Features `_. + +.. seealso:: See also :term:`scaffold`. diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 164ceb3bf..27239d34e 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -3,6 +3,10 @@ Creating Pyramid Scaffolds ========================== +.. deprecated:: 1.8 + + Scaffolds and the ``pcreate`` script used to generate :app:`Pyramid` projects from scaffolds have been deprecated. Use :ref:`cookiecutters` instead. + You can extend Pyramid by creating a :term:`scaffold` template. A scaffold template is useful if you'd like to distribute a customizable configuration of Pyramid to other users. Once you've created a scaffold, and someone has -- cgit v1.2.3 From f698dd71af8af59d4a18e274189a58ba0f66a7b7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:02:39 -0800 Subject: narr/assets - update --- docs/narr/assets.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 58f547fc9..f5a2f9684 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -28,7 +28,7 @@ asset: The use of assets is quite common in most web development projects. For example, when you create a :app:`Pyramid` application using one of the -available scaffolds, as described in :ref:`creating_a_project`, the directory +available :term:`cookiecutter`\ s, as described in :ref:`creating_a_project`, the directory representing the application contains a Python :term:`package`. Within that Python package, there are directories full of files which are static assets. For example, there's a ``static`` directory which contains ``.css``, ``.js``, -- cgit v1.2.3 From b0b2b0772a9e5b5767404a88f9d8da987f9afed4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:03:26 -0800 Subject: narr/extending - update --- docs/narr/extending.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index 9dc042024..bee30ec1a 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -190,7 +190,7 @@ The general pattern for extending an existing application looks something like this: - Create a new Python package. The easiest way to do this is to create a new - :app:`Pyramid` application using the scaffold mechanism. See + :app:`Pyramid` application using a :term:`cookiecutter`. See :ref:`creating_a_project` for more information. - In the new package, create Python files containing views and other overridden -- cgit v1.2.3 From 6b3f9e5846879e7335c38eaf629500a1f6a97435 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:09:35 -0800 Subject: narr/install - update --- docs/narr/install.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c3c2ba64c..10173aec8 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -260,5 +260,5 @@ What Gets Installed When you install :app:`Pyramid`, various libraries such as WebOb, PasteDeploy, and others are installed. -Additionally, as chronicled in :ref:`project_narr`, scaffolds will be -registered, which make it easy to start a new :app:`Pyramid` project. +Additionally, as chronicled in :ref:`project_narr`, :term:`cookiecutter`\ s will be +used, which make it easy to start a new :app:`Pyramid` project. -- cgit v1.2.3 From 0ff74073d3efc787a6fde1818d05f4aa9227d243 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:11:15 -0800 Subject: narr/introduction - update --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index adad196e4..7027d6601 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -182,7 +182,7 @@ available. Pyramid can automatically utilize changed templates when rendering pages and automatically restart the application to incorporate changed Python code. Plain old ``print()`` calls used for debugging can display to a console. -Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to +Pyramid's debug toolbar comes activated when you use a Pyramid :term:`cookiecutter` to render a project. This toolbar overlays your application in the browser, and allows you access to framework data, such as the routes configured, the last renderings performed, the current set of packages installed, SQLAlchemy queries @@ -494,7 +494,7 @@ Example: :ref:`view_configuration_parameters`. Transaction management ~~~~~~~~~~~~~~~~~~~~~~ -Pyramid's :term:`scaffold` system renders projects that include a *transaction +A couple of Pyramid's :term:`cookiecutter`\ s include a *transaction management* system, stolen from Zope. When you use this transaction management system, you cease being responsible for committing your data anymore. Instead Pyramid takes care of committing: it commits at the end of a request or aborts -- cgit v1.2.3 From 2d35e2fd2d893f580052e8c5840a9238edaecacd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:25:55 -0800 Subject: narr/logging - update --- docs/narr/logging.rst | 106 ++++++++------------------------------------------ 1 file changed, 16 insertions(+), 90 deletions(-) diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index c7b4b9d6f..f2c990861 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -9,11 +9,11 @@ to send log messages to loggers that you've configured. .. warning:: - This chapter assumes you've used a :term:`scaffold` to create a project + This chapter assumes you've used a :term:`cookiecutter` to create a project which contains ``development.ini`` and ``production.ini`` files which help - configure logging. All of the scaffolds which ship with :app:`Pyramid` do - this. If you're not using a scaffold, or if you've used a third-party - scaffold which does not create these files, the configuration information in + configure logging. All of the Pyramid cookiecutters provided by the Pylons Project do + this. If you're not using a cookiecutter, or if you've used a third-party + cookiecutter which does not create these files, the configuration information in this chapter may not be applicable. .. index: @@ -26,11 +26,11 @@ to send log messages to loggers that you've configured. Logging Configuration --------------------- -A :app:`Pyramid` project created from a :term:`scaffold` is configured to allow +A :app:`Pyramid` project created from a :term:`cookiecutter` is configured to allow you to send messages to :mod:`Python standard library logging package ` loggers from within your application. In particular, the :term:`PasteDeploy` ``development.ini`` and ``production.ini`` files created -when you use a scaffold include a basic configuration for the Python +when you use a cookiecutter include a basic configuration for the Python :mod:`logging` package. PasteDeploy ``.ini`` files use the Python standard library :mod:`ConfigParser @@ -43,94 +43,20 @@ from when you run ``pserve``. The ``pserve`` command calls the :func:`pyramid.paster.setup_logging` function, a thin wrapper around the :func:`logging.config.fileConfig` using the specified ``.ini`` file, if it contains a ``[loggers]`` section (all of the -scaffold-generated ``.ini`` files do). ``setup_logging`` reads the logging +cookiecutter-generated ``.ini`` files do). ``setup_logging`` reads the logging configuration from the ini file upon which ``pserve`` was invoked. Default logging configuration is provided in both the default -``development.ini`` and the ``production.ini`` file. The logging configuration +``development.ini`` and the ``production.ini`` files. If you use ``pyramid-cookiecutter-starter`` to generate a Pyramid project with the name of the package as ``hello_world``, then the logging configuration in the ``development.ini`` file is as follows: -.. code-block:: ini - :linenos: - - # Begin logging configuration - - [loggers] - keys = root, {{package_logger}} - - [handlers] - keys = console - - [formatters] - keys = generic - - [logger_root] - level = INFO - handlers = console - - [logger_{{package_logger}}] - level = DEBUG - handlers = - qualname = {{package}} - - [handler_console] - class = StreamHandler - args = (sys.stderr,) - level = NOTSET - formatter = generic - - [formatter_generic] - format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - - # End logging configuration +.. literalinclude:: ../quick_tour/package/development.ini + :language: ini + :lineno-match: + :lines: 29- The ``production.ini`` file uses the ``WARN`` level in its logger -configuration, but it is otherwise identical. - -The name ``{{package_logger}}`` above will be replaced with the name of your -project's :term:`package`, which is derived from the name you provide to your -project. For instance, if you do: - -.. code-block:: text - :linenos: - - pcreate -s starter MyApp - -The logging configuration will literally be: - -.. code-block:: ini - :linenos: - - # Begin logging configuration - - [loggers] - keys = root, myapp - - [handlers] - keys = console - - [formatters] - keys = generic - - [logger_root] - level = INFO - handlers = console - - [logger_myapp] - level = DEBUG - handlers = - qualname = myapp - - [handler_console] - class = StreamHandler - args = (sys.stderr,) - level = NOTSET - formatter = generic - - [formatter_generic] - format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - - # End logging configuration +configuration instead of ``DEBUG``, but it is otherwise identical. In this logging configuration: @@ -149,7 +75,7 @@ that ask for a logger (via ``logging.getLogger``) that has a name which begins with anything except your project's package name (e.g., ``myapp``). The logger with the same name as your package name is reserved for your own usage in your :app:`Pyramid` application. Its existence means that you can log to a known -logging location from any :app:`Pyramid` application generated via a scaffold. +logging location from any :app:`Pyramid` application generated via a cookiecutter. :app:`Pyramid` and many other libraries (such as Beaker, SQLAlchemy, Paste) log a number of messages to the root logger for debugging purposes. Switching the @@ -162,9 +88,9 @@ root logger level to ``DEBUG`` reveals them: level = DEBUG handlers = console -Some scaffolds configure additional loggers for additional subsystems they use +Some cookiecutters configure additional loggers for additional subsystems they use (such as SQLALchemy). Take a look at the ``production.ini`` and -``development.ini`` files rendered when you create a project from a scaffold. +``development.ini`` files rendered when you create a project from a cookiecutter. Sending Logging Messages ------------------------ -- cgit v1.2.3 From 0a11d04513d38f560d0e147eeb7d0c1d9d4ac261 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:27:29 -0800 Subject: narr/paste - update --- docs/narr/paste.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index 0a217e6e3..a3f1b866e 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -3,7 +3,7 @@ PasteDeploy Configuration Files =============================== -Packages generated via a :term:`scaffold` make use of a system created by Ian +Packages generated via a :term:`cookiecutter` make use of a system created by Ian Bicking named :term:`PasteDeploy`. PasteDeploy defines a way to declare :term:`WSGI` application configuration in an ``.ini`` file. @@ -14,7 +14,7 @@ runner ``pserve``, as well as other commands such as ``pviews``, ``pshell``, PasteDeploy is not a particularly integral part of Pyramid. It's possible to create a Pyramid application which does not use PasteDeploy at all. We show a Pyramid application that doesn't use PasteDeploy in :ref:`firstapp_chapter`. -However, all Pyramid scaffolds render PasteDeploy configuration files, to +However, all Pyramid cookiecutters render PasteDeploy configuration files, to provide new developers with a standardized way of setting deployment values, and to provide new users with a standardized way of starting, stopping, and debugging an application. @@ -80,7 +80,7 @@ In English, this entry point can thus be referred to as a "PasteDeploy application factory in the ``MyProject`` project which has the entry point named ``main`` where the entry point refers to a ``main`` function in the ``mypackage`` module". Indeed, if you open up the ``__init__.py`` module -generated within any scaffold-generated package, you'll see a ``main`` +generated within any cookiecutter-generated package, you'll see a ``main`` function. This is the function called by :term:`PasteDeploy` when the ``pserve`` command is invoked against our application. It accepts a global configuration object and *returns* an instance of our application. -- cgit v1.2.3 From e2cda93d7422de50d014bcbacc2f4c31b95508bd Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 00:35:50 -0800 Subject: narr/cookiecutters - revise --- docs/narr/cookiecutters.rst | 8 +++++--- docs/narr/project.rst | 37 ++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/docs/narr/cookiecutters.rst b/docs/narr/cookiecutters.rst index bb4c61616..abedb25b9 100644 --- a/docs/narr/cookiecutters.rst +++ b/docs/narr/cookiecutters.rst @@ -13,8 +13,10 @@ Pyramid cookiecutters have replaced the now deprecated Pyramid scaffolds, and sh * `pyramid-cookiecutter-starter `_ * `pyramid-cookiecutter-zodb `_ -Development of cookiecutters is documented under `Learn the Basics of Cookiecutter by Creating a Cookiecutter `_. +.. seealso:: -.. seealso:: See also `Cookiecutter Features `_. + See also `Cookiecutter Installation `_ and `Cookiecutter Features `_. Development of cookiecutters is documented under `Learn the Basics of Cookiecutter by Creating a Cookiecutter `_. -.. seealso:: See also :term:`scaffold`. +.. seealso:: + + See also :term:`scaffold`. diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 62c4723df..118a9fa89 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -5,33 +5,44 @@ Creating a :app:`Pyramid` Project As we saw in :ref:`firstapp_chapter`, it's possible to create a :app:`Pyramid` application completely manually. However, it's usually more convenient to use -a :term:`scaffold` to generate a basic :app:`Pyramid` :term:`project`. +a :term:`cookiecutter` to generate a basic :app:`Pyramid` :term:`project`. A project is a directory that contains at least one Python :term:`package`. -You'll use a scaffold to create a project, and you'll create your application +You'll use a cookiecutter to create a project, and you'll create your application logic within a package that lives inside the project. Even if your application is extremely simple, it is useful to place code that drives the application within a package, because (1) a package is more easily extended with new code, and (2) an application that lives inside a package can also be distributed more easily than one which does not live within a package. -:app:`Pyramid` comes with a variety of scaffolds that you can use to generate a -project. Each scaffold makes different configuration assumptions about what +The Pylons Project provides several :app:`Pyramid` cookiecutters that you can use to generate a +project. Each cookiecutter makes different configuration assumptions about what type of application you're trying to construct. -These scaffolds are rendered using the ``pcreate`` command that is installed as -part of Pyramid. +These cookiecutters are rendered using the ``cookiecutter`` command that you may install. + +.. seealso:: + + + .. index:: - single: scaffolds - single: starter scaffold - single: zodb scaffold - single: alchemy scaffold + single: cookiecutters + single: pyramid-cookiecutter-starter + single: pyramid-cookiecutter-zodb + single: pyramid-cookiecutter-alchemy -.. _additional_paster_scaffolds: +.. _additional_cookiecutters: + +:app:`Pyramid` cookiecutters +---------------------------- + +Pyramid cookiecutters released under the Pylons Project include: + +* `pyramid-cookiecutter-alchemy `_ +* `pyramid-cookiecutter-starter `_ +* `pyramid-cookiecutter-zodb `_ -Scaffolds Included with :app:`Pyramid` --------------------------------------- The convenience scaffolds included with :app:`Pyramid` differ from each other on a number of axes: -- cgit v1.2.3 From e1b26edbb88ab51b1043ef82f093507d987cc2a4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:36:30 -0800 Subject: narr/project - update for cookiecutters - update source files - update project.png - fix literalinclude reference in logging --- docs/narr/MyProject/CHANGES.txt | 4 - docs/narr/MyProject/MANIFEST.in | 2 - docs/narr/MyProject/README.txt | 12 - docs/narr/MyProject/development.ini | 59 ---- docs/narr/MyProject/myproject/__init__.py | 12 - .../MyProject/myproject/static/pyramid-16x16.png | Bin 1319 -> 0 bytes docs/narr/MyProject/myproject/static/pyramid.png | Bin 12901 -> 0 bytes docs/narr/MyProject/myproject/static/theme.css | 152 ---------- .../MyProject/myproject/templates/mytemplate.pt | 67 ----- docs/narr/MyProject/myproject/tests.py | 29 -- docs/narr/MyProject/myproject/views.py | 6 - docs/narr/MyProject/production.ini | 53 ---- docs/narr/MyProject/setup.py | 49 ---- docs/narr/logging.rst | 2 +- docs/narr/myproject/.coveragerc | 3 + docs/narr/myproject/CHANGES.txt | 4 + docs/narr/myproject/MANIFEST.in | 2 + docs/narr/myproject/README.txt | 29 ++ docs/narr/myproject/development.ini | 59 ++++ docs/narr/myproject/myproject/__init__.py | 12 + .../myproject/myproject/static/pyramid-16x16.png | Bin 0 -> 1319 bytes docs/narr/myproject/myproject/static/pyramid.png | Bin 0 -> 12901 bytes docs/narr/myproject/myproject/static/theme.css | 154 ++++++++++ .../myproject/myproject/templates/layout.jinja2 | 64 ++++ .../myproject/templates/mytemplate.jinja2 | 8 + docs/narr/myproject/myproject/tests.py | 29 ++ docs/narr/myproject/myproject/views.py | 6 + docs/narr/myproject/production.ini | 53 ++++ docs/narr/myproject/pytest.ini | 3 + docs/narr/myproject/setup.py | 51 ++++ docs/narr/project.png | Bin 133242 -> 98989 bytes docs/narr/project.rst | 322 ++++++++++++--------- 32 files changed, 664 insertions(+), 582 deletions(-) delete mode 100644 docs/narr/MyProject/CHANGES.txt delete mode 100644 docs/narr/MyProject/MANIFEST.in delete mode 100644 docs/narr/MyProject/README.txt delete mode 100644 docs/narr/MyProject/development.ini delete mode 100644 docs/narr/MyProject/myproject/__init__.py delete mode 100644 docs/narr/MyProject/myproject/static/pyramid-16x16.png delete mode 100644 docs/narr/MyProject/myproject/static/pyramid.png delete mode 100644 docs/narr/MyProject/myproject/static/theme.css delete mode 100644 docs/narr/MyProject/myproject/templates/mytemplate.pt delete mode 100644 docs/narr/MyProject/myproject/tests.py delete mode 100644 docs/narr/MyProject/myproject/views.py delete mode 100644 docs/narr/MyProject/production.ini delete mode 100644 docs/narr/MyProject/setup.py create mode 100644 docs/narr/myproject/.coveragerc create mode 100644 docs/narr/myproject/CHANGES.txt create mode 100644 docs/narr/myproject/MANIFEST.in create mode 100644 docs/narr/myproject/README.txt create mode 100644 docs/narr/myproject/development.ini create mode 100644 docs/narr/myproject/myproject/__init__.py create mode 100644 docs/narr/myproject/myproject/static/pyramid-16x16.png create mode 100644 docs/narr/myproject/myproject/static/pyramid.png create mode 100644 docs/narr/myproject/myproject/static/theme.css create mode 100644 docs/narr/myproject/myproject/templates/layout.jinja2 create mode 100644 docs/narr/myproject/myproject/templates/mytemplate.jinja2 create mode 100644 docs/narr/myproject/myproject/tests.py create mode 100644 docs/narr/myproject/myproject/views.py create mode 100644 docs/narr/myproject/production.ini create mode 100644 docs/narr/myproject/pytest.ini create mode 100644 docs/narr/myproject/setup.py diff --git a/docs/narr/MyProject/CHANGES.txt b/docs/narr/MyProject/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/narr/MyProject/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/narr/MyProject/MANIFEST.in b/docs/narr/MyProject/MANIFEST.in deleted file mode 100644 index fa1692163..000000000 --- a/docs/narr/MyProject/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include myproject *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/narr/MyProject/README.txt b/docs/narr/MyProject/README.txt deleted file mode 100644 index 70759eba1..000000000 --- a/docs/narr/MyProject/README.txt +++ /dev/null @@ -1,12 +0,0 @@ -MyProject README -================== - -Getting Started ---------------- - -- cd - -- $VENV/bin/pip install -e . - -- $VENV/bin/pserve development.ini - diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini deleted file mode 100644 index 3a83dcfac..000000000 --- a/docs/narr/MyProject/development.ini +++ /dev/null @@ -1,59 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html -### - -[app:main] -use = egg:MyProject - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_debugtoolbar - -# By default, the toolbar only appears for clients from IP addresses -# '127.0.0.1' and '::1'. -# debugtoolbar.hosts = 127.0.0.1 ::1 - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -listen = 127.0.0.1:6543 [::1]:6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html -### - -[loggers] -keys = root, myproject - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_myproject] -level = DEBUG -handlers = -qualname = myproject - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py deleted file mode 100644 index ad5ecbc6f..000000000 --- a/docs/narr/MyProject/myproject/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -from pyramid.config import Configurator - - -def main(global_config, **settings): - """ This function returns a Pyramid WSGI application. - """ - config = Configurator(settings=settings) - config.include('pyramid_chameleon') - config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('home', '/') - config.scan() - return config.make_wsgi_app() diff --git a/docs/narr/MyProject/myproject/static/pyramid-16x16.png b/docs/narr/MyProject/myproject/static/pyramid-16x16.png deleted file mode 100644 index 979203112..000000000 Binary files a/docs/narr/MyProject/myproject/static/pyramid-16x16.png and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/pyramid.png b/docs/narr/MyProject/myproject/static/pyramid.png deleted file mode 100644 index 4ab837be9..000000000 Binary files a/docs/narr/MyProject/myproject/static/pyramid.png and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/theme.css b/docs/narr/MyProject/myproject/static/theme.css deleted file mode 100644 index be50ad420..000000000 --- a/docs/narr/MyProject/myproject/static/theme.css +++ /dev/null @@ -1,152 +0,0 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); -body { - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-weight: 300; - color: #ffffff; - background: #bc2131; -} -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-weight: 300; -} -p { - font-weight: 300; -} -.font-normal { - font-weight: 400; -} -.font-semi-bold { - font-weight: 600; -} -.font-bold { - font-weight: 700; -} -.starter-template { - margin-top: 250px; -} -.starter-template .content { - margin-left: 10px; -} -.starter-template .content h1 { - margin-top: 10px; - font-size: 60px; -} -.starter-template .content h1 .smaller { - font-size: 40px; - color: #f2b7bd; -} -.starter-template .content .lead { - font-size: 25px; - color: #f2b7bd; -} -.starter-template .content .lead .font-normal { - color: #ffffff; -} -.starter-template .links { - float: right; - right: 0; - margin-top: 125px; -} -.starter-template .links ul { - display: block; - padding: 0; - margin: 0; -} -.starter-template .links ul li { - list-style: none; - display: inline; - margin: 0 10px; -} -.starter-template .links ul li:first-child { - margin-left: 0; -} -.starter-template .links ul li:last-child { - margin-right: 0; -} -.starter-template .links ul li.current-version { - color: #f2b7bd; - font-weight: 400; -} -.starter-template .links ul li a { - color: #ffffff; -} -.starter-template .links ul li a:hover { - text-decoration: underline; -} -.starter-template .links ul li .icon-muted { - color: #eb8b95; - margin-right: 5px; -} -.starter-template .links ul li:hover .icon-muted { - color: #ffffff; -} -.starter-template .copyright { - margin-top: 10px; - font-size: 0.9em; - color: #f2b7bd; - text-transform: lowercase; - float: right; - right: 0; -} -@media (max-width: 1199px) { - .starter-template .content h1 { - font-size: 45px; - } - .starter-template .content h1 .smaller { - font-size: 30px; - } - .starter-template .content .lead { - font-size: 20px; - } -} -@media (max-width: 991px) { - .starter-template { - margin-top: 0; - } - .starter-template .logo { - margin: 40px auto; - } - .starter-template .content { - margin-left: 0; - text-align: center; - } - .starter-template .content h1 { - margin-bottom: 20px; - } - .starter-template .links { - float: none; - text-align: center; - margin-top: 60px; - } - .starter-template .copyright { - float: none; - text-align: center; - } -} -@media (max-width: 767px) { - .starter-template .content h1 .smaller { - font-size: 25px; - display: block; - } - .starter-template .content .lead { - font-size: 16px; - } - .starter-template .links { - margin-top: 40px; - } - .starter-template .links ul li { - display: block; - margin: 0; - } - .starter-template .links ul li .icon-muted { - display: none; - } - .starter-template .copyright { - margin-top: 20px; - } -} diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt deleted file mode 100644 index 543663fe8..000000000 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - Starter Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    Pyramid Starter scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework 1.7.

    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py deleted file mode 100644 index fd414cced..000000000 --- a/docs/narr/MyProject/myproject/tests.py +++ /dev/null @@ -1,29 +0,0 @@ -import unittest - -from pyramid import testing - - -class ViewTests(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from .views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['project'], 'MyProject') - - -class FunctionalTests(unittest.TestCase): - def setUp(self): - from myproject import main - app = main({}) - from webtest import TestApp - self.testapp = TestApp(app) - - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/narr/MyProject/myproject/views.py b/docs/narr/MyProject/myproject/views.py deleted file mode 100644 index c383c5716..000000000 --- a/docs/narr/MyProject/myproject/views.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config - - -@view_config(route_name='home', renderer='templates/mytemplate.pt') -def my_view(request): - return {'project': 'MyProject'} diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini deleted file mode 100644 index c48ca6d9b..000000000 --- a/docs/narr/MyProject/production.ini +++ /dev/null @@ -1,53 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html -### - -[app:main] -use = egg:MyProject - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -listen = *:6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html -### - -[loggers] -keys = root, myproject - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_myproject] -level = WARN -handlers = -qualname = myproject - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py deleted file mode 100644 index a911eff6d..000000000 --- a/docs/narr/MyProject/setup.py +++ /dev/null @@ -1,49 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(here, 'README.txt')) as f: - README = f.read() -with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() - -requires = [ - 'pyramid', - 'pyramid_chameleon', - 'pyramid_debugtoolbar', - 'waitress', - ] - -tests_require = [ - 'WebTest >= 1.3.1', # py3 compat - 'pytest', # includes virtualenv - 'pytest-cov', - ] - -setup(name='MyProject', - version='0.0', - description='MyProject', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'testing': tests_require, - }, - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = myproject:main - """, - ) diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index f2c990861..ec3590e62 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -50,7 +50,7 @@ Default logging configuration is provided in both the default ``development.ini`` and the ``production.ini`` files. If you use ``pyramid-cookiecutter-starter`` to generate a Pyramid project with the name of the package as ``hello_world``, then the logging configuration in the ``development.ini`` file is as follows: -.. literalinclude:: ../quick_tour/package/development.ini +.. literalinclude:: MyProject/development.ini :language: ini :lineno-match: :lines: 29- diff --git a/docs/narr/myproject/.coveragerc b/docs/narr/myproject/.coveragerc new file mode 100644 index 000000000..f0c31d6d7 --- /dev/null +++ b/docs/narr/myproject/.coveragerc @@ -0,0 +1,3 @@ +[run] +source = myproject +omit = myproject/test* diff --git a/docs/narr/myproject/CHANGES.txt b/docs/narr/myproject/CHANGES.txt new file mode 100644 index 000000000..14b902fd1 --- /dev/null +++ b/docs/narr/myproject/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version. diff --git a/docs/narr/myproject/MANIFEST.in b/docs/narr/myproject/MANIFEST.in new file mode 100644 index 000000000..1c24b8c0c --- /dev/null +++ b/docs/narr/myproject/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include myproject *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 diff --git a/docs/narr/myproject/README.txt b/docs/narr/myproject/README.txt new file mode 100644 index 000000000..41ef0ff91 --- /dev/null +++ b/docs/narr/myproject/README.txt @@ -0,0 +1,29 @@ +MyProject +=============================== + +Getting Started +--------------- + +- Change directory into your newly created project. + + cd MyProject + +- Create a Python virtual environment. + + python3 -m venv env + +- Upgrade packaging tools. + + env/bin/pip install --upgrade pip setuptools + +- Install the project in editable mode with its testing requirements. + + env/bin/pip install -e ".[testing]" + +- Run your project's tests. + + env/bin/pytest + +- Run your project. + + env/bin/pserve development.ini diff --git a/docs/narr/myproject/development.ini b/docs/narr/myproject/development.ini new file mode 100644 index 000000000..5d110805a --- /dev/null +++ b/docs/narr/myproject/development.ini @@ -0,0 +1,59 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:myproject + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = 127.0.0.1:6543 [::1]:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, myproject + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_myproject] +level = DEBUG +handlers = +qualname = myproject + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/narr/myproject/myproject/__init__.py b/docs/narr/myproject/myproject/__init__.py new file mode 100644 index 000000000..49dde36d4 --- /dev/null +++ b/docs/narr/myproject/myproject/__init__.py @@ -0,0 +1,12 @@ +from pyramid.config import Configurator + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + config = Configurator(settings=settings) + config.include('pyramid_jinja2') + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/narr/myproject/myproject/static/pyramid-16x16.png b/docs/narr/myproject/myproject/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/narr/myproject/myproject/static/pyramid-16x16.png differ diff --git a/docs/narr/myproject/myproject/static/pyramid.png b/docs/narr/myproject/myproject/static/pyramid.png new file mode 100644 index 000000000..4ab837be9 Binary files /dev/null and b/docs/narr/myproject/myproject/static/pyramid.png differ diff --git a/docs/narr/myproject/myproject/static/theme.css b/docs/narr/myproject/myproject/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/narr/myproject/myproject/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/narr/myproject/myproject/templates/layout.jinja2 b/docs/narr/myproject/myproject/templates/layout.jinja2 new file mode 100644 index 000000000..bfac9e64e --- /dev/null +++ b/docs/narr/myproject/myproject/templates/layout.jinja2 @@ -0,0 +1,64 @@ + + + + + + + + + + + Cookiecutter Starter project for the Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + {% block content %} +

    No content

    + {% endblock content %} +
    +
    + +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/narr/myproject/myproject/templates/mytemplate.jinja2 b/docs/narr/myproject/myproject/templates/mytemplate.jinja2 new file mode 100644 index 000000000..ce042215d --- /dev/null +++ b/docs/narr/myproject/myproject/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Starter project

    +

    Welcome to MyProject, a Pyramid application generated by
    Cookiecutter.

    +
    +{% endblock content %} diff --git a/docs/narr/myproject/myproject/tests.py b/docs/narr/myproject/myproject/tests.py new file mode 100644 index 000000000..fd414cced --- /dev/null +++ b/docs/narr/myproject/myproject/tests.py @@ -0,0 +1,29 @@ +import unittest + +from pyramid import testing + + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], 'MyProject') + + +class FunctionalTests(unittest.TestCase): + def setUp(self): + from myproject import main + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'Pyramid' in res.body) diff --git a/docs/narr/myproject/myproject/views.py b/docs/narr/myproject/myproject/views.py new file mode 100644 index 000000000..9e9ec4320 --- /dev/null +++ b/docs/narr/myproject/myproject/views.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + + +@view_config(route_name='home', renderer='templates/mytemplate.jinja2') +def my_view(request): + return {'project': 'MyProject'} diff --git a/docs/narr/myproject/production.ini b/docs/narr/myproject/production.ini new file mode 100644 index 000000000..13be488e7 --- /dev/null +++ b/docs/narr/myproject/production.ini @@ -0,0 +1,53 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:myproject + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +listen = *:6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, myproject + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_myproject] +level = WARN +handlers = +qualname = myproject + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/narr/myproject/pytest.ini b/docs/narr/myproject/pytest.ini new file mode 100644 index 000000000..b1b5f4c38 --- /dev/null +++ b/docs/narr/myproject/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = myproject +python_files = *.py diff --git a/docs/narr/myproject/setup.py b/docs/narr/myproject/setup.py new file mode 100644 index 000000000..00e377349 --- /dev/null +++ b/docs/narr/myproject/setup.py @@ -0,0 +1,51 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + +requires = [ + 'pyramid', + 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', +] + +tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', + 'pytest-cov', +] + +setup( + name='myproject', + version='0.0', + description='MyProject', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + 'Programming Language :: Python', + 'Framework :: Pyramid', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + extras_require={ + 'testing': tests_require, + }, + install_requires=requires, + entry_points={ + 'paste.app_factory': [ + 'main = myproject:main', + ], + }, +) diff --git a/docs/narr/project.png b/docs/narr/project.png index e1afd97d4..0e17e57ab 100644 Binary files a/docs/narr/project.png and b/docs/narr/project.png differ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 118a9fa89..61759fe34 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -23,7 +23,7 @@ These cookiecutters are rendered using the ``cookiecutter`` command that you may .. seealso:: - + See also `Cookiecutter Installation `_. .. index:: @@ -37,73 +37,103 @@ These cookiecutters are rendered using the ``cookiecutter`` command that you may :app:`Pyramid` cookiecutters ---------------------------- -Pyramid cookiecutters released under the Pylons Project include: - -* `pyramid-cookiecutter-alchemy `_ -* `pyramid-cookiecutter-starter `_ -* `pyramid-cookiecutter-zodb `_ +Pyramid cookiecutters released under the Pylons Project include differ from each other on a number of axes: +- the persistence mechanism they offer (no persistence mechanism, :term:`SQLAlchemy` with SQLite, or :term:`ZODB`) -The convenience scaffolds included with :app:`Pyramid` differ from each other -on a number of axes: +- the mechanism they use to map URLs to code (:term:`URL dispatch` or :term:`traversal`) -- the persistence mechanism they offer (no persistence mechanism, :term:`ZODB`, - or :term:`SQLAlchemy`) +- templating libraries (:term:`Jinja2` or :term:`Chameleon`) -- the mechanism they use to map URLs to code (:term:`traversal` or :term:`URL - dispatch`) +* `pyramid-cookiecutter-starter `_ +* `pyramid-cookiecutter-alchemy `_ +* `pyramid-cookiecutter-zodb `_ -The included scaffolds are these: +These cookiecutters include: -``starter`` - URL mapping via :term:`URL dispatch` and no persistence mechanism +``pyramid-cookiecutter-starter`` + :term:`URL dispatch` for routing and :term:`Jinja2` for templating -``zodb`` - URL mapping via :term:`traversal` and persistence via :term:`ZODB` +``pyramid-cookiecutter-alchemy`` + SQLite for persistent storage, :term:`SQLAlchemy` for an ORM, :term:`URL dispatch` for routing, and :term:`Jinja2` for templating. -``alchemy`` - URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` +``pyramid-cookiecutter-zodb`` + :term:`ZODB` for persistent storage, :term:`traversal` for routing, and :term:`Chameleon` for templating .. index:: single: creating a project single: project - single: pcreate + single: cookiecutter .. _creating_a_project: Creating the Project -------------------- -.. seealso:: See also the output of :ref:`pcreate --help `. - In :ref:`installing_chapter`, you created a virtual Python environment via the -``venv`` command. To start a :app:`Pyramid` :term:`project`, use the -``pcreate`` command installed within the virtual environment. We'll choose the -``starter`` scaffold for this purpose. When we invoke ``pcreate``, it will -create a directory that represents our project. +``venv`` command. We called the virtual environment directory +``env`` and set an environment variable ``VENV`` to its path. + +We assume that you previously installed cookiecutter using the following command: + +.. code-block:: bash + + $ $VENV/bin/pip install cookiecutter -In :ref:`installing_chapter` we called the virtual environment directory -``env``. The following commands assume that our current working directory is -the ``env`` directory. +We'll choose ``pyramid-cookiecutter-starter`` to start the project. When we invoke ``cookiecutter``, it will create a directory that represents our project. -The below example uses the ``pcreate`` command to create a project with the -``starter`` scaffold. +The following commands assume that our current working directory is the value of ``$VENV``. On UNIX: .. code-block:: bash - $ $VENV/bin/pcreate -s starter MyProject + $ $VENV/bin/cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter Or on Windows: .. code-block:: doscon - c:\> %VENV%\Scripts\pcreate -s starter MyProject + c:\> %VENV%\cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter + +If prompted for the first item, accept the default ``yes`` by hitting return. + +#. ``You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before. Is it + okay to delete and re-clone it? [yes]:`` +#. ``project_name [Pyramid Scaffold]: myproject`` +#. ``repo_name [scaffold]: myproject`` + +We then run through the following commands. + +On UNIX: + +.. code-block:: bash + + # Reset our environment variable for a new virtual environment. + $ export VENV=~/env/myproject/env + # Change directory into your newly created project. + $ cd myproject + # Create a new virtual environment... + $ python3 -m venv $VENV + # ...where we upgrade packaging tools. + $ env/bin/pip install --upgrade pip setuptools + +Or on Windows: + +.. code-block:: doscon -As a result of invoking the ``pcreate`` command, a directory named -``MyProject`` is created. That directory is a :term:`project` directory. The + # Reset our environment variable for a new virtual environment. + c:\> set VENV=c:\env\myproject\env + # Change directory into your newly created project. + c:\> cd myproject + # Create a new virtual environment... + c:\myproject\> c:\Python3x\python -m venv %VENV% + # ...where we upgrade packaging tools. + c:\myproject\> %VENV%\Scripts\pip install --upgrade pip setuptools + +As a result of invoking the ``cookiecutter`` command, a directory named +``myproject`` is created. That directory is a :term:`project` directory. The ``setup.py`` file in that directory can be used to distribute your application, or install your application for deployment or development. @@ -118,15 +148,15 @@ debugger (to prevent inappropriate access and disclosure), and turns off a number of debugging settings. You can use this file to put your application into production. -The ``MyProject`` project directory contains an additional subdirectory named +The ``myproject`` project directory contains an additional subdirectory named ``myproject`` (note the case difference) representing a Python :term:`package` which holds very simple :app:`Pyramid` sample code. This is where you'll edit your application's Python code and templates. -We created this project within an ``env`` virtual environment directory. +We created this project in a directory next to its virtual environment directory. However, note that this is not mandatory. The project directory can go more or less anywhere on your filesystem. You don't need to put it in a special "web -server" directory, and you don't need to put it within a virtual environment +server" directory. You could put it within a virtual environment directory. The author uses Linux mainly, and tends to put project directories which he creates within his ``~/projects`` directory. On Windows, it's a good idea to put project directories within a directory that contains no space @@ -136,7 +166,7 @@ projects in ``C:\projects``. .. warning:: - You'll need to avoid using ``pcreate`` to create a project with the same + You'll need to avoid using ``cookiecutter`` to create a project with the same name as a Python standard library component. In particular, this means you should avoid using the names ``site`` or ``test``, both of which conflict with Python standard library packages. You should also avoid using the name @@ -155,7 +185,7 @@ newly created project directory and use the Python interpreter from the invoke the command ``pip install -e .``, which installs the project in development mode (``-e`` is for "editable") into the current directory (``.``). -The file named ``setup.py`` will be in the root of the pcreate-generated +The file named ``setup.py`` will be in the root of the cookiecutter-generated project directory. The ``python`` you're invoking should be the one that lives in the ``bin`` (or ``Scripts`` on Windows) directory of your virtual Python environment. Your terminal's current working directory *must* be the newly @@ -165,25 +195,24 @@ On UNIX: .. code-block:: bash - $ cd MyProject - $ $VENV/bin/pip install -e . + $ $VENV/bin/pip install -e . Or on Windows: .. code-block:: doscon - c:\> cd MyProject - c:\> %VENV%\Scripts\pip install -e . + c:\env\myproject\> %VENV%\Scripts\pip install -e . Elided output from a run of this command on UNIX is shown below: .. code-block:: bash - $ cd MyProject - $ $VENV/bin/pip install -e . - ... - Successfully installed Chameleon-2.24 Mako-1.0.4 MyProject \ - pyramid-chameleon-0.3 pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 + Running setup.py develop for myproject + Successfully installed Jinja2-2.8 Mako-1.0.6 MarkupSafe-0.23 \ + PasteDeploy-1.5.2 Pygments-2.1.3 WebOb-1.7.0 myproject pyramid-1.7.3 \ + pyramid-debugtoolbar-3.0.5 pyramid-jinja2-2.7 pyramid-mako-1.0.2 \ + repoze.lru-0.6 translationstring-1.3 venusian-1.0 waitress-1.0.1 \ + zope.deprecation-4.2.0 zope.interface-4.3.3 This will install a :term:`distribution` representing your project into the virtual environment interpreter's library set so it can be found by ``import`` @@ -210,7 +239,7 @@ On Windows: .. code-block:: doscon - c:\> %VENV%\Scripts\pip install -e ".[testing]" + c:\env\myproject\> %VENV%\Scripts\pip install -e ".[testing]" Once the testing requirements are installed, then you can run the tests using the ``py.test`` command that was just installed in the ``bin`` directory of @@ -226,7 +255,7 @@ On Windows: .. code-block:: doscon - c:\> %VENV%\Scripts\py.test -q + c:\env\myproject\> %VENV%\Scripts\py.test -q Here's sample output from a test run on UNIX: @@ -236,9 +265,7 @@ Here's sample output from a test run on UNIX: .. 2 passed in 0.47 seconds -The tests themselves are found in the ``tests.py`` module in your ``pcreate`` -generated project. Within a project generated by the ``starter`` scaffold, -only two sample tests exist. +The tests themselves are found in the ``tests.py`` module in your ``cookiecutter``-generated project. Within a project generated by the ``pyramid-cookiecutter-starter`` cookiecutter, only two sample tests exist. .. note:: @@ -253,7 +280,7 @@ to ``py.test``: $ $VENV/bin/py.test --cov -q -Scaffolds include configuration defaults for ``py.test`` and test coverage. +Cookiecutters include configuration defaults for ``py.test`` and test coverage. These configuration files are ``pytest.ini`` and ``.coveragerc``, located at the root of your package. Without these defaults, we would need to specify the path to the module on which we want to run tests and coverage. @@ -291,19 +318,18 @@ On UNIX: On Windows: -.. code-block:: text +.. code-block:: doscon - c:\> %VENV%\Scripts\pserve development.ini + c:\env\myproject\> %VENV%\Scripts\pserve development.ini Here's sample output from a run of ``pserve`` on UNIX: .. code-block:: bash $ $VENV/bin/pserve development.ini - Starting server in PID 16208. - Serving on http://127.0.0.1:6543 - Serving on http://[::1]:6543 - + Starting server in PID 77171. + Serving on http://localhost:6543 + Serving on http://localhost:6543 Access is restricted such that only a browser running on the same machine as Pyramid will be able to access your Pyramid application. However, if you want @@ -340,8 +366,8 @@ You can shut down a server started this way by pressing ``Ctrl-C`` (or ``Ctrl-Break`` on Windows). The default server used to run your Pyramid application when a project is -created from a scaffold is named :term:`Waitress`. This server is what prints -the ``serving on...`` line when you run ``pserve``. It's a good idea to use +created from a cookiecutter is named :term:`Waitress`. This server is what prints +the ``Serving on...`` line when you run ``pserve``. It's a good idea to use this server during development because it's very simple. It can also be used for light production. Setting your application up under a different server is not advised until you've done some development work under the default server, @@ -378,7 +404,8 @@ For example, on UNIX: $ $VENV/bin/pserve development.ini --reload Starting subprocess with file monitor Starting server in PID 16601. - serving on http://127.0.0.1:6543 + Serving on http://localhost:6543 + Serving on http://localhost:6543 Now if you make a change to any of your project's ``.py`` files or ``.ini`` files, you'll see the server restart automatically: @@ -388,12 +415,13 @@ files, you'll see the server restart automatically: development.ini changed; reloading... -------------------- Restarting -------------------- Starting server in PID 16602. - serving on http://127.0.0.1:6543 + Serving on http://localhost:6543 + Serving on http://localhost:6543 Changes to template files (such as ``.pt`` or ``.mak`` files) won't cause the server to restart. Changes to template files don't require a server restart as long as the ``pyramid.reload_templates`` setting in the ``development.ini`` -file is ``true``. Changes made to template files when this setting is true +file is ``true``. Changes made to template files when this setting is ``true`` will take effect immediately without a server restart. .. index:: @@ -408,8 +436,8 @@ browser like what is displayed in the following image: .. image:: project.png -This is the page shown by default when you visit an unmodified ``pcreate`` -generated ``starter`` application in a browser. +This is the page shown by default when you visit an unmodified ``cookiecutter`` +generated ``pyramid-cookiecutter-starter`` application in a browser. .. index:: single: debug toolbar @@ -490,48 +518,57 @@ this: The Project Structure --------------------- -The ``starter`` scaffold generated a :term:`project` (named ``MyProject``), +The ``pyramid-cookiecutter-starter`` cookiecutter generated a :term:`project` (named ``myproject``), which contains a Python :term:`package`. The package is *also* named -``myproject``, but it's lowercased; the scaffold generates a project which -contains a package that shares its name except for case. +``myproject``; the cookiecutter generates a project which +contains a package that shares its name. -All :app:`Pyramid` ``pcreate``-generated projects share a similar structure. -The ``MyProject`` project we've generated has the following directory structure: +All :app:`Pyramid` ``cookiecutter``-generated projects share a similar structure. +The ``myproject`` project we've generated has the following directory structure: .. code-block:: text - MyProject/ - |-- CHANGES.txt - |-- development.ini - |-- MANIFEST.in - |-- myproject - | |-- __init__.py - | |-- static - | | |-- pyramid-16x16.png - | | |-- pyramid.png - | | |-- theme.css - | | `-- theme.min.css - | |-- templates - | | `-- mytemplate.pt - | |-- tests.py - | `-- views.py - |-- production.ini - |-- README.txt - `-- setup.py - -The ``MyProject`` :term:`Project` + myproject/ + ├── .coveragerc + ├── CHANGES.txt + ├── MANIFEST.in + ├── myproject + │   ├── __init__.py + │   ├── static + │   │   ├── pyramid-16x16.png + │   │   ├── pyramid.png + │   │   └── theme.css + │   ├── templates + │   │   ├── layout.jinja2 + │   │   └── mytemplate.jinja2 + │   ├── tests.py + │   └── views.py + ├── README.txt + ├── development.ini + ├── production.ini + ├── pytest.ini + └── setup.py + + +The ``myproject`` :term:`Project` --------------------------------- -The ``MyProject`` :term:`project` directory is the distribution and deployment +The ``myproject`` :term:`project` directory is the distribution and deployment wrapper for your application. It contains both the ``myproject`` :term:`package` representing your application as well as files used to describe, run, and test your application. +#. ``.coveragerc`` configures coverage when running tests. + #. ``CHANGES.txt`` describes the changes you've made to the application. It is - conventionally written in :term:`ReStructuredText` format. + conventionally written in :term:`reStructuredText` format. + +#. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files + should be included in a source distribution of the package when ``python + setup.py sdist`` is run. #. ``README.txt`` describes the application in general. It is conventionally - written in :term:`ReStructuredText` format. + written in :term:`reStructuredText` format. #. ``development.ini`` is a :term:`PasteDeploy` configuration file that can be used to execute your application during development. @@ -539,9 +576,7 @@ describe, run, and test your application. #. ``production.ini`` is a :term:`PasteDeploy` configuration file that can be used to execute your application in a production configuration. -#. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files - should be included in a source distribution of the package when ``python - setup.py sdist`` is run. +#. ``pytest.ini`` is a configuration file for running tests. #. ``setup.py`` is the file you'll use to test and distribute your application. It is a standard :term:`setuptools` ``setup.py`` file. @@ -550,7 +585,7 @@ describe, run, and test your application. single: PasteDeploy single: ini file -.. _MyProject_ini: +.. _myproject_ini: ``development.ini`` ~~~~~~~~~~~~~~~~~~~ @@ -561,7 +596,7 @@ as the deployment settings provided to that application. The generated ``development.ini`` file looks like so: -.. literalinclude:: MyProject/development.ini +.. literalinclude:: myproject/development.ini :language: ini :linenos: @@ -570,15 +605,15 @@ This file contains several sections including ``[app:main]``, The ``[app:main]`` section represents configuration for your :app:`Pyramid` application. The ``use`` setting is the only setting required to be present in -the ``[app:main]`` section. Its default value, ``egg:MyProject``, indicates -that our MyProject project contains the application that should be served. +the ``[app:main]`` section. Its default value, ``egg:myproject``, indicates +that our myproject project contains the application that should be served. Other settings added to this section are passed as keyword arguments to the function named ``main`` in our package's ``__init__.py`` module. You can provide startup-time configuration parameters to your application by adding more settings to this section. .. seealso:: See :ref:`pastedeploy_entry_points` for more information about the - meaning of the ``use = egg:MyProject`` value in this section. + meaning of the ``use = egg:myproject`` value in this section. The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a :app:`Pyramid`-specific setting which is passed into the framework. If it @@ -612,7 +647,7 @@ The ``[server:main]`` section of the configuration file configures a WSGI server which listens on TCP port 6543. It is configured to listen on localhost only (``127.0.0.1``). -.. _MyProject_ini_logging: +.. _myproject_ini_logging: The sections after ``# logging configuration`` represent Python's standard library :mod:`logging` module configuration for your application. These @@ -673,7 +708,7 @@ directory didn't contain a ``MANIFEST.in`` file that told the ``sdist`` machinery to include ``*.pt`` files, the ``myproject/templates/mytemplate.pt`` file would not be included in the generated tarball. -Projects generated by Pyramid scaffolds include a default ``MANIFEST.in`` file. +Projects generated by Pyramid cookiecutters include a default ``MANIFEST.in`` file. The ``MANIFEST.in`` file contains declarations which tell it to include files like ``*.pt``, ``*.css`` and ``*.js`` in the generated tarball. If you include files with extensions other than the files named in the project's @@ -713,7 +748,7 @@ testing, as well as distributing your application. Our generated ``setup.py`` looks like this: -.. literalinclude:: MyProject/setup.py +.. literalinclude:: myproject/setup.py :language: python :linenos: @@ -756,7 +791,7 @@ you can try this command now: $ $VENV/bin/python setup.py sdist This will create a tarball of your application in a ``dist`` subdirectory named -``MyProject-0.0.tar.gz``. You can send this tarball to other people who want +``myproject-0.0.tar.gz``. You can send this tarball to other people who want to install and use your application. .. index:: @@ -765,7 +800,7 @@ to install and use your application. The ``myproject`` :term:`Package` --------------------------------- -The ``myproject`` :term:`package` lives inside the ``MyProject`` +The ``myproject`` :term:`package` lives inside the ``myproject`` :term:`project`. It contains: #. An ``__init__.py`` file signifies that this is a Python :term:`package`. It @@ -773,14 +808,14 @@ The ``myproject`` :term:`package` lives inside the ``MyProject`` ``main`` function which is used as a entry point for commands such as ``pserve``, ``pshell``, ``pviews``, and others. -#. A ``templates`` directory, which contains :term:`Chameleon` (or other types +#. A ``templates`` directory, which contains :term:`Jinja2` (or other types of) templates. #. A ``tests.py`` module, which contains unit test code for the application. #. A ``views.py`` module, which contains view code for the application. -These are purely conventions established by the scaffold. :app:`Pyramid` +These are purely conventions established by the cookiecutter. :app:`Pyramid` doesn't insist that you name things in any particular way. However, it's generally a good idea to follow Pyramid standards for naming, so that other Pyramid developers can get up to speed quickly on your code when you need help. @@ -798,7 +833,7 @@ advertises an entry point for use by our :term:`PasteDeploy` ``.ini`` file. This is the file named ``__init__.py``. The presence of an ``__init__.py`` also informs Python that the directory which contains it is a *package*. -.. literalinclude:: MyProject/myproject/__init__.py +.. literalinclude:: myproject/myproject/__init__.py :language: python :linenos: @@ -813,8 +848,8 @@ also informs Python that the directory which contains it is a *package*. Line 7 creates an instance of a :term:`Configurator`. - Line 8 adds support for Chameleon templating bindings, allowing us to - specify renderers with the ``.pt`` extension. + Line 8 adds support for Jinja2 templating bindings, allowing us to + specify renderers with the ``.jinja2`` extension. Line 9 registers a static view, which will serve up the files from the ``myproject:static`` :term:`asset specification` (the ``static`` directory @@ -840,7 +875,7 @@ callables*. A :term:`view callable` is the main tool of a :app:`Pyramid` web application developer; it is a bit of code which accepts a :term:`request` and which returns a :term:`response`. -.. literalinclude:: MyProject/myproject/views.py +.. literalinclude:: myproject/myproject/views.py :language: python :linenos: @@ -857,8 +892,8 @@ result of the view callable. This particular view declaration points at specifies the ``mytemplate.pt`` file within the ``templates`` directory of the ``myproject`` package. The asset specification could have also been specified as ``myproject:templates/mytemplate.pt``; the leading package name and colon is -optional. The template file pointed to is a :term:`Chameleon` ZPT template -file (``templates/my_template.pt``). +optional. The template file pointed to is a :term:`Jinja2` template +file (``templates/my_template.jinja2``). This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` @@ -871,9 +906,9 @@ the HTML in a :term:`response`. .. note:: Dictionaries provide values to :term:`template`\s. -.. note:: When the application is run with the scaffold's :ref:`default - development.ini ` configuration, :ref:`logging is set up - ` to aid debugging. If an exception is raised, +.. note:: When the application is run with the cookiecutter's :ref:`default + development.ini ` configuration, :ref:`logging is set up + ` to aid debugging. If an exception is raised, uncaught tracebacks are displayed after the startup messages on :ref:`the console running the server `. Also ``print()`` statements may be inserted into the application for debugging to @@ -882,7 +917,7 @@ the HTML in a :term:`response`. .. note:: ``development.ini`` has a setting that controls how templates are reloaded, ``pyramid.reload_templates``. - - When set to ``True`` (as in the scaffold ``development.ini``), changed + - When set to ``True`` (as in the cookiecutter ``development.ini``), changed templates automatically reload without a server restart. This is convenient while developing, but slows template rendering speed. @@ -913,31 +948,46 @@ the HTML in a :term:`response`. ``static`` ~~~~~~~~~~ -This directory contains static assets which support the ``mytemplate.pt`` +This directory contains static assets which support the ``layout.jinja2`` template. It includes CSS and images. -``templates/mytemplate.pt`` + +``templates/layout.jinja2`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This is the single :term:`Chameleon` template that exists in the project. Its -contents are too long to show here, but it displays a default page when -rendered. It is referenced by the call to ``@view_config`` as the ``renderer`` +This is the base layout content. It contains a single marker for content block. Other templates inherit its content, providing layout for the web application. Its contents are too long to show here, but here is an excerpt: + +.. literalinclude:: myproject/myproject/templates/layout.jinja2 + :language: jinja + :lines: 34-38 + :lineno-match: + + +``templates/mytemplate.jinja2`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the content :term:`Jinja2` template that exists in the project. It is referenced by the call to ``@view_config`` as the ``renderer`` of the ``my_view`` view callable in the ``views.py`` file. See -:ref:`views_which_use_a_renderer` for more information about renderers. +:ref:`views_which_use_a_renderer` for more information about renderers. It inherits ("extends") the HTML provided by ``layout.jinja2``, replacing the content block with its own content. + +.. literalinclude:: myproject/myproject/templates/mytemplate.jinja2 + :language: jinja + :linenos: Templates are accessed and used by view configurations and sometimes by view functions themselves. See :ref:`templates_used_directly` and :ref:`templates_used_as_renderers`. + .. index:: single: tests.py ``tests.py`` ~~~~~~~~~~~~ -The ``tests.py`` module includes unit tests for your application. +The ``tests.py`` module includes tests for your application. -.. literalinclude:: MyProject/myproject/tests.py +.. literalinclude:: myproject/myproject/tests.py :language: python :linenos: @@ -959,16 +1009,16 @@ Modifying Package Structure --------------------------- It is best practice for your application's code layout to not stray too much -from accepted Pyramid scaffold defaults. If you refrain from changing things +from accepted Pyramid cookiecutter defaults. If you refrain from changing things very much, other Pyramid coders will be able to more quickly understand your -application. However, the code layout choices made for you by a scaffold are +application. However, the code layout choices made for you by a cookiecutter are in no way magical or required. Despite the choices made for you by any -scaffold, you can decide to lay your code out any way you see fit. +cookiecutter, you can decide to lay your code out any way you see fit. For example, the configuration method named :meth:`~pyramid.config.Configurator.add_view` requires you to pass a :term:`dotted Python name` or a direct object reference as the class or -function to be used as a view. By default, the ``starter`` scaffold would have +function to be used as a view. By default, the ``starter`` cookiecutter would have you add view functions to the ``views.py`` module in your package. However, you might be more comfortable creating a ``views`` *directory*, and adding a single file for each view. @@ -1010,7 +1060,7 @@ Pyramid application via ``pserve``. This can be a useful debugging tool. See What Is This ``pserve`` Thing ----------------------------- -The code generated by a :app:`Pyramid` scaffold assumes that you will be using +The code generated by a :app:`Pyramid` cookiecutter assumes that you will be using the ``pserve`` command to start your application while you do development. ``pserve`` is a command that reads a :term:`PasteDeploy` ``.ini`` file (e.g., ``development.ini``), and configures a server to serve a :app:`Pyramid` @@ -1020,7 +1070,7 @@ application based on the data in the file. application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to run a :app:`Pyramid` application is purely conventional based on the output of -its scaffolding. But we strongly recommend using ``pserve`` while developing +its cookiecutter. But we strongly recommend using ``pserve`` while developing your application because many other convenience introspection commands (such as ``pviews``, ``prequest``, ``proutes``, and others) are also implemented in terms of configuration availability of this ``.ini`` file format. It also @@ -1032,7 +1082,7 @@ restarting of the server when code changes. Using an Alternate WSGI Server ------------------------------ -Pyramid scaffolds generate projects which use the :term:`Waitress` WSGI server. +Pyramid cookiecutters generate projects which use the :term:`Waitress` WSGI server. Waitress is a server that is suited for development and light production usage. It's not the fastest nor the most featureful WSGI server. Instead, its main feature is that it works on all platforms that Pyramid needs to run on, -- cgit v1.2.3 From 2afc74b72502a6ff5594ccb2e77e5ee427bee2ac Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:39:42 -0800 Subject: tutorials/modwsgi/index - update for cookiecutters --- docs/tutorials/modwsgi/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index c66786b11..568620917 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -73,7 +73,7 @@ specific path information for commands and files. The first argument to ``get_app`` is the project configuration file name. It's best to use the ``production.ini`` file provided by your - scaffold, as it contains settings appropriate for + cookiecutter, as it contains settings appropriate for production. The second is the name of the section within the .ini file that should be loaded by ``mod_wsgi``. The assignment to the name ``application`` is important: mod_wsgi requires finding such an -- cgit v1.2.3 From af33f7133018b8821597cb885ea5c03f225ab77c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:42:48 -0800 Subject: glossary - moar updates for cookiecutters --- docs/designdefense.rst | 2 +- docs/glossary.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 5f65671bb..0a72ff27d 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -591,7 +591,7 @@ extensibility because it must be deployed in multiple locations. Pyramid Is Too Big ------------------ -"The :app:`Pyramid` compressed tarball is larger than 2MB. It must beenormous!" +"The :app:`Pyramid` compressed tarball is larger than 2MB. It must be enormous!" No. We just ship it with docs, test code, and scaffolding. Here's a breakdown of what's included in subdirectories of the package tree: diff --git a/docs/glossary.rst b/docs/glossary.rst index 35d35740d..cd63c5c67 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -992,7 +992,7 @@ Glossary pages rendered by your application, displaying request, routing, and database information. :mod:`pyramid_debugtoolbar` is configured into the ``development.ini`` of all applications which use a Pyramid - :term:`scaffold`. For more information, see + :term:`cookiecutter`. For more information, see http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/. scaffold @@ -1063,7 +1063,7 @@ Glossary Waitress A :term:`WSGI` server that runs on UNIX and Windows under Python 2.6+ - and Python 3.2+. Projects generated via Pyramid scaffolding use + and Python 3.2+. Projects generated via Pyramid cookiecutters use Waitress as a WGSI server. See http://docs.pylonsproject.org/projects/waitress/en/latest/ for detailed information. -- cgit v1.2.3 From d5b5d0829ccab21d8eeb24cb0be54c62cb5ebf80 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:44:48 -0800 Subject: quicktour - moar updates for cookiecutters --- docs/quick_tour.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 186cab29e..053846276 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -116,7 +116,7 @@ part of a web application, web developers need a robust, mature set of software for web requests. Pyramid has always fit nicely into the existing world of Python web development -(virtual environments, packaging, scaffolding, one of the first to embrace +(virtual environments, packaging, cookiecutters, one of the first to embrace Python 3, etc.). Pyramid turned to the well-regarded :term:`WebOb` Python library for request and response handling. In our example above, Pyramid hands ``hello_world`` a ``request`` that is :ref:`based on WebOb `. @@ -547,7 +547,7 @@ Let's look at ``pserve`` and configuration in more depth. .. seealso:: See also: :ref:`Quick Tutorial Cookiecutters `, :ref:`project_narr`, and - :doc:`../narr/scaffolding` + :doc:`../narr/cookiecutters` Application running with ``pserve`` =================================== @@ -613,7 +613,7 @@ We have a few decisions made for us in this configuration: #. *Interfaces:* ``listen = 127.0.0.1:6543 [::1]:6543`` tells ``waitress`` to listen on all interfaces on port 6543 for both IPv4 and IPv6. -Additionally the ``development.ini`` generated by this scaffold wired up +Additionally the ``development.ini`` generated by this cookiecutter wired up Python's standard logging. We'll now see in the console, for example, a log on every request that comes in, as well as traceback information. @@ -893,7 +893,7 @@ database with tables. Let's run it, then start the application: $ $VENV/bin/pserve development.ini The ORM eases the mapping of database structures into a programming language. -SQLAlchemy uses "models" for this mapping. The scaffold generated a sample +SQLAlchemy uses "models" for this mapping. The cookiecutter generated a sample model: .. literalinclude:: quick_tour/sqla_demo/sqla_demo/models/mymodel.py -- cgit v1.2.3 From 8e09458231e1f3431ba3d138f36406f41af7a766 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:45:01 -0800 Subject: latexindex - update for cookiecutters --- docs/latexindex.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/latexindex.rst b/docs/latexindex.rst index a1e70425a..0a6b3400f 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -78,6 +78,7 @@ Narrative Documentation narr/extending narr/advconfig narr/extconfig + narr/cookiecutters narr/scaffolding narr/upgrading narr/threadlocals -- cgit v1.2.3 From b52d1a2b799a425b3f8d6c9faeb3299976fce09b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:51:18 -0800 Subject: quick_tutorial - moar updates for cookiecutters --- docs/quick_tutorial/databases.rst | 2 +- docs/quick_tutorial/ini.rst | 2 +- docs/quick_tutorial/logging.rst | 2 +- docs/quick_tutorial/request_response.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/quick_tutorial/databases.rst b/docs/quick_tutorial/databases.rst index c8d87c180..87f2703c7 100644 --- a/docs/quick_tutorial/databases.rst +++ b/docs/quick_tutorial/databases.rst @@ -21,7 +21,7 @@ storage and retrieval for the wiki pages in the previous step. .. note:: - The ``alchemy`` scaffold is really helpful for getting an SQLAlchemy + The ``pyramid-cookiecutter-alchemy`` cookiecutter is really helpful for getting an SQLAlchemy project going, including generation of the console script. Since we want to see all the decisions, we will forgo convenience in this tutorial, and wire it up ourselves. diff --git a/docs/quick_tutorial/ini.rst b/docs/quick_tutorial/ini.rst index 9a65d66d1..96dfc5b5f 100644 --- a/docs/quick_tutorial/ini.rst +++ b/docs/quick_tutorial/ini.rst @@ -136,7 +136,7 @@ Extra credit .. seealso:: :ref:`project_narr`, - :ref:`scaffolding_chapter`, + :ref:`cookiecutters`, :ref:`what_is_this_pserve_thing`, :ref:`environment_chapter`, :ref:`paste_chapter` diff --git a/docs/quick_tutorial/logging.rst b/docs/quick_tutorial/logging.rst index cbbf7860e..0a530e91f 100644 --- a/docs/quick_tutorial/logging.rst +++ b/docs/quick_tutorial/logging.rst @@ -15,7 +15,7 @@ It's important to know what is going on inside our web application. In development we might need to collect some output. In production, 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 +Fortunately Pyramid uses the normal Python approach to logging. The project 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. diff --git a/docs/quick_tutorial/request_response.rst b/docs/quick_tutorial/request_response.rst index 0ac9b4f6d..ece8cdd6f 100644 --- a/docs/quick_tutorial/request_response.rst +++ b/docs/quick_tutorial/request_response.rst @@ -26,7 +26,7 @@ part of a web application, web developers need a robust, mature set of software for web requests and returning web responses. Pyramid has always fit nicely into the existing world of Python web development -(virtual environments, packaging, scaffolding, first to embrace Python 3, and +(virtual environments, packaging, cookiecutters, first to embrace Python 3, and so on). Pyramid turned to the well-regarded :term:`WebOb` Python library for request and response handling. In our example above, Pyramid hands ``hello_world`` a ``request`` that is :ref:`based on WebOb `. -- cgit v1.2.3 From 72a96e2cb94428bc6ae40048435f0af87703aedf Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:53:23 -0800 Subject: narr/startup - update for cookiecutters --- docs/narr/startup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 1be8037a3..1c2b7c492 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -50,7 +50,7 @@ Here's a high-level time-ordered overview of what happens when you press application or a pipeline, you're using a "composite" (e.g., ``[composite:main]``), refer to the documentation for that particular composite to understand how to make it refer to your :app:`Pyramid` - application. In most cases, a Pyramid application built from a scaffold + application. In most cases, a Pyramid application built from a cookiecutter will have a single ``[app:main]`` section in it, and this will be the application served. -- cgit v1.2.3 From af098b66c60b2451d6e9e932d5b4bddfaa63f323 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 02:53:56 -0800 Subject: narr/webob - update for cookiecutters --- docs/narr/webob.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index ce1586834..578fdeb51 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -345,8 +345,8 @@ against your ``mypackage`` package during application initialization. .. note:: This is only an example. In particular, it is not necessary to cause - ``DBSession.remove`` to be called in an application generated from any - :app:`Pyramid` scaffold, because these all use the ``pyramid_tm`` package. + ``DBSession.remove`` to be called in an application generated from a + :app:`Pyramid` cookiecutter, because these all use the ``pyramid_tm`` package. The cleanup done by ``DBSession.remove`` is unnecessary when ``pyramid_tm`` :term:`middleware` is configured into the application. -- cgit v1.2.3 From fb77c9006eda49c144203a1474fcbeed2fea55cb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 03:00:09 -0800 Subject: quick_tutorial - refactor MyProject/myproject for cookiecutters --- docs/narr/logging.rst | 6 +++--- docs/narr/paste.rst | 22 +++++++++++----------- docs/narr/startup.rst | 6 +++--- docs/narr/testing.rst | 12 ++++++------ 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index ec3590e62..87682158b 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -50,7 +50,7 @@ Default logging configuration is provided in both the default ``development.ini`` and the ``production.ini`` files. If you use ``pyramid-cookiecutter-starter`` to generate a Pyramid project with the name of the package as ``hello_world``, then the logging configuration in the ``development.ini`` file is as follows: -.. literalinclude:: MyProject/development.ini +.. literalinclude:: myproject/development.ini :language: ini :lineno-match: :lines: 29- @@ -253,14 +253,14 @@ translogger and your application in it. For instance, change from this: .. code-block:: ini [app:main] - use = egg:MyProject + use = egg:myproject To this: .. code-block:: ini [app:mypyramidapp] - use = egg:MyProject + use = egg:myproject [filter:translogger] use = egg:Paste#translogger diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index a3f1b866e..2d4e76e24 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -40,25 +40,25 @@ Entry Points and PasteDeploy ``.ini`` Files In the :ref:`project_narr` chapter, we breezed over the meaning of a configuration line in the ``deployment.ini`` file. This was the ``use = -egg:MyProject`` line in the ``[app:main]`` section. We breezed over it because +egg:myproject`` line in the ``[app:main]`` section. We breezed over it because it's pretty confusing and "too much information" for an introduction to the system. We'll try to give it a bit of attention here. Let's see the config file again: -.. literalinclude:: MyProject/development.ini +.. literalinclude:: myproject/development.ini :language: ini :linenos: -The line in ``[app:main]`` above that says ``use = egg:MyProject`` is actually -shorthand for a longer spelling: ``use = egg:MyProject#main``. The ``#main`` +The line in ``[app:main]`` above that says ``use = egg:myproject`` is actually +shorthand for a longer spelling: ``use = egg:myproject#main``. The ``#main`` part is omitted for brevity, as ``#main`` is a default defined by PasteDeploy. -``egg:MyProject#main`` is a string which has meaning to PasteDeploy. It points +``egg:myproject#main`` is a string which has meaning to PasteDeploy. It points at a :term:`setuptools` :term:`entry point` named ``main`` defined in the -``MyProject`` project. +``myproject`` project. Take a look at the generated ``setup.py`` file for this project. -.. literalinclude:: MyProject/setup.py +.. literalinclude:: myproject/setup.py :language: python :linenos: @@ -66,18 +66,18 @@ Note that ``entry_points`` is assigned a string which looks a lot like an ``.ini`` file. This string representation of an ``.ini`` file has a section named ``[paste.app_factory]``. Within this section, there is a key named ``main`` (the entry point name) which has a value ``myproject:main``. The -*key* ``main`` is what our ``egg:MyProject#main`` value of the ``use`` section +*key* ``main`` is what our ``egg:myproject#main`` value of the ``use`` section in our config file is pointing at, although it is actually shortened to -``egg:MyProject`` there. The value represents a :term:`dotted Python name` +``egg:myproject`` there. The value represents a :term:`dotted Python name` path, which refers to a callable in our ``myproject`` package's ``__init__.py`` module. -The ``egg:`` prefix in ``egg:MyProject`` indicates that this is an entry point +The ``egg:`` prefix in ``egg:myproject`` indicates that this is an entry point *URI* specifier, where the "scheme" is "egg". An "egg" is created when you run ``setup.py install`` or ``setup.py develop`` within your project. In English, this entry point can thus be referred to as a "PasteDeploy -application factory in the ``MyProject`` project which has the entry point +application factory in the ``myproject`` project which has the entry point named ``main`` where the entry point refers to a ``main`` function in the ``mypackage`` module". Indeed, if you open up the ``__init__.py`` module generated within any cookiecutter-generated package, you'll see a ``main`` diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 1c2b7c492..cf4612602 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -70,7 +70,7 @@ Here's a high-level time-ordered overview of what happens when you press :app:`Pyramid` :term:`router` instance. Here's the contents of an example ``__init__.py`` module: - .. literalinclude:: MyProject/myproject/__init__.py + .. literalinclude:: myproject/myproject/__init__.py :language: python :linenos: @@ -86,12 +86,12 @@ Here's a high-level time-ordered overview of what happens when you press Our generated ``development.ini`` file looks like so: - .. literalinclude:: MyProject/development.ini + .. literalinclude:: myproject/development.ini :language: ini :linenos: In this case, the ``myproject.__init__:main`` function referred to by the - entry point URI ``egg:MyProject`` (see :ref:`MyProject_ini` for more + entry point URI ``egg:myproject`` (see :ref:`myproject_ini` for more information about entry point URIs, and how they relate to callables) will receive the key/value pairs ``{pyramid.reload_templates = true, pyramid.debug_authorization = false, pyramid.debug_notfound = false, diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 354a462d4..406383bbd 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -370,11 +370,11 @@ coverage reports. Regardless of which testing :term:`package` you use, be sure to add a ``tests_require`` dependency on that package to your application's ``setup.py`` -file. Using the project ``MyProject`` generated by the starter scaffold as +file. Using the project ``myproject`` generated by the starter cookiecutter as described in :doc:`project`, we would insert the following code immediately -following the ``requires`` block in the file ``MyProject/setup.py``. +following the ``requires`` block in the file ``myproject/setup.py``. -.. literalinclude:: MyProject/setup.py +.. literalinclude:: myproject/setup.py :language: python :linenos: :lines: 11-22 @@ -383,7 +383,7 @@ following the ``requires`` block in the file ``MyProject/setup.py``. Remember to change the dependency. -.. literalinclude:: MyProject/setup.py +.. literalinclude:: myproject/setup.py :language: python :linenos: :lines: 40-44 @@ -401,14 +401,14 @@ In your ``MyPackage`` project, your :term:`package` is named ``myproject`` which contains a ``views`` module, which in turn contains a :term:`view` function ``my_view`` that returns an HTML body when the root URL is invoked: - .. literalinclude:: MyProject/myproject/views.py + .. literalinclude:: myproject/myproject/views.py :linenos: :language: python The following example functional test demonstrates invoking the above :term:`view`: - .. literalinclude:: MyProject/myproject/tests.py + .. literalinclude:: myproject/myproject/tests.py :linenos: :pyobject: FunctionalTests :language: python -- cgit v1.2.3 From d81ed38b00b922dc597b676fb39ce7225583e464 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 03:00:38 -0800 Subject: replace pcreate with pserve --- docs/typographical-conventions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/typographical-conventions.rst b/docs/typographical-conventions.rst index 58aaff332..5efc49682 100644 --- a/docs/typographical-conventions.rst +++ b/docs/typographical-conventions.rst @@ -83,7 +83,7 @@ Windows commands are prefixed with a drive letter with an optional directory nam .. code-block:: doscon - c:\> %VENV%\Scripts\pcreate -s starter MyProject + c:\> %VENV%\Scripts\pserve development.ini cfg: -- cgit v1.2.3 From c66842cdc7070758c5b7bd7b89348fa641d456f4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 03:06:06 -0800 Subject: narr/commandline - update for cookiecutters --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 242bc7ec7..98663cca6 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -839,7 +839,7 @@ In general, you can make your script into a console script by doing the following: - Use an existing distribution (such as one you've already created via - ``pcreate``) or create a new distribution that possesses at least one package + ``cookiecutter``) or create a new distribution that possesses at least one package or module. It should, within any module within the distribution, house a callable (usually a function) that takes no arguments and which runs any of the code you wish to run. -- cgit v1.2.3 From b648effe2371f8fdb75c2c4317ef828360bd964a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 03:07:29 -0800 Subject: undo update for tutorials/modwsgi - This requires changes with virtual environments, pcreate, and possibly configuration files. Deferring. --- docs/tutorials/modwsgi/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index 568620917..c66786b11 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -73,7 +73,7 @@ specific path information for commands and files. The first argument to ``get_app`` is the project configuration file name. It's best to use the ``production.ini`` file provided by your - cookiecutter, as it contains settings appropriate for + scaffold, as it contains settings appropriate for production. The second is the name of the section within the .ini file that should be loaded by ``mod_wsgi``. The assignment to the name ``application`` is important: mod_wsgi requires finding such an -- cgit v1.2.3 From 7d16c02d9d1a4c1fd230d7d6a44517e75eb4ae2b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Dec 2016 12:49:03 -0800 Subject: update Sphinx link target --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 10173aec8..ee1808b01 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -111,7 +111,7 @@ following options: You might also need to download and install the Python for Windows extensions. .. seealso:: See the official Python documentation :ref:`Using Python on - Windows ` for full details. + Windows ` for full details. .. seealso:: Download and install the `Python for Windows extensions `_. Carefully read -- cgit v1.2.3 From 43549fb2a3cbe915d8c727cd680e94389532d2e1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 28 Dec 2016 13:47:10 -0800 Subject: fix link target --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index ee1808b01..10173aec8 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -111,7 +111,7 @@ following options: You might also need to download and install the Python for Windows extensions. .. seealso:: See the official Python documentation :ref:`Using Python on - Windows ` for full details. + Windows ` for full details. .. seealso:: Download and install the `Python for Windows extensions `_. Carefully read -- cgit v1.2.3 From b867c82ee8f502ed239a3efa3d5c03685b58c569 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 1 Jan 2017 10:48:42 -0800 Subject: Remove notes about cookiecutter installation, as they now remove sudo for most systems --- docs/tutorials/wiki/installation.rst | 4 ---- docs/tutorials/wiki2/installation.rst | 4 ---- 2 files changed, 8 deletions(-) diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index b99196474..6cd7fbbc2 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -19,10 +19,6 @@ Install cookiecutter -------------------- We will use a :term:`cookiecutter` to create a Python package project from a Python package project template. See `Cookiecutter Installation `_ for instructions. -.. note:: - - At the time of writing, the installation instructions for Cookiecutter suggest the optional use of ``sudo``, implying to install it in the system Python. We suggest that you install it in a virtual environment instead. - Generate a Pyramid project from a cookiecutter ---------------------------------------------- diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 2142a0c0c..794566985 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -31,10 +31,6 @@ Install cookiecutter -------------------- We will use a :term:`cookiecutter` to create a Python package project from a Python package project template. See `Cookiecutter Installation `_ for instructions. -.. note:: - - At the time of writing, the installation instructions for Cookiecutter suggest the optional use of ``sudo``, implying to install it in the system Python. We suggest that you install it in a virtual environment instead. - Generate a Pyramid project from a cookiecutter ---------------------------------------------- -- cgit v1.2.3 From 5e20f9c6686481d67020cf82e18802f06c54964e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 2 Jan 2017 14:32:01 -0600 Subject: improve the registry documentation to cover usage as a dictionary fixes #2891 --- docs/conf.py | 3 ++- pyramid/registry.py | 43 ++++++++++++++++++++++++++++++------------ pyramid/tests/test_registry.py | 4 ++++ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 5eb18f15f..d61df6580 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -81,7 +81,8 @@ intersphinx_mapping = { 'webtest': ('http://webtest.pythonpaste.org/en/latest', None), 'who': ('http://repozewho.readthedocs.org/en/latest', None), 'zcml': ('http://docs.pylonsproject.org/projects/pyramid-zcml/en/latest', None), - 'zcomponent': ('http://zopecomponent.readthedocs.io/en/stable/', None), + 'zcomponent': ('http://zopecomponent.readthedocs.io/en/latest/', None), + 'zinterface': ('http://zopeinterface.readthedocs.io/en/latest/', None), } diff --git a/pyramid/registry.py b/pyramid/registry.py index df9a10822..e2bcba9f9 100644 --- a/pyramid/registry.py +++ b/pyramid/registry.py @@ -9,28 +9,44 @@ from pyramid.compat import text_ from pyramid.decorator import reify from pyramid.interfaces import ( - ISettings, IIntrospector, IIntrospectable, + ISettings, ) +from pyramid.path import ( + CALLER_PACKAGE, + caller_package, +) + empty = text_('') class Registry(Components, dict): - """ A registry object is an :term:`application registry`. It is used by - the framework itself to perform mappings of URLs to view callables, as - well as servicing other various framework duties. A registry has its own - internal API, but this API is rarely used by Pyramid application - developers (it's usually only used by developers of the Pyramid - framework). But it has a number of attributes that may be useful to - application developers within application code, such as ``settings``, - which is a dictionary containing application deployment settings. + """ A registry object is an :term:`application registry`. + + It is used by the framework itself to perform mappings of URLs to view + callables, as well as servicing other various framework duties. A registry + has its own internal API, but this API is rarely used by Pyramid + application developers (it's usually only used by developers of the + Pyramid framework and Pyramid addons). But it has a number of attributes + that may be useful to application developers within application code, + such as ``settings``, which is a dictionary containing application + deployment settings. For information about the purpose and usage of the application registry, see :ref:`zca_chapter`. + The registry may be used both as an :class:`pyramid.interfaces.IDict` and + as a Zope component registry. + These two ways of storing configuration are independent. + Applications will tend to prefer to store information as key-values + whereas addons may prefer to use the component registry to avoid naming + conflicts and to provide more complex lookup mechanisms. + The application registry is usually accessed as ``request.registry`` in - application code. + application code. By the time a registry is used to handle requests it + should be considered frozen and read-only. Any changes to its internal + state should be done with caution and concern for thread-safety. """ @@ -40,13 +56,16 @@ class Registry(Components, dict): _settings = None - def __init__(self, *arg, **kw): + def __init__(self, package_name=CALLER_PACKAGE): # add a registry-instance-specific lock, which is used when the lookup # cache is mutated self._lock = threading.Lock() # add a view lookup cache self._clear_view_lookup_cache() - Components.__init__(self, *arg, **kw) + if package_name is CALLER_PACKAGE: + package_name = caller_package().__name__ + Components.__init__(self, package_name) + dict.__init__(self) def _clear_view_lookup_cache(self): self._view_lookup_cache = {} diff --git a/pyramid/tests/test_registry.py b/pyramid/tests/test_registry.py index c9dff5b22..7b3357e61 100644 --- a/pyramid/tests/test_registry.py +++ b/pyramid/tests/test_registry.py @@ -27,6 +27,10 @@ class TestRegistry(unittest.TestCase): registry = self._getTargetClass()(package_name) self.assertEqual(registry.package_name, package_name) + def test_default_package_name(self): + registry = self._getTargetClass()() + self.assertEqual(registry.package_name, 'pyramid.tests') + def test_registerHandler_and_notify(self): registry = self._makeOne() self.assertEqual(registry.has_listeners, False) -- cgit v1.2.3 From bdb8e0a9d0c55110e58a28f35a871c8e46a2f951 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 2 Jan 2017 17:47:38 -0600 Subject: changelog for #2893 --- CHANGES.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 48c4e4fe2..9571666e9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,12 @@ +unreleased +========== + +Documentation Changes +--------------------- + +- Improve registry documentation to discuss uses as a component registry + and as a dictionary. See https://github.com/Pylons/pyramid/pull/2893 + 1.8a1 (2016-12-25) ================== -- cgit v1.2.3 From a36d33bf7872575fb79cdc0e5959a62b30df5742 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 2 Jan 2017 17:18:12 -0800 Subject: Waitress dropped 2.6 and 3.2 support --- docs/glossary.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index cd63c5c67..b4673f73e 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1062,8 +1062,8 @@ Glossary :class:`pyramid.interfaces.IAssetDescriptor`. Waitress - A :term:`WSGI` server that runs on UNIX and Windows under Python 2.6+ - and Python 3.2+. Projects generated via Pyramid cookiecutters use + A :term:`WSGI` server that runs on UNIX and Windows under Python 2.7+ + and Python 3.3+. Projects generated via Pyramid cookiecutters use Waitress as a WGSI server. See http://docs.pylonsproject.org/projects/waitress/en/latest/ for detailed information. -- cgit v1.2.3 From fca6c19ae2dd13f6d9036a2bb8117d997b773235 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 2 Jan 2017 19:12:37 -0800 Subject: add changelog and whatsnew entry for #2888 and #2889 --- CHANGES.txt | 5 +++++ docs/whatsnew-1.8.rst | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 48c4e4fe2..86ae2bce7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -258,3 +258,8 @@ Documentation Changes - Improve output of p* script descriptions for help. See https://github.com/Pylons/pyramid/pull/2886 + +- Quick Tour, Quick Tutorial, and most files throughout the documentation have + been updated to use cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2888 and + https://github.com/Pylons/pyramid/pull/2889 diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index e666f0cd1..908c17ec4 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -212,3 +212,8 @@ Documentation Enhancements See https://github.com/Pylons/pyramid/pull/2881 and https://github.com/Pylons/pyramid/pull/2883. + +- Quick Tour, Quick Tutorial, and most files throughout the documentation have + been updated to use cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2888 and + https://github.com/Pylons/pyramid/pull/2889 -- cgit v1.2.3 From e2f85af76722bdc8ddae25ce8dc39eac2df7bb25 Mon Sep 17 00:00:00 2001 From: ramgoer Date: Sun, 8 Jan 2017 15:20:59 +0900 Subject: Update project.rst incorrect cookietcutter path for windows environment %VENV%\Scripts\cookiecutter --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 61759fe34..17005f15c 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -95,7 +95,7 @@ Or on Windows: .. code-block:: doscon - c:\> %VENV%\cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter + c:\> %VENV%\Scripts\cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter If prompted for the first item, accept the default ``yes`` by hitting return. -- cgit v1.2.3 From 0844c664ad00fcbb6600231a012ad6384da15f5a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 24 Dec 2016 14:23:47 -0600 Subject: require tests to pass on py36 on travis and appveyor --- .travis.yml | 3 +-- appveyor.yml | 2 ++ tox.ini | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 02e844196..b0e63ba97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,12 +18,11 @@ matrix: env: TOXENV=docs - python: 3.5 env: TOXENV=pep8 - - python: 3.6-dev + - python: 3.6 env: TOXENV=py36 - python: nightly env: TOXENV=py37 allow_failures: - - env: TOXENV=py36 - env: TOXENV=py37 install: diff --git a/appveyor.yml b/appveyor.yml index 4c684bfc6..abbbfea92 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,7 @@ environment: matrix: + - PYTHON: "C:\\Python36" + TOXENV: "py36" - PYTHON: "C:\\Python35" TOXENV: "py35" - PYTHON: "C:\\Python27" diff --git a/tox.ini b/tox.ini index d1df0f031..242decfc4 100644 --- a/tox.ini +++ b/tox.ini @@ -40,6 +40,12 @@ commands = python pyramid/scaffolds/tests.py deps = virtualenv +[testenv:py36-scaffolds] +basepython = python3.6 +commands = + python pyramid/scaffolds/tests.py +deps = virtualenv + [testenv:pypy-scaffolds] basepython = pypy commands = -- cgit v1.2.3 From fb7a98bbdacebc4edfef8fb3e6093bb9e6590111 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 10 Jan 2017 01:16:42 -0600 Subject: fix unittests in wiki2 to work without deps on py2 and py3 fixes #2882 --- .../wiki2/src/tests/tutorial/tests/test_initdb.py | 18 +++++++----------- .../wiki2/src/tests/tutorial/tests/test_security.py | 8 +++++--- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py index 97511d5e8..f5273456e 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py @@ -1,20 +1,16 @@ -import mock +import os import unittest class TestInitializeDB(unittest.TestCase): - @mock.patch('tutorial.scripts.initializedb.sys') - def test_usage(self, mocked_sys): + def test_usage(self): from ..scripts.initializedb import main - main(argv=['foo']) - mocked_sys.exit.assert_called_with(1) + with self.assertRaises(SystemExit): + main(argv=['foo']) - @mock.patch('tutorial.scripts.initializedb.get_tm_session') - @mock.patch('tutorial.scripts.initializedb.sys') - def test_run(self, mocked_sys, mocked_session): + def test_run(self): from ..scripts.initializedb import main main(argv=['foo', 'development.ini']) - mocked_session.assert_called_once() - - + self.assertTrue(os.path.exists('tutorial.sqlite')) + os.remove('tutorial.sqlite') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py index 4c3b72946..cbec6420d 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py @@ -1,11 +1,11 @@ -import mock import unittest +from pyramid.testing import DummyRequest class TestMyAuthenticationPolicy(unittest.TestCase): def test_no_user(self): - request = mock.Mock() + request = DummyRequest() request.user = None from ..security import MyAuthenticationPolicy @@ -13,7 +13,9 @@ class TestMyAuthenticationPolicy(unittest.TestCase): self.assertEqual(policy.authenticated_userid(request), None) def test_authenticated_user(self): - request = mock.Mock() + from ..models import User + request = DummyRequest() + request.user = User() request.user.id = 'foo' from ..security import MyAuthenticationPolicy -- cgit v1.2.3 From 47e51ddff121e0ab18d3151870c00cb536e500e7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 10 Jan 2017 11:53:06 -0800 Subject: update docs per https://github.com/Pylons/pyramid/commit/fb7a98bbdacebc4edfef8fb3e6093bb9e6590111 --- docs/tutorials/wiki2/tests.rst | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index 67c7e65e0..e1f83a755 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -50,20 +50,36 @@ so on. View the results of all our edits to ``tests`` subpackage ========================================================= -Open ``tutorial/tests/test_views.py``, and edit it such that it appears as -follows: +Create ``tutorial/tests/test_views.py`` such that it appears as follows: .. literalinclude:: src/tests/tutorial/tests/test_views.py :linenos: :language: python -Open ``tutorial/tests/test_functional.py``, and edit it such that it appears as -follows: +Create ``tutorial/tests/test_functional.py`` such that it appears as follows: .. literalinclude:: src/tests/tutorial/tests/test_functional.py :linenos: :language: python +Create ``tutorial/tests/test_initdb.py`` such that it appears as follows: + +.. literalinclude:: src/tests/tutorial/tests/test_initdb.py + :linenos: + :language: python + +Create ``tutorial/tests/test_security.py`` such that it appears as follows: + +.. literalinclude:: src/tests/tutorial/tests/test_security.py + :linenos: + :language: python + +Create ``tutorial/tests/test_user_model.py`` such that it appears as follows: + +.. literalinclude:: src/tests/tutorial/tests/test_user_model.py + :linenos: + :language: python + .. note:: @@ -77,32 +93,27 @@ follows: Running the tests ================= -We can run these tests similarly to how we did in :ref:`running_tests`: +We can run these tests similarly to how we did in :ref:`running_tests`, but first delete the SQLite database ``tutorial.sqlite``. If you do not delete the database, then you will see an integrity error when running the tests. On UNIX: .. code-block:: bash + $ rm tutorial.sqlite $ $VENV/bin/py.test -q On Windows: .. code-block:: doscon + c:\tutorial> del tutorial.sqlite c:\tutorial> %VENV%\Scripts\py.test -q The expected result should look like the following: .. code-block:: text - ...................... - 22 passed, 1 pytest-warnings in 5.81 seconds - -.. note:: If you use Python 3 during this tutorial, you will see deprecation - warnings in the output, which we will choose to ignore. In making this - tutorial run on both Python 2 and 3, the authors prioritized simplicity and - focus for the learner over accommodating warnings. In your own app or as - extra credit, you may choose to either drop Python 2 support or hack your - code to work without warnings on both Python 2 and 3. + ................................ + 32 passed in 9.90 seconds .. _webtest: http://docs.pylonsproject.org/projects/webtest/en/latest/ -- cgit v1.2.3 From 9cd5b66b9d3cd59e0aac11460077a1722b420924 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 15 Jan 2017 13:37:36 -0800 Subject: Update Windows installation docs --- docs/narr/install.rst | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 10173aec8..59ef9210d 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -91,29 +91,22 @@ If your Windows system doesn't have a Python interpreter, you'll need to install it by downloading a Python 3.x-series interpreter executable from `python.org's download section `_ (the files labeled "Windows Installer"). Once you've downloaded it, double click on the -executable, and select appropriate options during the installation process. To +executable and select appropriate options during the installation process. To standardize this documentation, we used the GUI installer and selected the following options: - Screen 1: Install Python 3.x.x (32- or 64-bit) - - Check "Install launcher for all users (recommended)" - - Check "Add Python 3.x to PATH" - - Click "Customize installation" -- Screen 2: Optional Features - - Check all options - - Click "Next" -- Screen 3: Advanced Options - - Check all options - - Customize install location: "C:\\Python3x", where "x" is the minor - version of Python - - Click "Next" - -You might also need to download and install the Python for Windows extensions. + - Check "Install launcher for all users (recommended)". + - Check "Add Python 3.x to PATH". + - Click "Install Now". +- Screen 2: User Account Control + - Click "Yes". .. seealso:: See the official Python documentation :ref:`Using Python on Windows ` for full details. -.. seealso:: Download and install the `Python for Windows extensions +.. seealso:: You might also need to download and install the `Python for + Windows extensions `_. Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper 32- or 64-bit build and Python @@ -123,15 +116,21 @@ You might also need to download and install the Python for Windows extensions. `_ provides a command ``py`` that allows users to run any installed version of Python. -.. warning:: - - After you install Python on Windows, you might need to add the - ``c:\Python3x`` directory to your environment's ``Path``, where ``x`` is the - minor version of installed Python, in order to make it possible to invoke - Python from a command prompt by typing ``python``. To do so, right click - ``My Computer``, select ``Properties`` --> ``Advanced Tab`` --> - ``Environment Variables``, and add that directory to the end of the ``Path`` - environment variable. +.. warning:: After you install Python on Windows, you might need to add the + directory where Python and other programs—such as pip, setuptools, and + cookiecutter—are installed to your environment's ``Path``. This will make it + possible to invoke them from a command prompt. + + To do so, search for "Environment Variables" on your computer (on Windows + 10, it is under ``System Properties`` --> ``Advanced``) and append that + directory to the end of the ``Path`` environment variable, separating each + path segment with a semi-colon (;) or use the GUI to add New or Edit + existing path segments. Example segments should look like + ``C:\Users\\AppData\Local\Programs\Python3x-32``, where you have + your username instead of the bracketed example, and your version of Python + and whether it is 32- or 64-bit. Additionally ensure you have the path + segment ending with ``\Scripts``, i.e., + ``C:\Users\\AppData\Local\Programs\Python3x-32\Scripts``. .. seealso:: See `Configuring Python (on Windows) `_ for @@ -231,9 +230,9 @@ After installing Python as described previously in .. code-block:: doscon + c:\> cd \dir c:\> set VENV=c:\env - # replace "x" with your minor version of Python 3 - c:\> c:\Python3x\python -m venv %VENV% + c:\> python -m venv %VENV% c:\> cd %VENV% You can either follow the use of the environment variable ``%VENV%``, or -- cgit v1.2.3 From 7ed8e2e83a7b71d171989600c6c04dc50c1be34d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 15 Jan 2017 15:37:44 -0800 Subject: Update Windows docs - Installation overhauled - update project.rst to remove duplication - Windows paths never end with "\" except for a drive name, for example C:\ - use backslashes for paths - backslashes cannot be used for line continuation on Windows - update extra packages for Windows - Python now has a Windows launcher --- docs/narr/install.rst | 23 ++++++++++++++--------- docs/narr/project.rst | 30 ++++++++++-------------------- docs/narr/upgrading.rst | 2 +- docs/quick_tutorial/requirements.rst | 4 ++-- docs/tutorials/wiki/installation.rst | 7 +++---- docs/tutorials/wiki2/installation.rst | 4 ++-- 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 59ef9210d..2a25ad84d 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -122,15 +122,20 @@ following options: possible to invoke them from a command prompt. To do so, search for "Environment Variables" on your computer (on Windows - 10, it is under ``System Properties`` --> ``Advanced``) and append that - directory to the end of the ``Path`` environment variable, separating each - path segment with a semi-colon (;) or use the GUI to add New or Edit - existing path segments. Example segments should look like + 10, it is under ``System Properties`` --> ``Advanced``) and add that + directory to the ``Path`` environment variable, using the GUI to edit path + segments. + + Example segments should look like ``C:\Users\\AppData\Local\Programs\Python3x-32``, where you have - your username instead of the bracketed example, and your version of Python - and whether it is 32- or 64-bit. Additionally ensure you have the path - segment ending with ``\Scripts``, i.e., - ``C:\Users\\AppData\Local\Programs\Python3x-32\Scripts``. + your username instead of ````, and your version of Python and + whether it is 32- or 64-bit. Additionally ensure you have the path segment + ending with ``\Scripts``, i.e., + ``C:\Users\\AppData\Local\Programs\Python3x-32\Scripts``, and for + user-installed Python programs, ``%APPDATA%\Python\Python3x\Scripts``. + + You may need to restart your command prompt session to load the environment + variables. .. seealso:: See `Configuring Python (on Windows) `_ for @@ -230,7 +235,7 @@ After installing Python as described previously in .. code-block:: doscon - c:\> cd \dir + c:\> cd \ c:\> set VENV=c:\env c:\> python -m venv %VENV% c:\> cd %VENV% diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 17005f15c..3d17a4191 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -75,27 +75,17 @@ In :ref:`installing_chapter`, you created a virtual Python environment via the ``venv`` command. We called the virtual environment directory ``env`` and set an environment variable ``VENV`` to its path. -We assume that you previously installed cookiecutter using the following command: - -.. code-block:: bash - - $ $VENV/bin/pip install cookiecutter +We assume that you :ref:`previously installed cookiecutter `, following its installation instructions. We'll choose ``pyramid-cookiecutter-starter`` to start the project. When we invoke ``cookiecutter``, it will create a directory that represents our project. -The following commands assume that our current working directory is the value of ``$VENV``. +We assume our current working directory is the value of ``VENV``. -On UNIX: +On all platforms, generate a project using cookiecutter. .. code-block:: bash - $ $VENV/bin/cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter - -Or on Windows: - -.. code-block:: doscon - - c:\> %VENV%\Scripts\cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter + $ cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter If prompted for the first item, accept the default ``yes`` by hitting return. @@ -128,9 +118,9 @@ Or on Windows: # Change directory into your newly created project. c:\> cd myproject # Create a new virtual environment... - c:\myproject\> c:\Python3x\python -m venv %VENV% + c:\myproject> python -m venv %VENV% # ...where we upgrade packaging tools. - c:\myproject\> %VENV%\Scripts\pip install --upgrade pip setuptools + c:\myproject> %VENV%\Scripts\pip install --upgrade pip setuptools As a result of invoking the ``cookiecutter`` command, a directory named ``myproject`` is created. That directory is a :term:`project` directory. The @@ -201,7 +191,7 @@ Or on Windows: .. code-block:: doscon - c:\env\myproject\> %VENV%\Scripts\pip install -e . + c:\env\myproject> %VENV%\Scripts\pip install -e . Elided output from a run of this command on UNIX is shown below: @@ -239,7 +229,7 @@ On Windows: .. code-block:: doscon - c:\env\myproject\> %VENV%\Scripts\pip install -e ".[testing]" + c:\env\myproject> %VENV%\Scripts\pip install -e ".[testing]" Once the testing requirements are installed, then you can run the tests using the ``py.test`` command that was just installed in the ``bin`` directory of @@ -255,7 +245,7 @@ On Windows: .. code-block:: doscon - c:\env\myproject\> %VENV%\Scripts\py.test -q + c:\env\myproject> %VENV%\Scripts\py.test -q Here's sample output from a test run on UNIX: @@ -320,7 +310,7 @@ On Windows: .. code-block:: doscon - c:\env\myproject\> %VENV%\Scripts\pserve development.ini + c:\env\myproject> %VENV%\Scripts\pserve development.ini Here's sample output from a run of ``pserve`` on UNIX: diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index 4e434c3c6..e0482d5a2 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -208,7 +208,7 @@ On Windows, you need to issue two commands: .. code-block:: doscon c:\> set PYTHONWARNINGS=default - c:\> Scripts/pserve.exe development.ini + c:\> Scripts\pserve development.ini At this point, it's ensured that deprecation warnings will be printed to the console whenever a codepath is hit that generates one. You can then click diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index f95dac488..70e68514b 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -156,7 +156,7 @@ environment variable. .. code-block:: doscon # Windows - c:\> c:\Python35\python -m venv %VENV% + c:\> python -m venv %VENV% .. seealso:: See also Python 3's :mod:`venv module ` and Python 2's `virtualenv `_ package. @@ -214,4 +214,4 @@ tutorial. .. code-block:: doscon # Windows - c:\> %VENV%\Scripts\pip install webtest deform sqlalchemy pyramid_chameleon pyramid_debugtoolbar pyramid_jinja2 waitress pyramid_tm zope.sqlalchemy + c:\> %VENV%\Scripts\pip install webtest pytest pytest-cov deform sqlalchemy pyramid_chameleon pyramid_debugtoolbar pyramid_jinja2 waitress pyramid_tm zope.sqlalchemy diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index 6cd7fbbc2..c735bdf9d 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -102,7 +102,7 @@ On UNIX On Windows ^^^^^^^^^^ -Each version of Python uses different paths, so you will need to adjust the path to the command for your Python version. +Each version of Python uses different paths, so you might need to adjust the path to the command for your Python version. Recent versions of the Python 3 installer for Windows now install a Python launcher. Python 2.7: @@ -114,7 +114,7 @@ Python 3.6: .. code-block:: doscon - c:\tutorial> c:\Python36\Scripts\python -m venv %VENV% + c:\tutorial> python -m venv %VENV% Upgrade packaging tools in the virtual environment @@ -242,8 +242,7 @@ On Windows .. code-block:: doscon - c:\tutorial> %VENV%\Scripts\py.test --cov \ - --cov-report=term-missing + c:\tutorial> %VENV%\Scripts\py.test --cov --cov-report=term-missing If successful, you will see output something like this: diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 794566985..fd323fcfc 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -114,7 +114,7 @@ On UNIX On Windows ^^^^^^^^^^ -Each version of Python uses different paths, so you will need to adjust the path to the command for your Python version. +Each version of Python uses different paths, so you will need to adjust the path to the command for your Python version. Recent versions of the Python 3 installer for Windows now install a Python launcher. Python 2.7: @@ -126,7 +126,7 @@ Python 3.6: .. code-block:: doscon - c:\tutorial> c:\Python36\Scripts\python -m venv %VENV% + c:\tutorial> python -m venv %VENV% Upgrade packaging tools in the virtual environment -- cgit v1.2.3 From e82f3d1f30eae5f6b8b0c490cc404e973f512d2f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 15 Jan 2017 21:38:47 -0600 Subject: changelog cleanups --- CHANGES.txt | 16 ++++++++++++---- docs/whatsnew-1.8.rst | 8 ++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3b849a49b..261d45a13 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,16 @@ Documentation Changes - Improve registry documentation to discuss uses as a component registry and as a dictionary. See https://github.com/Pylons/pyramid/pull/2893 +- Quick Ttutorial and most other remaining documentation updated to use + cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2889 + +- Fix unittests in wiki2 to work without different dependencies between + py2 and py3. See https://github.com/Pylons/pyramid/pull/2899 + +- Update Windows documentation to track newer Python 3 improvements to the + installer. See https://github.com/Pylons/pyramid/pull/2900 + 1.8a1 (2016-12-25) ================== @@ -268,7 +278,5 @@ Documentation Changes - Improve output of p* script descriptions for help. See https://github.com/Pylons/pyramid/pull/2886 -- Quick Tour, Quick Tutorial, and most files throughout the documentation have - been updated to use cookiecutters instead of pcreate and scaffolds. - See https://github.com/Pylons/pyramid/pull/2888 and - https://github.com/Pylons/pyramid/pull/2889 +- Quick Tour updated to use cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2888 diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 908c17ec4..ece26f8d1 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -73,6 +73,10 @@ Minor Feature Additions exception - the pipeline can be optimized at config-time. See https://github.com/Pylons/pyramid/pull/2660 +- ``pcreate`` learned about ``--package-name`` to allow you to create a new + project in an existing folder with a different package name than the project + name. See https://github.com/Pylons/pyramid/pull/2783 + - ``pserve`` should now work with ``gevent`` and other workers that need to monkeypatch the process, assuming the server and / or the app do so as soon as possible before importing the rest of pyramid. @@ -129,10 +133,6 @@ Backwards Incompatibilities encoding via ``Accept-Encoding`` request headers. See https://github.com/Pylons/pyramid/pull/2810 -- ``pcreate`` learned about ``--package-name`` to allow you to create a new - project in an existing folder with a different package name than the project - name. See https://github.com/Pylons/pyramid/pull/2783 - - ``pcreate`` is now interactive by default. You will be prompted if a file already exists with different content. Previously if there were similar files it would silently skip them unless you specified ``--interactive`` -- cgit v1.2.3 From 8eac26ea9b30d5683d70275cda32952b4927b4d9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 15 Jan 2017 21:10:23 -0800 Subject: Fix typo and add PR reference --- CHANGES.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 261d45a13..5db5ae002 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,9 +7,10 @@ Documentation Changes - Improve registry documentation to discuss uses as a component registry and as a dictionary. See https://github.com/Pylons/pyramid/pull/2893 -- Quick Ttutorial and most other remaining documentation updated to use - cookiecutters instead of pcreate and scaffolds. - See https://github.com/Pylons/pyramid/pull/2889 +- Quick Tour, Quick Tutorial, and most other remaining documentation updated to + use cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2888 and + https://github.com/Pylons/pyramid/pull/2889 - Fix unittests in wiki2 to work without different dependencies between py2 and py3. See https://github.com/Pylons/pyramid/pull/2899 -- cgit v1.2.3 From 7af93317a111d328825dd97ec1772143b799bb2e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 15 Jan 2017 22:42:38 -0600 Subject: update mod_wsgi tutorial to use a cookiecutter closes #2890 --- docs/tutorials/modwsgi/index.rst | 70 +++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index c66786b11..ef42589c6 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -32,60 +32,59 @@ specific path information for commands and files. `_ for your platform into your system's Apache installation. -#. Create a :term:`virtual environment` which we'll use to install our - application. +#. Create a :app:`Pyramid` application. For this tutorial we'll use the + ``starter`` :term:`cookiecutter`. See :ref:`project_narr` for more + in-depth information about creating a new project. - .. code-block:: text + .. code-block:: bash $ cd ~ - $ mkdir modwsgi - $ cd modwsgi - $ python3 -m venv env + $ cookiecutter https://github.com/Pylons/pyramid-cookiecutter-starter + project_name [Pyramid Scaffold]: myproject + repo_name [scaffold]: myproject -#. Install :app:`Pyramid` into the newly created virtual environment: +#. Create a :term:`virtual environment` which we'll use to install our + application. It is important to use the same base Python interpreter + that was used to build ``mod_wsgi``. For example, if ``mod_wsgi`` was + built against the system Python 3.x, then your project should use a + virtual environment created from that same system Python 3.x. - .. parsed-literal:: + .. code-block:: bash - $ cd ~/modwsgi/env - $ $VENV/bin/pip install "pyramid==\ |release|\ " + $ cd myproject + $ python3 -m venv env -#. Create and install your :app:`Pyramid` application. For the purposes of - this tutorial, we'll just be using the ``pyramid_starter`` application as - a baseline application. Substitute your existing :app:`Pyramid` - application as necessary if you already have one. +#. Install your :app:`Pyramid` application and its dependencies. - .. code-block:: text + .. code-block:: bash - $ cd ~/modwsgi/env - $ $VENV/bin/pcreate -s starter myapp - $ cd myapp - $ $VENV/bin/pip install -e . + $ env/bin/pip install -e . -#. Within the virtual environment directory (``~/modwsgi/env``), create a - script named ``pyramid.wsgi``. Give it these contents: +#. Within the project directory (``~/myproject``), create a script + named ``pyramid.wsgi``. Give it these contents: .. code-block:: python from pyramid.paster import get_app, setup_logging - ini_path = '/Users/chrism/modwsgi/env/myapp/production.ini' + ini_path = '/Users/chrism/myproject/production.ini' setup_logging(ini_path) application = get_app(ini_path, 'main') - The first argument to ``get_app`` is the project configuration file - name. It's best to use the ``production.ini`` file provided by your - scaffold, as it contains settings appropriate for - production. The second is the name of the section within the .ini file - that should be loaded by ``mod_wsgi``. The assignment to the name + The first argument to :func:`pyramid.paster.get_app` is the project + configuration file name. It's best to use the ``production.ini`` file + provided by your cookiecutter, as it contains settings appropriate for + production. The second is the name of the section within the ``.ini`` + file that should be loaded by ``mod_wsgi``. The assignment to the name ``application`` is important: mod_wsgi requires finding such an assignment when it opens the file. - The call to ``setup_logging`` initializes the standard library's - `logging` module to allow logging within your application. + The call to :func:`pyramid.paster.setup_logging` initializes the standard + library's `logging` module to allow logging within your application. See :ref:`logging_config`. There is no need to make the ``pyramid.wsgi`` script executable. However, you'll need to make sure that *two* users have access to change - into the ``~/modwsgi/env`` directory: your current user (mine is + into the ``~/myproject`` directory: your current user (mine is ``chrism`` and the user that Apache will run as often named ``apache`` or ``httpd``). Make sure both of these users can "cd" into that directory. @@ -101,18 +100,17 @@ specific path information for commands and files. WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On WSGIDaemonProcess pyramid user=chrism group=staff threads=4 \ - python-path=/Users/chrism/modwsgi/env/lib/python2.7/site-packages - WSGIScriptAlias /myapp /Users/chrism/modwsgi/env/pyramid.wsgi + python-path=/Users/chrism/myproject/env/lib/python3.5/site-packages + WSGIScriptAlias /myapp /Users/chrism/myproject/pyramid.wsgi - + WSGIProcessGroup pyramid - Order allow,deny - Allow from all + Require all granted #. Restart Apache - .. code-block:: text + .. code-block:: bash $ sudo /usr/sbin/apachectl restart -- cgit v1.2.3 From 776666628b70fe80ca42d60d161c946397a48ed0 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 15 Jan 2017 23:27:00 -0600 Subject: changelog for #2901 --- CHANGES.txt | 3 +++ docs/whatsnew-1.8.rst | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 5db5ae002..2ca81db40 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -18,6 +18,9 @@ Documentation Changes - Update Windows documentation to track newer Python 3 improvements to the installer. See https://github.com/Pylons/pyramid/pull/2900 +- Updated the ``mod_wsgi`` tutorial to use cookiecutters and Apache 2.4+. + See https://github.com/Pylons/pyramid/pull/2901 + 1.8a1 (2016-12-25) ================== diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index ece26f8d1..d0954f62b 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -217,3 +217,6 @@ Documentation Enhancements been updated to use cookiecutters instead of pcreate and scaffolds. See https://github.com/Pylons/pyramid/pull/2888 and https://github.com/Pylons/pyramid/pull/2889 + +- Updated the ``mod_wsgi`` tutorial to use cookiecutters and Apache 2.4+. + See https://github.com/Pylons/pyramid/pull/2901 -- cgit v1.2.3 From b24aeb73e7849dc360aefb634376ef0595abd0ca Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 16 Jan 2017 23:26:17 -0600 Subject: avoid doing lookup in loop --- pyramid/config/i18n.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 9387a693b..9538d766b 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -68,11 +68,12 @@ class I18NConfiguratorMixin(object): earlier in the list trump ones later in the list). """ - directories = [] introspectables = [] - resolver = AssetResolver(self.package_name) def register(): + directories = [] + resolver = AssetResolver(self.package_name) + # defer spec resolution until register to allow for asset # overrides to take place in an earlier config phase for spec in specs[::-1]: # reversed @@ -91,13 +92,11 @@ class I18NConfiguratorMixin(object): introspectables.append(intr) directories.append(directory) + tdirs = self.registry.queryUtility(ITranslationDirectories) + if tdirs is None: + tdirs = [] + self.registry.registerUtility(tdirs, ITranslationDirectories) for directory in directories: - tdirs = self.registry.queryUtility(ITranslationDirectories) - if tdirs is None: - tdirs = [] - self.registry.registerUtility(tdirs, - ITranslationDirectories) - tdirs.insert(0, directory) self.action(None, register, introspectables=introspectables) -- cgit v1.2.3 From c1374524655ac9da42c6f45281f5e11b086f5973 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Jan 2017 01:07:58 -0600 Subject: fix the add_translation_dirs documentation to reflect the current impl fixes #1473 --- pyramid/config/i18n.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 9538d766b..96fd30a51 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -57,15 +57,19 @@ class I18NConfiguratorMixin(object): config.add_translation_dirs('/usr/share/locale', 'some.package:locale') - Later calls to ``add_translation_dir`` insert directories into the - beginning of the list of translation directories created by earlier - calls. This means that the same translation found in a directory - added later in the configuration process will be found before one - added earlier in the configuration process. However, if multiple - specs are provided in a single call to ``add_translation_dirs``, the - directories will be inserted into the beginning of the directory list - in the order they're provided in the ``*specs`` list argument (items - earlier in the list trump ones later in the list). + The translation directories are defined as a list in which + translations defined later have precedence over translations defined + earlier. + + If multiple specs are provided in a single call to + ``add_translation_dirs``, the directories will be inserted in the + order they're provided (earlier items are trumped by later items). + + .. warning:: + + Consecutive calls to ``add_translation_dirs`` will sort the + directories such that the later calls will add folders with + lower precedence than earlier calls. """ introspectables = [] @@ -76,7 +80,7 @@ class I18NConfiguratorMixin(object): # defer spec resolution until register to allow for asset # overrides to take place in an earlier config phase - for spec in specs[::-1]: # reversed + for spec in specs[::-1]: # reversed # the trailing slash helps match asset overrides for folders if not spec.endswith('/'): spec += '/' -- cgit v1.2.3 From d009c0bda6723df3124da3b5c10ef6e1f961fcd5 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Jan 2017 01:41:51 -0600 Subject: add ``override`` option to ``add_translation_dirs`` fixes #1474 --- pyramid/config/i18n.py | 28 ++++++++++++++++++++-------- pyramid/tests/test_config/test_i18n.py | 17 +++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/pyramid/config/i18n.py b/pyramid/config/i18n.py index 96fd30a51..9c5b7e682 100644 --- a/pyramid/config/i18n.py +++ b/pyramid/config/i18n.py @@ -42,7 +42,7 @@ class I18NConfiguratorMixin(object): self.registry.registerUtility(locale_negotiator, ILocaleNegotiator) @action_method - def add_translation_dirs(self, *specs): + def add_translation_dirs(self, *specs, **kw): """ Add one or more :term:`translation directory` paths to the current configuration state. The ``specs`` argument is a sequence that may contain absolute directory paths @@ -61,18 +61,27 @@ class I18NConfiguratorMixin(object): translations defined later have precedence over translations defined earlier. + By default, consecutive calls to ``add_translation_dirs`` will add + directories to the start of the list. This means later calls to + ``add_translation_dirs`` will have their translations trumped by + earlier calls. If you explicitly need this call to trump an earlier + call then you may set ``override`` to ``True``. + If multiple specs are provided in a single call to ``add_translation_dirs``, the directories will be inserted in the order they're provided (earlier items are trumped by later items). - .. warning:: + .. versionchanged:: 1.8 - Consecutive calls to ``add_translation_dirs`` will sort the - directories such that the later calls will add folders with - lower precedence than earlier calls. + The ``override`` parameter was added to allow a later call + to ``add_translation_dirs`` to override an earlier call, inserting + folders at the beginning of the translation directory list. """ introspectables = [] + override = kw.pop('override', False) + if kw: + raise TypeError('invalid keyword arguments: %s', sorted(kw.keys())) def register(): directories = [] @@ -80,7 +89,7 @@ class I18NConfiguratorMixin(object): # defer spec resolution until register to allow for asset # overrides to take place in an earlier config phase - for spec in specs[::-1]: # reversed + for spec in specs: # the trailing slash helps match asset overrides for folders if not spec.endswith('/'): spec += '/' @@ -100,8 +109,11 @@ class I18NConfiguratorMixin(object): if tdirs is None: tdirs = [] self.registry.registerUtility(tdirs, ITranslationDirectories) - for directory in directories: - tdirs.insert(0, directory) + if override: + tdirs.extend(directories) + else: + for directory in reversed(directories): + tdirs.insert(0, directory) self.action(None, register, introspectables=introspectables) diff --git a/pyramid/tests/test_config/test_i18n.py b/pyramid/tests/test_config/test_i18n.py index adfb6191c..c10ab6bdb 100644 --- a/pyramid/tests/test_config/test_i18n.py +++ b/pyramid/tests/test_config/test_i18n.py @@ -79,6 +79,23 @@ class TestI18NConfiguratorMixin(unittest.TestCase): self.assertEqual(config.registry.getUtility(ITranslationDirectories), [locale3, locale, locale2]) + def test_add_translation_dirs_override_multiple_specs_multiple_calls(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', + 'pyramid.tests.pkgs.localeapp:locale2') + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3', + override=True) + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale, locale2, locale3]) + + def test_add_translation_dirs_invalid_kwargs(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + with self.assertRaises(TypeError): + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', + foo=1) + def test_add_translation_dirs_abspath(self): from pyramid.interfaces import ITranslationDirectories config = self._makeOne(autocommit=True) -- cgit v1.2.3 From 814cb527b6584856f0f3e1b5389914b77a990cba Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Jan 2017 02:10:25 -0600 Subject: changelog for #2902 --- CHANGES.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 2ca81db40..431a159f8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,13 @@ unreleased ========== +Features +-------- + +- Added an ``override`` option to ``config.add_translation_dirs`` to allow + later calls to place translation directories at a higher priority then + earlier calls. See https://github.com/Pylons/pyramid/pull/2902 + Documentation Changes --------------------- -- cgit v1.2.3 From ed16e19bce476bf403f83213f8b457c9a29e212f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Jan 2017 02:12:59 -0600 Subject: fix rst syntax in changelog --- CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 431a159f8..7502b72c3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -274,8 +274,8 @@ Documentation Changes See https://github.com/Pylons/pyramid/pull/2764 - Clarify a possible misuse of the ``headers`` kwarg to subclasses of - :class:`pyramid.httpexceptions.HTTPException` in which more appropriate - kwargs from the parent class :class:`pyramid.response.Response` should be + ``pyramid.httpexceptions.HTTPException`` in which more appropriate + kwargs from the parent class ``pyramid.response.Response`` should be used instead. See https://github.com/Pylons/pyramid/pull/2750 - The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and -- cgit v1.2.3 From bf700d3b5f6fef6b85624db7d39f62b47f1898b8 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Jan 2017 02:13:30 -0600 Subject: prep 1.8b1 --- CHANGES.txt | 4 ++-- docs/whatsnew-1.8.rst | 4 ++++ setup.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7502b72c3..7f65e4b1b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,5 @@ -unreleased -========== +1.8b1 (2017-01-17) +================== Features -------- diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index d0954f62b..561ffb73e 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -109,6 +109,10 @@ Minor Feature Additions ``--help`` output as well as enabling nicer documentation of their options. See https://github.com/Pylons/pyramid/pull/2864 +- Added an ``override`` option to ``config.add_translation_dirs`` to allow + later calls to place translation directories at a higher priority then + earlier calls. See https://github.com/Pylons/pyramid/pull/2902 + Backwards Incompatibilities --------------------------- diff --git a/setup.py b/setup.py index 2439e59bc..fd8763bee 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ testing_extras = tests_require + [ ] setup(name='pyramid', - version='1.8a1', + version='1.8b1', description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ -- cgit v1.2.3 From 1eaf3dbf08b1cd3c019adf2a46cde443369efff0 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Jan 2017 02:15:20 -0600 Subject: link to method in whatsnew --- docs/whatsnew-1.8.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 561ffb73e..91cae780e 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -109,7 +109,8 @@ Minor Feature Additions ``--help`` output as well as enabling nicer documentation of their options. See https://github.com/Pylons/pyramid/pull/2864 -- Added an ``override`` option to ``config.add_translation_dirs`` to allow +- Added an ``override`` option to + :meth:`pyraid.config.Configurator.add_translation_dirs` to allow later calls to place translation directories at a higher priority then earlier calls. See https://github.com/Pylons/pyramid/pull/2902 -- cgit v1.2.3 From da004dacca884d6e015e4b7d7ccf5ec8f4edff39 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 20 Jan 2017 11:33:04 -0800 Subject: Fix typo to be consistent with API docs - Closes #2904 --- docs/narr/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index d21edc7b4..63279027a 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -160,7 +160,7 @@ forbidden view: def main(globals, **settings): config = Configurator() - config.add_forbidden_view(forbidden_view) + config.add_forbidden_view(forbidden) If instead you prefer to use decorators and a :term:`scan`, you can use the :class:`pyramid.view.forbidden_view_config` decorator to mark a view callable -- cgit v1.2.3 From 8ffa42a601e058c1ce3c433b9dc1f4466d07af06 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 21 Jan 2017 18:26:30 -0600 Subject: swap back to master travis-ci on master branch --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 7179fa8db..b7c03a7ae 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,9 @@ Pyramid ======= -.. image:: https://travis-ci.org/Pylons/pyramid.png?branch=1.8-branch +.. image:: https://travis-ci.org/Pylons/pyramid.png?branch=master :target: https://travis-ci.org/Pylons/pyramid - :alt: 1.8-branch Travis CI Status + :alt: master Travis CI Status .. image:: https://readthedocs.org/projects/pyramid/badge/?version=master :target: http://docs.pylonsproject.org/projects/pyramid/en/master/ -- cgit v1.2.3 From 7ef69ebc3630abfcd70afcba6abe14fab8092474 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 21 Jan 2017 19:18:40 -0600 Subject: typo --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7f65e4b1b..44699c3b0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,7 +5,7 @@ Features -------- - Added an ``override`` option to ``config.add_translation_dirs`` to allow - later calls to place translation directories at a higher priority then + later calls to place translation directories at a higher priority than earlier calls. See https://github.com/Pylons/pyramid/pull/2902 Documentation Changes -- cgit v1.2.3 From b38bbfb1b64a38e04490aaf3ed061067968c42f5 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 21 Jan 2017 20:11:12 -0600 Subject: switch to 1.9.dev0 --- CHANGES.txt | 284 +-------------------------------------------------------- HISTORY.txt | 299 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 2 +- 3 files changed, 304 insertions(+), 281 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 44699c3b0..218fea289 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,293 +1,17 @@ -1.8b1 (2017-01-17) -================== +unreleased +========== Features -------- -- Added an ``override`` option to ``config.add_translation_dirs`` to allow - later calls to place translation directories at a higher priority than - earlier calls. See https://github.com/Pylons/pyramid/pull/2902 - -Documentation Changes ---------------------- - -- Improve registry documentation to discuss uses as a component registry - and as a dictionary. See https://github.com/Pylons/pyramid/pull/2893 - -- Quick Tour, Quick Tutorial, and most other remaining documentation updated to - use cookiecutters instead of pcreate and scaffolds. - See https://github.com/Pylons/pyramid/pull/2888 and - https://github.com/Pylons/pyramid/pull/2889 - -- Fix unittests in wiki2 to work without different dependencies between - py2 and py3. See https://github.com/Pylons/pyramid/pull/2899 - -- Update Windows documentation to track newer Python 3 improvements to the - installer. See https://github.com/Pylons/pyramid/pull/2900 - -- Updated the ``mod_wsgi`` tutorial to use cookiecutters and Apache 2.4+. - See https://github.com/Pylons/pyramid/pull/2901 - -1.8a1 (2016-12-25) -================== - -Backward Incompatibilities --------------------------- - -- Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 - has been removed. See https://github.com/Pylons/pyramid/pull/2822 - -- Following the Pyramid deprecation period (1.6 -> 1.8), - daemon support for pserve has been removed. This includes removing the - daemon commands (start, stop, restart, status) as well as the following - arguments: ``--daemon``, ``--pid-file``, ``--log-file``, - ``--monitor-restart``, ``--status``, ``--user``, ``--group``, - ``--stop-daemon`` - - To run your server as a daemon you should use a process manager instead of - pserve. - - See https://github.com/Pylons/pyramid/pull/2615 - -- ``pcreate`` is now interactive by default. You will be prompted if a file - already exists with different content. Previously if there were similar - files it would silently skip them unless you specified ``--interactive`` - or ``--overwrite``. - See https://github.com/Pylons/pyramid/pull/2775 - -- Removed undocumented argument ``cachebust_match`` from - ``pyramid.static.static_view``. This argument was shipped accidentally - in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 - -- Change static view to avoid setting the ``Content-Encoding`` response header - to an encoding guessed using Python's ``mimetypes`` module. This was causing - clients to decode the content of gzipped files when downloading them. The - client would end up with a ``foo.txt.gz`` file on disk that was already - decoded, thus should really be ``foo.txt``. Also, the ``Content-Encoding`` - should only have been used if the client itself broadcast support for the - encoding via ``Accept-Encoding`` request headers. - See https://github.com/Pylons/pyramid/pull/2810 - -- Settings are no longer accessible as attributes on the settings object - (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. - See https://github.com/Pylons/pyramid/pull/2823 - -Features --------- - -- Python 3.6 compatibility. - https://github.com/Pylons/pyramid/issues/2835 - -- ``pcreate`` learned about ``--package-name`` to allow you to create a new - project in an existing folder with a different package name than the project - name. See https://github.com/Pylons/pyramid/pull/2783 - -- The ``_get_credentials`` private method of ``BasicAuthAuthenticationPolicy`` - has been extracted into standalone function ``extract_http_basic_credentials`` - in ``pyramid.authentication`` module, this function extracts HTTP Basic - credentials from a ``request`` object, and returns them as a named tuple. - See https://github.com/Pylons/pyramid/pull/2662 - -- Pyramid 1.4 silently dropped a feature of the configurator that has been - restored. It's again possible for action discriminators to conflict across - different action orders. - See https://github.com/Pylons/pyramid/pull/2757 - -- ``pyramid.paster.bootstrap`` and its sibling ``pyramid.scripting.prepare`` - can now be used as context managers to automatically invoke the ``closer`` - and pop threadlocals off of the stack to prevent memory leaks. - See https://github.com/Pylons/pyramid/pull/2760 - -- Added ``pyramid.config.Configurator.add_exception_view`` and the - ``pyramid.view.exception_view_config`` decorator. It is now possible using - these methods or via the new ``exception_only=True`` option to ``add_view`` - to add a view which will only be matched when handling an exception. - Previously any exception views were also registered for a traversal - context that inherited from the exception class which prevented any - exception-only optimizations. - See https://github.com/Pylons/pyramid/pull/2660 - -- Added the ``exception_only`` boolean to - ``pyramid.interfaces.IViewDeriverInfo`` which can be used by view derivers - to determine if they are wrapping a view which only handles exceptions. - This means that it is no longer necessary to perform request-time checks - for ``request.exception`` to determine if the view is handling an exception - - the pipeline can be optimized at config-time. - See https://github.com/Pylons/pyramid/pull/2660 - -- ``pserve`` should now work with ``gevent`` and other workers that need - to monkeypatch the process, assuming the server and / or the app do so - as soon as possible before importing the rest of pyramid. - See https://github.com/Pylons/pyramid/pull/2797 - -- Pyramid no longer copies the settings object passed to the - ``pyramid.config.Configurator(settings=)``. The original ``dict`` is kept. - See https://github.com/Pylons/pyramid/pull/2823 - -- The csrf trusted origins setting may now be a whitespace-separated list of - domains. Previously only a python list was allowed. Also, it can now be set - using the ``PYRAMID_CSRF_TRUSTED_ORIGINS`` environment variable similar to - other settings. See https://github.com/Pylons/pyramid/pull/2823 - -- ``pserve --reload`` now uses the - `hupper ` - library to monitor file changes. This comes with many improvements: - - - If the `watchdog `_ package is - installed then monitoring will be done using inotify instead of - cpu and disk-intensive polling. - - - The monitor is now a separate process that will not crash and starts up - before any of your code. - - - The monitor will not restart the process after a crash until a file is - saved. - - - The monitor works on windows. - - - You can now trigger a reload manually from a pyramid view or any other - code via ``hupper.get_reloader().trigger_reload()``. Kind of neat. - - - You can trigger a reload by issuing a ``SIGHUP`` to the monitor process. - - See https://github.com/Pylons/pyramid/pull/2805 - -- A new ``[pserve]`` section is supported in your config files with a - ``watch_files`` key that can configure ``pserve --reload`` to monitor custom - file paths. See https://github.com/Pylons/pyramid/pull/2827 - -- Allow streaming responses to be made from subclasses of - ``pyramid.httpexceptions.HTTPException``. Previously the response would - be unrolled while testing for a body, making it impossible to stream - a response. - See https://github.com/Pylons/pyramid/pull/2863 - -- Update starter, alchemy and zodb scaffolds to support IPv6 by using the - new ``listen`` directives in waitress. - See https://github.com/Pylons/pyramid/pull/2853 - -- All p* scripts now use argparse instead of optparse. This improves their - ``--help`` output as well as enabling nicer documentation of their options. - See https://github.com/Pylons/pyramid/pull/2864 - -- Any deferred configuration action registered via ``config.action`` may now - depend on threadlocal state, such as asset overrides, being active when - the action is executed. - See https://github.com/Pylons/pyramid/pull/2873 - -- Asset specifications for directories passed to - ``config.add_translation_dirs`` now support overriding the entire asset - specification, including the folder name. Previously only the package name - was supported and the folder would always need to have the same name. - See https://github.com/Pylons/pyramid/pull/2873 - -- ``config.begin()`` will propagate the current threadlocal request through - as long as the registry is the same. For example: - - .. code-block:: python - - request = Request.blank(...) - config.begin(request) # pushes a request - config.begin() # propagates the previous request through unchanged - assert get_current_request() is request - - See https://github.com/Pylons/pyramid/pull/2873 - Bug Fixes --------- -- Fixed bug in ``proutes`` such that it now shows the correct view when a - class and ``attr`` is involved. - See: https://github.com/Pylons/pyramid/pull/2687 - -- Fix a ``FutureWarning`` in Python 3.5 when using ``re.split`` on the - ``format`` setting to the ``proutes`` script. - See https://github.com/Pylons/pyramid/pull/2714 - -- Fix a ``RuntimeWarning`` emitted by WebOb when using arbitrary objects - as the ``userid`` in the ``AuthTktAuthenticationPolicy``. This is now caught - by the policy and the object is serialized as a base64 string to avoid - the cryptic warning. Since the userid will be read back as a string on - subsequent requests a more useful warning is emitted encouraging you to - use a primitive type instead. - See https://github.com/Pylons/pyramid/pull/2715 - -- Pyramid 1.6 introduced the ability for an action to invoke another action. - There was a bug in the way that ``config.add_view`` would interact with - custom view derivers introduced in Pyramid 1.7 because the view's - discriminator cannot be computed until view derivers and view predicates - have been created in earlier orders. Invoking an action from another action - would trigger an unrolling of the pipeline and would compute discriminators - before they were ready. The new behavior respects the ``order`` of the action - and ensures the discriminators are not computed until dependent actions - from previous orders have executed. - See https://github.com/Pylons/pyramid/pull/2757 - -- Fix bug in i18n where the default domain would always use the Germanic plural - style, even if a different plural function is defined in the relevant - messages file. See https://github.com/Pylons/pyramid/pull/2859 - -- The ``config.override_asset`` method now occurs during - ``pyramid.config.PHASE1_CONFIG`` such that it is ordered to execute before - any calls to ``config.add_translation_dirs``. - See https://github.com/Pylons/pyramid/pull/2873 - Deprecations ------------ -- The ``pcreate`` script and related scaffolds have been deprecated in favor - of the popular - `cookiecutter `_ project. - - All of Pyramid's official scaffolds as well as the tutorials have been - ported to cookiecutters: - - - `pyramid-cookiecutter-starter - `_ - - - `pyramid-cookiecutter-alchemy - `_ - - - `pyramid-cookiecutter-zodb - `_ - - See https://github.com/Pylons/pyramid/pull/2780 +Backward Incompatibilities +-------------------------- Documentation Changes --------------------- - -- Update Typographical Conventions. - https://github.com/Pylons/pyramid/pull/2838 - -- Add `pyramid_nacl_session - `_ - to session factories. See https://github.com/Pylons/pyramid/issues/2791 - -- Update ``HACKING.txt`` from stale branch that was never merged to master. - See https://github.com/Pylons/pyramid/pull/2782 - -- Updated Windows installation instructions and related bits. - See https://github.com/Pylons/pyramid/issues/2661 - -- Fix an inconsistency in the documentation between view predicates and - route predicates and highlight the differences in their APIs. - See https://github.com/Pylons/pyramid/pull/2764 - -- Clarify a possible misuse of the ``headers`` kwarg to subclasses of - ``pyramid.httpexceptions.HTTPException`` in which more appropriate - kwargs from the parent class ``pyramid.response.Response`` should be - used instead. See https://github.com/Pylons/pyramid/pull/2750 - -- The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and - ZODB + Traversal + Chameleon (``wiki``) tutorials have been updated to - utilize the new cookiecutters and drop support for the ``pcreate`` - scaffolds. - - See https://github.com/Pylons/pyramid/pull/2881 and - https://github.com/Pylons/pyramid/pull/2883. - -- Improve output of p* script descriptions for help. - See https://github.com/Pylons/pyramid/pull/2886 - -- Quick Tour updated to use cookiecutters instead of pcreate and scaffolds. - See https://github.com/Pylons/pyramid/pull/2888 diff --git a/HISTORY.txt b/HISTORY.txt index 5de5b20bd..c10747af4 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,302 @@ +1.8 (2017-01-21) +================ + +- No major changes from 1.8b1. + +1.8b1 (2017-01-17) +================== + +Features +-------- + +- Added an ``override`` option to ``config.add_translation_dirs`` to allow + later calls to place translation directories at a higher priority than + earlier calls. See https://github.com/Pylons/pyramid/pull/2902 + +Documentation Changes +--------------------- + +- Improve registry documentation to discuss uses as a component registry + and as a dictionary. See https://github.com/Pylons/pyramid/pull/2893 + +- Quick Tour, Quick Tutorial, and most other remaining documentation updated to + use cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2888 and + https://github.com/Pylons/pyramid/pull/2889 + +- Fix unittests in wiki2 to work without different dependencies between + py2 and py3. See https://github.com/Pylons/pyramid/pull/2899 + +- Update Windows documentation to track newer Python 3 improvements to the + installer. See https://github.com/Pylons/pyramid/pull/2900 + +- Updated the ``mod_wsgi`` tutorial to use cookiecutters and Apache 2.4+. + See https://github.com/Pylons/pyramid/pull/2901 + +1.8a1 (2016-12-25) +================== + +Backward Incompatibilities +-------------------------- + +- Support for the ``IContextURL`` interface that was deprecated in Pyramid 1.3 + has been removed. See https://github.com/Pylons/pyramid/pull/2822 + +- Following the Pyramid deprecation period (1.6 -> 1.8), + daemon support for pserve has been removed. This includes removing the + daemon commands (start, stop, restart, status) as well as the following + arguments: ``--daemon``, ``--pid-file``, ``--log-file``, + ``--monitor-restart``, ``--status``, ``--user``, ``--group``, + ``--stop-daemon`` + + To run your server as a daemon you should use a process manager instead of + pserve. + + See https://github.com/Pylons/pyramid/pull/2615 + +- ``pcreate`` is now interactive by default. You will be prompted if a file + already exists with different content. Previously if there were similar + files it would silently skip them unless you specified ``--interactive`` + or ``--overwrite``. + See https://github.com/Pylons/pyramid/pull/2775 + +- Removed undocumented argument ``cachebust_match`` from + ``pyramid.static.static_view``. This argument was shipped accidentally + in Pyramid 1.6. See https://github.com/Pylons/pyramid/pull/2681 + +- Change static view to avoid setting the ``Content-Encoding`` response header + to an encoding guessed using Python's ``mimetypes`` module. This was causing + clients to decode the content of gzipped files when downloading them. The + client would end up with a ``foo.txt.gz`` file on disk that was already + decoded, thus should really be ``foo.txt``. Also, the ``Content-Encoding`` + should only have been used if the client itself broadcast support for the + encoding via ``Accept-Encoding`` request headers. + See https://github.com/Pylons/pyramid/pull/2810 + +- Settings are no longer accessible as attributes on the settings object + (e.g. ``request.registry.settings.foo``). This was deprecated in Pyramid 1.2. + See https://github.com/Pylons/pyramid/pull/2823 + +Features +-------- + +- Python 3.6 compatibility. + https://github.com/Pylons/pyramid/issues/2835 + +- ``pcreate`` learned about ``--package-name`` to allow you to create a new + project in an existing folder with a different package name than the project + name. See https://github.com/Pylons/pyramid/pull/2783 + +- The ``_get_credentials`` private method of ``BasicAuthAuthenticationPolicy`` + has been extracted into standalone function ``extract_http_basic_credentials`` + in ``pyramid.authentication`` module, this function extracts HTTP Basic + credentials from a ``request`` object, and returns them as a named tuple. + See https://github.com/Pylons/pyramid/pull/2662 + +- Pyramid 1.4 silently dropped a feature of the configurator that has been + restored. It's again possible for action discriminators to conflict across + different action orders. + See https://github.com/Pylons/pyramid/pull/2757 + +- ``pyramid.paster.bootstrap`` and its sibling ``pyramid.scripting.prepare`` + can now be used as context managers to automatically invoke the ``closer`` + and pop threadlocals off of the stack to prevent memory leaks. + See https://github.com/Pylons/pyramid/pull/2760 + +- Added ``pyramid.config.Configurator.add_exception_view`` and the + ``pyramid.view.exception_view_config`` decorator. It is now possible using + these methods or via the new ``exception_only=True`` option to ``add_view`` + to add a view which will only be matched when handling an exception. + Previously any exception views were also registered for a traversal + context that inherited from the exception class which prevented any + exception-only optimizations. + See https://github.com/Pylons/pyramid/pull/2660 + +- Added the ``exception_only`` boolean to + ``pyramid.interfaces.IViewDeriverInfo`` which can be used by view derivers + to determine if they are wrapping a view which only handles exceptions. + This means that it is no longer necessary to perform request-time checks + for ``request.exception`` to determine if the view is handling an exception + - the pipeline can be optimized at config-time. + See https://github.com/Pylons/pyramid/pull/2660 + +- ``pserve`` should now work with ``gevent`` and other workers that need + to monkeypatch the process, assuming the server and / or the app do so + as soon as possible before importing the rest of pyramid. + See https://github.com/Pylons/pyramid/pull/2797 + +- Pyramid no longer copies the settings object passed to the + ``pyramid.config.Configurator(settings=)``. The original ``dict`` is kept. + See https://github.com/Pylons/pyramid/pull/2823 + +- The csrf trusted origins setting may now be a whitespace-separated list of + domains. Previously only a python list was allowed. Also, it can now be set + using the ``PYRAMID_CSRF_TRUSTED_ORIGINS`` environment variable similar to + other settings. See https://github.com/Pylons/pyramid/pull/2823 + +- ``pserve --reload`` now uses the + `hupper ` + library to monitor file changes. This comes with many improvements: + + - If the `watchdog `_ package is + installed then monitoring will be done using inotify instead of + cpu and disk-intensive polling. + + - The monitor is now a separate process that will not crash and starts up + before any of your code. + + - The monitor will not restart the process after a crash until a file is + saved. + + - The monitor works on windows. + + - You can now trigger a reload manually from a pyramid view or any other + code via ``hupper.get_reloader().trigger_reload()``. Kind of neat. + + - You can trigger a reload by issuing a ``SIGHUP`` to the monitor process. + + See https://github.com/Pylons/pyramid/pull/2805 + +- A new ``[pserve]`` section is supported in your config files with a + ``watch_files`` key that can configure ``pserve --reload`` to monitor custom + file paths. See https://github.com/Pylons/pyramid/pull/2827 + +- Allow streaming responses to be made from subclasses of + ``pyramid.httpexceptions.HTTPException``. Previously the response would + be unrolled while testing for a body, making it impossible to stream + a response. + See https://github.com/Pylons/pyramid/pull/2863 + +- Update starter, alchemy and zodb scaffolds to support IPv6 by using the + new ``listen`` directives in waitress. + See https://github.com/Pylons/pyramid/pull/2853 + +- All p* scripts now use argparse instead of optparse. This improves their + ``--help`` output as well as enabling nicer documentation of their options. + See https://github.com/Pylons/pyramid/pull/2864 + +- Any deferred configuration action registered via ``config.action`` may now + depend on threadlocal state, such as asset overrides, being active when + the action is executed. + See https://github.com/Pylons/pyramid/pull/2873 + +- Asset specifications for directories passed to + ``config.add_translation_dirs`` now support overriding the entire asset + specification, including the folder name. Previously only the package name + was supported and the folder would always need to have the same name. + See https://github.com/Pylons/pyramid/pull/2873 + +- ``config.begin()`` will propagate the current threadlocal request through + as long as the registry is the same. For example: + + .. code-block:: python + + request = Request.blank(...) + config.begin(request) # pushes a request + config.begin() # propagates the previous request through unchanged + assert get_current_request() is request + + See https://github.com/Pylons/pyramid/pull/2873 + +Bug Fixes +--------- + +- Fixed bug in ``proutes`` such that it now shows the correct view when a + class and ``attr`` is involved. + See: https://github.com/Pylons/pyramid/pull/2687 + +- Fix a ``FutureWarning`` in Python 3.5 when using ``re.split`` on the + ``format`` setting to the ``proutes`` script. + See https://github.com/Pylons/pyramid/pull/2714 + +- Fix a ``RuntimeWarning`` emitted by WebOb when using arbitrary objects + as the ``userid`` in the ``AuthTktAuthenticationPolicy``. This is now caught + by the policy and the object is serialized as a base64 string to avoid + the cryptic warning. Since the userid will be read back as a string on + subsequent requests a more useful warning is emitted encouraging you to + use a primitive type instead. + See https://github.com/Pylons/pyramid/pull/2715 + +- Pyramid 1.6 introduced the ability for an action to invoke another action. + There was a bug in the way that ``config.add_view`` would interact with + custom view derivers introduced in Pyramid 1.7 because the view's + discriminator cannot be computed until view derivers and view predicates + have been created in earlier orders. Invoking an action from another action + would trigger an unrolling of the pipeline and would compute discriminators + before they were ready. The new behavior respects the ``order`` of the action + and ensures the discriminators are not computed until dependent actions + from previous orders have executed. + See https://github.com/Pylons/pyramid/pull/2757 + +- Fix bug in i18n where the default domain would always use the Germanic plural + style, even if a different plural function is defined in the relevant + messages file. See https://github.com/Pylons/pyramid/pull/2859 + +- The ``config.override_asset`` method now occurs during + ``pyramid.config.PHASE1_CONFIG`` such that it is ordered to execute before + any calls to ``config.add_translation_dirs``. + See https://github.com/Pylons/pyramid/pull/2873 + +Deprecations +------------ + +- The ``pcreate`` script and related scaffolds have been deprecated in favor + of the popular + `cookiecutter `_ project. + + All of Pyramid's official scaffolds as well as the tutorials have been + ported to cookiecutters: + + - `pyramid-cookiecutter-starter + `_ + + - `pyramid-cookiecutter-alchemy + `_ + + - `pyramid-cookiecutter-zodb + `_ + + See https://github.com/Pylons/pyramid/pull/2780 + +Documentation Changes +--------------------- + +- Update Typographical Conventions. + https://github.com/Pylons/pyramid/pull/2838 + +- Add `pyramid_nacl_session + `_ + to session factories. See https://github.com/Pylons/pyramid/issues/2791 + +- Update ``HACKING.txt`` from stale branch that was never merged to master. + See https://github.com/Pylons/pyramid/pull/2782 + +- Updated Windows installation instructions and related bits. + See https://github.com/Pylons/pyramid/issues/2661 + +- Fix an inconsistency in the documentation between view predicates and + route predicates and highlight the differences in their APIs. + See https://github.com/Pylons/pyramid/pull/2764 + +- Clarify a possible misuse of the ``headers`` kwarg to subclasses of + ``pyramid.httpexceptions.HTTPException`` in which more appropriate + kwargs from the parent class ``pyramid.response.Response`` should be + used instead. See https://github.com/Pylons/pyramid/pull/2750 + +- The SQLAlchemy + URL Dispatch + Jinja2 (``wiki2``) and + ZODB + Traversal + Chameleon (``wiki``) tutorials have been updated to + utilize the new cookiecutters and drop support for the ``pcreate`` + scaffolds. + + See https://github.com/Pylons/pyramid/pull/2881 and + https://github.com/Pylons/pyramid/pull/2883. + +- Improve output of p* script descriptions for help. + See https://github.com/Pylons/pyramid/pull/2886 + +- Quick Tour updated to use cookiecutters instead of pcreate and scaffolds. + See https://github.com/Pylons/pyramid/pull/2888 + 1.7 (2016-05-19) ================ diff --git a/setup.py b/setup.py index fd8763bee..d9fcec4c8 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ testing_extras = tests_require + [ ] setup(name='pyramid', - version='1.8b1', + version='1.9.dev0', description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ -- cgit v1.2.3 From 5a0d1e7b90223f4954b47e710953f8d680088589 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 21 Jan 2017 22:25:25 -0800 Subject: forward port item for pylons_sphinx_latesturl --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index d61df6580..df58064e5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -146,6 +146,7 @@ if book: # 'whatsnew-1.5': 'index', # 'whatsnew-1.6': 'index', # 'whatsnew-1.7': 'index', +# 'whatsnew-1.8': 'index', # 'tutorials/gae/index': 'index', # 'api/chameleon_text': 'api', # 'api/chameleon_zpt': 'api', -- cgit v1.2.3 From bba80db362c5f72b69f0d6935e43c20f191077fb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 21 Jan 2017 23:59:33 -0800 Subject: remove pylonshq - HUZZAH! --- RELEASING.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/RELEASING.txt b/RELEASING.txt index 73cf38aa7..464cb37bd 100644 --- a/RELEASING.txt +++ b/RELEASING.txt @@ -108,10 +108,6 @@ Update previous version (final releases only) Marketing and communications ---------------------------- -- Edit Pylons/pylonshq/templates/home/home.mako. - -- Edit Pylons/pylonshq/templates/home/inside.rst for major releases only. - - Edit Pylons/trypyramid.com/src/templates/resources.html for major releases only. -- cgit v1.2.3 From 8814851b1f0df0c8f5cc6d0a497f9381101fdd45 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 22 Jan 2017 00:11:20 -0800 Subject: save a redirect (cherry picked from commit 981869a) --- README.rst | 2 +- docs/index.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index b7c03a7ae..f05dd8bbf 100644 --- a/README.rst +++ b/README.rst @@ -38,7 +38,7 @@ and deployment more fun, more predictable, and more productive. server = make_server('0.0.0.0', 8080, app) server.serve_forever() -Pyramid is a project of the `Pylons Project `_. +Pyramid is a project of the `Pylons Project `_. Support and Documentation ------------------------- diff --git a/docs/index.rst b/docs/index.rst index 668347744..ed5b458ea 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,7 +5,7 @@ The Pyramid Web Framework ========================= :app:`Pyramid` is a small, fast, down-to-earth Python web framework. It is -developed as part of the `Pylons Project `_. +developed as part of the `Pylons Project `_. It is licensed under a `BSD-like license `_. Here is one of the simplest :app:`Pyramid` applications you can make: -- cgit v1.2.3 From 3730d910668ea42305d438897ce864b91ae8b864 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 23 Jan 2017 21:39:17 -0600 Subject: update todo --- TODO.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO.txt b/TODO.txt index b064cd8e8..a3ae9d8c0 100644 --- a/TODO.txt +++ b/TODO.txt @@ -114,8 +114,6 @@ Nice-to-Have Future ------ -- 1.6: Remove IContextURL and TraversalContextURL. - - 1.9: Remove set_request_property. - 1.9: Remove extra code enabling ``pyramid.security.remember(principal=...)`` and force use of ``userid``. -- cgit v1.2.3 From 5c71ad944e463ec1591613d018b7797b81d23eae Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 23 Jan 2017 21:42:30 -0600 Subject: update manifest checks --- RELEASING.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASING.txt b/RELEASING.txt index 464cb37bd..c7a23309b 100644 --- a/RELEASING.txt +++ b/RELEASING.txt @@ -63,10 +63,10 @@ Prepare new release branch - Change setup.py version to the release version number. -- Make sure PyPI long description renders (requires ``collective.dist`` - installed into your Python):: +- Make sure PyPI long description renders (requires ``readme`` installed + into your Python):: - $ python setup.py check -r + $ python setup.py check -r -s -m - Create a release tag. -- cgit v1.2.3 From f6af107a78b36c7e428ccb58c2db939275d8fa99 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 24 Jan 2017 22:42:14 -0600 Subject: restore the registry signature and add tests to show why fixes #2916 --- pyramid/registry.py | 4 ++-- pyramid/tests/test_registry.py | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pyramid/registry.py b/pyramid/registry.py index e2bcba9f9..20b3643e9 100644 --- a/pyramid/registry.py +++ b/pyramid/registry.py @@ -56,7 +56,7 @@ class Registry(Components, dict): _settings = None - def __init__(self, package_name=CALLER_PACKAGE): + def __init__(self, package_name=CALLER_PACKAGE, *args, **kw): # add a registry-instance-specific lock, which is used when the lookup # cache is mutated self._lock = threading.Lock() @@ -64,7 +64,7 @@ class Registry(Components, dict): self._clear_view_lookup_cache() if package_name is CALLER_PACKAGE: package_name = caller_package().__name__ - Components.__init__(self, package_name) + Components.__init__(self, package_name, *args, **kw) dict.__init__(self) def _clear_view_lookup_cache(self): diff --git a/pyramid/tests/test_registry.py b/pyramid/tests/test_registry.py index 7b3357e61..aa44b5408 100644 --- a/pyramid/tests/test_registry.py +++ b/pyramid/tests/test_registry.py @@ -5,8 +5,8 @@ class TestRegistry(unittest.TestCase): from pyramid.registry import Registry return Registry - def _makeOne(self): - return self._getTargetClass()() + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) def test___nonzero__(self): registry = self._makeOne() @@ -24,11 +24,11 @@ class TestRegistry(unittest.TestCase): def test_package_name(self): package_name = 'testing' - registry = self._getTargetClass()(package_name) + registry = self._makeOne(package_name) self.assertEqual(registry.package_name, package_name) def test_default_package_name(self): - registry = self._getTargetClass()() + registry = self._makeOne() self.assertEqual(registry.package_name, 'pyramid.tests') def test_registerHandler_and_notify(self): @@ -61,6 +61,25 @@ class TestRegistry(unittest.TestCase): registry.settings = 'foo' self.assertEqual(registry._settings, 'foo') + def test_init_forwards_args(self): + from zope.interface import Interface + from zope.interface.registry import Components + dummy = object() + c = Components() + c.registerUtility(dummy, Interface) + registry = self._makeOne('foo', (c,)) + self.assertEqual(registry.__name__, 'foo') + self.assertEqual(registry.getUtility(Interface), dummy) + + def test_init_forwards_kw(self): + from zope.interface import Interface + from zope.interface.registry import Components + dummy = object() + c = Components() + c.registerUtility(dummy, Interface) + registry = self._makeOne(bases=(c,)) + self.assertEqual(registry.getUtility(Interface), dummy) + class TestIntrospector(unittest.TestCase): def _getTargetClass(slf): from pyramid.registry import Introspector -- cgit v1.2.3 From ff7fc483fadbbda2f1845fa3b100b7db8b97cceb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Jan 2017 01:09:44 -0800 Subject: grammar fix --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 3d17a4191..2190a3fb1 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -37,7 +37,7 @@ These cookiecutters are rendered using the ``cookiecutter`` command that you may :app:`Pyramid` cookiecutters ---------------------------- -Pyramid cookiecutters released under the Pylons Project include differ from each other on a number of axes: +Pyramid cookiecutters released under the Pylons Project differ from each other on a number of axes: - the persistence mechanism they offer (no persistence mechanism, :term:`SQLAlchemy` with SQLite, or :term:`ZODB`) -- cgit v1.2.3 From ac05dc8b7bebd5e67956d7d3e36f6667aa2b9120 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Jan 2017 01:13:02 -0800 Subject: rest syntax fix --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 2190a3fb1..7a0adab98 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1105,7 +1105,7 @@ Automatically Reloading Your Code During development, it can be really useful to automatically have the webserver restart when you make changes. ``pserve`` has a ``--reload`` switch to enable this. It uses the -`hupper ` package +`hupper `_ package to enable this behavior. When your code crashes, ``hupper`` will wait for another change or the ``SIGHUP`` signal before restarting again. -- cgit v1.2.3 From f8e8ab0e4271c2bc798ccc199d26ec21e3781afa Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Jan 2017 01:15:16 -0800 Subject: rest syntax fix --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 7a0adab98..54bcf37b4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1115,7 +1115,7 @@ inotify support By default, ``hupper`` will poll the filesystem for changes to all python code. This can be pretty inefficient in larger projects. To be nicer to your hard drive, you should install the -`watchdog ` package in development. +`watchdog `_ package in development. ``hupper`` will automatically use ``watchdog`` to more efficiently poll the filesystem. -- cgit v1.2.3 From 0aa967f02c8ccf133730ae7b7ed8b3a90ab17372 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Jan 2017 01:18:03 -0800 Subject: grammar fixes --- docs/narr/project.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 54bcf37b4..be2e5a389 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1112,7 +1112,7 @@ another change or the ``SIGHUP`` signal before restarting again. inotify support ~~~~~~~~~~~~~~~ -By default, ``hupper`` will poll the filesystem for changes to all python +By default ``hupper`` will poll the filesystem for changes to all Python code. This can be pretty inefficient in larger projects. To be nicer to your hard drive, you should install the `watchdog `_ package in development. @@ -1124,11 +1124,11 @@ Monitoring Custom Files By default, ``pserve --reload`` will monitor all imported Python code (everything in ``sys.modules``) as well as the config file passed to -``pserve`` (e.g. ``development.ini``). You can instruct ``pserve`` to watch +``pserve`` (e.g., ``development.ini``). You can instruct ``pserve`` to watch other files for changes as well by defining a ``[pserve]`` section in your configuration file. For example, let's say your application loads the ``favicon.ico`` file at startup and stores it in memory to efficiently -serve it many times. When you change it you want ``pserve`` to restart: +serve it many times. When you change it, you want ``pserve`` to restart: .. code-block:: ini @@ -1137,6 +1137,6 @@ serve it many times. When you change it you want ``pserve`` to restart: myapp/static/favicon.ico Paths may be absolute or relative to the configuration file. They may also -be an :term:`asset specification`. These paths are passed to ``hupper`` which +be an :term:`asset specification`. These paths are passed to ``hupper``, which has some basic support for globbing. Acceptable glob patterns depend on the version of Python being used. -- cgit v1.2.3 From 7ad5f3d841bb0e54c648b8ad22c62c8e0043fbd6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Jan 2017 01:41:56 -0800 Subject: undo borkage: wsgiref does not use listen, it uses port - ref: #2919 --- docs/quick_tutorial/authentication/development.ini | 2 +- docs/quick_tutorial/authorization/development.ini | 2 +- docs/quick_tutorial/databases/development.ini | 2 +- docs/quick_tutorial/debugtoolbar/development.ini | 2 +- docs/quick_tutorial/forms/development.ini | 2 +- docs/quick_tutorial/functional_testing/development.ini | 2 +- docs/quick_tutorial/ini/development.ini | 2 +- docs/quick_tutorial/jinja2/development.ini | 2 +- docs/quick_tutorial/json/development.ini | 2 +- docs/quick_tutorial/logging/development.ini | 2 +- docs/quick_tutorial/more_view_classes/development.ini | 2 +- docs/quick_tutorial/request_response/development.ini | 2 +- docs/quick_tutorial/retail_forms/development.ini | 2 +- docs/quick_tutorial/routing/development.ini | 2 +- docs/quick_tutorial/sessions/development.ini | 2 +- docs/quick_tutorial/static_assets/development.ini | 2 +- docs/quick_tutorial/templating/development.ini | 2 +- docs/quick_tutorial/unit_testing/development.ini | 2 +- docs/quick_tutorial/view_classes/development.ini | 2 +- docs/quick_tutorial/views/development.ini | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/quick_tutorial/authentication/development.ini b/docs/quick_tutorial/authentication/development.ini index 7665b90a4..a4586d45f 100644 --- a/docs/quick_tutorial/authentication/development.ini +++ b/docs/quick_tutorial/authentication/development.ini @@ -7,4 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/authorization/development.ini b/docs/quick_tutorial/authorization/development.ini index 7665b90a4..a4586d45f 100644 --- a/docs/quick_tutorial/authorization/development.ini +++ b/docs/quick_tutorial/authorization/development.ini @@ -7,4 +7,4 @@ tutorial.secret = 98zd [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini index f6e903d37..270643071 100644 --- a/docs/quick_tutorial/databases/development.ini +++ b/docs/quick_tutorial/databases/development.ini @@ -9,7 +9,7 @@ sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 # Begin logging configuration diff --git a/docs/quick_tutorial/debugtoolbar/development.ini b/docs/quick_tutorial/debugtoolbar/development.ini index e84d29665..17b479011 100644 --- a/docs/quick_tutorial/debugtoolbar/development.ini +++ b/docs/quick_tutorial/debugtoolbar/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/forms/development.ini b/docs/quick_tutorial/forms/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/forms/development.ini +++ b/docs/quick_tutorial/forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/functional_testing/development.ini b/docs/quick_tutorial/functional_testing/development.ini index e84d29665..17b479011 100644 --- a/docs/quick_tutorial/functional_testing/development.ini +++ b/docs/quick_tutorial/functional_testing/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/ini/development.ini b/docs/quick_tutorial/ini/development.ini index 4f0991fad..cffbd66c9 100644 --- a/docs/quick_tutorial/ini/development.ini +++ b/docs/quick_tutorial/ini/development.ini @@ -3,4 +3,4 @@ use = egg:tutorial [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/jinja2/development.ini b/docs/quick_tutorial/jinja2/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/jinja2/development.ini +++ b/docs/quick_tutorial/jinja2/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/json/development.ini b/docs/quick_tutorial/json/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/json/development.ini +++ b/docs/quick_tutorial/json/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/logging/development.ini b/docs/quick_tutorial/logging/development.ini index 5e8e65a7c..b869ca5b6 100644 --- a/docs/quick_tutorial/logging/development.ini +++ b/docs/quick_tutorial/logging/development.ini @@ -6,7 +6,7 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 # Begin logging configuration diff --git a/docs/quick_tutorial/more_view_classes/development.ini b/docs/quick_tutorial/more_view_classes/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/more_view_classes/development.ini +++ b/docs/quick_tutorial/more_view_classes/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/request_response/development.ini b/docs/quick_tutorial/request_response/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/request_response/development.ini +++ b/docs/quick_tutorial/request_response/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/retail_forms/development.ini b/docs/quick_tutorial/retail_forms/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/retail_forms/development.ini +++ b/docs/quick_tutorial/retail_forms/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/routing/development.ini b/docs/quick_tutorial/routing/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/routing/development.ini +++ b/docs/quick_tutorial/routing/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/sessions/development.ini b/docs/quick_tutorial/sessions/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/sessions/development.ini +++ b/docs/quick_tutorial/sessions/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/static_assets/development.ini b/docs/quick_tutorial/static_assets/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/static_assets/development.ini +++ b/docs/quick_tutorial/static_assets/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/templating/development.ini b/docs/quick_tutorial/templating/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/templating/development.ini +++ b/docs/quick_tutorial/templating/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/unit_testing/development.ini b/docs/quick_tutorial/unit_testing/development.ini index e84d29665..17b479011 100644 --- a/docs/quick_tutorial/unit_testing/development.ini +++ b/docs/quick_tutorial/unit_testing/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/view_classes/development.ini b/docs/quick_tutorial/view_classes/development.ini index d5436148d..7066668bf 100644 --- a/docs/quick_tutorial/view_classes/development.ini +++ b/docs/quick_tutorial/view_classes/development.ini @@ -6,4 +6,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 diff --git a/docs/quick_tutorial/views/development.ini b/docs/quick_tutorial/views/development.ini index e84d29665..17b479011 100644 --- a/docs/quick_tutorial/views/development.ini +++ b/docs/quick_tutorial/views/development.ini @@ -5,4 +5,4 @@ pyramid.includes = [server:main] use = egg:pyramid#wsgiref -listen = *:6543 +port = 6543 -- cgit v1.2.3 From 8a5966918e377b1dfa35331da66d9cff2c33d7e4 Mon Sep 17 00:00:00 2001 From: John Jimenez Date: Fri, 27 Jan 2017 20:42:33 -0800 Subject: Minor change minor change to flow better (cherry picked from commit 0c705c9) --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/views.rst b/docs/narr/views.rst index ab139ea19..d4826be4d 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -52,7 +52,7 @@ of exceptions from within the body of a view callable. Defining a View Callable as a Function -------------------------------------- -One of the easiest way to define a view callable is to create a function that +One of the easiest ways to define a view callable is to create a function that accepts a single argument named ``request``, and which returns a :term:`Response` object. For example, this is a "hello world" view callable implemented as a function: -- cgit v1.2.3 From 00a16de1ea5d7323b1b9474c796b4ed6fdb25b2e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 28 Jan 2017 15:48:28 -0800 Subject: scaffold starter now uses Jinja2 - Closes misplaced issue https://github.com/Pylons/pyramid-cookiecutter-starter/issues/13 --- pyramid/scaffolds/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/scaffolds/__init__.py b/pyramid/scaffolds/__init__.py index 841dc403e..719b4fe76 100644 --- a/pyramid/scaffolds/__init__.py +++ b/pyramid/scaffolds/__init__.py @@ -52,7 +52,7 @@ class PyramidTemplate(Template): class StarterProjectTemplate(PyramidTemplate): _template_dir = 'starter' - summary = 'Pyramid starter project using URL dispatch and Chameleon' + summary = 'Pyramid starter project using URL dispatch and Jinja2' class ZODBProjectTemplate(PyramidTemplate): _template_dir = 'zodb' -- cgit v1.2.3 From 659ea6dc622666376f345f03c1c444463ba01835 Mon Sep 17 00:00:00 2001 From: John Jimenez Date: Sat, 28 Jan 2017 07:35:44 -0800 Subject: Minor change distinguish between Pyramid itself and view code raising the exception as in previous exception listing. (cherry picked from commit eb166fb) --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/views.rst b/docs/narr/views.rst index d4826be4d..1a840fb5c 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -246,7 +246,7 @@ within view code, the result of the :term:`Not Found View` will be returned to the user agent which performed the request. If :exc:`~pyramid.httpexceptions.HTTPForbidden` is raised by Pyramid itself -within view code, the result of the :term:`Forbidden View` will be returned to +or within view code, the result of the :term:`Forbidden View` will be returned to the user agent which performed the request. .. index:: -- cgit v1.2.3 From 3ef8d92dbbd8b97ec66d5652b9a66a3652904722 Mon Sep 17 00:00:00 2001 From: John Jimenez Date: Sat, 28 Jan 2017 08:51:43 -0800 Subject: Minor change "functions, classes or any callable that accept" was messing with the flow while reading. Proposed change flows a little better for me. (cherry picked from commit 87d8aba) --- docs/narr/views.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 1a840fb5c..e8a07202e 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -523,8 +523,7 @@ Alternate View Callable Argument/Calling Conventions ---------------------------------------------------- Usually view callables are defined to accept only a single argument: -``request``. However, view callables may alternately be defined as classes, -functions, or any callable that accept *two* positional arguments: a +``request``. However, a view callable may alternately be defined as any class, function, or callable that accepts *two* positional arguments: a :term:`context` resource as the first argument and a :term:`request` as the second argument. -- cgit v1.2.3 From 67d0917480d46d657c36a1feab58734ac1f5d037 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Tue, 31 Jan 2017 20:50:44 +0200 Subject: Fix typo --- docs/whatsnew-1.8.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/whatsnew-1.8.rst b/docs/whatsnew-1.8.rst index 91cae780e..adc60b34b 100644 --- a/docs/whatsnew-1.8.rst +++ b/docs/whatsnew-1.8.rst @@ -110,7 +110,7 @@ Minor Feature Additions See https://github.com/Pylons/pyramid/pull/2864 - Added an ``override`` option to - :meth:`pyraid.config.Configurator.add_translation_dirs` to allow + :meth:`pyramid.config.Configurator.add_translation_dirs` to allow later calls to place translation directories at a higher priority then earlier calls. See https://github.com/Pylons/pyramid/pull/2902 -- cgit v1.2.3 From ce889449afa3147e77c987067afdcca31bcd9f05 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 3 Feb 2017 12:38:10 -0800 Subject: update links and reST syntax for mod_wsgi --- docs/glossary.rst | 2 +- docs/narr/introduction.rst | 2 +- docs/narr/project.rst | 4 ++-- docs/tutorials/modwsgi/index.rst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index b4673f73e..0f299c169 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -568,7 +568,7 @@ Glossary :ref:`adding_and_overriding_renderers` for more information. mod_wsgi - `mod_wsgi `_ is an Apache + `mod_wsgi `_ is an Apache module developed by Graham Dumpleton. It allows :term:`WSGI` applications (such as applications developed using :app:`Pyramid`) to be served using the Apache web server. diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7027d6601..3aa603bcf 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -433,7 +433,7 @@ for speed. It only does as much work as absolutely necessary when you ask it to get a job done. Extraneous function calls and suboptimal algorithms in its core codepaths are avoided. It is feasible to get, for example, between 3500 and 4000 requests per second from a simple Pyramid view on commodity dual-core -laptop hardware and an appropriate WSGI server (mod_wsgi or gunicorn). In any +laptop hardware and an appropriate WSGI server (:term:`mod_wsgi` or gunicorn). In any case, performance statistics are largely useless without requirements and goals, but if you need speed, Pyramid will almost certainly never be your application's bottleneck; at least no more than Python will be a bottleneck. diff --git a/docs/narr/project.rst b/docs/narr/project.rst index be2e5a389..f32fad370 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1089,13 +1089,13 @@ configuration on a local system that you have complete control over; it will provide the best development experience. One popular production alternative to the default Waitress server is -:term:`mod_wsgi`. You can use mod_wsgi to serve your :app:`Pyramid` application +:term:`mod_wsgi`. You can use ``mod_wsgi`` to serve your :app:`Pyramid` application using the Apache web server rather than any "pure-Python" server like Waitress. It is fast and featureful. See :ref:`modwsgi_tutorial` for details. Another good production alternative is :term:`Green Unicorn` (aka ``gunicorn``). It's faster than Waitress and slightly easier to configure than -mod_wsgi, although it depends, in its default configuration, on having a +``mod_wsgi``, although it depends, in its default configuration, on having a buffering HTTP proxy in front of it. It does not, as of this writing, work on Windows. diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index ef42589c6..0c3b58bac 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -120,5 +120,5 @@ specific path information for commands and files. :term:`mod_wsgi` has many knobs and a great variety of deployment modes. This is just one representation of how you might use it to serve up a :app:`Pyramid` application. See the `mod_wsgi configuration documentation -`_ +`_ for more in-depth configuration information. -- cgit v1.2.3 From f894370e65ad2b255bcf17895b844584ace75bdc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 4 Feb 2017 18:08:04 -0800 Subject: configuration should not be quoted - closes #2944 --- docs/narr/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index cde166b21..ee54e3acd 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -54,7 +54,7 @@ configured imperatively: server.serve_forever() We won't talk much about what this application does yet. Just note that the -"configuration' statements take place underneath the ``if __name__ == +configuration statements take place underneath the ``if __name__ == '__main__':`` stanza in the form of method calls on a :term:`Configurator` object (e.g., ``config.add_view(...)``). These statements take place one after the other, and are executed in order, so the full power of Python, including -- cgit v1.2.3 From ff1ca2887d0a0ec5a2ffb6b48503245e1032b6f2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 5 Feb 2017 11:14:17 -0800 Subject: update templates per deform 2.0 migration notes - See https://github.com/Pylons/pyramid/issues/2897#issuecomment-277494816 - Closes #2897 --- .../quick_tutorial/databases/tutorial/wikipage_addedit.pt | 15 +++++++++++++-- docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt index d1fea0d7f..25bab04d0 100644 --- a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt +++ b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt @@ -2,12 +2,23 @@ WikiPage: Add/Edit + + + href="${request.static_url(reqt)}"/> + + + - diff --git a/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt index d1fea0d7f..25bab04d0 100644 --- a/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt +++ b/docs/quick_tutorial/forms/tutorial/wikipage_addedit.pt @@ -2,12 +2,23 @@ WikiPage: Add/Edit + + + href="${request.static_url(reqt)}"/> + + + - -- cgit v1.2.3 From d95a421694ade78dbe332a7becb8fd492bd2a01c Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Mon, 6 Feb 2017 21:28:55 -0700 Subject: Test to verify that httpexc.detail may be non-str --- pyramid/tests/test_httpexceptions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyramid/tests/test_httpexceptions.py b/pyramid/tests/test_httpexceptions.py index 224fa4cf0..e2d463008 100644 --- a/pyramid/tests/test_httpexceptions.py +++ b/pyramid/tests/test_httpexceptions.py @@ -2,6 +2,7 @@ import unittest from pyramid.compat import ( bytes_, + string_types, text_, ) @@ -364,6 +365,11 @@ class TestHTTPException(unittest.TestCase): body = list(exc(environ, start_response))[0] self.assertEqual(body, b'200 OK\n\n/La Pe\xc3\xb1a') + def test_allow_detail_non_str(self): + exc = self._makeOne(detail={'error': 'This is a test'}) + self.assertIsInstance(exc.__str__(), string_types) + + class TestRenderAllExceptionsWithoutArguments(unittest.TestCase): def _doit(self, content_type): from pyramid.httpexceptions import status_map -- cgit v1.2.3 From 309e6be0e83b5ed08f954c7dd66c5e8cf959a006 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Mon, 6 Feb 2017 21:32:03 -0700 Subject: stringify self.detail in case it is not a string --- pyramid/httpexceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index a22b088c6..1f3934fdc 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -238,7 +238,7 @@ ${body}''') del self.content_length def __str__(self): - return self.detail or self.explanation + return str(self.detail) if self.detail else self.explanation def _json_formatter(self, status, body, title, environ): return {'message': body, -- cgit v1.2.3 From 564b63771ae370fafe059c5cf8e4a6bd7a1a5853 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Mon, 6 Feb 2017 21:37:52 -0700 Subject: Update CHANGES.txt for #2951 --- CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 218fea289..59a733bcd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,10 @@ Features Bug Fixes --------- +- HTTPException's accepts a detail kwarg that may be used to pass additional + details to the exception. You may now pass objects so long as they have a + valid __str__ method. See https://github.com/Pylons/pyramid/pull/2951 + Deprecations ------------ -- cgit v1.2.3 From cf40ff8ca0b8cd32cd184b8b09ccfcb90e356e4e Mon Sep 17 00:00:00 2001 From: drnextgis Date: Thu, 9 Feb 2017 03:24:04 +0700 Subject: Make code more readable by using namedtuple attribute --- pyramid/authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyramid/authentication.py b/pyramid/authentication.py index 2ee5576d9..03b204e1a 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -1098,7 +1098,7 @@ class BasicAuthAuthenticationPolicy(CallbackAuthenticationPolicy): """ The userid parsed from the ``Authorization`` request header.""" credentials = extract_http_basic_credentials(request) if credentials: - return credentials[0] + return credentials.username def remember(self, request, userid, **kw): """ A no-op. Basic authentication does not provide a protocol for -- cgit v1.2.3