summaryrefslogtreecommitdiff
path: root/docs/narr
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2020-01-03 23:14:53 -0600
committerMichael Merickel <michael@merickel.org>2020-01-03 23:14:53 -0600
commit828e069de5d0c98e6d54cfdbf20b1a8acd1f6b39 (patch)
treebe692270de956199b4cfb1eda8a9fc24ceb8374e /docs/narr
parent7820b922cc1b87147cc60288dff0bbdfd7b5bc8a (diff)
parent148cf5138638ce6b1b92b4e13fe1444df9451e34 (diff)
downloadpyramid-828e069de5d0c98e6d54cfdbf20b1a8acd1f6b39.tar.gz
pyramid-828e069de5d0c98e6d54cfdbf20b1a8acd1f6b39.tar.bz2
pyramid-828e069de5d0c98e6d54cfdbf20b1a8acd1f6b39.zip
Merge branch 'master' into security-docs
Diffstat (limited to 'docs/narr')
-rw-r--r--docs/narr/commandline.rst2
-rw-r--r--docs/narr/myproject/.coveragerc1
-rw-r--r--docs/narr/myproject/MANIFEST.in3
-rw-r--r--docs/narr/myproject/README.txt4
-rw-r--r--docs/narr/myproject/myproject/views/default.py2
-rw-r--r--docs/narr/myproject/myproject/views/notfound.py2
-rw-r--r--docs/narr/myproject/pytest.ini7
-rw-r--r--docs/narr/myproject/setup.py4
-rw-r--r--docs/narr/myproject/tests/__init__.py0
-rw-r--r--docs/narr/myproject/tests/test_it.py (renamed from docs/narr/myproject/myproject/tests.py)14
-rw-r--r--docs/narr/paste.rst4
-rw-r--r--docs/narr/project.rst137
-rw-r--r--docs/narr/testing.rst19
13 files changed, 111 insertions, 88 deletions
diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst
index 0c5189903..149488206 100644
--- a/docs/narr/commandline.rst
+++ b/docs/narr/commandline.rst
@@ -1025,7 +1025,7 @@ top-level directory, your ``setup.py`` file will look something like this:
author_email='',
url='',
keywords='web pyramid pylons',
- packages=find_packages(),
+ packages=find_packages(exclude=['tests']),
include_package_data=True,
zip_safe=False,
install_requires=requires,
diff --git a/docs/narr/myproject/.coveragerc b/docs/narr/myproject/.coveragerc
index f0c31d6d7..5837f5504 100644
--- a/docs/narr/myproject/.coveragerc
+++ b/docs/narr/myproject/.coveragerc
@@ -1,3 +1,2 @@
[run]
source = myproject
-omit = myproject/test*
diff --git a/docs/narr/myproject/MANIFEST.in b/docs/narr/myproject/MANIFEST.in
index 1c24b8c0c..f516697f5 100644
--- a/docs/narr/myproject/MANIFEST.in
+++ b/docs/narr/myproject/MANIFEST.in
@@ -1,2 +1,5 @@
include *.txt *.ini *.cfg *.rst
recursive-include myproject *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
+recursive-include tests *
+recursive-exclude * __pycache__
+recursive-exclude * *.py[co]
diff --git a/docs/narr/myproject/README.txt b/docs/narr/myproject/README.txt
index 2ffc0acba..6c5a0fee0 100644
--- a/docs/narr/myproject/README.txt
+++ b/docs/narr/myproject/README.txt
@@ -1,4 +1,4 @@
-MyProject
+myproject
=========
Getting Started
@@ -6,7 +6,7 @@ Getting Started
- Change directory into your newly created project.
- cd MyProject
+ cd myproject
- Create a Python virtual environment.
diff --git a/docs/narr/myproject/myproject/views/default.py b/docs/narr/myproject/myproject/views/default.py
index 8324cfe32..619ce1c0f 100644
--- a/docs/narr/myproject/myproject/views/default.py
+++ b/docs/narr/myproject/myproject/views/default.py
@@ -1,6 +1,6 @@
from pyramid.view import view_config
-@view_config(route_name='home', renderer='../templates/mytemplate.jinja2')
+@view_config(route_name='home', renderer='myproject:templates/mytemplate.jinja2')
def my_view(request):
return {'project': 'myproject'}
diff --git a/docs/narr/myproject/myproject/views/notfound.py b/docs/narr/myproject/myproject/views/notfound.py
index 69d6e2804..5abebb277 100644
--- a/docs/narr/myproject/myproject/views/notfound.py
+++ b/docs/narr/myproject/myproject/views/notfound.py
@@ -1,7 +1,7 @@
from pyramid.view import notfound_view_config
-@notfound_view_config(renderer='../templates/404.jinja2')
+@notfound_view_config(renderer='myproject:templates/404.jinja2')
def notfound_view(request):
request.response.status = 404
return {}
diff --git a/docs/narr/myproject/pytest.ini b/docs/narr/myproject/pytest.ini
index b1b5f4c38..5c8c59068 100644
--- a/docs/narr/myproject/pytest.ini
+++ b/docs/narr/myproject/pytest.ini
@@ -1,3 +1,6 @@
[pytest]
-testpaths = myproject
-python_files = *.py
+addopts = --strict
+
+testpaths =
+ myproject
+ tests
diff --git a/docs/narr/myproject/setup.py b/docs/narr/myproject/setup.py
index 1ee272270..e5872df29 100644
--- a/docs/narr/myproject/setup.py
+++ b/docs/narr/myproject/setup.py
@@ -25,7 +25,7 @@ tests_require = [
setup(
name='myproject',
version='0.0',
- description='MyProject',
+ description='myproject',
long_description=README + '\n\n' + CHANGES,
classifiers=[
'Programming Language :: Python',
@@ -37,7 +37,7 @@ setup(
author_email='',
url='',
keywords='web pyramid pylons',
- packages=find_packages(),
+ packages=find_packages(exclude=['tests']),
include_package_data=True,
zip_safe=False,
extras_require={
diff --git a/docs/narr/myproject/tests/__init__.py b/docs/narr/myproject/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/docs/narr/myproject/tests/__init__.py
diff --git a/docs/narr/myproject/myproject/tests.py b/docs/narr/myproject/tests/test_it.py
index 05ccadcfb..b300da34d 100644
--- a/docs/narr/myproject/myproject/tests.py
+++ b/docs/narr/myproject/tests/test_it.py
@@ -11,10 +11,16 @@ class ViewTests(unittest.TestCase):
testing.tearDown()
def test_my_view(self):
- from .views.default import my_view
+ from myproject.views.default import my_view
request = testing.DummyRequest()
info = my_view(request)
- self.assertEqual(info['project'], 'MyProject')
+ self.assertEqual(info['project'], 'myproject')
+
+ def test_notfound_view(self):
+ from myproject.views.notfound import notfound_view
+ request = testing.DummyRequest()
+ info = notfound_view(request)
+ self.assertEqual(info, {})
class FunctionalTests(unittest.TestCase):
@@ -27,3 +33,7 @@ class FunctionalTests(unittest.TestCase):
def test_root(self):
res = self.testapp.get('/', status=200)
self.assertTrue(b'Pyramid' in res.body)
+
+ def test_notfound(self):
+ res = self.testapp.get('/badurl', status=404)
+ self.assertTrue(res.status_code == 404)
diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst
index fe2846dd3..e198176d4 100644
--- a/docs/narr/paste.rst
+++ b/docs/narr/paste.rst
@@ -95,4 +95,6 @@ application's ``main`` function as ``global_config`` (see the reference to the
Alternative Configuration File Formats
--------------------------------------
-It is possible to use different file formats with :app:`Pyramid` if you do not like :term:`PasteDeploy`. Under the hood all command-line scripts such as ``pserve`` and ``pshell`` pass the ``config_uri`` (e.g. ``development.ini`` or ``production.ini``) to the :term:`plaster` library which performs a lookup for an appropriate parser. For ``.ini`` files it uses PasteDeploy but you can register your own configuration formats that plaster will find instead.
+It is possible to use different file formats with :app:`Pyramid` if you do not like :term:`PasteDeploy`.
+Under the hood all command-line scripts such as ``pserve`` and ``pshell`` pass the ``config_uri`` (e.g., ``development.ini`` or ``production.ini``) to the :term:`plaster` library which performs a lookup for an appropriate parser.
+For ``.ini`` files it uses PasteDeploy but you can register your own configuration formats that plaster will find instead.
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 58bef5701..043f77754 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -117,7 +117,7 @@ On Unix:
# Create a new virtual environment...
python3 -m venv $VENV
# ...where we upgrade packaging tools.
- env/bin/pip install --upgrade pip setuptools
+ $VENV/bin/pip install --upgrade pip setuptools
Or on Windows:
@@ -208,11 +208,12 @@ Elided output from a run of this command on Unix is shown below:
.. code-block:: bash
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
+ Successfully installed Jinja2-2.10.3 Mako-1.1.0 MarkupSafe-1.1.1 \
+ PasteDeploy-2.0.1 Pygments-2.5.2 hupper-1.9.1 myproject plaster-1.0 \
+ plaster-pastedeploy-0.7 pyramid-1.10.4 pyramid-debugtoolbar-4.5.1 \
+ pyramid-jinja2-2.8 pyramid-mako-1.1.0 repoze.lru-0.7 \
+ translationstring-1.3 venusian-3.0.0 waitress-1.4.1 webob-1.8.5 \
+ zope.deprecation-4.4.0 zope.interface-4.7.1
This will install a :term:`distribution` representing your project into the
virtual environment interpreter's library set so it can be found by ``import``
@@ -262,10 +263,11 @@ Here's sample output from a test run on Unix:
.. code-block:: bash
$VENV/bin/pytest -q
- ..
- 2 passed in 0.47 seconds
+ ....
+ 4 passed in 0.45 seconds
-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.
+The tests themselves are found in the ``test_it.py`` module in the ``tests`` package in your ``cookiecutter``-generated project.
+Within this project generated by the ``pyramid-cookiecutter-starter`` cookiecutter, only a few sample tests exist.
.. note::
@@ -287,7 +289,7 @@ path to the module on which we want to run tests and coverage.
.. code-block:: bash
- $VENV/bin/pytest --cov=myproject myproject/tests.py -q
+ $VENV/bin/pytest --cov=myproject myproject tests -q
.. seealso:: See ``pytest``'s documentation for :ref:`pytest:usage` or invoke
``pytest -h`` to see its full set of options.
@@ -402,8 +404,8 @@ For example, on Unix:
.. code-block:: text
$VENV/bin/pserve development.ini --reload
- Starting subprocess with file monitor
- Starting server in PID 16601.
+ Starting monitor for PID 36224.
+ Starting server in PID 36224.
Serving on http://localhost:6543
Serving on http://localhost:6543
@@ -412,9 +414,10 @@ files, you'll see the server restart automatically:
.. code-block:: text
- development.ini changed; reloading...
- -------------------- Restarting --------------------
- Starting server in PID 16602.
+ /file-path-to/myproject/development.ini changed; reloading ...
+ Gracefully killing the server.
+ Starting monitor for PID 36286.
+ Starting server in PID 36286.
Serving on http://localhost:6543
Serving on http://localhost:6543
@@ -462,7 +465,7 @@ browsing from a system that does not have debugging access. By default, for
security reasons, only a browser originating from ``localhost`` (``127.0.0.1``)
can see the debug toolbar. To allow your browser on a remote system to access
the server, add a line within the ``[app:main]`` section of the
-``development.ini`` file in the form ``debugtoolbar.hosts = X .X.X.X``. For
+``development.ini`` file in the form ``debugtoolbar.hosts = X.X.X.X``. For
example, if your Pyramid application is running on a remote system, and you're
browsing from a host with the IP address ``192.168.1.1``, you'd add something
like this to enable the toolbar when your system contacts Pyramid:
@@ -470,7 +473,7 @@ like this to enable the toolbar when your system contacts Pyramid:
.. code-block:: ini
[app:main]
- # .. other settings ...
+ # ... other settings ...
debugtoolbar.hosts = 192.168.1.1
For more information about what the debug toolbar allows you to do, see the
@@ -533,6 +536,8 @@ The ``myproject`` project we've generated has the following directory structure:
├── .gitignore
├── CHANGES.txt
├── MANIFEST.in
+ ├── README.txt
+ ├── development.ini
├── myproject
│   ├── __init__.py
│   ├── routes.py
@@ -544,16 +549,37 @@ The ``myproject`` project we've generated has the following directory structure:
│   │   ├── 404.jinja2
│   │   ├── layout.jinja2
│   │   └── mytemplate.jinja2
- │   ├── tests.py
│   └── views
│   ├── __init__.py
│   ├── default.py
│   └── notfound.py
- ├── README.txt
- ├── development.ini
├── production.ini
├── pytest.ini
- └── setup.py
+ ├── setup.py
+ └── tests
+ ├── __init__.py
+ └── test_it.py
+
+
+.. index::
+ single: tests
+
+``test_it.py``
+~~~~~~~~~~~~~~
+
+The ``test_it.py`` module in the ``tests`` package includes tests for your application.
+
+.. literalinclude:: myproject/tests/test_it.py
+ :language: python
+ :linenos:
+
+This sample ``test_it.py`` file has two unit tests and two functional tests defined within it.
+These tests are executed when you run ``pytest -q``.
+You may add more tests here as you build your application.
+You are not required to write tests to use :app:`Pyramid`.
+This file is simply provided for convenience and example.
+
+See :ref:`testing_chapter` for more information about writing :app:`Pyramid` unit tests.
The ``myproject`` :term:`Project`
@@ -589,6 +615,8 @@ describe, run, and test your application.
#. ``setup.py`` is the file you'll use to test and distribute your application.
It is a standard :term:`Setuptools` ``setup.py`` file.
+#. ``tests`` package which contains unit and functional test code for the application.
+
.. index::
single: PasteDeploy
single: ini file
@@ -701,9 +729,8 @@ specifies the non-Python files that should be included when a
setup.py sdist``. Due to the information contained in the default
``MANIFEST.in``, an sdist of your Pyramid project will include ``.txt`` files,
``.ini`` files, ``.rst`` files, graphics files, and template files, as well as
-``.py`` files. See
-https://docs.python.org/2/distutils/sourcedist.html#the-manifest-in-template
-for more information about the syntax and usage of ``MANIFEST.in``.
+``.py`` files.
+See the Python Packaging Authority's Python Packaging User Guide `Including files in source distributions with MANIFEST.in <https://packaging.python.org/guides/using-manifest-in/>`_ for more information about the syntax and usage of ``MANIFEST.in``.
Without the presence of a ``MANIFEST.in`` file or without checking your source
code into a version control repository, ``setup.py sdist`` places only *Python
@@ -720,9 +747,8 @@ like ``*.pt``, ``*.css`` and ``*.js`` in the generated tarball. If you include
files with extensions other than the files named in the project's
``MANIFEST.in`` and you don't make use of a Setuptools-compatible version
control system, you'll need to edit the ``MANIFEST.in`` file and include the
-statements necessary to include your new files. See
-https://docs.python.org/2/distutils/sourcedist.html#principle for more
-information about how to do this.
+statements necessary to include your new files.
+In the aforementioned Python Packaging User Guide, see `MANIFEST.in commands <https://packaging.python.org/guides/using-manifest-in/#manifest-in-commands>`_ for more information about how to do this.
You can also delete ``MANIFEST.in`` from your project and rely on a :term:`Setuptools`
feature which simply causes all files checked into a version control system to
@@ -775,15 +801,17 @@ together. The ``classifiers`` field is a list of `Trove classifiers
<https://pypi.org/pypi?%3Aaction=list_classifiers>`_ describing your
application. ``author`` and ``author_email`` are text fields which probably
don't need any description. ``url`` is a field that should point at your
-application project's URL (if any). ``packages=find_packages()`` causes all
+application project's URL (if any).
+``keywords`` are keywords that describe your project.
+``packages=find_packages(exclude=['tests'])`` causes all
packages within the project to be found when packaging the application.
``include_package_data`` will include non-Python files when the application is
packaged if those files are checked into version control. ``zip_safe=False``
indicates that this package is not safe to use as a zipped egg; instead it will
-always unpack as a directory, which is more convenient. ``install_requires``
-indicates that this package depends on the ``pyramid`` package.
-``extras_require`` is a Python dictionary that defines what is required to be
-installed for running tests. We examined ``entry_points`` in our discussion of
+always unpack as a directory, which is more convenient.
+``extras_require`` is a Python dictionary that defines what is required to be installed for running tests.
+``install_requires`` indicates that this package depends on the ``pyramid`` package.
+We examined ``entry_points`` in our discussion of
the ``development.ini`` file; this file defines the ``main`` entry point that
represents our project's application.
@@ -817,8 +845,6 @@ The ``myproject`` :term:`package` lives inside the ``myproject``
#. 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 ``routes.py`` module, which contains routing code for the application.
#. A ``views`` package, which contains view code for the application.
@@ -850,7 +876,7 @@ also informs Python that the directory which contains it is a *package*.
#. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config`
that we use later.
-#. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid`
+#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid`
WSGI application. This function is meant to be called by the
:term:`PasteDeploy` framework as a result of running ``pserve``.
@@ -924,11 +950,13 @@ route named ``home`` to the URL pattern ``/``, this route will match when a
visitor visits the root URL. The view_config decorator also names a
``renderer``, which in this case is a template that will be used to render the
result of the view callable. This particular view declaration points at
-``../templates/mytemplate.jinja2``, which is an :term:`asset specification` that
+``myproject:templates/mytemplate.jinja2``, which is an :term:`asset specification` that
specifies the ``mytemplate.jinja2`` file within the ``templates`` directory of the
-``myproject`` package. The asset specification could have also been specified
-as ``myproject:templates/mytemplate.jinja2``; the leading package name and colon is
-optional. The template file pointed to is a :term:`Jinja2` template
+``myproject`` package.
+There is a second form of asset specification: a relative asset specification.
+Instead of using an "absolute" asset specification which includes the package name, in certain circumstances you can omit the package name from the specification.
+For example, you might be able to use ``../templates/mytemplate.jinja2``.
+The template file pointed to is a :term:`Jinja2` template
file (``templates/mytemplate.jinja2``).
This view callable function is handed a single piece of information: the
@@ -949,7 +977,7 @@ Now let's look at ``notfound.py``.
:linenos:
This file is similar to ``default.py``.
-It merely returns a ``404`` response status and an empty dictionary to the template at ``../templates/404.jinja2``.
+It merely returns a ``404`` response status and an empty dictionary to the template at ``myproject:templates/404.jinja2``.
.. note:: When the application is run with the cookiecutter's :ref:`default
development.ini <myproject_ini>` configuration, :ref:`logging is set up
@@ -1037,27 +1065,6 @@ It inherits the HTML provided by ``layout.jinja2``, replacing the content block
.. index::
- single: tests.py
-
-``tests.py``
-~~~~~~~~~~~~
-
-The ``tests.py`` module includes tests for your application.
-
-.. literalinclude:: myproject/myproject/tests.py
- :language: python
- :linenos:
-
-This sample ``tests.py`` file has one unit test and one functional test defined
-within it. These tests are executed when you run ``pytest -q``. You may add
-more tests here as you build your application. You are not required to write
-tests to use :app:`Pyramid`. This file is simply provided for convenience and
-example.
-
-See :ref:`testing_chapter` for more information about writing :app:`Pyramid`
-unit tests.
-
-.. index::
pair: modifying; package structure
.. _modifying_package_structure:
@@ -1159,11 +1166,9 @@ 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 <https://pythonhosted.org/watchdog/>`_ package in development.
-``hupper`` will automatically use ``watchdog`` to more efficiently poll the
-filesystem.
+code. This can be pretty inefficient in larger projects.
+To be nicer to your hard drive, you should install either the `watchman <https://facebook.github.io/watchman/>`_ or `watchdog <https://pythonhosted.org/watchdog/>`_ package in development.
+``hupper`` will use, in order of preference for efficiency, if available, ``watchman``, ``watchdog``, or finally polling to detect changes to the filesystem.
Monitoring Custom Files
~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst
index 2182082a8..0fa1e98fd 100644
--- a/docs/narr/testing.rst
+++ b/docs/narr/testing.rst
@@ -403,20 +403,21 @@ function ``my_view`` that returns an HTML body when the root URL is invoked:
:linenos:
:language: python
-The following example functional test demonstrates invoking the above
-:term:`view`:
+The following example functional tests demonstrate invoking the above :term:`view`:
- .. literalinclude:: myproject/myproject/tests.py
+ .. literalinclude:: myproject/tests/test_it.py
:linenos:
:pyobject: FunctionalTests
:language: python
-When this test is run, each test method creates a "real" :term:`WSGI`
-application using the ``main`` function in your ``myproject.__init__`` module,
-using :term:`WebTest` to wrap that WSGI application. It assigns the result to
-``self.testapp``. In the test named ``test_root``, the ``TestApp``'s ``GET``
-method is used to invoke the root URL. Finally, an assertion is made that the
-returned HTML contains the text ``Pyramid``.
+When these tests are run, each test method creates a "real" :term:`WSGI` application using the ``main`` function in your ``myproject.__init__`` module, using :term:`WebTest` to wrap that WSGI application.
+It assigns the result to ``self.testapp``.
+
+In the test named ``test_root``, the ``TestApp``'s ``GET`` method is used to invoke the root URL.
+An assertion is made that the returned HTML contains the text ``Pyramid``.
+
+In the test named ``test_notfound``, the ``TestApp``'s ``GET`` method is used to invoke a bad URL ``/badurl``.
+An assertion is made that the returned status code in the response is ``404``.
See the :term:`WebTest` documentation for further information about the methods
available to a :class:`webtest.app.TestApp` instance.