From 47900408a701be8f7d09ef1377186f7b63327cdf Mon Sep 17 00:00:00 2001 From: JC Bohin Date: Mon, 13 Jun 2016 17:59:29 +0200 Subject: Fix flake8's noqa directive in documentation and scaffolds --- docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py | 2 +- docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py | 4 ++-- docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py | 4 ++-- docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py | 2 +- docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py | 2 +- docs/tutorials/wiki2/src/models/tutorial/models/__init__.py | 4 ++-- docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py | 4 ++-- docs/tutorials/wiki2/src/views/tutorial/models/__init__.py | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) (limited to 'docs') 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 6ffc10a78..76e0fd26b 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,7 @@ from sqlalchemy.orm import configure_mappers # import all models classes here for sqlalchemy mappers # to pick up -from .mymodel import MyModel # flake8: noqa +from .mymodel import MyModel # noqa # run configure mappers to ensure we avoid any race conditions configure_mappers() diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py index a8871f6f5..8147052ad 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # flake8: noqa -from .user import User # flake8: noqa +from .page import Page # noqa +from .user import User # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py index a8871f6f5..8147052ad 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # flake8: noqa -from .user import User # flake8: noqa +from .page import Page # noqa +from .user import User # 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/models/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py index 48a957ecb..3fc82cfba 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 # flake8: noqa +from .mymodel import MyModel # 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/models/__init__.py b/docs/tutorials/wiki2/src/installation/tutorial/models/__init__.py index 48a957ecb..3fc82cfba 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 # flake8: noqa +from .mymodel import MyModel # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/models/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/models/tutorial/models/__init__.py index a8871f6f5..8147052ad 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # flake8: noqa -from .user import User # flake8: noqa +from .page import Page # noqa +from .user import User # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py index a8871f6f5..fb250da60 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # flake8: noqa -from .user import User # flake8: noqa +from .page import Page # noqa +from .user import User # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py index a8871f6f5..fb250da60 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # flake8: noqa -from .user import User # flake8: noqa +from .page import Page # noqa +from .user import User # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup -- cgit v1.2.3 From ba7ab2c0a3b8797d02d7f522fa52818c0d390e09 Mon Sep 17 00:00:00 2001 From: JC Bohin Date: Mon, 13 Jun 2016 18:03:30 +0200 Subject: pep8: inline comment must have 2 spaces before --- docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py | 4 ++-- docs/tutorials/wiki2/src/views/tutorial/models/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py index fb250da60..8147052ad 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # noqa -from .user import User # noqa +from .page import Page # noqa +from .user import User # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py index fb250da60..8147052ad 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models/__init__.py @@ -5,8 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .page import Page # noqa -from .user import User # noqa +from .page import Page # noqa +from .user import User # noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup -- cgit v1.2.3 From 715ec5efbc3fc46e8e1cfef458667bded49d243e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 16 Jun 2016 11:01:25 -0700 Subject: Quick Tour - static_assets - closes #2648 - swap contents of jinja2 templates - use __main__ to specify package - carry forward template to json step - use :language: python directive for correct syntax highlighting --- docs/quick_tour.rst | 13 +++++++------ docs/quick_tour/json/hello_world.jinja2 | 2 +- docs/quick_tour/static_assets/hello_world.jinja2 | 2 +- docs/quick_tour/static_assets/hello_world_static.jinja2 | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'docs') diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index b170e5d98..55557f501 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -339,9 +339,10 @@ Static assets Of course the Web is more than just markup. You need static assets: CSS, JS, and images. Let's point our web app at a directory from which Pyramid will serve some static assets. First let's make another call to the -:term:`configurator`: +:term:`configurator` in ``app.py``: .. literalinclude:: quick_tour/static_assets/app.py + :language: python :linenos: :lines: 6-8 :lineno-start: 6 @@ -359,7 +360,7 @@ Next make a directory named ``static``, and place ``app.css`` inside: All we need to do now is point to it in the ```` of our Jinja2 template, ``hello_world.jinja2``: -.. literalinclude:: quick_tour/static_assets/hello_world.jinja2 +.. literalinclude:: quick_tour/static_assets/hello_world_static.jinja2 :language: jinja :linenos: :lines: 4-6 @@ -371,16 +372,16 @@ the site is later moved under ``/somesite/static/``? Or perhaps a web developer changes the arrangement on disk? Pyramid provides a helper to allow flexibility on URL generation: -.. literalinclude:: quick_tour/static_assets/hello_world_static.jinja2 +.. literalinclude:: quick_tour/static_assets/hello_world.jinja2 :language: jinja :linenos: :lines: 4-6 :lineno-start: 4 :emphasize-lines: 2 -By using ``request.static_url`` to generate the full URL to the static -assets, you both ensure you stay in sync with the configuration and -gain refactoring flexibility later. +By using ``request.static_url`` to generate the full URL to the static assets, +you ensure that you stay in sync with the configuration and gain refactoring +flexibility later. .. seealso:: See also: :ref:`Quick Tutorial Static Assets `, diff --git a/docs/quick_tour/json/hello_world.jinja2 b/docs/quick_tour/json/hello_world.jinja2 index 4fb9be074..a55865231 100644 --- a/docs/quick_tour/json/hello_world.jinja2 +++ b/docs/quick_tour/json/hello_world.jinja2 @@ -2,7 +2,7 @@ Hello World - +

Hello {{ name }}!

diff --git a/docs/quick_tour/static_assets/hello_world.jinja2 b/docs/quick_tour/static_assets/hello_world.jinja2 index 0fb2ce296..a55865231 100644 --- a/docs/quick_tour/static_assets/hello_world.jinja2 +++ b/docs/quick_tour/static_assets/hello_world.jinja2 @@ -2,7 +2,7 @@ Hello World - +

Hello {{ name }}!

diff --git a/docs/quick_tour/static_assets/hello_world_static.jinja2 b/docs/quick_tour/static_assets/hello_world_static.jinja2 index 4fb9be074..0fb2ce296 100644 --- a/docs/quick_tour/static_assets/hello_world_static.jinja2 +++ b/docs/quick_tour/static_assets/hello_world_static.jinja2 @@ -2,7 +2,7 @@ Hello World - +

Hello {{ name }}!

-- cgit v1.2.3 From da42d5794a1d2fff3e6a57980cf7018ec2e361b9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 16 Jun 2016 11:05:06 -0700 Subject: Quick Tour - explicitly use :language: python directive for proper syntax highlighting --- docs/quick_tour.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'docs') diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 55557f501..dde91b495 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -1,3 +1,4 @@ + .. _quick_tour: ===================== @@ -70,6 +71,7 @@ step. Here's a tiny application in Pyramid: .. literalinclude:: quick_tour/hello_world/app.py :linenos: + :language: python This simple example is easy to run. Save this as ``app.py`` and run it: @@ -120,6 +122,7 @@ library for request and response handling. In our example above, Pyramid hands Let's see some features of requests and responses in action: .. literalinclude:: quick_tour/requests/app.py + :language: python :pyobject: hello_world In this Pyramid view, we get the URL being visited from ``request.url``. Also @@ -159,6 +162,7 @@ Let's move the views out to their own ``views.py`` module and change the First our revised ``app.py``: .. literalinclude:: quick_tour/views/app.py + :language: python :linenos: We added some more routes, but we also removed the view code. Our views and @@ -169,6 +173,7 @@ We now have a ``views.py`` module that is focused on handling requests and responses: .. literalinclude:: quick_tour/views/views.py + :language: python :linenos: We have four views, each leading to the other. If you start at @@ -214,6 +219,7 @@ What if we want part of the URL to be available as data in my view? We can use this route declaration, for example: .. literalinclude:: quick_tour/routing/app.py + :language: python :linenos: :lines: 6 :lineno-start: 6 @@ -222,6 +228,7 @@ With this, URLs such as ``/howdy/amy/smith`` will assign ``amy`` to ``first`` and ``smith`` to ``last``. We can then use this data in our view: .. literalinclude:: quick_tour/routing/views.py + :language: python :linenos: :lines: 5-8 :lineno-start: 5 @@ -260,6 +267,7 @@ With the package installed, we can include the template bindings into our configuration in ``app.py``: .. literalinclude:: quick_tour/templating/app.py + :language: python :linenos: :lines: 6-8 :lineno-start: 6 @@ -268,6 +276,7 @@ configuration in ``app.py``: Now lets change our ``views.py`` file: .. literalinclude:: quick_tour/templating/views.py + :language: python :linenos: :emphasize-lines: 4,6 @@ -304,6 +313,7 @@ With the package installed, we can include the template bindings into our configuration: .. literalinclude:: quick_tour/jinja2/app.py + :language: python :linenos: :lines: 6-8 :lineno-start: 6 @@ -312,6 +322,7 @@ configuration: The only change in our view is to point the renderer at the ``.jinja2`` file: .. literalinclude:: quick_tour/jinja2/views.py + :language: python :linenos: :lines: 4-6 :lineno-start: 4 @@ -397,6 +408,7 @@ to update the UI in the browser by requesting server data as JSON. Pyramid supports this with a JSON renderer: .. literalinclude:: quick_tour/json/views.py + :language: python :linenos: :lines: 9- :lineno-start: 9 @@ -409,6 +421,7 @@ We also need to add a route to ``app.py`` so that our app will know how to respond to a request for ``hello.json``. .. literalinclude:: quick_tour/json/app.py + :language: python :linenos: :lines: 6-8 :lineno-start: 6 @@ -438,6 +451,7 @@ The following shows a "Hello World" example with three operations: view a form, save a change, or press the delete button in our ``views.py``: .. literalinclude:: quick_tour/view_classes/views.py + :language: python :linenos: :lines: 7- :lineno-start: 7 @@ -729,6 +743,7 @@ Our unit test passed, although its coverage is incomplete. 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 @@ -882,6 +897,7 @@ SQLAlchemy uses "models" for this mapping. The scaffold generated a sample model: .. literalinclude:: quick_tour/sqla_demo/sqla_demo/models/mymodel.py + :language: python :start-after: Start Sphinx Include :end-before: End Sphinx Include @@ -889,6 +905,7 @@ 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 -- cgit v1.2.3 From 49783e1f9b3b42721c02b7253002826d6f25c79a Mon Sep 17 00:00:00 2001 From: dowwie Date: Mon, 20 Jun 2016 11:33:07 -0400 Subject: typo fix within urldispatch narrative, example 2 --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2472ace31..7d37c04df 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -557,7 +557,7 @@ Here is an example of a corresponding ``mypackage.views`` module: @view_config(route_name='idea') def idea_view(request): - return Response(request.matchdict['id']) + return Response(request.matchdict['idea']) @view_config(route_name='user') def user_view(request): -- cgit v1.2.3 From 108121ee8a08837c39379cdd0e2e9c2b5b3712e8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 2 Jul 2016 01:34:25 -0700 Subject: Update Windows installation instructions and related bits. - Use proper Windows commands, drives, and paths - Use doscon for Windows console lexer --- docs/conventions.rst | 15 ++++--------- docs/narr/firstapp.rst | 6 +++--- docs/narr/i18n.rst | 2 +- docs/narr/install.rst | 42 +++++++++++++++++++++++++++--------- docs/narr/project.rst | 16 +++++++------- docs/narr/upgrading.rst | 6 +++--- docs/quick_tour.rst | 4 ++-- docs/quick_tutorial/requirements.rst | 2 +- 8 files changed, 54 insertions(+), 39 deletions(-) (limited to 'docs') diff --git a/docs/conventions.rst b/docs/conventions.rst index 43853882c..de041da04 100644 --- a/docs/conventions.rst +++ b/docs/conventions.rst @@ -57,23 +57,16 @@ character, e.g.: $ $VENV/bin/py.test -q -(See :term:`venv` for the meaning of ``$VENV``) +See :term:`venv` for the meaning of ``$VENV``. -Example blocks representing Windows ``cmd.exe`` commands are prefixed with a -drive letter and/or a directory name, e.g.: +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%``) - -Sometimes, when it's unknown which directory is current, Windows ``cmd.exe`` -example block commands are prefixed only with a ``>`` character, e.g.: - - .. code-block:: doscon - - > %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 diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index a8491eabd..ad05976c0 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -27,15 +27,15 @@ installed, an HTTP server is started on TCP port 8080. On UNIX: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/python helloworld.py On Windows: -.. code-block:: text +.. code-block:: doscon - C:\> %VENV%\Scripts\python.exe helloworld.py + c:\> %VENV%\Scripts\python helloworld.py This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the server will diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 131832aae..3549b53a5 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -294,7 +294,7 @@ Lingua like so: .. code-block:: doscon - C> %VENV%\Scripts\pip install lingua + c:\> %VENV%\Scripts\pip install lingua .. index:: diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 7d96f4074..c59ced2a5 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -92,8 +92,24 @@ 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 accept the defaults during the installation process. You may -also need to download and install the Python for Windows extensions. +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. .. seealso:: See the official Python documentation :ref:`Using Python on Windows ` for full details. @@ -104,14 +120,19 @@ also need to download and install the Python for Windows extensions. directions. Make sure you get the proper 32- or 64-bit build and Python version. +.. seealso:: `Python launcher for Windows + `_ provides a command + ``py`` that allows users to run any installed version of Python. + .. warning:: - After you install Python on Windows, you may 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. + 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. .. seealso:: See `Configuring Python (on Windows) `_ for @@ -190,7 +211,8 @@ After installing Python as described previously in c:\> set VENV=c:\env # replace "x" with your minor version of Python 3 - c:\> c:\Python3x\Scripts\python3 -m venv %VENV% + c:\> c:\Python3x\python -m venv %VENV% + c:\> cd %VENV% You can either follow the use of the environment variable ``%VENV%``, or replace it with the root directory of the virtual environment. If you choose @@ -204,7 +226,7 @@ After installing Python as described previously in .. parsed-literal:: - c:\\env> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " + c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " What Gets Installed diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 1ce12a938..812404b76 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -87,9 +87,9 @@ On UNIX: Or on Windows: -.. code-block:: text +.. code-block:: doscon - > %VENV%\Scripts\pcreate -s starter MyProject + c:\> %VENV%\Scripts\pcreate -s starter MyProject As a result of invoking the ``pcreate`` command, a directory named ``MyProject`` is created. That directory is a :term:`project` directory. The @@ -161,8 +161,8 @@ Or on Windows: .. code-block:: doscon - > cd MyProject - > %VENV%\Scripts\pip install -e . + c:\> cd MyProject + c:\> %VENV%\Scripts\pip install -e . Elided output from a run of this command on UNIX is shown below: @@ -199,7 +199,7 @@ On Windows: .. code-block:: doscon - > %VENV%\Scripts\pip install -e ".[testing]" + c:\> %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 @@ -215,7 +215,7 @@ On Windows: .. code-block:: doscon - > %VENV%\Scripts\py.test -q + c:\> %VENV%\Scripts\py.test -q Here's sample output from a test run on UNIX: @@ -266,7 +266,7 @@ path to the module on which we want to run tests and coverage. Running the Project Application ------------------------------- -.. seealso:: See also the output of :ref:`pserve --help `. +.. seealso:: See also the output of :ref:`pserve --help `. Once a project is installed for development, you can run the application it represents using the ``pserve`` command against the generated configuration @@ -282,7 +282,7 @@ On Windows: .. code-block:: text - > %VENV%\Scripts\pserve development.ini + c:\> %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 21b696775..4e434c3c6 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -205,10 +205,10 @@ On UNIX, you can do that via: On Windows, you need to issue two commands: -.. code-block:: bash +.. code-block:: doscon - C:\> set PYTHONWARNINGS=default - C:\> Scripts/pserve.exe development.ini + c:\> set PYTHONWARNINGS=default + c:\> Scripts/pserve.exe 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_tour.rst b/docs/quick_tour.rst index dde91b495..fb957be1c 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -44,9 +44,9 @@ For Windows: .. parsed-literal:: # set an environment variable to where you want your virtual environment - c:\> set VENV=c:\env + c:\\> set VENV=c:\\env # create the virtual environment - c:\\> c:\\Python35\\python3 -m venv %VENV% + c:\\> %VENV%\\Scripts\\python -m venv %VENV% # install pyramid c:\\> %VENV%\\Scripts\\pip install pyramid # or for a specific released version diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index 62dd570fc..958347a90 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\python3 -m venv %VENV% + c:\> c:\Python35\python -m venv %VENV% .. seealso:: See also Python 3's :mod:`venv module ` and Python 2's `virtualenv `_ package. -- cgit v1.2.3 From fa257dd74588c9cc80cc3a6b4158ff2c627eacd5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 2 Jul 2016 01:55:29 -0700 Subject: fix overly aggressive refactor --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 812404b76..71bd176f6 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -266,7 +266,7 @@ path to the module on which we want to run tests and coverage. Running the Project Application ------------------------------- -.. seealso:: See also the output of :ref:`pserve --help `. +.. seealso:: See also the output of :ref:`pserve --help `. Once a project is installed for development, you can run the application it represents using the ``pserve`` command against the generated configuration -- cgit v1.2.3 From 65687fee7e933593eda844bfb01aea5a968271aa Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 2 Jul 2016 05:03:39 -0700 Subject: proper case heading --- docs/quick_tutorial/debugtoolbar.rst | 2 +- docs/quick_tutorial/hello_world.rst | 2 +- docs/quick_tutorial/ini.rst | 2 +- docs/quick_tutorial/unit_testing.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/quick_tutorial/debugtoolbar.rst b/docs/quick_tutorial/debugtoolbar.rst index aaf904390..b02363d40 100644 --- a/docs/quick_tutorial/debugtoolbar.rst +++ b/docs/quick_tutorial/debugtoolbar.rst @@ -90,7 +90,7 @@ temporarily. .. seealso:: See also :ref:`pyramid_debugtoolbar `. -Extra Credit +Extra credit ============ #. Why don't we add ``pyramid_debugtoolbar`` to the list of diff --git a/docs/quick_tutorial/hello_world.rst b/docs/quick_tutorial/hello_world.rst index 4e35da7bb..56dccde58 100644 --- a/docs/quick_tutorial/hello_world.rst +++ b/docs/quick_tutorial/hello_world.rst @@ -88,7 +88,7 @@ Pyramid development. Building an application from loosely-coupled parts via revisit regularly in this *Quick Tutorial*. -Extra Credit +Extra credit ============ #. Why do we do this: diff --git a/docs/quick_tutorial/ini.rst b/docs/quick_tutorial/ini.rst index fba5ce29e..9a65d66d1 100644 --- a/docs/quick_tutorial/ini.rst +++ b/docs/quick_tutorial/ini.rst @@ -120,7 +120,7 @@ filesystem for changes to relevant code (Python files, the INI file, etc.) and, when something changes, restart the application. Very handy during development. -Extra Credit +Extra credit ============ #. If you don't like configuration and/or ``.ini`` files, could you do this diff --git a/docs/quick_tutorial/unit_testing.rst b/docs/quick_tutorial/unit_testing.rst index 56fd2b297..7c85d5289 100644 --- a/docs/quick_tutorial/unit_testing.rst +++ b/docs/quick_tutorial/unit_testing.rst @@ -92,7 +92,7 @@ necessary when your test needs to make use of the ``config`` object (it's a Configurator) to add stuff to the configuration state before calling the view. -Extra Credit +Extra credit ============ #. Change the test to assert that the response status code should be ``404`` -- cgit v1.2.3 From 0d37a99d86bf57f5254448b75665499682b9a613 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 5 Jul 2016 03:07:05 -0700 Subject: Add missing tests to quick_tutorial/forms. - Closes #2673 --- docs/quick_tutorial/forms.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/quick_tutorial/forms.rst b/docs/quick_tutorial/forms.rst index 66e77491d..1f421ee67 100644 --- a/docs/quick_tutorial/forms.rst +++ b/docs/quick_tutorial/forms.rst @@ -74,13 +74,18 @@ Steps :language: html :linenos: -#. Finally, a template at ``forms/tutorial/wikipage_view.pt`` for viewing a - wiki page: +#. Add a template at ``forms/tutorial/wikipage_view.pt`` for viewing a wiki + page: .. literalinclude:: forms/tutorial/wikipage_view.pt :language: html :linenos: +#. Our tests in ``forms/tutorial/tests.py`` don't run, so let's modify them: + + .. literalinclude:: forms/tutorial/tests.py + :linenos: + #. Run the tests: .. code-block:: bash -- cgit v1.2.3 From 9c84d8fd48802c86b342f977e634fae0871b4d90 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 6 Jul 2016 09:50:45 -0700 Subject: Update links for Alembix --- docs/quick_tour/sqla_demo/sqla_demo/models/meta.py | 2 +- docs/tutorials/wiki2/src/authentication/tutorial/models/meta.py | 2 +- docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py | 2 +- docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py | 2 +- docs/tutorials/wiki2/src/installation/tutorial/models/meta.py | 2 +- docs/tutorials/wiki2/src/models/tutorial/models/meta.py | 2 +- docs/tutorials/wiki2/src/tests/tutorial/models/meta.py | 2 +- docs/tutorials/wiki2/src/views/tutorial/models/meta.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'docs') 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 80ececd8c..03c50ae93 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py @@ -6,7 +6,7 @@ import zope.sqlalchemy # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/models/meta.py b/docs/tutorials/wiki2/src/authentication/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py b/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/models/tutorial/models/meta.py b/docs/tutorials/wiki2/src/models/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py b/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", diff --git a/docs/tutorials/wiki2/src/views/tutorial/models/meta.py b/docs/tutorials/wiki2/src/views/tutorial/models/meta.py index fc3e8f1dd..0682247b5 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models/meta.py @@ -3,7 +3,7 @@ from sqlalchemy.schema import MetaData # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more -# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html +# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", -- cgit v1.2.3 From fb9c227408d77551edf7dc876670b69df488175c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 16 Jul 2016 10:41:54 -0700 Subject: Fix link to zope.component docs --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index 518f7e784..c3a7170fc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -78,7 +78,7 @@ 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://docs.zope.org/zope.component', None), + 'zcomponent': ('http://zopecomponent.readthedocs.io/en/stable/', None), } -- cgit v1.2.3 From ba71cf32d543257cf51d1f00104f4a89ca794a42 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 16 Jul 2016 16:53:53 -0500 Subject: fix the wiki2 tutorial to set the password as unicode Something really weird is happening but this fixes it. SQLAlchemy is returning the "password_hash" from queries as the type that it was inserted as. Not consistently unicode or bytes. If I insert bytes, then I get bytes back out. If I insert unicode then I get unicode back out. It's unclear why, as the type is Text, the data we're storing is unambiguously US-ASCII and the connection is using a consistent text_factory for unicode conversions of "str" on Python 3. Here, we ensure that we always insert the value as unicode which appears to fix downstream issues like those mentioned in #2605. I was able to reproduce that bug and confirm this fixes it if the original database is initialized using this fix. Obsoletes #2623. --- docs/tutorials/wiki2/src/authentication/tutorial/models/user.py | 5 ++--- docs/tutorials/wiki2/src/authorization/tutorial/models/user.py | 5 ++--- docs/tutorials/wiki2/src/models/tutorial/models/user.py | 5 ++--- docs/tutorials/wiki2/src/tests/tutorial/models/user.py | 5 ++--- docs/tutorials/wiki2/src/views/tutorial/models/user.py | 5 ++--- 5 files changed, 10 insertions(+), 15 deletions(-) (limited to 'docs') diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py b/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py index 6fb32a1b2..9228b48f7 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/models/user.py @@ -19,11 +19,10 @@ class User(Base): def set_password(self, pw): pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) - self.password_hash = pwhash + self.password_hash = pwhash.decode('utf8') def check_password(self, pw): if self.password_hash is not None: expected_hash = self.password_hash.encode('utf8') - actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) - return expected_hash == actual_hash + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) return False diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py index 6fb32a1b2..9228b48f7 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py @@ -19,11 +19,10 @@ class User(Base): def set_password(self, pw): pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) - self.password_hash = pwhash + self.password_hash = pwhash.decode('utf8') def check_password(self, pw): if self.password_hash is not None: expected_hash = self.password_hash.encode('utf8') - actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) - return expected_hash == actual_hash + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) return False diff --git a/docs/tutorials/wiki2/src/models/tutorial/models/user.py b/docs/tutorials/wiki2/src/models/tutorial/models/user.py index 6fb32a1b2..9228b48f7 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/models/tutorial/models/user.py @@ -19,11 +19,10 @@ class User(Base): def set_password(self, pw): pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) - self.password_hash = pwhash + self.password_hash = pwhash.decode('utf8') def check_password(self, pw): if self.password_hash is not None: expected_hash = self.password_hash.encode('utf8') - actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) - return expected_hash == actual_hash + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) return False diff --git a/docs/tutorials/wiki2/src/tests/tutorial/models/user.py b/docs/tutorials/wiki2/src/tests/tutorial/models/user.py index 6fb32a1b2..9228b48f7 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/models/user.py @@ -19,11 +19,10 @@ class User(Base): def set_password(self, pw): pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) - self.password_hash = pwhash + self.password_hash = pwhash.decode('utf8') def check_password(self, pw): if self.password_hash is not None: expected_hash = self.password_hash.encode('utf8') - actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) - return expected_hash == actual_hash + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) return False diff --git a/docs/tutorials/wiki2/src/views/tutorial/models/user.py b/docs/tutorials/wiki2/src/views/tutorial/models/user.py index 6fb32a1b2..9228b48f7 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/views/tutorial/models/user.py @@ -19,11 +19,10 @@ class User(Base): def set_password(self, pw): pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) - self.password_hash = pwhash + self.password_hash = pwhash.decode('utf8') def check_password(self, pw): if self.password_hash is not None: expected_hash = self.password_hash.encode('utf8') - actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) - return expected_hash == actual_hash + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) return False -- cgit v1.2.3 From 251ddd3c2035fa3172ef9221c4a13fa53cdd3385 Mon Sep 17 00:00:00 2001 From: Christian Kollee Date: Sat, 16 Jul 2016 22:57:58 -0700 Subject: Corrected command line for tests (cherry picked from commit df3db24) --- docs/quick_tutorial/routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/quick_tutorial/routing.rst b/docs/quick_tutorial/routing.rst index 27c8c2c22..d88adfa1e 100644 --- a/docs/quick_tutorial/routing.rst +++ b/docs/quick_tutorial/routing.rst @@ -79,7 +79,7 @@ Steps .. code-block:: bash - $ $VENV/bin/$VENV/bin/py.test tutorial/tests.py -q + $ $VENV/bin/py.test tutorial/tests.py -q .. 2 passed in 0.39 seconds -- cgit v1.2.3 From b9ed3ffd2bf7e7061eee6137f527e13b44c79ae8 Mon Sep 17 00:00:00 2001 From: Christian Kollee Date: Sat, 16 Jul 2016 23:27:54 -0700 Subject: Corrected test command in static_assets.rst (cherry picked from commit 619c4b8) --- docs/quick_tutorial/static_assets.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/quick_tutorial/static_assets.rst b/docs/quick_tutorial/static_assets.rst index 65b34f8f9..b8482492d 100644 --- a/docs/quick_tutorial/static_assets.rst +++ b/docs/quick_tutorial/static_assets.rst @@ -47,7 +47,7 @@ Steps .. code-block:: bash - $ $VENV/bin/$VENV/bin/py.test tutorial/tests.py -q + $ $VENV/bin/py.test tutorial/tests.py -q .... 4 passed in 0.50 seconds -- cgit v1.2.3 From c898ddfe8d31718aa47fe697f8760dbc0ec79572 Mon Sep 17 00:00:00 2001 From: Jon Davidson Date: Mon, 18 Jul 2016 13:05:40 -1000 Subject: Change gendered language in examples Some examples in documentation use "dude" and "bro" -- for example, "Not found, bro". While playful, this language can make some people uncomfortable. I have changed the wording to something equally playful that doesn't make assumptions about the reader's gender. --- docs/narr/hooks.rst | 8 ++++---- docs/narr/urldispatch.rst | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'docs') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 49ef29d3f..c54b213f1 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -26,7 +26,7 @@ Not Found View by using the :linenos: def notfound(request): - return Response('Not Found, dude', status='404 Not Found') + return Response('Not Found', status='404 Not Found') def main(globals, **settings): config = Configurator() @@ -45,7 +45,7 @@ and a :term:`scan`, you can replace the Not Found View by using the @notfound_view_config() def notfound(request): - return Response('Not Found, dude', status='404 Not Found') + return Response('Not Found', status='404 Not Found') def main(globals, **settings): config = Configurator() @@ -67,11 +67,11 @@ Views can carry predicates limiting their applicability. For example: @notfound_view_config(request_method='GET') def notfound_get(request): - return Response('Not Found during GET, dude', status='404 Not Found') + return Response('Not Found during GET', status='404 Not Found') @notfound_view_config(request_method='POST') def notfound_post(request): - return Response('Not Found during POST, dude', status='404 Not Found') + return Response('Not Found during POST', status='404 Not Found') def main(globals, **settings): config = Configurator() diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 7d37c04df..9ac01e24a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -850,7 +850,7 @@ application: from pyramid.httpexceptions import HTTPNotFound def notfound(request): - return HTTPNotFound('Not found, bro.') + return HTTPNotFound() def no_slash(request): return Response('No slash') @@ -871,7 +871,7 @@ If a request enters the application with the ``PATH_INFO`` value of However, if a request enters the application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route will match, and the slash-appending not found view will not find a matching route with an appended slash. As a result, the -``notfound`` view will be called and it will return a "Not found, bro." body. +``notfound`` view will be called and it will return a "Not found" body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the @@ -892,7 +892,7 @@ exactly the same job: @notfound_view_config(append_slash=True) def notfound(request): - return HTTPNotFound('Not found, bro.') + return HTTPNotFound() @view_config(route_name='noslash') def no_slash(request): -- cgit v1.2.3 From 29d12cd3917c1a792c3a891e39ab15f99e8b380d Mon Sep 17 00:00:00 2001 From: Keith Yang Date: Sat, 16 Jul 2016 16:28:25 +0800 Subject: Add one-way password hash to security example in Quick Tutorial. --- docs/quick_tutorial/authentication.rst | 23 ++++++++++++++++++++++ docs/quick_tutorial/authentication/setup.py | 3 ++- .../authentication/tutorial/security.py | 16 +++++++++++++-- .../authentication/tutorial/views.py | 7 +++++-- docs/quick_tutorial/authorization/setup.py | 3 ++- .../authorization/tutorial/security.py | 16 +++++++++++++-- .../quick_tutorial/authorization/tutorial/views.py | 7 +++++-- 7 files changed, 65 insertions(+), 10 deletions(-) (limited to 'docs') diff --git a/docs/quick_tutorial/authentication.rst b/docs/quick_tutorial/authentication.rst index acff97f3b..c28958b33 100644 --- a/docs/quick_tutorial/authentication.rst +++ b/docs/quick_tutorial/authentication.rst @@ -34,6 +34,17 @@ Steps .. code-block:: bash $ cd ..; cp -r view_classes authentication; cd authentication + +#. This step depends on bcrypt_, so add it as a dependency in + ``authentication/setup.py``: + + .. literalinclude:: authentication/setup.py + :linenos: + +#. Now we can activate the development-mode distribution: + + .. code-block:: bash + $ $VENV/bin/pip install -e . #. Put the security hash in the ``authentication/development.ini`` @@ -103,6 +114,11 @@ In this example we chose to use the bundled :ref:`AuthTktAuthenticationPolicy ` policy. We enabled it in our configuration and provided a ticket-signing secret in our INI file. +The function ``hash_password`` hashes user's password by bcrypt_ instead of +storing password in plain text directly as a best practice [1]_. And function +``check_password`` will compare the hashed value of the submitted password +against the hashed value of the user's password. + Our view class grew a login view. When you reached it via a ``GET`` request, it returned a login form. When reached via ``POST``, it processed the submitted username and password against the "groupfinder" callable that we registered in @@ -126,3 +142,10 @@ Extra credit .. seealso:: See also :ref:`security_chapter`, :ref:`AuthTktAuthenticationPolicy `. + +.. _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/quick_tutorial/authentication/setup.py b/docs/quick_tutorial/authentication/setup.py index 2221b72e9..7a6ff4226 100644 --- a/docs/quick_tutorial/authentication/setup.py +++ b/docs/quick_tutorial/authentication/setup.py @@ -2,7 +2,8 @@ from setuptools import setup requires = [ 'pyramid', - 'pyramid_chameleon' + 'pyramid_chameleon', + 'bcrypt' ] setup(name='tutorial', diff --git a/docs/quick_tutorial/authentication/tutorial/security.py b/docs/quick_tutorial/authentication/tutorial/security.py index ab90bab2c..e585e2642 100644 --- a/docs/quick_tutorial/authentication/tutorial/security.py +++ b/docs/quick_tutorial/authentication/tutorial/security.py @@ -1,5 +1,17 @@ -USERS = {'editor': 'editor', - 'viewer': 'viewer'} +import bcrypt + + +def hash_password(pw): + pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) + return pwhash.decode('utf8') + +def check_password(pw, hashed_pw): + expected_hash = hashed_pw.encode('utf8') + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) + + +USERS = {'editor': hash_password('editor'), + 'viewer': hash_password('viewer')} GROUPS = {'editor': ['group:editors']} diff --git a/docs/quick_tutorial/authentication/tutorial/views.py b/docs/quick_tutorial/authentication/tutorial/views.py index ab46eb2dd..b07538d5e 100644 --- a/docs/quick_tutorial/authentication/tutorial/views.py +++ b/docs/quick_tutorial/authentication/tutorial/views.py @@ -9,7 +9,10 @@ from pyramid.view import ( view_defaults ) -from .security import USERS +from .security import ( + USERS, + check_password +) @view_defaults(renderer='home.pt') @@ -40,7 +43,7 @@ class TutorialViews: if 'form.submitted' in request.params: login = request.params['login'] password = request.params['password'] - if USERS.get(login) == password: + if check_password(password, USERS.get(login)): headers = remember(request, login) return HTTPFound(location=came_from, headers=headers) diff --git a/docs/quick_tutorial/authorization/setup.py b/docs/quick_tutorial/authorization/setup.py index 2221b72e9..7a6ff4226 100644 --- a/docs/quick_tutorial/authorization/setup.py +++ b/docs/quick_tutorial/authorization/setup.py @@ -2,7 +2,8 @@ from setuptools import setup requires = [ 'pyramid', - 'pyramid_chameleon' + 'pyramid_chameleon', + 'bcrypt' ] setup(name='tutorial', diff --git a/docs/quick_tutorial/authorization/tutorial/security.py b/docs/quick_tutorial/authorization/tutorial/security.py index ab90bab2c..e585e2642 100644 --- a/docs/quick_tutorial/authorization/tutorial/security.py +++ b/docs/quick_tutorial/authorization/tutorial/security.py @@ -1,5 +1,17 @@ -USERS = {'editor': 'editor', - 'viewer': 'viewer'} +import bcrypt + + +def hash_password(pw): + pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) + return pwhash.decode('utf8') + +def check_password(pw, hashed_pw): + expected_hash = hashed_pw.encode('utf8') + return bcrypt.checkpw(pw.encode('utf8'), expected_hash) + + +USERS = {'editor': hash_password('editor'), + 'viewer': hash_password('viewer')} GROUPS = {'editor': ['group:editors']} diff --git a/docs/quick_tutorial/authorization/tutorial/views.py b/docs/quick_tutorial/authorization/tutorial/views.py index 43d14455a..b2dc905c0 100644 --- a/docs/quick_tutorial/authorization/tutorial/views.py +++ b/docs/quick_tutorial/authorization/tutorial/views.py @@ -10,7 +10,10 @@ from pyramid.view import ( forbidden_view_config ) -from .security import USERS +from .security import ( + USERS, + check_password +) @view_defaults(renderer='home.pt') @@ -42,7 +45,7 @@ class TutorialViews: if 'form.submitted' in request.params: login = request.params['login'] password = request.params['password'] - if USERS.get(login) == password: + if check_password(password, USERS.get(login)): headers = remember(request, login) return HTTPFound(location=came_from, headers=headers) -- cgit v1.2.3 From e5c279b1d4d0484bc58c9101c523959d09641f7d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 23 Jul 2016 14:52:09 -0700 Subject: Rewrite Quick Tutorial narrative in authentication.rst for consistent flow --- docs/quick_tutorial/authentication.rst | 42 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'docs') diff --git a/docs/quick_tutorial/authentication.rst b/docs/quick_tutorial/authentication.rst index c28958b33..892beb3ec 100644 --- a/docs/quick_tutorial/authentication.rst +++ b/docs/quick_tutorial/authentication.rst @@ -1,7 +1,7 @@ .. _qtut_authentication: ============================== -20: Logins With Authentication +20: Logins with authentication ============================== Login views that authenticate a username and password against a list of users. @@ -35,13 +35,14 @@ Steps $ cd ..; cp -r view_classes authentication; cd authentication -#. This step depends on bcrypt_, so add it as a dependency in - ``authentication/setup.py``: +#. Add ``bcrypt`` as a dependency in ``authentication/setup.py``: .. literalinclude:: authentication/setup.py + :language: python + :emphasize-lines: 5-6 :linenos: -#. Now we can activate the development-mode distribution: +#. We can now install our project in development mode: .. code-block:: bash @@ -107,23 +108,32 @@ Unlike many web frameworks, Pyramid includes a built-in but optional security model for authentication and authorization. This security system is intended to be flexible and support many needs. In this security model, authentication (who are you) and authorization (what are you allowed to do) are not just pluggable, -but de-coupled. To learn one step at a time, we provide a system that -identifies users and lets them log out. +but decoupled. To learn one step at a time, we provide a system that identifies +users and lets them log out. In this example we chose to use the bundled :ref:`AuthTktAuthenticationPolicy ` policy. We enabled it in our configuration and provided a ticket-signing secret in our INI file. -The function ``hash_password`` hashes user's password by bcrypt_ instead of -storing password in plain text directly as a best practice [1]_. And function -``check_password`` will compare the hashed value of the submitted password -against the hashed value of the user's password. - Our view class grew a login view. When you reached it via a ``GET`` request, it returned a login form. When reached via ``POST``, it processed the submitted username and password against the "groupfinder" callable that we registered in the configuration. +The function ``hash_password`` uses a one-way hashing algorithm with a salt on +the user's password via ``bcrypt``, instead of storing the password in plain +text. This is considered to be a "best practice" for security. + +.. note:: + There are alternative libraries to ``bcrypt`` if it is an issue on your + system. Just make sure that the library uses an algorithm approved for + storing passwords securely. + +The function ``check_password`` will compare the two hashed values of the +submitted password and the user's password stored in the database. If the +hashed values are equivalent, then the user is authenticated, else +authentication fails. + In our template, we fetched the ``logged_in`` value from the view class. We use this to calculate the logged-in user, if any. In the template we can then choose to show a login link to anonymous visitors or a logout link to logged-in @@ -141,11 +151,5 @@ Extra credit request? Use ``import pdb; pdb.set_trace()`` to answer this. .. seealso:: See also :ref:`security_chapter`, - :ref:`AuthTktAuthenticationPolicy `. - -.. _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. + :ref:`AuthTktAuthenticationPolicy `, `bcrypt + `_ -- cgit v1.2.3 From ebd2ea5a21978865804fc7569d4383f0ed90d489 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 23 Jul 2016 23:22:05 -0700 Subject: Add highlighting of changed lines --- docs/quick_tutorial/forms.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs') diff --git a/docs/quick_tutorial/forms.rst b/docs/quick_tutorial/forms.rst index 1f421ee67..84ceb13d6 100644 --- a/docs/quick_tutorial/forms.rst +++ b/docs/quick_tutorial/forms.rst @@ -41,6 +41,7 @@ Steps pulls in Colander as a dependency: .. literalinclude:: forms/setup.py + :emphasize-lines: 5-6 :linenos: #. We can now install our project in development mode: -- cgit v1.2.3 From a37645742645589bd1700adf771a46d74568877c Mon Sep 17 00:00:00 2001 From: andrew david burt Date: Fri, 29 Jul 2016 14:46:59 -0700 Subject: remove essentially duplicate "note" section under "initializing the database" The note section under "initializing the database" was entered twice, the same except differing verb tenses. I removed one. (cherry picked from commit 96c1e36) --- docs/tutorials/wiki2/installation.rst | 7 ------- 1 file changed, 7 deletions(-) (limited to 'docs') diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index a214b1306..0440c2d1d 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -402,13 +402,6 @@ initialize our database. already have a database, you should delete it before running ``initialize_tutorial_db`` again. -.. note:: - - The ``initialize_tutorial_db`` command is not performing a migration but - rather simply creating missing tables and adding some dummy data. If you - already have a database, you should delete it before running - ``initialize_tutorial_db`` again. - Type the following command, making sure you are still in the ``tutorial`` directory (the directory with a ``development.ini`` in it): -- cgit v1.2.3 From 3caa9dab20789a4d8cce58a9dec9e4ff25be6127 Mon Sep 17 00:00:00 2001 From: andrew david burt Date: Fri, 29 Jul 2016 16:18:21 -0700 Subject: corrected folder name in docs one of the instances of the tutorial's folder name was mistyped as "tutorials" rather than "tutorial" in the "Route declarations" section (cherry picked from commit 696f17c) --- docs/tutorials/wiki2/basiclayout.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index ce67bb9e3..98a14c644 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -114,7 +114,7 @@ Finally ``main`` is finished configuring things, so it uses the Route declarations ------------------ -Open the ``tutorials/routes.py`` file. It should already contain the following: +Open the ``tutorial/routes.py`` file. It should already contain the following: .. literalinclude:: src/basiclayout/tutorial/routes.py :linenos: -- cgit v1.2.3 From 830bcb8aea8d9c842ef1ccd9a80470836f4c6442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20G=C3=B3recki?= Date: Wed, 10 Aug 2016 11:46:45 +0100 Subject: Add docs & explict tests --- docs/api/authentication.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs') diff --git a/docs/api/authentication.rst b/docs/api/authentication.rst index 19d08618b..de2c73491 100644 --- a/docs/api/authentication.rst +++ b/docs/api/authentication.rst @@ -35,4 +35,7 @@ Helper Classes :members: +Helper Functions +~~~~~~~~~~~~~~~~ + .. autofunction:: extract_http_basic_credentials -- cgit v1.2.3 From ab69a91aaa5d04fcdf72dad0e8810eaabea67745 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 15 Aug 2016 01:43:58 -0700 Subject: update output of pcreate --list for Quick Tour --- docs/quick_tour.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index fb957be1c..88cd69400 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -504,10 +504,10 @@ Pyramid's ``pcreate`` command can list the available scaffolds: $ pcreate --list Available scaffolds: - alchemy: Pyramid SQLAlchemy project using url dispatch + alchemy: Pyramid project using SQLAlchemy, SQLite, URL dispatch, and Jinja2 pyramid_jinja2_starter: Pyramid Jinja2 starter project - starter: Pyramid starter project - zodb: Pyramid ZODB project using traversal + starter: Pyramid starter project using URL dispatch and Chameleon + zodb: Pyramid project using ZODB, traversal, and Chameleon 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 -- cgit v1.2.3 From 6775670519e5e869264065e3f6cdd1a0dfe71d66 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 18 Aug 2016 00:32:56 -0700 Subject: update output for pcreate --list in Quick Tutorial --- docs/quick_tutorial/scaffolds.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/quick_tutorial/scaffolds.rst b/docs/quick_tutorial/scaffolds.rst index 7845f2b71..ad002f4fd 100644 --- a/docs/quick_tutorial/scaffolds.rst +++ b/docs/quick_tutorial/scaffolds.rst @@ -38,9 +38,9 @@ Steps $ $VENV/bin/pcreate --list Available scaffolds: - alchemy: Pyramid SQLAlchemy project using url dispatch - starter: Pyramid starter project - zodb: Pyramid ZODB project using traversal + 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: -- cgit v1.2.3 From 0295ae858cb18bc280c6ace76fda44b4154a085c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 31 Aug 2016 23:46:45 -0500 Subject: rename the credentials class --- docs/api/authentication.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs') diff --git a/docs/api/authentication.rst b/docs/api/authentication.rst index de2c73491..57f32327a 100644 --- a/docs/api/authentication.rst +++ b/docs/api/authentication.rst @@ -34,6 +34,8 @@ Helper Classes .. autoclass:: AuthTktCookieHelper :members: + .. autoclass:: HTTPBasicCredentials + :members: Helper Functions ~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From a5c8100d780155643063742c716ac8d2f54e2e45 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 1 Sep 2016 00:30:13 -0500 Subject: drop support for python 3.3 and error on 2.6 closes #2476 --- docs/narr/install.rst | 5 ++--- docs/narr/introduction.rst | 2 +- docs/quick_tutorial/requirements.rst | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'docs') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c59ced2a5..677c27e4a 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -21,9 +21,8 @@ the following sections. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.7, - Python 3.3, Python 3.4, Python 3.5, PyPy, and PyPy3. :app:`Pyramid` does - not run under any version of Python before 2.7. + As of this writing, :app:`Pyramid` is tested against Python 2.7, + Python 3.4, Python 3.5, 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 de6ac408b..47638579b 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.3, Python 3.4, Python 3.5, PyPy, and PyPy3 +and Jenkins on Python 2.7, Python 3.4, Python 3.5, 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_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index 958347a90..1de9a8acf 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -19,7 +19,7 @@ virtual environment.) This *Quick Tutorial* is based on: -* **Python 3.5**. Pyramid fully supports Python 3.3+ and Python 2.7+. This +* **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. * **venv**. We believe in virtual environments. For this tutorial, we use -- cgit v1.2.3 From bdd5440023f016f3b6597c66dc26cc30e22960eb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 1 Sep 2016 01:06:37 -0700 Subject: One more for 2.6 --- docs/quick_tour.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 88cd69400..b2dec77e9 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -52,7 +52,7 @@ For Windows: # or for a specific released version c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " -Of course Pyramid runs fine on Python 2.6+, as do the examples in this *Quick +Of course Pyramid runs fine on Python 2.7+, as do the examples in this *Quick Tour*. We're showing Python 3 for simplicity. (Pyramid had production support for Python 3 in October 2011.) Also for simplicity, the remaining examples will show only UNIX commands. -- cgit v1.2.3 From df0e20f3440bcf039f6d40822a1280efa26bfc87 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 3 Sep 2016 22:47:44 -0500 Subject: update docs to support the bootstrap context manager from #2760 --- docs/narr/commandline.rst | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'docs') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 6cd90d42f..242bc7ec7 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -649,6 +649,10 @@ using the :func:`pyramid.paster.bootstrap` command in the body of your script. .. versionadded:: 1.1 :func:`pyramid.paster.bootstrap` +.. versionchanged:: 1.8 + Added the ability for ``bootstrap`` to cleanup automatically via the + ``with`` statement. + In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a single argument, which accepts the :term:`PasteDeploy` ``.ini`` file representing your Pyramid application's configuration as a single argument: @@ -656,8 +660,9 @@ representing your Pyramid application's configuration as a single argument: .. code-block:: python from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini') - print(env['request'].route_url('home')) + + with bootstrap('/path/to/my/development.ini') as env: + print(env['request'].route_url('home')) :func:`pyramid.paster.bootstrap` returns a dictionary containing framework-related information. This dictionary will always contain a @@ -723,8 +728,9 @@ load instead of ``main``: .. code-block:: python from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini#another') - print(env['request'].route_url('home')) + + with bootstrap('/path/to/my/development.ini#another') as env: + print(env['request'].route_url('home')) The above example specifies the ``another`` ``app``, ``pipeline``, or ``composite`` section of your PasteDeploy configuration file. The ``app`` @@ -761,9 +767,9 @@ desired request and passing it into :func:`~pyramid.paster.bootstrap`: from pyramid.request import Request request = Request.blank('/', base_url='https://example.com/prefix') - env = bootstrap('/path/to/my/development.ini#another', request=request) - print(env['request'].application_url) - # will print 'https://example.com/prefix' + with bootstrap('/path/to/my/development.ini#another', request=request) as env: + print(env['request'].application_url) + # will print 'https://example.com/prefix' Now you can readily use Pyramid's APIs for generating URLs: @@ -776,7 +782,9 @@ Now you can readily use Pyramid's APIs for generating URLs: Cleanup ~~~~~~~ -When your scripting logic finishes, it's good manners to call the ``closer`` +If you're using the ``with``-statement variant then there's nothing to +worry about. However if you're using the returned environment directly then +when your scripting logic finishes, it's good manners to call the ``closer`` callback: .. code-block:: python @@ -891,15 +899,12 @@ contains the following code: omit = options.omit if omit is None: omit = [] - env = bootstrap(config_uri) - settings, closer = env['registry'].settings, env['closer'] - try: + with bootstrap(config_uri) as env: + settings = env['registry'].settings for k, v in settings.items(): if any([k.startswith(x) for x in omit]): continue print('%-40s %-20s' % (k, v)) - finally: - closer() This script uses the Python ``optparse`` module to allow us to make sense out of extra arguments passed to the script. It uses the -- cgit v1.2.3 From ad05d18fd74e2add5a1abc149f63ad389a908dc5 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 12 Sep 2016 21:13:29 -0500 Subject: document more clearly the ``__call__`` method on route and view predicates fixes #1549 --- docs/narr/hooks.rst | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'docs') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index c54b213f1..6d0a2a5a3 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1481,7 +1481,7 @@ method. For example: phash = text def __call__(self, context, request): - return getattr(context, 'content_type', None) == self.val + return request.content_type == self.val The constructor of a predicate factory takes two arguments: ``val`` and ``config``. The ``val`` argument will be the argument passed to @@ -1500,13 +1500,28 @@ with the name and the value serialized. The result of ``phash`` is not seen in output anywhere, it just informs the uniqueness constraints for view configuration. -The ``__call__`` method of a predicate factory must accept a resource -(``context``) and a request, and must return ``True`` or ``False``. It is the -"meat" of the predicate. +The ``__call__`` method differs depending on whether the predicate is used as +a :term:`view predicate` or a :term:`route predicate`: -You can use the same predicate factory as both a view predicate and as a route -predicate, but you'll need to call ``add_view_predicate`` and -``add_route_predicate`` separately with the same factory. +- When used as a route predicate, the ``__call__`` signature is + ``(info, request)``. The ``info`` object is a dictionary containing two + keys: ``match`` and ``route``. ``info['match']`` is the matchdict containing + the patterns matched in the route pattern. ``info['route']`` is the + :class:`pyramid.interfaces.IRoute` object for the current route. + +- When used as a view predicate, the ``__call__`` signature is + ``(context, request)``. The ``context`` is the result of :term:`traversal` + performed using either the route's :term:`root factory` or the app's + :term:`default root factory`. + +In both cases the ``__call__`` method is expected to return ``True`` or +``False``. + +It is possible to use the same predicate factory as both a view predicate and +as a route predicate, but they'll need to handle the ``info`` or ``context`` +argument specially (many predicates do not need this argument) and you'll need +to call ``add_view_predicate`` and ``add_route_predicate`` separately with +the same factory. .. _subscriber_predicates: -- cgit v1.2.3 From 21f2b61272f83de110087344e68f32953cd7b42f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Sep 2016 20:39:45 -0700 Subject: Why use venv/bin/pip instead of source bin/activate then pip? - Closes #2610 --- docs/narr/install.rst | 21 +++++++++++++++++++++ docs/quick_tour.rst | 4 +++- docs/quick_tutorial/requirements.rst | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 677c27e4a..7b5d8361b 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -191,6 +191,24 @@ After installing Python as described previously in :ref:`for-mac-os-x-users` or $ $VENV/bin/pip install "pyramid==\ |release|\ " +.. index:: + single: $VENV/bin/pip vs. source bin/activate + +.. _venv-bin-pip-vs-source-bin-activate: + +.. note:: Why use ``$VENV/bin/pip`` instead of ``source bin/activate``, then + ``pip``? + + Although the latter method requires fewer key strokes to issue commands once + invoked, there are numerous reasons why one should avoid using ``activate`` + within a virtual environment. Michael F. Lamb (datagrok) presents a summary + in `Virtualenv's bin/activate is Doing It Wrong + `_, and proposes alternatives, + followed by comments from other developers. + + However, we prefer to keep things simple. ``$VENV/bin/pip`` is already + UNIX-y. The few extra key strokes are worth avoiding the mess altogether. + .. index:: single: installing on Windows @@ -227,6 +245,9 @@ After installing Python as described previously in c:\\> %VENV%\\Scripts\\pip install "pyramid==\ |release|\ " +.. note:: See the note above for :ref:`Why use $VENV/bin/pip instead of source + bin/activate, then pip `. + What Gets Installed ------------------- diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index b2dec77e9..39b4cafb3 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -59,7 +59,9 @@ show only UNIX commands. .. seealso:: See also: :ref:`Quick Tutorial section on Requirements `, - :ref:`installing_unix`, :ref:`Before You Install `, and + :ref:`installing_unix`, :ref:`Before You Install `, + :ref:`Why use $VENV/bin/pip instead of source bin/activate, then pip + `, and :ref:`Installing Pyramid on a Windows System `. diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index 1de9a8acf..afa8ed104 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -179,6 +179,9 @@ time of its release. # Windows c:\> %VENV%\Scripts\pip install --upgrade pip setuptools +.. seealso:: See also :ref:`Why use $VENV/bin/pip instead of source + bin/activate, then pip `. + .. _install-pyramid: -- cgit v1.2.3 From 781cf1a5d685daf21ab7b885fda4ab21b05ce940 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Sep 2016 00:18:34 -0700 Subject: Revise Why use venv/bin/pip instead of source bin/activate then pip? - Closes #2610 --- docs/narr/install.rst | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'docs') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 7b5d8361b..570cb2285 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -199,15 +199,20 @@ After installing Python as described previously in :ref:`for-mac-os-x-users` or .. note:: Why use ``$VENV/bin/pip`` instead of ``source bin/activate``, then ``pip``? - Although the latter method requires fewer key strokes to issue commands once - invoked, there are numerous reasons why one should avoid using ``activate`` - within a virtual environment. Michael F. Lamb (datagrok) presents a summary - in `Virtualenv's bin/activate is Doing It Wrong - `_, and proposes alternatives, - followed by comments from other developers. - - However, we prefer to keep things simple. ``$VENV/bin/pip`` is already - UNIX-y. The few extra key strokes are worth avoiding the mess altogether. + ``$VENV/bin/pip`` clearly specifies that ``pip`` is run from within the + virtual environment and not at the system level. + + ``activate`` drops turds into the user's shell environment, leaving them + vulnerable to executing commands in the wrong context. ``deactivate`` might + not correctly restore previous shell environment variables. + + Although using ``source bin/activate``, then ``pip``, requires fewer key + strokes to issue commands once invoked, there are other things to consider. + Michael F. Lamb (datagrok) presents a summary in `Virtualenv's bin/activate + is Doing It Wrong `_. + + Ultimately we prefer to keep things clear and simple, so we use + ``$VENV/bin/pip``. .. index:: -- cgit v1.2.3 From e8c66a339e9f7d83bd2408952de53ef30dba0794 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Sep 2016 23:52:05 -0500 Subject: derive exception views separately from normal views - previously the multiview was shared for both exception and hot-route, but now that we allow some exception-only views this needed to be separated - add ViewDeriverInfo.exception_only to detect exception views - do not prevent http_cache on exception views - optimize secured_view and csrf_view derivers to remove themselves from the view pipeline for exception views --- docs/narr/hooks.rst | 23 +++++++++++++++++++++-- docs/narr/viewconfig.rst | 19 ++++++++++++++++++- docs/narr/views.rst | 40 ++++++++++++++++++++++++++-------------- 3 files changed, 65 insertions(+), 17 deletions(-) (limited to 'docs') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 49ef29d3f..7fbac2080 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1639,7 +1639,8 @@ the user-defined :term:`view callable`: Enforce the ``permission`` defined on the view. This element is a no-op if no permission is defined. Note there will always be a permission defined if a default permission was assigned via - :meth:`pyramid.config.Configurator.set_default_permission`. + :meth:`pyramid.config.Configurator.set_default_permission` unless the + view is an :term:`exception view`. This element will also output useful debugging information when ``pyramid.debug_authorization`` is enabled. @@ -1649,7 +1650,8 @@ the user-defined :term:`view callable`: Used to check the CSRF token provided in the request. This element is a no-op if ``require_csrf`` view option is not ``True``. Note there will always be a ``require_csrf`` option if a default value was assigned via - :meth:`pyramid.config.Configurator.set_default_csrf_options`. + :meth:`pyramid.config.Configurator.set_default_csrf_options` unless + the view is an :term:`exception view`. ``owrapped_view`` @@ -1695,6 +1697,8 @@ around monitoring and security. In order to register a custom :term:`view deriver`, you should create a callable that conforms to the :class:`pyramid.interfaces.IViewDeriver` interface, and then register it with your application using :meth:`pyramid.config.Configurator.add_view_deriver`. +The callable should accept the ``view`` to be wrapped and the ``info`` object +which is an instance of :class:`pyramid.interfaces.IViewDeriverInfo`. For example, below is a callable that can provide timing information for the view pipeline: @@ -1745,6 +1749,21 @@ View derivers are unique in that they have access to most of the options passed to :meth:`pyramid.config.Configurator.add_view` in order to decide what to do, and they have a chance to affect every view in the application. +.. _exception_view_derivers: + +Exception Views and View Derivers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A :term:`view deriver` has the opportunity to wrap any view, including +an :term:`exception view`. In general this is fine, but certain view derivers +may wish to avoid doing certain things when handling exceptions. For example, +the ``csrf_view`` and ``secured_view`` built-in view derivers will not perform +security checks on exception views unless explicitly told to do so. + +You can check for ``info.exception_only`` on the +:class:`pyramid.interfaces.IViewDeriverInfo` object when wrapping the view +to determine whether you are wrapping an exception view or a normal view. + Ordering View Derivers ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index cd5b8feb0..76eaf3cc5 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -34,7 +34,7 @@ determine the set of circumstances which must be true for the view callable to be invoked. A view configuration statement is made about information present in the -:term:`context` resource and the :term:`request`. +:term:`context` resource (or exception) and the :term:`request`. View configuration is performed in one of two ways: @@ -306,9 +306,26 @@ configured view. represented class or if the :term:`context` resource provides the represented interface; it is otherwise false. + It is possible to pass an exception class as the context if your context may + subclass an exception. In this case **two** views will be registered. One + will match normal incoming requests and the other will match as an + :term:`exception view` which only occurs when an exception is raised during + the normal request processing pipeline. + If ``context`` is not supplied, the value ``None``, which matches any resource, is used. +``exception_only`` + + When this value is ``True`` the ``context`` argument must be a subclass of + ``Exception``. This flag indicates that only an :term:`exception view` should + be created and that this view should not match if the traversal + :term:`context` matches the ``context`` argument. If the ``context`` is a + subclass of ``Exception`` and this value is ``False`` (the default) then a + view will be registered to match the traversal :term:`context` as well. + + .. versionadded:: 1.8 + ``route_name`` If ``route_name`` is supplied, the view callable will be invoked only when the named route has matched. diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 770d27919..465062651 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -262,10 +262,16 @@ specialized views as described in :ref:`special_exceptions_in_callables` can also be used by application developers to convert arbitrary exceptions to responses. -To register a view that should be called whenever a particular exception is -raised from within :app:`Pyramid` view code, use the exception class (or one of -its superclasses) as the :term:`context` of a view configuration which points -at a view callable for which you'd like to generate a response. +To register a :term:`exception view` that should be called whenever a +particular exception is raised from within :app:`Pyramid` view code, use +:meth:`pyramid.config.Configurator.add_exception_view` to register a view +configuration which matches the exception (or a subclass of the exception) and +points at a view callable for which you'd like to generate a response. The +exception will be passed as the ``context`` argument to any +:term:`view predicate` registered with the view as well as to the view itself. +For convenience a new decorator exists, +:class:`pyramid.views.exception_view_config`, which may be used to easily +register exception views. For example, given the following exception class in a module named ``helloworld.exceptions``: @@ -277,17 +283,16 @@ For example, given the following exception class in a module named def __init__(self, msg): self.msg = msg - You can wire a view callable to be called whenever any of your *other* code raises a ``helloworld.exceptions.ValidationFailure`` exception: .. code-block:: python :linenos: - from pyramid.view import view_config + from pyramid.view import exception_view_config from helloworld.exceptions import ValidationFailure - @view_config(context=ValidationFailure) + @exception_view_config(ValidationFailure) def failed_validation(exc, request): response = Response('Failed validation: %s' % exc.msg) response.status_int = 500 @@ -308,7 +313,7 @@ view registration: from pyramid.view import view_config from helloworld.exceptions import ValidationFailure - @view_config(context=ValidationFailure, route_name='home') + @exception_view_config(ValidationFailure, route_name='home') def failed_validation(exc, request): response = Response('Failed validation: %s' % exc.msg) response.status_int = 500 @@ -327,14 +332,21 @@ which have a name will be ignored. .. note:: - Normal (i.e., non-exception) views registered against a context resource type - which inherits from :exc:`Exception` will work normally. When an exception - view configuration is processed, *two* views are registered. One as a - "normal" view, the other as an "exception" view. This means that you can use - an exception as ``context`` for a normal view. + In most cases, you should register an :term:`exception view` by using + :meth:`pyramid.config.Configurator.add_exception_view`. However, it is + possible to register 'normal' (i.e., non-exception) views against a context + resource type which inherits from :exc:`Exception` (i.e., + ``config.add_view(context=Exception)``). When the view configuration is + processed, *two* views are registered. One as a "normal" view, the other + as an :term:`exception view`. This means that you can use an exception as + ``context`` for a normal view. + + The view derivers that wrap these two views may behave differently. + See :ref:`exception_view_derivers` for more information about this. Exception views can be configured with any view registration mechanism: -``@view_config`` decorator or imperative ``add_view`` styles. +``@exception_view_config`` decorator or imperative ``add_exception_view`` +styles. .. note:: -- cgit v1.2.3 From 160aabb3798b4f613c89054ce4a60cba7374ddae Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 29 Sep 2016 00:04:01 -0700 Subject: Clean up docstrings/narr docs from PR #2660 - Closes #2768 --- docs/narr/viewconfig.rst | 10 +++++----- docs/narr/views.rst | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'docs') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 76eaf3cc5..7cb8e0306 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -307,8 +307,8 @@ configured view. interface; it is otherwise false. It is possible to pass an exception class as the context if your context may - subclass an exception. In this case **two** views will be registered. One - will match normal incoming requests and the other will match as an + subclass an exception. In this case *two* views will be registered. One + will match normal incoming requests, and the other will match as an :term:`exception view` which only occurs when an exception is raised during the normal request processing pipeline. @@ -317,11 +317,11 @@ configured view. ``exception_only`` - When this value is ``True`` the ``context`` argument must be a subclass of + When this value is ``True``, the ``context`` argument must be a subclass of ``Exception``. This flag indicates that only an :term:`exception view` should - be created and that this view should not match if the traversal + be created, and that this view should not match if the traversal :term:`context` matches the ``context`` argument. If the ``context`` is a - subclass of ``Exception`` and this value is ``False`` (the default) then a + subclass of ``Exception`` and this value is ``False`` (the default), then a view will be registered to match the traversal :term:`context` as well. .. versionadded:: 1.8 diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 465062651..ab139ea19 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -262,13 +262,13 @@ specialized views as described in :ref:`special_exceptions_in_callables` can also be used by application developers to convert arbitrary exceptions to responses. -To register a :term:`exception view` that should be called whenever a +To register an :term:`exception view` that should be called whenever a particular exception is raised from within :app:`Pyramid` view code, use :meth:`pyramid.config.Configurator.add_exception_view` to register a view configuration which matches the exception (or a subclass of the exception) and points at a view callable for which you'd like to generate a response. The exception will be passed as the ``context`` argument to any -:term:`view predicate` registered with the view as well as to the view itself. +:term:`view predicate` registered with the view, as well as to the view itself. For convenience a new decorator exists, :class:`pyramid.views.exception_view_config`, which may be used to easily register exception views. @@ -334,7 +334,7 @@ which have a name will be ignored. In most cases, you should register an :term:`exception view` by using :meth:`pyramid.config.Configurator.add_exception_view`. However, it is - possible to register 'normal' (i.e., non-exception) views against a context + possible to register "normal" (i.e., non-exception) views against a context resource type which inherits from :exc:`Exception` (i.e., ``config.add_view(context=Exception)``). When the view configuration is processed, *two* views are registered. One as a "normal" view, the other -- cgit v1.2.3 From bf22edc86d0f8dc9b072b974cfd5b4604688efa6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 6 Oct 2016 11:43:22 -0700 Subject: Add pyramid_nacl_session to session factories - closes #2791 --- docs/narr/sessions.rst | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'docs') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index a1319e45f..5b24201a9 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -157,6 +157,12 @@ The following session factories exist at the time of this writing. ======================= ======= ============================= Session Factory Backend Description ======================= ======= ============================= +pyramid_nacl_session_ PyNaCl_ Defines an encrypting, + pickle-based cookie + serializer, using PyNaCl to + generate the symmetric + encryption for the cookie + state. pyramid_redis_sessions_ Redis_ Server-side session library for Pyramid, using Redis for storage. @@ -165,6 +171,9 @@ pyramid_beaker_ Beaker_ Session factory for Pyramid sessioning system. ======================= ======= ============================= +.. _pyramid_nacl_session: https://pypi.python.org/pypi/pyramid_nacl_session +.. _PyNaCl: https://pynacl.readthedocs.io/en/latest/secret/ + .. _pyramid_redis_sessions: https://pypi.python.org/pypi/pyramid_redis_sessions .. _Redis: http://redis.io/ -- cgit v1.2.3