diff options
351 files changed, 1315 insertions, 1258 deletions
diff --git a/HACKING.txt b/HACKING.txt index 492b8675b..87c96aef1 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -48,11 +48,10 @@ In order to add a feature to Pyramid: Coding Style ------------ -- Pyramid uses Black for code formatting style. - https://pypi.org/project/black/ - To run Black: +- Pyramid uses Black (https://pypi.org/project/black/) and isort (https://pypi.org/project/isort/) for code formatting style. + To run formatters: - $ tox -e black + $ tox -e format Running Tests diff --git a/docs/glossary.rst b/docs/glossary.rst index 5a33ff39d..61ba34f45 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -61,8 +61,7 @@ Glossary .. seealso:: - See also `PkgResources - <http://peak.telecommunity.com/DevCenter/PkgResources>`_. + See also `Package Discovery and Resource Access using pkg_resources <https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_. asset Any file contained within a Python :term:`package` which is *not* @@ -443,7 +442,7 @@ Glossary dispatching and other application configuration tasks. reStructuredText - A `plain text markup format <http://docutils.sourceforge.net/rst.html>`_ + A `plain text markup format <https://docutils.sourceforge.io/rst.html>`_ that is the defacto standard for documenting Python projects. The Pyramid documentation is written in reStructuredText. 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/tutorials/wiki2/src/tests/tutorial/tests/__init__.py b/docs/narr/myproject/tests/__init__.py index e69de29bb..e69de29bb 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/__init__.py +++ 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. diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index a428a77c3..062693d24 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -493,7 +493,8 @@ So far we have done all of our *Quick Tour* as a single Python file. No Python packages, no structure. Most Pyramid projects, though, aren't developed this way. -To ease the process of getting started, the Pylons Project provides a :term:`cookiecutter` that generates sample Pyramid projects from project templates. This cookiecutter will install Pyramid and its dependencies as well. +To ease the process of getting started, the Pylons Project provides a :term:`cookiecutter` that generates a sample Pyramid project from project templates. +This cookiecutter will install Pyramid and its dependencies as well. First you'll need to install cookiecutter. @@ -675,15 +676,15 @@ the relevant ``.ini`` configuration file. :ref:`Quick Tutorial pyramid_debugtoolbar <qtut_debugtoolbar>` and :ref:`pyramid_debugtoolbar <toolbar:overview>` -Unit tests and ``pytest`` -========================= +Unit and functional tests and ``pytest`` +======================================== Yikes! We got this far and we haven't yet discussed tests. This is particularly egregious, as Pyramid has had a deep commitment to full test coverage since before its release. -Our ``pyramid-cookiecutter-starter`` cookiecutter generated a ``tests.py`` module with -one unit test and one functional test in it. It also configured ``setup.py`` with test requirements: +Our ``pyramid-cookiecutter-starter`` cookiecutter generated a ``test_it.py`` module inside the ``tests`` package with two unit tests and two functional tests in it. +It also configured ``setup.py`` with test requirements: ``pytest`` as the test runner, ``WebTest`` for running view tests, and the ``pytest-cov`` tool which yells at us for code that isn't tested: @@ -708,33 +709,35 @@ This yields the following output. .. code-block:: text =========================== test session starts =========================== - platform darwin -- Python 3.6.0, pytest-3.0.5, py-1.4.32, pluggy-0.4.0 - rootdir: /Users/stevepiercy/hello_world, inifile: pytest.ini - plugins: cov-2.4.0 - collected 2 items - - hello_world/tests.py .. - - ------------- coverage: platform darwin, python 3.6.0-final-0 ------------- - Name Stmts Miss Cover Missing - ----------------------------------------------------------------------- - hello_world/__init__.py 8 0 100% - hello_world/views.py 3 0 100% - ----------------------------------------------------------------------- - TOTAL 11 0 100% - - - ========================= 2 passed in 1.37 seconds ========================= + platform darwin -- Python 3.7.3, pytest-5.3.2, py-1.8.1, pluggy-0.13.1 + rootdir: /<somepath>/hello_world, inifile: pytest.ini, testpaths: hello_world, tests + plugins: cov-2.8.1 + collected 4 items + + tests/test_it.py .... [100%] + + ---------- coverage: platform darwin, python 3.7.3-final-0 ----------- + Name Stmts Miss Cover Missing + ------------------------------------------------------------- + hello_world/__init__.py 7 0 100% + hello_world/routes.py 3 0 100% + hello_world/views/__init__.py 0 0 100% + hello_world/views/default.py 3 0 100% + hello_world/views/notfound.py 4 0 100% + ------------------------------------------------------------- + TOTAL 17 0 100% + + ======================== 4 passed in 0.65 seconds ========================= Our tests passed, and its coverage is complete. What did our test look like? -.. literalinclude:: quick_tour/package/hello_world/tests.py +.. literalinclude:: quick_tour/package/tests/test_it.py :language: python :linenos: -Pyramid supplies helpers for test writing, which we use in the test setup and -teardown. Our first test imports the view, makes a dummy request, and sees if the -view returns what we expected. Our second test verifies that the response body from a request to the web root contains what we expected. +Pyramid supplies helpers for test writing, which we use in the test setup and teardown. +Our view tests import the view, make a dummy request, and sees if the view returns what we expected. +Our functional tests verify that the response body from a request to the web root contains what we expected and that the expected response code for making a request to ``/badurl`` results in ``404``. .. seealso:: See also: :ref:`Quick Tutorial Unit Testing <qtut_unit_testing>`, :ref:`Quick @@ -894,9 +897,22 @@ We then run through the following commands as before. # Reset our environment variable for a new virtual environment. export VENV=~/sqla_demo/env -We now have a working sample SQLAlchemy application with all dependencies -installed. The sample project provides a console script to initialize a SQLite -database with tables. Let's run it, then start the application: +We now have a working sample SQLAlchemy application with all dependencies installed. +The sample project provides a method to generate a database migration from existing models and upgrade the database schema using Alembic. +Let's generate the first revision. + +.. code-block:: bash + + $VENV/bin/alembic -c development.ini revision --autogenerate -m "init" + +Now let's upgrade the database schema. + +.. code-block:: bash + + $VENV/bin/alembic -c development.ini upgrade head + +The sample project also provides a console script to load data into the SQLite database. +Let's run it, then start the application: .. code-block:: bash diff --git a/docs/quick_tour/logging/.coveragerc b/docs/quick_tour/logging/.coveragerc index 128e26410..a94933b5f 100644 --- a/docs/quick_tour/logging/.coveragerc +++ b/docs/quick_tour/logging/.coveragerc @@ -1,3 +1,2 @@ [run] source = hello_world -omit = hello_world/test* diff --git a/docs/quick_tour/logging/MANIFEST.in b/docs/quick_tour/logging/MANIFEST.in index a75da6dad..7a73762f7 100644 --- a/docs/quick_tour/logging/MANIFEST.in +++ b/docs/quick_tour/logging/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include hello_world *.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/quick_tour/logging/hello_world/views/default.py b/docs/quick_tour/logging/hello_world/views/default.py index bbb99d78c..4bbc01e11 100644 --- a/docs/quick_tour/logging/hello_world/views/default.py +++ b/docs/quick_tour/logging/hello_world/views/default.py @@ -3,7 +3,7 @@ from pyramid.view import view_config import logging log = logging.getLogger(__name__) -@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +@view_config(route_name='home', renderer='hello_world:templates/mytemplate.jinja2') def my_view(request): log.debug('Some Message') return {'project': 'hello_world'} diff --git a/docs/quick_tour/logging/hello_world/views/notfound.py b/docs/quick_tour/logging/hello_world/views/notfound.py index 69d6e2804..6d0ff4193 100644 --- a/docs/quick_tour/logging/hello_world/views/notfound.py +++ b/docs/quick_tour/logging/hello_world/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='hello_world:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/quick_tour/logging/setup.py b/docs/quick_tour/logging/setup.py index e9c15db04..1fec15ce5 100644 --- a/docs/quick_tour/logging/setup.py +++ b/docs/quick_tour/logging/setup.py @@ -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/quick_tour/logging/tests/__init__.py b/docs/quick_tour/logging/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/quick_tour/logging/tests/__init__.py diff --git a/docs/quick_tour/logging/hello_world/tests.py b/docs/quick_tour/logging/tests/test_it.py index f01ae2a3c..90c6302fe 100644 --- a/docs/quick_tour/logging/hello_world/tests.py +++ b/docs/quick_tour/logging/tests/test_it.py @@ -11,11 +11,17 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from hello_world.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'hello_world') + def test_notfound_view(self): + from hello_world.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + class FunctionalTests(unittest.TestCase): def setUp(self): @@ -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/quick_tour/package/.coveragerc b/docs/quick_tour/package/.coveragerc index 128e26410..a94933b5f 100644 --- a/docs/quick_tour/package/.coveragerc +++ b/docs/quick_tour/package/.coveragerc @@ -1,3 +1,2 @@ [run] source = hello_world -omit = hello_world/test* diff --git a/docs/quick_tour/package/MANIFEST.in b/docs/quick_tour/package/MANIFEST.in index a75da6dad..7a73762f7 100644 --- a/docs/quick_tour/package/MANIFEST.in +++ b/docs/quick_tour/package/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include hello_world *.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/quick_tour/package/hello_world/views/default.py b/docs/quick_tour/package/hello_world/views/default.py index 7458da006..000a66e2e 100644 --- a/docs/quick_tour/package/hello_world/views/default.py +++ b/docs/quick_tour/package/hello_world/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='hello_world:templates/mytemplate.jinja2') def my_view(request): return {'project': 'hello_world'} diff --git a/docs/quick_tour/package/hello_world/views/notfound.py b/docs/quick_tour/package/hello_world/views/notfound.py index 69d6e2804..6d0ff4193 100644 --- a/docs/quick_tour/package/hello_world/views/notfound.py +++ b/docs/quick_tour/package/hello_world/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='hello_world:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/quick_tour/package/setup.py b/docs/quick_tour/package/setup.py index e9c15db04..1fec15ce5 100644 --- a/docs/quick_tour/package/setup.py +++ b/docs/quick_tour/package/setup.py @@ -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/quick_tour/package/tests/__init__.py b/docs/quick_tour/package/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/quick_tour/package/tests/__init__.py diff --git a/docs/quick_tour/package/hello_world/tests.py b/docs/quick_tour/package/tests/test_it.py index f01ae2a3c..90c6302fe 100644 --- a/docs/quick_tour/package/hello_world/tests.py +++ b/docs/quick_tour/package/tests/test_it.py @@ -11,11 +11,17 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from hello_world.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'hello_world') + def test_notfound_view(self): + from hello_world.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + class FunctionalTests(unittest.TestCase): def setUp(self): @@ -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/quick_tour/sessions/.coveragerc b/docs/quick_tour/sessions/.coveragerc index 128e26410..a94933b5f 100644 --- a/docs/quick_tour/sessions/.coveragerc +++ b/docs/quick_tour/sessions/.coveragerc @@ -1,3 +1,2 @@ [run] source = hello_world -omit = hello_world/test* diff --git a/docs/quick_tour/sessions/MANIFEST.in b/docs/quick_tour/sessions/MANIFEST.in index a75da6dad..7a73762f7 100644 --- a/docs/quick_tour/sessions/MANIFEST.in +++ b/docs/quick_tour/sessions/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include hello_world *.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/quick_tour/sessions/hello_world/views/default.py b/docs/quick_tour/sessions/hello_world/views/default.py index 33b8d8ded..52e002cf5 100644 --- a/docs/quick_tour/sessions/hello_world/views/default.py +++ b/docs/quick_tour/sessions/hello_world/views/default.py @@ -3,7 +3,7 @@ from pyramid.view import view_config import logging log = logging.getLogger(__name__) -@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +@view_config(route_name='home', renderer='hello_world:templates/mytemplate.jinja2') def my_view(request): log.debug('Some Message') session = request.session diff --git a/docs/quick_tour/sessions/hello_world/views/notfound.py b/docs/quick_tour/sessions/hello_world/views/notfound.py index 69d6e2804..6d0ff4193 100644 --- a/docs/quick_tour/sessions/hello_world/views/notfound.py +++ b/docs/quick_tour/sessions/hello_world/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='hello_world:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/quick_tour/sessions/setup.py b/docs/quick_tour/sessions/setup.py index e9c15db04..1fec15ce5 100644 --- a/docs/quick_tour/sessions/setup.py +++ b/docs/quick_tour/sessions/setup.py @@ -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/quick_tour/sessions/tests/__init__.py b/docs/quick_tour/sessions/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/quick_tour/sessions/tests/__init__.py diff --git a/docs/quick_tour/sessions/hello_world/tests.py b/docs/quick_tour/sessions/tests/test_it.py index f01ae2a3c..90c6302fe 100644 --- a/docs/quick_tour/sessions/hello_world/tests.py +++ b/docs/quick_tour/sessions/tests/test_it.py @@ -11,11 +11,17 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from hello_world.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'hello_world') + def test_notfound_view(self): + from hello_world.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + class FunctionalTests(unittest.TestCase): def setUp(self): @@ -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/quick_tour/sqla_demo/.coveragerc b/docs/quick_tour/sqla_demo/.coveragerc index 918f8dea0..8b6a8026a 100644 --- a/docs/quick_tour/sqla_demo/.coveragerc +++ b/docs/quick_tour/sqla_demo/.coveragerc @@ -1,3 +1,2 @@ [run] source = sqla_demo -omit = sqla_demo/test* diff --git a/docs/quick_tour/sqla_demo/MANIFEST.in b/docs/quick_tour/sqla_demo/MANIFEST.in index e079655f9..13a26726d 100644 --- a/docs/quick_tour/sqla_demo/MANIFEST.in +++ b/docs/quick_tour/sqla_demo/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include sqla_demo *.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/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini index 056a672e4..a087e17a7 100644 --- a/docs/quick_tour/sqla_demo/development.ini +++ b/docs/quick_tour/sqla_demo/development.ini @@ -45,7 +45,7 @@ listen = localhost:6543 ### [loggers] -keys = root, sqla_demo, sqlalchemy +keys = root, sqla_demo, sqlalchemy, alembic [handlers] keys = console @@ -70,6 +70,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini index fe7f946bd..ee588605d 100644 --- a/docs/quick_tour/sqla_demo/production.ini +++ b/docs/quick_tour/sqla_demo/production.ini @@ -39,7 +39,7 @@ listen = *:6543 ### [loggers] -keys = root, sqla_demo, sqlalchemy +keys = root, sqla_demo, sqlalchemy, alembic [handlers] keys = console @@ -64,6 +64,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/quick_tour/sqla_demo/pytest.ini b/docs/quick_tour/sqla_demo/pytest.ini index b4b690a0f..e7fd17682 100644 --- a/docs/quick_tour/sqla_demo/pytest.ini +++ b/docs/quick_tour/sqla_demo/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = sqla_demo -python_files = test*.py +addopts = --strict + +testpaths = + sqla_demo + tests diff --git a/docs/quick_tour/sqla_demo/setup.py b/docs/quick_tour/sqla_demo/setup.py index 28a8e0815..f3302a7e9 100644 --- a/docs/quick_tour/sqla_demo/setup.py +++ b/docs/quick_tour/sqla_demo/setup.py @@ -9,17 +9,17 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ - 'alembic', 'plaster_pastedeploy', - 'pyramid >= 1.9', - 'pyramid_debugtoolbar', + 'pyramid', 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', + 'alembic', 'pyramid_retry', 'pyramid_tm', 'SQLAlchemy', 'transaction', 'zope.sqlalchemy', - 'waitress', ] tests_require = [ @@ -43,7 +43,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={ @@ -55,7 +55,7 @@ setup( 'main = sqla_demo:main', ], 'console_scripts': [ - 'initialize_sqla_demo_db = sqla_demo.scripts.initialize_db:main', + 'initialize_sqla_demo_db=sqla_demo.scripts.initialize_db:main', ], }, ) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py index 28bd1f80d..5c2ba5cc0 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.scan() return config.make_wsgi_app() diff --git a/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako b/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako +++ b/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt b/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt +++ b/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/quick_tour/sqla_demo/sqla_demo/pshell.py b/docs/quick_tour/sqla_demo/sqla_demo/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/pshell.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 index 1917f83c7..aaf12413f 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 index 107691acf..82017688a 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 @@ -8,7 +8,7 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="{{request.static_url('sqla_demo:static/pyramid-16x16.png')}}"> - <title>Cookiecutter Alchemy project for the Pyramid Web Framework</title> + <title>Cookiecutter Starter project for the Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 index d8b0a4232..f2e7283f8 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a Pyramid application generated by<br><span class="font-normal">Cookiecutter</span>.</p> </div> -{% endblock content %}
\ No newline at end of file +{% endblock content %} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views/default.py b/docs/quick_tour/sqla_demo/sqla_demo/views/default.py index f7ad4c8f2..3aadb905f 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/views/default.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/views/default.py @@ -1,12 +1,12 @@ -from pyramid.response import Response from pyramid.view import view_config +from pyramid.response import Response from sqlalchemy.exc import DBAPIError from .. import models -@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +@view_config(route_name='home', renderer='sqla_demo:templates/mytemplate.jinja2') def my_view(request): try: query = request.dbsession.query(models.MyModel) @@ -21,7 +21,7 @@ Pyramid is having a problem using your SQL database. The problem might be caused by one of the following things: 1. You may need to initialize your database tables with `alembic`. - Check your README.txt for description and try to run it. + Check your README.txt for descriptions and try to run it. 2. Your database server may not be running. Check that the database server referred to by the "sqlalchemy.url" setting in diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py b/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py index 69d6e2804..3e088ab15 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py +++ b/docs/quick_tour/sqla_demo/sqla_demo/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='sqla_demo:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/quick_tour/sqla_demo/tests/__init__.py b/docs/quick_tour/sqla_demo/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/quick_tour/sqla_demo/tests/__init__.py diff --git a/docs/quick_tour/sqla_demo/sqla_demo/tests.py b/docs/quick_tour/sqla_demo/tests/test_it.py index 6db538ffd..c79e05022 100644 --- a/docs/quick_tour/sqla_demo/sqla_demo/tests.py +++ b/docs/quick_tour/sqla_demo/tests/test_it.py @@ -1,8 +1,9 @@ import unittest -import transaction from pyramid import testing +import transaction + def dummy_request(dbsession): return testing.DummyRequest(dbsession=dbsession) @@ -13,10 +14,10 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models') + self.config.include('sqla_demo.models') settings = self.config.get_settings() - from .models import ( + from sqla_demo.models import ( get_engine, get_session_factory, get_tm_session, @@ -28,11 +29,11 @@ class BaseTest(unittest.TestCase): self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models.meta import Base + from sqla_demo.models.meta import Base Base.metadata.create_all(self.engine) def tearDown(self): - from .models.meta import Base + from sqla_demo.models.meta import Base testing.tearDown() transaction.abort() @@ -45,13 +46,13 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models import MyModel + from sqla_demo.models import MyModel model = MyModel(name='one', value=55) self.session.add(model) def test_passing_view(self): - from .views.default import my_view + from sqla_demo.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') self.assertEqual(info['project'], 'sqla_demo') @@ -60,6 +61,6 @@ class TestMyViewSuccessCondition(BaseTest): class TestMyViewFailureCondition(BaseTest): def test_failing_view(self): - from .views.default import my_view + from sqla_demo.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info.status_int, 500) diff --git a/docs/quick_tutorial/cookiecutters.rst b/docs/quick_tutorial/cookiecutters.rst index e4a585a33..a1d60c181 100644 --- a/docs/quick_tutorial/cookiecutters.rst +++ b/docs/quick_tutorial/cookiecutters.rst @@ -73,8 +73,8 @@ Steps .. code-block:: text - Starting subprocess with file monitor - Starting server in PID 73732. + Starting monitor for PID 60461. + Starting server in PID 60461. Serving on http://localhost:6543 Serving on http://localhost:6543 diff --git a/docs/quick_tutorial/cookiecutters/.coveragerc b/docs/quick_tutorial/cookiecutters/.coveragerc index 1bcbb8c3e..8aa37b9e7 100644 --- a/docs/quick_tutorial/cookiecutters/.coveragerc +++ b/docs/quick_tutorial/cookiecutters/.coveragerc @@ -1,3 +1,2 @@ [run] source = cc_starter -omit = cc_starter/test* diff --git a/docs/quick_tutorial/cookiecutters/MANIFEST.in b/docs/quick_tutorial/cookiecutters/MANIFEST.in index 79c7ec16c..4071776f9 100644 --- a/docs/quick_tutorial/cookiecutters/MANIFEST.in +++ b/docs/quick_tutorial/cookiecutters/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include cc_starter *.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/quick_tutorial/cookiecutters/cc_starter/views/default.py b/docs/quick_tutorial/cookiecutters/cc_starter/views/default.py index 47af359b5..21c30e0b2 100644 --- a/docs/quick_tutorial/cookiecutters/cc_starter/views/default.py +++ b/docs/quick_tutorial/cookiecutters/cc_starter/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='cc_starter:templates/mytemplate.jinja2') def my_view(request): return {'project': 'cc_starter'} diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/views/notfound.py b/docs/quick_tutorial/cookiecutters/cc_starter/views/notfound.py index 69d6e2804..e8b8f26f3 100644 --- a/docs/quick_tutorial/cookiecutters/cc_starter/views/notfound.py +++ b/docs/quick_tutorial/cookiecutters/cc_starter/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='cc_starter:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/quick_tutorial/cookiecutters/pytest.ini b/docs/quick_tutorial/cookiecutters/pytest.ini index a7bd797f0..515cc3cf0 100644 --- a/docs/quick_tutorial/cookiecutters/pytest.ini +++ b/docs/quick_tutorial/cookiecutters/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = cc_starter -python_files = *.py +addopts = --strict + +testpaths = + cc_starter + tests diff --git a/docs/quick_tutorial/cookiecutters/setup.py b/docs/quick_tutorial/cookiecutters/setup.py index d5d3d018b..9c9d54e5b 100644 --- a/docs/quick_tutorial/cookiecutters/setup.py +++ b/docs/quick_tutorial/cookiecutters/setup.py @@ -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/quick_tutorial/cookiecutters/tests/__init__.py b/docs/quick_tutorial/cookiecutters/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/quick_tutorial/cookiecutters/tests/__init__.py diff --git a/docs/quick_tutorial/cookiecutters/cc_starter/tests.py b/docs/quick_tutorial/cookiecutters/tests/test_it.py index f3886be84..634abfdf2 100644 --- a/docs/quick_tutorial/cookiecutters/cc_starter/tests.py +++ b/docs/quick_tutorial/cookiecutters/tests/test_it.py @@ -11,11 +11,17 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from cc_starter.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'cc_starter') + def test_notfound_view(self): + from cc_starter.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + class FunctionalTests(unittest.TestCase): def setUp(self): @@ -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/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index ef914cab5..2ff9deb31 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -99,7 +99,7 @@ Here we use "dummy" data to represent user and groups sources. Add an ACL ~~~~~~~~~~ -Open ``tutorial/models.py`` and add the following import statement near the top: +Open ``tutorial/models/__init__.py`` and add the following import statement near the top: .. literalinclude:: src/authorization/tutorial/models/__init__.py :lines: 4-8 @@ -179,7 +179,7 @@ Open ``tutorial/views/default.py`` and add a ``permission='edit'`` parameter to :language: python .. literalinclude:: src/authorization/tutorial/views/default.py - :lines: 68-70 + :lines: 69-71 :emphasize-lines: 2-3 :language: python @@ -191,12 +191,12 @@ Add a ``permission='view'`` parameter to the ``@view_config`` decorator for ``view_wiki()`` and ``view_page()`` as follows: .. literalinclude:: src/authorization/tutorial/views/default.py - :lines: 23-24 + :lines: 21-22 :emphasize-lines: 1-2 :language: python .. literalinclude:: src/authorization/tutorial/views/default.py - :lines: 28-29 + :lines: 27-28 :emphasize-lines: 1-2 :language: python @@ -318,7 +318,7 @@ Our ``tutorial/__init__.py`` will look like this when we are done: Only the highlighted lines need to be added or edited. -Our ``tutorial/models.py`` will look like this when we are done: +Our ``tutorial/models/__init__.py`` will look like this when we are done: .. literalinclude:: src/authorization/tutorial/models/__init__.py :linenos: diff --git a/docs/tutorials/wiki/basiclayout.rst b/docs/tutorials/wiki/basiclayout.rst index 52d3f4670..4eb5c4283 100644 --- a/docs/tutorials/wiki/basiclayout.rst +++ b/docs/tutorials/wiki/basiclayout.rst @@ -107,6 +107,12 @@ Next include routes from the ``.routes`` module. :lineno-match: :language: py +The included module contains the following function. + +.. literalinclude:: src/basiclayout/tutorial/routes.py + :linenos: + :language: py + This registers a "static view" using the :meth:`pyramid.config.Configurator.add_static_view` method. This view answers requests whose URL path starts with ``/static``. This statement registers a view that will serve up static assets, such as CSS and image files. @@ -121,7 +127,7 @@ Alternatively the cookiecutter could have used an *absolute* asset specification The third argument is an optional ``cache_max_age`` which specifies the number of seconds the static asset will be HTTP-cached. -Next perform a :term:`scan`. +Back into our ``__init__.py``, next perform a :term:`scan`. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 21 @@ -208,12 +214,12 @@ Let's try to understand the components in this module: The ``context`` argument signifies that the decorated view callable ``my_view`` should only be run when :term:`traversal` finds the ``tutorial.models.MyModel`` :term:`resource` as the :term:`context` of a request. In English this means that when the URL ``/`` is visited, and because ``MyModel`` is the root model, this view callable will be invoked. - The ``renderer`` argument names an :term:`asset specification` of ``templates/mytemplate.pt``. + The ``renderer`` argument names an :term:`asset specification` of ``tutorial:templates/mytemplate.pt``. This asset specification points at a :term:`Chameleon` template which lives in the ``mytemplate.pt`` file within the ``templates`` directory of the ``tutorial`` package. And indeed if you look in the ``templates`` directory of this package, you will see a ``mytemplate.pt`` template file This template renders the default home page of the generated project. - This asset specification is *relative* to the ``views`` package. - Alternatively we could have used the absolute asset specification ``tutorial:templates/mytemplate.pt``. + This asset specification is *absolute* to the ``views`` package. + Alternatively we could have used the relative asset specification ``../templates/mytemplate.pt``. Since this call to ``@view_config`` doesn't pass a ``name`` argument, the ``my_view`` function which it decorates represents the "default" view callable used when the context is of the type ``MyModel``. @@ -225,7 +231,7 @@ Let's try to understand the components in this module: The function returns the dictionary ``{'project': 'myproj'}``. This dictionary is used by the template named by the ``mytemplate.pt`` asset specification to fill in certain values on the page. -Let us open ``tutorial/views/default.py`` in the ``views`` package to look at the second view. +Let us open ``tutorial/views/notfound.py`` in the ``views`` package to look at the second view. .. literalinclude:: src/basiclayout/tutorial/views/notfound.py :linenos: @@ -237,7 +243,7 @@ Without repeating ourselves, we will point out the differences between this view The ``notfound_view`` function is decorated with ``@notfound_view_config``. This decorator registers a :term:`Not Found View` using :meth:`pyramid.config.Configurator.add_notfound_view`. - The ``renderer`` argument names an :term:`asset specification` of ``templates/404.pt``. + The ``renderer`` argument names an :term:`asset specification` of ``tutorial:templates/404.pt``. #. *Lines 5-7*. A :term:`view callable` named ``notfound_view`` is defined, which is decorated in the step above. diff --git a/docs/tutorials/wiki/definingviews.rst b/docs/tutorials/wiki/definingviews.rst index bd8dc6ecf..2e4d009a1 100644 --- a/docs/tutorials/wiki/definingviews.rst +++ b/docs/tutorials/wiki/definingviews.rst @@ -73,7 +73,7 @@ Success executing this command will end with a line to the console similar to th .. code-block:: text - Successfully installed docutils-0.14 tutorial + Successfully installed docutils-0.15.2 tutorial Adding view functions in the ``views`` package @@ -356,7 +356,7 @@ Our templates name static assets, including CSS and images. We don't need to create these files within our package's ``static`` directory because they were provided by the cookiecutter at the time we created the project. As an example, the CSS file will be accessed via ``http://localhost:6543/static/theme.css`` by virtue of the call to the ``add_static_view`` directive in the ``routes.py`` file. -Any number and type of static assets can be placed in this directory (or subdirectories) +Any number and type of static assets can be placed in this directory (or subdirectories). They are referred to by either URL or using the convenience method ``static_url``, for example ``request.static_url('<package>:static/foo.css')``, within templates. diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst index cfa021540..6088f577d 100644 --- a/docs/tutorials/wiki/installation.rst +++ b/docs/tutorials/wiki/installation.rst @@ -185,18 +185,20 @@ The console will show ``pip`` checking for packages and installing missing packa .. code-block:: bash - Successfully installed BTrees-4.5.1 Chameleon-3.5 Mako-1.0.7 \ - MarkupSafe-1.1.0 PasteDeploy-1.5.2 Pygments-2.2.0 WebTest-2.0.32 \ - ZConfig-3.3.0 ZEO-5.2.0 ZODB-5.5.1 ZODB3-3.11.0 atomicwrites-1.2.1 \ - attrs-18.2.0 beautifulsoup4-4.6.3 coverage-4.5.2 hupper-1.4.1 \ - more-itertools-4.3.0 persistent-4.4.3 plaster-1.0 plaster-pastedeploy-0.6 \ - pluggy-0.8.0 py-1.7.0 pyramid-1.10.1 pyramid-chameleon-0.3 \ - pyramid-debugtoolbar-4.5 pyramid-mako-1.0.2 pyramid-retry-1.0 \ - pyramid-tm-2.2.1 pyramid-zodbconn-0.8.1 pytest-4.0.0 pytest-cov-2.6.0 \ - repoze.lru-0.7 six-1.11.0 transaction-2.4.0 translationstring-1.3 \ - tutorial venusian-1.1.0 waitress-1.1.0 webob-1.8.4 zc.lockfile-1.4 \ - zdaemon-4.3 zodbpickle-1.0.2 zodburi-2.3.0 zope.deprecation-4.3.0 \ - zope.interface-4.6.0 + Successfully installed BTrees-4.6.1 Chameleon-3.6.2 Mako-1.1.0 \ + MarkupSafe-1.1.1 PasteDeploy-2.0.1 Pygments-2.5.2 WebTest-2.0.33 \ + ZConfig-3.5.0 ZEO-5.2.1 ZODB-5.5.1 ZODB3-3.11.0 attrs-19.3.0 \ + beautifulsoup4-4.8.2 cffi-1.13.2 coverage-5.0.1 hupper-1.9.1 \ + importlib-metadata-1.3.0 more-itertools-8.0.2 packaging-19.2 \ + persistent-4.5.1 plaster-1.0 plaster-pastedeploy-0.7 pluggy-0.13.1 \ + py-1.8.1 pycparser-2.19 pyparsing-2.4.6 pyramid-1.10.4 \ + pyramid-chameleon-0.3 pyramid-debugtoolbar-4.5.1 pyramid-mako-1.1.0 \ + pyramid-retry-2.1 pyramid-tm-2.3 pyramid-zodbconn-0.8.1 pytest-5.3.2 \ + pytest-cov-2.8.1 repoze.lru-0.7 six-1.13.0 soupsieve-1.9.5 \ + transaction-3.0.0 translationstring-1.3 tutorial venusian-3.0.0 \ + waitress-1.4.1 wcwidth-0.1.7 webob-1.8.5 zc.lockfile-2.0 zdaemon-4.3 \ + zipp-0.6.0 zodbpickle-2.0.0 zodburi-2.4.0 zope.deprecation-4.4.0 \ + zope.interface-4.7.1 Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas. @@ -241,8 +243,8 @@ For a successful test run, you should see output that ends like this: .. code-block:: bash - . - 1 passed in 0.24 seconds + .. + 2 passed in 0.49 seconds Expose test coverage information @@ -274,29 +276,28 @@ If successful, you will see output something like this: .. code-block:: bash ======================== test session starts ========================= - platform darwin -- Python 3.7.0, pytest-4.0.0, py-1.7.0, pluggy-0.8.0 - rootdir: /Users/stevepiercy/projects/hack-on-pyramid/tutorial, inifile: pytest.ini - plugins: cov-2.6.0 - collected 1 item + platform darwin -- Python 3.7.3, pytest-5.3.2, py-1.8.1, pluggy-0.13.1 + rootdir: /filepath/tutorial, inifile: pytest.ini, testpaths: tutorial + plugins: cov-2.8.1 + collected 2 items + + tutorial/tests.py .. [100%] - tutorial/tests.py . - [100%] ---------- coverage: platform darwin, python 3.7.0-final-0 ----------- Name Stmts Miss Cover Missing ----------------------------------------------------------- - tutorial/__init__.py 17 12 29% 7-8, 14-23 + tutorial/__init__.py 16 11 31% 7-8, 14-22 tutorial/models/__init__.py 8 4 50% 9-12 tutorial/pshell.py 6 6 0% 1-12 tutorial/routes.py 2 2 0% 1-2 tutorial/views/__init__.py 0 0 100% tutorial/views/default.py 4 0 100% - tutorial/views/notfound.py 4 4 0% 1-7 + tutorial/views/notfound.py 4 0 100% ----------------------------------------------------------- - TOTAL 41 28 32% - + TOTAL 40 23 42% - ===================== 1 passed in 0.31 seconds ======================= + ===================== 2 passed in 0.55 seconds ======================= Our package doesn't quite have 100% test coverage. @@ -316,14 +317,14 @@ On Unix .. code-block:: bash - $VENV/bin/pytest --cov=tutorial tutorial/tests.py -q + $VENV/bin/pytest --cov=tutorial tests.py -q On Windows ^^^^^^^^^^ .. code-block:: doscon - %VENV%\Scripts\pytest --cov=tutorial tutorial\tests.py -q + %VENV%\Scripts\pytest --cov=tutorial tests -q ``pytest`` follows :ref:`conventions for Python test discovery <pytest:test discovery>`. @@ -365,8 +366,8 @@ If successful, you will see something like this on your console: .. code-block:: text - Starting subprocess with file monitor - Starting server in PID 44078. + Starting monitor for PID 65233. + Starting server in PID 65233. Serving on http://localhost:6543 Serving on http://localhost:6543 diff --git a/docs/tutorials/wiki/src/authorization/.coveragerc b/docs/tutorials/wiki/src/authorization/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki/src/authorization/.coveragerc +++ b/docs/tutorials/wiki/src/authorization/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/authorization/MANIFEST.in b/docs/tutorials/wiki/src/authorization/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki/src/authorization/MANIFEST.in +++ b/docs/tutorials/wiki/src/authorization/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki/src/authorization/pytest.ini b/docs/tutorials/wiki/src/authorization/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki/src/authorization/pytest.ini +++ b/docs/tutorials/wiki/src/authorization/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki/src/authorization/setup.py b/docs/tutorials/wiki/src/authorization/setup.py index fa5948acb..f19d643e6 100644 --- a/docs/tutorials/wiki/src/authorization/setup.py +++ b/docs/tutorials/wiki/src/authorization/setup.py @@ -44,7 +44,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/tutorials/wiki/src/authorization/tests/__init__.py b/docs/tutorials/wiki/src/authorization/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki/src/authorization/tests/__init__.py diff --git a/docs/tutorials/wiki/src/models/tutorial/tests.py b/docs/tutorials/wiki/src/authorization/tests/test_it.py index 6279d9f66..6c72bcc62 100644 --- a/docs/tutorials/wiki/src/models/tutorial/tests.py +++ b/docs/tutorials/wiki/src/authorization/tests/test_it.py @@ -11,8 +11,14 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from tutorial.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'myproj') + def test_notfound_view(self): + from tutorial.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/layout.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/layout.pt index b606e8dad..06a3c8157 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/layout.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/layout.pt @@ -1,5 +1,5 @@ <!DOCTYPE html metal:define-macro="layout"> -<html lang="{{request.locale_name}}"> +<html lang="${request.locale_name}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki/src/authorization/tutorial/views/default.py index 3a3b170e2..7ba99c65b 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/views/default.py @@ -24,7 +24,7 @@ def view_wiki(context, request): return HTTPFound(location=request.resource_url(context, 'FrontPage')) -@view_config(context='..models.Page', renderer='../templates/view.pt', +@view_config(context='..models.Page', renderer='tutorial:templates/view.pt', permission='view') def view_page(context, request): wiki = context.__parent__ @@ -47,7 +47,7 @@ def view_page(context, request): @view_config(name='add_page', context='..models.Wiki', - renderer='../templates/edit.pt', + renderer='tutorial:templates/edit.pt', permission='edit') def add_page(context, request): pagename = request.subpath[0] @@ -67,7 +67,7 @@ def add_page(context, request): @view_config(name='edit_page', context='..models.Page', - renderer='../templates/edit.pt', + renderer='tutorial:templates/edit.pt', permission='edit') def edit_page(context, request): if 'form.submitted' in request.params: @@ -80,8 +80,8 @@ def edit_page(context, request): @view_config(context='..models.Wiki', name='login', - renderer='../templates/login.pt') -@forbidden_view_config(renderer='../templates/login.pt') + renderer='tutorial:templates/login.pt') +@forbidden_view_config(renderer='tutorial:templates/login.pt') def login(request): login_url = request.resource_url(request.context, 'login') referrer = request.url diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views/notfound.py b/docs/tutorials/wiki/src/authorization/tutorial/views/notfound.py index d44b4d0e6..dd0b00488 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/views/notfound.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/views/notfound.py @@ -3,7 +3,7 @@ from pyramid.view import notfound_view_config from ..models import Page -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='tutorial:templates/404.pt') def notfound_view(request): request.response.status = 404 pagename = request.path diff --git a/docs/tutorials/wiki/src/basiclayout/.coveragerc b/docs/tutorials/wiki/src/basiclayout/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki/src/basiclayout/.coveragerc +++ b/docs/tutorials/wiki/src/basiclayout/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/basiclayout/MANIFEST.in b/docs/tutorials/wiki/src/basiclayout/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki/src/basiclayout/MANIFEST.in +++ b/docs/tutorials/wiki/src/basiclayout/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki/src/basiclayout/pytest.ini b/docs/tutorials/wiki/src/basiclayout/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki/src/basiclayout/pytest.ini +++ b/docs/tutorials/wiki/src/basiclayout/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki/src/basiclayout/setup.py b/docs/tutorials/wiki/src/basiclayout/setup.py index d6d488ed2..f85780010 100644 --- a/docs/tutorials/wiki/src/basiclayout/setup.py +++ b/docs/tutorials/wiki/src/basiclayout/setup.py @@ -42,7 +42,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/tutorials/wiki/src/basiclayout/tests/__init__.py b/docs/tutorials/wiki/src/basiclayout/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki/src/basiclayout/tests/__init__.py diff --git a/docs/tutorials/wiki/src/installation/tutorial/tests.py b/docs/tutorials/wiki/src/basiclayout/tests/test_it.py index 6279d9f66..6c72bcc62 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/tests.py +++ b/docs/tutorials/wiki/src/basiclayout/tests/test_it.py @@ -11,8 +11,14 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from tutorial.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'myproj') + def test_notfound_view(self): + from tutorial.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/layout.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/layout.pt index 9fdaef00f..9ca01382b 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/layout.pt +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/layout.pt @@ -1,5 +1,5 @@ <!DOCTYPE html metal:define-macro="layout"> -<html lang="{{request.locale_name}}"> +<html lang="${request.locale_name}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/views/default.py b/docs/tutorials/wiki/src/basiclayout/tutorial/views/default.py index 5d708d15c..51ec5ed98 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/views/default.py +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/views/default.py @@ -3,6 +3,6 @@ from pyramid.view import view_config from ..models import MyModel -@view_config(context=MyModel, renderer='../templates/mytemplate.pt') +@view_config(context=MyModel, renderer='tutorial:templates/mytemplate.pt') def my_view(request): return {'project': 'myproj'} diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/views/notfound.py b/docs/tutorials/wiki/src/basiclayout/tutorial/views/notfound.py index 728791d0a..59a37280e 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/views/notfound.py +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/views/notfound.py @@ -1,7 +1,7 @@ from pyramid.view import notfound_view_config -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='tutorial:templates/404.pt') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki/src/installation/.coveragerc b/docs/tutorials/wiki/src/installation/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki/src/installation/.coveragerc +++ b/docs/tutorials/wiki/src/installation/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/installation/MANIFEST.in b/docs/tutorials/wiki/src/installation/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki/src/installation/MANIFEST.in +++ b/docs/tutorials/wiki/src/installation/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki/src/installation/pytest.ini b/docs/tutorials/wiki/src/installation/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki/src/installation/pytest.ini +++ b/docs/tutorials/wiki/src/installation/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki/src/installation/setup.py b/docs/tutorials/wiki/src/installation/setup.py index d6d488ed2..f85780010 100644 --- a/docs/tutorials/wiki/src/installation/setup.py +++ b/docs/tutorials/wiki/src/installation/setup.py @@ -42,7 +42,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/tutorials/wiki/src/installation/tests/__init__.py b/docs/tutorials/wiki/src/installation/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki/src/installation/tests/__init__.py diff --git a/docs/tutorials/wiki/src/authorization/tutorial/tests.py b/docs/tutorials/wiki/src/installation/tests/test_it.py index 6279d9f66..6c72bcc62 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki/src/installation/tests/test_it.py @@ -11,8 +11,14 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from tutorial.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'myproj') + def test_notfound_view(self): + from tutorial.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + diff --git a/docs/tutorials/wiki/src/installation/tutorial/templates/layout.pt b/docs/tutorials/wiki/src/installation/tutorial/templates/layout.pt index 9fdaef00f..9ca01382b 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/templates/layout.pt +++ b/docs/tutorials/wiki/src/installation/tutorial/templates/layout.pt @@ -1,5 +1,5 @@ <!DOCTYPE html metal:define-macro="layout"> -<html lang="{{request.locale_name}}"> +<html lang="${request.locale_name}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> diff --git a/docs/tutorials/wiki/src/installation/tutorial/views/default.py b/docs/tutorials/wiki/src/installation/tutorial/views/default.py index 5d708d15c..51ec5ed98 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/views/default.py +++ b/docs/tutorials/wiki/src/installation/tutorial/views/default.py @@ -3,6 +3,6 @@ from pyramid.view import view_config from ..models import MyModel -@view_config(context=MyModel, renderer='../templates/mytemplate.pt') +@view_config(context=MyModel, renderer='tutorial:templates/mytemplate.pt') def my_view(request): return {'project': 'myproj'} diff --git a/docs/tutorials/wiki/src/installation/tutorial/views/notfound.py b/docs/tutorials/wiki/src/installation/tutorial/views/notfound.py index 728791d0a..59a37280e 100644 --- a/docs/tutorials/wiki/src/installation/tutorial/views/notfound.py +++ b/docs/tutorials/wiki/src/installation/tutorial/views/notfound.py @@ -1,7 +1,7 @@ from pyramid.view import notfound_view_config -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='tutorial:templates/404.pt') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki/src/models/.coveragerc b/docs/tutorials/wiki/src/models/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki/src/models/.coveragerc +++ b/docs/tutorials/wiki/src/models/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/models/MANIFEST.in b/docs/tutorials/wiki/src/models/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki/src/models/MANIFEST.in +++ b/docs/tutorials/wiki/src/models/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki/src/models/pytest.ini b/docs/tutorials/wiki/src/models/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki/src/models/pytest.ini +++ b/docs/tutorials/wiki/src/models/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki/src/models/setup.py b/docs/tutorials/wiki/src/models/setup.py index d6d488ed2..f85780010 100644 --- a/docs/tutorials/wiki/src/models/setup.py +++ b/docs/tutorials/wiki/src/models/setup.py @@ -42,7 +42,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/tutorials/wiki/src/models/tests/__init__.py b/docs/tutorials/wiki/src/models/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki/src/models/tests/__init__.py diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki/src/models/tests/test_it.py index 6279d9f66..6c72bcc62 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/tests.py +++ b/docs/tutorials/wiki/src/models/tests/test_it.py @@ -11,8 +11,14 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from .views.default import my_view + from tutorial.views.default import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'myproj') + def test_notfound_view(self): + from tutorial.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/layout.pt b/docs/tutorials/wiki/src/models/tutorial/templates/layout.pt index 9fdaef00f..9ca01382b 100644 --- a/docs/tutorials/wiki/src/models/tutorial/templates/layout.pt +++ b/docs/tutorials/wiki/src/models/tutorial/templates/layout.pt @@ -1,5 +1,5 @@ <!DOCTYPE html metal:define-macro="layout"> -<html lang="{{request.locale_name}}"> +<html lang="${request.locale_name}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> diff --git a/docs/tutorials/wiki/src/models/tutorial/views/default.py b/docs/tutorials/wiki/src/models/tutorial/views/default.py index 5d708d15c..51ec5ed98 100644 --- a/docs/tutorials/wiki/src/models/tutorial/views/default.py +++ b/docs/tutorials/wiki/src/models/tutorial/views/default.py @@ -3,6 +3,6 @@ from pyramid.view import view_config from ..models import MyModel -@view_config(context=MyModel, renderer='../templates/mytemplate.pt') +@view_config(context=MyModel, renderer='tutorial:templates/mytemplate.pt') def my_view(request): return {'project': 'myproj'} diff --git a/docs/tutorials/wiki/src/models/tutorial/views/notfound.py b/docs/tutorials/wiki/src/models/tutorial/views/notfound.py index 728791d0a..59a37280e 100644 --- a/docs/tutorials/wiki/src/models/tutorial/views/notfound.py +++ b/docs/tutorials/wiki/src/models/tutorial/views/notfound.py @@ -1,7 +1,7 @@ from pyramid.view import notfound_view_config -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='tutorial:templates/404.pt') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki/src/tests/.coveragerc b/docs/tutorials/wiki/src/tests/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki/src/tests/.coveragerc +++ b/docs/tutorials/wiki/src/tests/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/tests/MANIFEST.in b/docs/tutorials/wiki/src/tests/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki/src/tests/MANIFEST.in +++ b/docs/tutorials/wiki/src/tests/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki/src/tests/pytest.ini b/docs/tutorials/wiki/src/tests/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki/src/tests/pytest.ini +++ b/docs/tutorials/wiki/src/tests/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki/src/tests/setup.py b/docs/tutorials/wiki/src/tests/setup.py index fa5948acb..f19d643e6 100644 --- a/docs/tutorials/wiki/src/tests/setup.py +++ b/docs/tutorials/wiki/src/tests/setup.py @@ -44,7 +44,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/tutorials/wiki/src/tests/tests/__init__.py b/docs/tutorials/wiki/src/tests/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki/src/tests/tests/__init__.py diff --git a/docs/tutorials/wiki/src/tests/tutorial/tests.py b/docs/tutorials/wiki/src/tests/tests/test_it.py index ff1c07b7c..e45380e6f 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/tests.py +++ b/docs/tutorials/wiki/src/tests/tests/test_it.py @@ -5,7 +5,7 @@ from pyramid import testing class PageModelTests(unittest.TestCase): def _getTargetClass(self): - from .models import Page + from tutorial.models import Page return Page def _makeOne(self, data='some data'): @@ -18,7 +18,7 @@ class PageModelTests(unittest.TestCase): class WikiModelTests(unittest.TestCase): def _getTargetClass(self): - from .models import Wiki + from tutorial.models import Wiki return Wiki def _makeOne(self): @@ -32,7 +32,7 @@ class WikiModelTests(unittest.TestCase): class AppmakerTests(unittest.TestCase): def _callFUT(self, zodb_root): - from .models import appmaker + from tutorial.models import appmaker return appmaker(zodb_root) def test_it(self): @@ -43,7 +43,7 @@ class AppmakerTests(unittest.TestCase): class ViewWikiTests(unittest.TestCase): def test_it(self): - from .views.default import view_wiki + from tutorial.views.default import view_wiki context = testing.DummyResource() request = testing.DummyRequest() response = view_wiki(context, request) @@ -51,7 +51,7 @@ class ViewWikiTests(unittest.TestCase): class ViewPageTests(unittest.TestCase): def _callFUT(self, context, request): - from .views.default import view_page + from tutorial.views.default import view_page return view_page(context, request) def test_it(self): @@ -77,7 +77,7 @@ class ViewPageTests(unittest.TestCase): class AddPageTests(unittest.TestCase): def _callFUT(self, context, request): - from .views.default import add_page + from tutorial.views.default import add_page return add_page(context, request) def test_it_notsubmitted(self): @@ -103,7 +103,7 @@ class AddPageTests(unittest.TestCase): class EditPageTests(unittest.TestCase): def _callFUT(self, context, request): - from .views.default import edit_page + from tutorial.views.default import edit_page return edit_page(context, request) def test_it_notsubmitted(self): @@ -124,7 +124,7 @@ class EditPageTests(unittest.TestCase): class SecurityTests(unittest.TestCase): def test_hashing(self): - from .security import hash_password, check_password + from tutorial.security import hash_password, check_password password = 'secretpassword' hashed_password = hash_password(password) self.assertTrue(check_password(hashed_password, password)) @@ -145,7 +145,7 @@ class FunctionalTests(unittest.TestCase): def setUp(self): import tempfile import os.path - from . import main + from tutorial import main self.tmpdir = tempfile.mkdtemp() dbpath = os.path.join( self.tmpdir, 'test.db') diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/layout.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/layout.pt index b606e8dad..06a3c8157 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/layout.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/layout.pt @@ -1,5 +1,5 @@ <!DOCTYPE html metal:define-macro="layout"> -<html lang="{{request.locale_name}}"> +<html lang="${request.locale_name}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> diff --git a/docs/tutorials/wiki/src/tests/tutorial/views/default.py b/docs/tutorials/wiki/src/tests/tutorial/views/default.py index 3a3b170e2..7ba99c65b 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/views/default.py +++ b/docs/tutorials/wiki/src/tests/tutorial/views/default.py @@ -24,7 +24,7 @@ def view_wiki(context, request): return HTTPFound(location=request.resource_url(context, 'FrontPage')) -@view_config(context='..models.Page', renderer='../templates/view.pt', +@view_config(context='..models.Page', renderer='tutorial:templates/view.pt', permission='view') def view_page(context, request): wiki = context.__parent__ @@ -47,7 +47,7 @@ def view_page(context, request): @view_config(name='add_page', context='..models.Wiki', - renderer='../templates/edit.pt', + renderer='tutorial:templates/edit.pt', permission='edit') def add_page(context, request): pagename = request.subpath[0] @@ -67,7 +67,7 @@ def add_page(context, request): @view_config(name='edit_page', context='..models.Page', - renderer='../templates/edit.pt', + renderer='tutorial:templates/edit.pt', permission='edit') def edit_page(context, request): if 'form.submitted' in request.params: @@ -80,8 +80,8 @@ def edit_page(context, request): @view_config(context='..models.Wiki', name='login', - renderer='../templates/login.pt') -@forbidden_view_config(renderer='../templates/login.pt') + renderer='tutorial:templates/login.pt') +@forbidden_view_config(renderer='tutorial:templates/login.pt') def login(request): login_url = request.resource_url(request.context, 'login') referrer = request.url diff --git a/docs/tutorials/wiki/src/tests/tutorial/views/notfound.py b/docs/tutorials/wiki/src/tests/tutorial/views/notfound.py index d44b4d0e6..dd0b00488 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/views/notfound.py +++ b/docs/tutorials/wiki/src/tests/tutorial/views/notfound.py @@ -3,7 +3,7 @@ from pyramid.view import notfound_view_config from ..models import Page -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='tutorial:templates/404.pt') def notfound_view(request): request.response.status = 404 pagename = request.path diff --git a/docs/tutorials/wiki/src/views/.coveragerc b/docs/tutorials/wiki/src/views/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki/src/views/.coveragerc +++ b/docs/tutorials/wiki/src/views/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki/src/views/MANIFEST.in b/docs/tutorials/wiki/src/views/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki/src/views/MANIFEST.in +++ b/docs/tutorials/wiki/src/views/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki/src/views/pytest.ini b/docs/tutorials/wiki/src/views/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki/src/views/pytest.ini +++ b/docs/tutorials/wiki/src/views/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki/src/views/setup.py b/docs/tutorials/wiki/src/views/setup.py index 6f3cae397..439bb7759 100644 --- a/docs/tutorials/wiki/src/views/setup.py +++ b/docs/tutorials/wiki/src/views/setup.py @@ -43,7 +43,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/tutorials/wiki/src/views/tests/__init__.py b/docs/tutorials/wiki/src/views/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki/src/views/tests/__init__.py diff --git a/docs/tutorials/wiki/src/views/tests/test_it.py b/docs/tutorials/wiki/src/views/tests/test_it.py new file mode 100644 index 000000000..6c72bcc62 --- /dev/null +++ b/docs/tutorials/wiki/src/views/tests/test_it.py @@ -0,0 +1,24 @@ +import unittest + +from pyramid import testing + + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from tutorial.views.default import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], 'myproj') + + def test_notfound_view(self): + from tutorial.views.notfound import notfound_view + request = testing.DummyRequest() + info = notfound_view(request) + self.assertEqual(info, {}) + diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/layout.pt b/docs/tutorials/wiki/src/views/tutorial/templates/layout.pt index b606e8dad..06a3c8157 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/layout.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/layout.pt @@ -1,5 +1,5 @@ <!DOCTYPE html metal:define-macro="layout"> -<html lang="{{request.locale_name}}"> +<html lang="${request.locale_name}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> diff --git a/docs/tutorials/wiki/src/views/tutorial/tests.py b/docs/tutorials/wiki/src/views/tutorial/tests.py deleted file mode 100644 index 6279d9f66..000000000 --- a/docs/tutorials/wiki/src/views/tutorial/tests.py +++ /dev/null @@ -1,18 +0,0 @@ -import unittest - -from pyramid import testing - - -class ViewTests(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from .views.default import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['project'], 'myproj') - diff --git a/docs/tutorials/wiki/src/views/tutorial/views/default.py b/docs/tutorials/wiki/src/views/tutorial/views/default.py index b4b65a49b..e7921cf2f 100644 --- a/docs/tutorials/wiki/src/views/tutorial/views/default.py +++ b/docs/tutorials/wiki/src/views/tutorial/views/default.py @@ -15,7 +15,7 @@ def view_wiki(context, request): return HTTPFound(location=request.resource_url(context, 'FrontPage')) -@view_config(context='..models.Page', renderer='../templates/view.pt') +@view_config(context='..models.Page', renderer='tutorial:templates/view.pt') def view_page(context, request): wiki = context.__parent__ @@ -36,7 +36,7 @@ def view_page(context, request): @view_config(name='add_page', context='..models.Wiki', - renderer='../templates/edit.pt') + renderer='tutorial:templates/edit.pt') def add_page(context, request): pagename = request.subpath[0] if 'form.submitted' in request.params: @@ -54,7 +54,7 @@ def add_page(context, request): @view_config(name='edit_page', context='..models.Page', - renderer='../templates/edit.pt') + renderer='tutorial:templates/edit.pt') def edit_page(context, request): if 'form.submitted' in request.params: context.data = request.params['body'] diff --git a/docs/tutorials/wiki/src/views/tutorial/views/notfound.py b/docs/tutorials/wiki/src/views/tutorial/views/notfound.py index d44b4d0e6..dd0b00488 100644 --- a/docs/tutorials/wiki/src/views/tutorial/views/notfound.py +++ b/docs/tutorials/wiki/src/views/tutorial/views/notfound.py @@ -3,7 +3,7 @@ from pyramid.view import notfound_view_config from ..models import Page -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='tutorial:templates/404.pt') def notfound_view(request): request.response.status = 404 pagename = request.path diff --git a/docs/tutorials/wiki/tests.rst b/docs/tutorials/wiki/tests.rst index 9dacc5f96..f710b3b10 100644 --- a/docs/tutorials/wiki/tests.rst +++ b/docs/tutorials/wiki/tests.rst @@ -4,7 +4,7 @@ Adding Tests ============ -We will now add tests for the models and the views and a few functional tests in ``tests.py``. +We will now add tests for the models and the views and a few functional tests in ``tests/test_it.py``. Tests ensure that an application works, and that it continues to work when changes are made in the future. @@ -12,10 +12,9 @@ Test the models =============== We write tests for the ``model`` classes and the ``appmaker``. -Changing ``tests.py``, we will write a separate test class for each ``model`` class +We will modify our ``test_it.py`` file, writing a separate test class for each ``model`` class. We will also write a test class for the ``appmaker``. -To do so, we will retain the ``tutorial.tests.ViewTests`` class that was generated from choosing the ``zodb`` backend option. We will add three test classes, one for each of the following: - the ``Page`` model named ``PageModelTests`` @@ -26,7 +25,7 @@ We will add three test classes, one for each of the following: Test the views ============== -We will modify our ``tests.py`` file, adding tests for each view function that we added previously. +We will modify our ``test_it.py`` file, adding tests for each view function that we added previously. As a result, we will delete the ``ViewTests`` class that the ``zodb`` backend option provided, and add four other test classes: ``ViewWikiTests``, ``ViewPageTests``, ``AddPageTests``, and ``EditPageTests``. These test the ``view_wiki``, ``view_page``, ``add_page``, and ``edit_page`` views. @@ -35,14 +34,15 @@ Functional tests ================ We will test the whole application, covering security aspects that are not tested in the unit tests, such as logging in, logging out, checking that the ``viewer`` user cannot add or edit pages, but the ``editor`` user can, and so on. +As a result we will add two test classes, ``SecurityTests`` and ``FunctionalTests``. -View the results of all our edits to ``tests.py`` -================================================= +View the results of all our edits to ``tests/test_it.py`` +========================================================= -Open the ``tutorial/tests.py`` module, and edit it such that it appears as follows: +Open the ``tests/test_it.py`` module, and edit it such that it appears as follows: -.. literalinclude:: src/tests/tutorial/tests.py +.. literalinclude:: src/tests/tests/test_it.py :linenos: :language: python diff --git a/docs/tutorials/wiki2/basiclayout.rst b/docs/tutorials/wiki2/basiclayout.rst index f3a9db223..ae58d80a5 100644 --- a/docs/tutorials/wiki2/basiclayout.rst +++ b/docs/tutorials/wiki2/basiclayout.rst @@ -58,16 +58,16 @@ dictionary of settings parsed from the ``.ini`` file, which contains deployment-related values, such as ``pyramid.reload_templates``, ``sqlalchemy.url``, and so on. -Next include :term:`Jinja2` templating bindings so that we can use renderers -with the ``.jinja2`` extension within our project. +Next include the package ``models`` using a dotted Python path. The exact +setup of the models will be covered later. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 8 :lineno-match: :language: py -Next include the package ``models`` using a dotted Python path. The exact -setup of the models will be covered later. +Next include :term:`Jinja2` templating bindings so that we can use renderers +with the ``.jinja2`` extension within our project. .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 9 @@ -184,6 +184,25 @@ database and provide an alternate error response. That response will include the text shown at the end of the file, which will be displayed in the browser to inform the user about possible actions to take to solve the problem. +Open ``tutorial/views/notfound.py`` in the ``views`` package to look at the second view. + +.. literalinclude:: src/basiclayout/tutorial/views/notfound.py + :linenos: + :language: python + +Without repeating ourselves, we will point out the differences between this view and the previous. + +#. *Line 4*. + The ``notfound_view`` function is decorated with ``@notfound_view_config``. + This decorator registers a :term:`Not Found View` using :meth:`pyramid.config.Configurator.add_notfound_view`. + + The ``renderer`` argument names an :term:`asset specification` of ``tutorial:templates/404.jinja2``. + +#. *Lines 5-7*. + A :term:`view callable` named ``notfound_view`` is defined, which is decorated in the step above. + It sets the HTTP response status code to ``404``. + The function returns an empty dictionary to the template ``404.jinja2``, which accepts no parameters anyway. + Content models with the ``models`` package ------------------------------------------ diff --git a/docs/tutorials/wiki2/definingmodels.rst b/docs/tutorials/wiki2/definingmodels.rst index 6624e4cdc..4b80e09ac 100644 --- a/docs/tutorials/wiki2/definingmodels.rst +++ b/docs/tutorials/wiki2/definingmodels.rst @@ -33,10 +33,12 @@ Open ``tutorial/setup.py`` and edit it to look like the following: .. literalinclude:: src/models/setup.py :linenos: - :emphasize-lines: 13 + :emphasize-lines: 11-24 :language: python -Only the highlighted line needs to be added. +It is a good practice to sort packages alphabetically to make them easier to find. +Our cookiecutter does not have its packages sorted because it merely tacks on additional packages depending on our selections. +After adding ``bcrypt`` and sorting packages, we should have the above ``requires`` list. .. note:: @@ -70,7 +72,7 @@ like the following. .. code-block:: text - Successfully installed bcrypt-3.1.4 cffi-1.11.5 pycparser-2.18 tutorial + Successfully installed bcrypt-3.1.7 cffi-1.13.2 pycparser-2.19 tutorial Remove ``mymodel.py`` @@ -185,86 +187,19 @@ Success executing these commands will generate output similar to the following. .. code-block:: text - 2018-06-29 01:28:42,407 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-06-29 01:28:42,407 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-29 01:28:42,408 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-06-29 01:28:42,408 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-29 01:28:42,409 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("alembic_version") - 2018-06-29 01:28:42,409 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,410 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT alembic_version.version_num - FROM alembic_version - 2018-06-29 01:28:42,410 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,411 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT name FROM sqlite_master WHERE type='table' ORDER BY name - 2018-06-29 01:28:42,412 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,413 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("models") - 2018-06-29 01:28:42,413 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,414 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE name = 'models' AND type = 'table' - 2018-06-29 01:28:42,414 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,414 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA foreign_key_list("models") - 2018-06-29 01:28:42,414 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,414 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE name = 'models' AND type = 'table' - 2018-06-29 01:28:42,415 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,416 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA index_list("models") - 2018-06-29 01:28:42,416 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,416 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA index_info("my_index") - 2018-06-29 01:28:42,416 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,417 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA index_list("models") - 2018-06-29 01:28:42,417 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,417 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA index_info("my_index") - 2018-06-29 01:28:42,417 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:28:42,417 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE name = 'models' AND type = 'table' - 2018-06-29 01:28:42,417 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - Generating /<somepath>/tutorial/tutorial/alembic/versions/20180629_23e9f8eb6c28.py ... done + 2019-12-28 02:02:31,841 INFO [alembic.runtime.migration:154][MainThread] Context impl SQLiteImpl. + 2019-12-28 02:02:31,841 INFO [alembic.runtime.migration:161][MainThread] Will assume non-transactional DDL. + 2019-12-28 02:02:31,844 INFO [alembic.autogenerate.compare:134][MainThread] Detected added table 'users' + 2019-12-28 02:02:31,845 INFO [alembic.autogenerate.compare:134][MainThread] Detected added table 'pages' + 2019-12-28 02:02:31,853 INFO [alembic.autogenerate.compare:621][MainThread] Detected removed index 'my_index' on 'models' + 2019-12-28 02:02:31,853 INFO [alembic.autogenerate.compare:176][MainThread] Detected removed table 'models' + Generating <somepath>/tutorial/tutorial/alembic/versions/20191228_226a73ffaeef.py ... done .. code-block:: text - 2018-06-29 01:29:37,957 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-06-29 01:29:37,958 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-29 01:29:37,958 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-06-29 01:29:37,958 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-29 01:29:37,960 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("alembic_version") - 2018-06-29 01:29:37,960 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,960 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT alembic_version.version_num - FROM alembic_version - 2018-06-29 01:29:37,960 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,963 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] - CREATE TABLE users ( - id INTEGER NOT NULL, - name TEXT NOT NULL, - role TEXT NOT NULL, - password_hash TEXT, - CONSTRAINT pk_users PRIMARY KEY (id), - CONSTRAINT uq_users_name UNIQUE (name) - ) - - - 2018-06-29 01:29:37,963 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,966 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-29 01:29:37,968 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] - CREATE TABLE pages ( - id INTEGER NOT NULL, - name TEXT NOT NULL, - data TEXT NOT NULL, - creator_id INTEGER NOT NULL, - CONSTRAINT pk_pages PRIMARY KEY (id), - CONSTRAINT fk_pages_creator_id_users FOREIGN KEY(creator_id) REFERENCES users (id), - CONSTRAINT uq_pages_name UNIQUE (name) - ) - - - 2018-06-29 01:29:37,968 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,969 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-29 01:29:37,969 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] - DROP INDEX my_index - 2018-06-29 01:29:37,969 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,970 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-29 01:29:37,970 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] - DROP TABLE models - 2018-06-29 01:29:37,970 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,971 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-29 01:29:37,972 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] UPDATE alembic_version SET version_num='23e9f8eb6c28' WHERE alembic_version.version_num = 'b6b22ae3e628' - 2018-06-29 01:29:37,972 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-29 01:29:37,972 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT + 2019-12-28 02:03:15,390 INFO [alembic.runtime.migration:154][MainThread] Context impl SQLiteImpl. + 2019-12-28 02:03:15,391 INFO [alembic.runtime.migration:161][MainThread] Will assume non-transactional DDL. + 2019-12-28 02:03:15,393 INFO [alembic.runtime.migration:513][MainThread] Running upgrade a8e203c3ce9c -> 226a73ffaeef, use new models Page and User .. _wiki2_alembic_overview: @@ -318,26 +253,23 @@ Only the highlighted lines need to be changed. Populating the database ======================= -Because our model has changed, and to repopulate the database, we -need to rerun the ``initialize_tutorial_db`` command to pick up the changes -we've made to the initialize_db.py file. See :ref:`initialize_db_wiki2` for instructions. +Because our model has changed, and to repopulate the database, we need to rerun the ``initialize_tutorial_db`` command to pick up the changes we've made to the ``initialize_db.py`` file. -Success will look something like this: +On Unix +------- -.. code-block:: text +.. code-block:: bash + + $VENV/bin/initialize_tutorial_db development.ini + +On Windows +---------- + +.. code-block:: doscon + + %VENV%\Scripts\initialize_tutorial_db development.ini - 2018-06-29 01:30:39,326 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-06-29 01:30:39,326 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-29 01:30:39,327 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-06-29 01:30:39,327 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-29 01:30:39,328 INFO [sqlalchemy.engine.base.Engine:682][MainThread] BEGIN (implicit) - 2018-06-29 01:30:39,329 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) - 2018-06-29 01:30:39,329 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] ('editor', 'editor', '$2b$12$PlaJSN7goVbyx8OFs8yAju9n5gHGdI6PZ2QRJGM2jDCiEU4ItUNxy') - 2018-06-29 01:30:39,330 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] INSERT INTO users (name, role, password_hash) VALUES (?, ?, ?) - 2018-06-29 01:30:39,330 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] ('basic', 'basic', '$2b$12$MvXdM8jlkbjEyPZ6uXzRg.yatZZK8jCwfPaM7kFkmVJiJjRoCCvmW') - 2018-06-29 01:30:39,331 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] INSERT INTO pages (name, data, creator_id) VALUES (?, ?, ?) - 2018-06-29 01:30:39,331 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] ('FrontPage', 'This is the front page', 1) - 2018-06-29 01:30:39,332 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT +There should be no output to your console to indicate success. View the application in a browser diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 705979065..55fca15a1 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -177,26 +177,30 @@ The console will show ``pip`` checking for packages and installing missing packa .. code-block:: bash - Successfully installed Jinja2-2.8 Mako-1.0.6 MarkupSafe-0.23 \ - PasteDeploy-1.5.2 Pygments-2.1.3 SQLAlchemy-1.1.4 WebOb-1.6.3 \ - WebTest-2.0.24 beautifulsoup4-4.5.1 coverage-4.2 py-1.4.32 pyramid-1.7.3 \ - pyramid-debugtoolbar-3.0.5 pyramid-jinja2-2.7 pyramid-mako-1.0.2 \ - pyramid-tm-1.1.1 pytest-3.0.5 pytest-cov-2.4.0 repoze.lru-0.6 six-1.10.0 \ - transaction-2.0.3 translationstring-1.3 tutorial venusian-1.0 \ - waitress-1.0.1 zope.deprecation-4.2.0 zope.interface-4.3.3 \ - zope.sqlalchemy-0.7.7 + Successfully installed Jinja2-2.10.3 Mako-1.1.0 MarkupSafe-1.1.1 \ + PasteDeploy-2.0.1 Pygments-2.5.2 SQLAlchemy-1.3.12 WebTest-2.0.33 \ + alembic-1.3.2 attrs-19.3.0 beautifulsoup4-4.8.2 coverage-5.0.1 \ + hupper-1.9.1 importlib-metadata-1.3.0 more-itertools-8.0.2 packaging-19.2 \ + plaster-1.0 plaster-pastedeploy-0.7 pluggy-0.13.1 py-1.8.1 \ + pyparsing-2.4.6 pyramid-1.10.4 pyramid-debugtoolbar-4.5.1 \ + pyramid-jinja2-2.8 pyramid-mako-1.1.0 pyramid-retry-2.1 pyramid-tm-2.3 \ + pytest-5.3.2 pytest-cov-2.8.1 python-dateutil-2.8.1 python-editor-1.0.4 \ + repoze.lru-0.7 six-1.13.0 soupsieve-1.9.5 transaction-3.0.0 \ + translationstring-1.3 tutorial venusian-3.0.0 waitress-1.4.1 \ + wcwidth-0.1.7 webob-1.8.5 zipp-0.6.0 zope.deprecation-4.4.0 \ + zope.interface-4.7.1 zope.sqlalchemy-1.2 Testing requirements are defined in our project's ``setup.py`` file, in the ``tests_require`` and ``extras_require`` stanzas. .. literalinclude:: src/installation/setup.py :language: python :lineno-match: - :lines: 24-28 + :lines: 25-29 .. literalinclude:: src/installation/setup.py :language: python :lineno-match: - :lines: 48-50 + :lines: 49-51 .. _initialize_db_wiki2: @@ -226,26 +230,11 @@ The output to your console should be something like this: .. code-block:: text - 2018-06-22 17:57:31,587 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-06-22 17:57:31,587 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-22 17:57:31,588 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-06-22 17:57:31,588 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-22 17:57:31,589 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("alembic_version") - 2018-06-22 17:57:31,589 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:31,590 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("alembic_version") - 2018-06-22 17:57:31,590 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:31,590 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] - CREATE TABLE alembic_version ( - version_num VARCHAR(32) NOT NULL, - CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num) - ) - - - 2018-06-22 17:57:31,591 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:31,591 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-22 17:57:31,594 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT name FROM sqlite_master WHERE type='table' ORDER BY name - 2018-06-22 17:57:31,594 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - Generating /<somepath>/tutorial/alembic/versions/20180622_bab5a278ce04.py ... done + 2019-12-28 00:46:03,850 INFO [alembic.runtime.migration:154][MainThread] Context impl SQLiteImpl. + 2019-12-28 00:46:03,850 INFO [alembic.runtime.migration:161][MainThread] Will assume non-transactional DDL. + 2019-12-28 00:46:03,853 INFO [alembic.autogenerate.compare:134][MainThread] Detected added table 'models' + 2019-12-28 00:46:03,853 INFO [alembic.autogenerate.compare:586][MainThread] Detected added index 'my_index' on '['name']' + Generating <somepath>/tutorial/tutorial/alembic/versions/20191228_a8e203c3ce9c.py ... done Upgrade to that revision. @@ -267,34 +256,9 @@ The output to your console should be something like this: .. code-block:: text - 2018-06-22 17:57:37,814 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-06-22 17:57:37,814 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-22 17:57:37,814 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-06-22 17:57:37,814 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-22 17:57:37,816 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("alembic_version") - 2018-06-22 17:57:37,816 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:37,817 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] SELECT alembic_version.version_num - FROM alembic_version - 2018-06-22 17:57:37,817 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:37,817 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] PRAGMA table_info("alembic_version") - 2018-06-22 17:57:37,817 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:37,819 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] - CREATE TABLE models ( - id INTEGER NOT NULL, - name TEXT, - value INTEGER, - CONSTRAINT pk_models PRIMARY KEY (id) - ) - - - 2018-06-22 17:57:37,820 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:37,822 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-22 17:57:37,824 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] CREATE UNIQUE INDEX my_index ON models (name) - 2018-06-22 17:57:37,824 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:37,825 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - 2018-06-22 17:57:37,825 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] INSERT INTO alembic_version (version_num) VALUES ('bab5a278ce04') - 2018-06-22 17:57:37,825 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] () - 2018-06-22 17:57:37,825 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT + 2019-12-28 00:52:12,158 INFO [alembic.runtime.migration:154][MainThread] Context impl SQLiteImpl. + 2019-12-28 00:52:12,158 INFO [alembic.runtime.migration:161][MainThread] Will assume non-transactional DDL. + 2019-12-28 00:52:12,160 INFO [alembic.runtime.migration:513][MainThread] Running upgrade -> a8e203c3ce9c, init .. _load_data_wiki2: @@ -318,22 +282,9 @@ On Windows %VENV%\Scripts\initialize_tutorial_db development.ini -The output to your console should be something like this: - -.. code-block:: bash - - 2018-06-22 17:57:46,241 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 - 2018-06-22 17:57:46,241 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-22 17:57:46,242 INFO [sqlalchemy.engine.base.Engine:1254][MainThread] SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 - 2018-06-22 17:57:46,242 INFO [sqlalchemy.engine.base.Engine:1255][MainThread] () - 2018-06-22 17:57:46,243 INFO [sqlalchemy.engine.base.Engine:682][MainThread] BEGIN (implicit) - 2018-06-22 17:57:46,244 INFO [sqlalchemy.engine.base.Engine:1151][MainThread] INSERT INTO models (name, value) VALUES (?, ?) - 2018-06-22 17:57:46,245 INFO [sqlalchemy.engine.base.Engine:1154][MainThread] ('one', 1) - 2018-06-22 17:57:46,246 INFO [sqlalchemy.engine.base.Engine:722][MainThread] COMMIT - -Success! You should now have a ``tutorial.sqlite`` file in your current -working directory. This is an SQLite database with a single table defined in it -(``models``) and single record inside of that. +There should be no output to your console. +You should now have a ``tutorial.sqlite`` file in your current working directory. +This is an SQLite database with three tables defined in it, ``alembic_version``, ``models``, and ``master``, where the first two tables each have single record inside of them. .. _sql_running_tests: @@ -398,29 +349,31 @@ If successful, you will see output something like this: .. code-block:: bash ======================== test session starts ======================== - platform Python 3.6.5, pytest-3.6.2, py-1.5.3, pluggy-0.6.0 - rootdir: /<somepath>/tutorial, inifile: pytest.ini - plugins: cov-2.5.1 + platform -- Python 3.7.3, pytest-5.3.2, py-1.8.1, pluggy-0.13.1 + rootdir: <somepath>/tutorial, inifile: pytest.ini, testpaths: tutorial + plugins: cov-2.8.1 collected 2 items tutorial/tests.py .. - ------------------ coverage: platform Python 3.6.5 ------------------ + + ------------------ coverage: platform Python 3.7.3 ------------------ Name Stmts Miss Cover Missing ----------------------------------------------------------------- tutorial/__init__.py 8 6 25% 7-12 tutorial/models/__init__.py 24 0 100% tutorial/models/meta.py 5 0 100% tutorial/models/mymodel.py 8 0 100% + tutorial/pshell.py 7 7 0% 1-13 tutorial/routes.py 3 3 0% 1-3 tutorial/scripts/__init__.py 0 0 100% - tutorial/scripts/initialize_db.py 24 24 0% 1-34 + tutorial/scripts/initialize_db.py 22 22 0% 1-38 tutorial/views/__init__.py 0 0 100% tutorial/views/default.py 12 0 100% tutorial/views/notfound.py 4 4 0% 1-7 ----------------------------------------------------------------- - TOTAL 88 37 58% + TOTAL 93 42 55% - ===================== 2 passed in 0.57 seconds ====================== + ===================== 2 passed in 0.64 seconds ====================== Our package doesn't quite have 100% test coverage. @@ -440,7 +393,7 @@ On Unix .. code-block:: bash - $VENV/bin/pytest --cov=tutorial tutorial/tests.py -q + $VENV/bin/pytest --cov=tutorial tests -q On Windows ^^^^^^^^^^ @@ -489,8 +442,8 @@ If successful, you will see something like this on your console: .. code-block:: text - Starting subprocess with file monitor - Starting server in PID 44078. + Starting monitor for PID 68932. + Starting server in PID 68932. Serving on http://localhost:6543 Serving on http://localhost:6543 diff --git a/docs/tutorials/wiki2/src/authentication/.coveragerc b/docs/tutorials/wiki2/src/authentication/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/authentication/.coveragerc +++ b/docs/tutorials/wiki2/src/authentication/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/authentication/MANIFEST.in b/docs/tutorials/wiki2/src/authentication/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/authentication/MANIFEST.in +++ b/docs/tutorials/wiki2/src/authentication/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/authentication/development.ini b/docs/tutorials/wiki2/src/authentication/development.ini index 8fbb5fd38..7fda4cb7b 100644 --- a/docs/tutorials/wiki2/src/authentication/development.ini +++ b/docs/tutorials/wiki2/src/authentication/development.ini @@ -47,7 +47,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -72,6 +72,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/authentication/production.ini b/docs/tutorials/wiki2/src/authentication/production.ini index 9fef64f83..8e878a707 100644 --- a/docs/tutorials/wiki2/src/authentication/production.ini +++ b/docs/tutorials/wiki2/src/authentication/production.ini @@ -41,7 +41,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -66,6 +66,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/authentication/pytest.ini b/docs/tutorials/wiki2/src/authentication/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/authentication/pytest.ini +++ b/docs/tutorials/wiki2/src/authentication/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/authentication/setup.py b/docs/tutorials/wiki2/src/authentication/setup.py index f71998afc..500c5e599 100644 --- a/docs/tutorials/wiki2/src/authentication/setup.py +++ b/docs/tutorials/wiki2/src/authentication/setup.py @@ -13,7 +13,7 @@ requires = [ 'bcrypt', 'docutils', 'plaster_pastedeploy', - 'pyramid >= 1.9', + 'pyramid', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', @@ -45,7 +45,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={ @@ -57,7 +57,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/authentication/tests/__init__.py b/docs/tutorials/wiki2/src/authentication/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/authentication/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/installation/tutorial/tests.py b/docs/tutorials/wiki2/src/authentication/tests/test_it.py index ce650ca7c..ea16534fc 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authentication/tests/test_it.py @@ -1,8 +1,9 @@ import unittest -import transaction from pyramid import testing +import transaction + def dummy_request(dbsession): return testing.DummyRequest(dbsession=dbsession) @@ -13,10 +14,10 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models') + self.config.include('tutorial.models') settings = self.config.get_settings() - from .models import ( + from tutorial.models import ( get_engine, get_session_factory, get_tm_session, @@ -28,11 +29,11 @@ class BaseTest(unittest.TestCase): self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models.meta import Base + from tutorial.models.meta import Base Base.metadata.create_all(self.engine) def tearDown(self): - from .models.meta import Base + from tutorial.models.meta import Base testing.tearDown() transaction.abort() @@ -45,13 +46,13 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models import MyModel + from tutorial.models import MyModel model = MyModel(name='one', value=55) self.session.add(model) def test_passing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') self.assertEqual(info['project'], 'myproj') @@ -60,6 +61,6 @@ class TestMyViewSuccessCondition(BaseTest): class TestMyViewFailureCondition(BaseTest): def test_failing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/__init__.py b/docs/tutorials/wiki2/src/authentication/tutorial/__init__.py index 5d4bae3d7..ce2e9f12a 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.include('.security') config.scan() diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/authentication/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/pshell.py b/docs/tutorials/wiki2/src/authentication/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/authentication/tutorial/templates/404.jinja2 index 37b0a16b6..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/authentication/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid tutorial wiki</span> <span class="smaller">(based on TurboGears 20-Minute Wiki)</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/views/auth.py b/docs/tutorials/wiki2/src/authentication/tutorial/views/auth.py index 2b993b430..16fa616e5 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/views/auth.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/views/auth.py @@ -11,7 +11,7 @@ from pyramid.view import ( from ..models import User -@view_config(route_name='login', renderer='../templates/login.jinja2') +@view_config(route_name='login', renderer='tutorial:templates/login.jinja2') def login(request): next_url = request.params.get('next', request.referrer) if not next_url: diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py index 2f0210255..d1c429950 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/views/default.py @@ -20,7 +20,7 @@ def view_wiki(request): next_url = request.route_url('view_page', pagename='FrontPage') return HTTPFound(location=next_url) -@view_config(route_name='view_page', renderer='../templates/view.jinja2') +@view_config(route_name='view_page', renderer='tutorial:templates/view.jinja2') def view_page(request): pagename = request.matchdict['pagename'] page = request.dbsession.query(models.Page).filter_by(name=pagename).first() @@ -42,7 +42,7 @@ def view_page(request): edit_url = request.route_url('edit_page', pagename=page.name) return dict(page=page, content=content, edit_url=edit_url) -@view_config(route_name='edit_page', renderer='../templates/edit.jinja2') +@view_config(route_name='edit_page', renderer='tutorial:templates/edit.jinja2') def edit_page(request): pagename = request.matchdict['pagename'] page = request.dbsession.query(models.Page).filter_by(name=pagename).one() @@ -59,7 +59,7 @@ def edit_page(request): save_url=request.route_url('edit_page', pagename=page.name), ) -@view_config(route_name='add_page', renderer='../templates/edit.jinja2') +@view_config(route_name='add_page', renderer='tutorial:templates/edit.jinja2') def add_page(request): user = request.user if user is None or user.role not in ('editor', 'basic'): diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/authentication/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/authentication/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/src/authorization/.coveragerc b/docs/tutorials/wiki2/src/authorization/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/authorization/.coveragerc +++ b/docs/tutorials/wiki2/src/authorization/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/authorization/MANIFEST.in b/docs/tutorials/wiki2/src/authorization/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/authorization/MANIFEST.in +++ b/docs/tutorials/wiki2/src/authorization/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 8fbb5fd38..7fda4cb7b 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -47,7 +47,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -72,6 +72,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 9fef64f83..8e878a707 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -41,7 +41,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -66,6 +66,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/authorization/pytest.ini b/docs/tutorials/wiki2/src/authorization/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/authorization/pytest.ini +++ b/docs/tutorials/wiki2/src/authorization/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index f71998afc..500c5e599 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -13,7 +13,7 @@ requires = [ 'bcrypt', 'docutils', 'plaster_pastedeploy', - 'pyramid >= 1.9', + 'pyramid', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', @@ -45,7 +45,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={ @@ -57,7 +57,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/authorization/tests/__init__.py b/docs/tutorials/wiki2/src/authorization/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tests/test_it.py index ce650ca7c..ea16534fc 100644 --- a/docs/tutorials/wiki2/src/authentication/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tests/test_it.py @@ -1,8 +1,9 @@ import unittest -import transaction from pyramid import testing +import transaction + def dummy_request(dbsession): return testing.DummyRequest(dbsession=dbsession) @@ -13,10 +14,10 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models') + self.config.include('tutorial.models') settings = self.config.get_settings() - from .models import ( + from tutorial.models import ( get_engine, get_session_factory, get_tm_session, @@ -28,11 +29,11 @@ class BaseTest(unittest.TestCase): self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models.meta import Base + from tutorial.models.meta import Base Base.metadata.create_all(self.engine) def tearDown(self): - from .models.meta import Base + from tutorial.models.meta import Base testing.tearDown() transaction.abort() @@ -45,13 +46,13 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models import MyModel + from tutorial.models import MyModel model = MyModel(name='one', value=55) self.session.add(model) def test_passing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') self.assertEqual(info['project'], 'myproj') @@ -60,6 +61,6 @@ class TestMyViewSuccessCondition(BaseTest): class TestMyViewFailureCondition(BaseTest): def test_failing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 5d4bae3d7..ce2e9f12a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.include('.security') config.scan() diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/authorization/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/authorization/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/authorization/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/pshell.py b/docs/tutorials/wiki2/src/authorization/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 index 37b0a16b6..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid tutorial wiki</span> <span class="smaller">(based on TurboGears 20-Minute Wiki)</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py index 2b993b430..16fa616e5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py @@ -11,7 +11,7 @@ from pyramid.view import ( from ..models import User -@view_config(route_name='login', renderer='../templates/login.jinja2') +@view_config(route_name='login', renderer='tutorial:templates/login.jinja2') def login(request): next_url = request.params.get('next', request.referrer) if not next_url: diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py index ad8491b7b..de0bcd816 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -15,7 +15,7 @@ def view_wiki(request): next_url = request.route_url('view_page', pagename='FrontPage') return HTTPFound(location=next_url) -@view_config(route_name='view_page', renderer='../templates/view.jinja2', +@view_config(route_name='view_page', renderer='tutorial:templates/view.jinja2', permission='view') def view_page(request): page = request.context.page @@ -35,7 +35,7 @@ def view_page(request): edit_url = request.route_url('edit_page', pagename=page.name) return dict(page=page, content=content, edit_url=edit_url) -@view_config(route_name='edit_page', renderer='../templates/edit.jinja2', +@view_config(route_name='edit_page', renderer='tutorial:templates/edit.jinja2', permission='edit') def edit_page(request): page = request.context.page @@ -49,7 +49,7 @@ def edit_page(request): save_url=request.route_url('edit_page', pagename=page.name), ) -@view_config(route_name='add_page', renderer='../templates/edit.jinja2', +@view_config(route_name='add_page', renderer='tutorial:templates/edit.jinja2', permission='create') def add_page(request): pagename = request.context.pagename diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/src/basiclayout/.coveragerc b/docs/tutorials/wiki2/src/basiclayout/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/basiclayout/.coveragerc +++ b/docs/tutorials/wiki2/src/basiclayout/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in +++ b/docs/tutorials/wiki2/src/basiclayout/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 564aefb56..f02c4b1b6 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -45,7 +45,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -70,6 +70,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index 29cdda1e1..f8e83f21f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -39,7 +39,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -64,6 +64,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/basiclayout/pytest.ini b/docs/tutorials/wiki2/src/basiclayout/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/basiclayout/pytest.ini +++ b/docs/tutorials/wiki2/src/basiclayout/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index 746012a74..5e7a0111d 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -9,17 +9,17 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ - 'alembic', 'plaster_pastedeploy', - 'pyramid >= 1.9', - 'pyramid_debugtoolbar', + 'pyramid', 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', + 'alembic', 'pyramid_retry', 'pyramid_tm', 'SQLAlchemy', 'transaction', 'zope.sqlalchemy', - 'waitress', ] tests_require = [ @@ -43,7 +43,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={ @@ -55,7 +55,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/basiclayout/tests/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/basiclayout/tests/test_it.py index ce650ca7c..ea16534fc 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/basiclayout/tests/test_it.py @@ -1,8 +1,9 @@ import unittest -import transaction from pyramid import testing +import transaction + def dummy_request(dbsession): return testing.DummyRequest(dbsession=dbsession) @@ -13,10 +14,10 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models') + self.config.include('tutorial.models') settings = self.config.get_settings() - from .models import ( + from tutorial.models import ( get_engine, get_session_factory, get_tm_session, @@ -28,11 +29,11 @@ class BaseTest(unittest.TestCase): self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models.meta import Base + from tutorial.models.meta import Base Base.metadata.create_all(self.engine) def tearDown(self): - from .models.meta import Base + from tutorial.models.meta import Base testing.tearDown() transaction.abort() @@ -45,13 +46,13 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models import MyModel + from tutorial.models import MyModel model = MyModel(name='one', value=55) self.session.add(model) def test_passing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') self.assertEqual(info['project'], 'myproj') @@ -60,6 +61,6 @@ class TestMyViewSuccessCondition(BaseTest): class TestMyViewFailureCondition(BaseTest): def test_failing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py index 28bd1f80d..5c2ba5cc0 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/pshell.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/404.jinja2 index 1917f83c7..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 index 5d4313fe2..f5a086f0e 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="{{request.static_url('tutorial:static/pyramid-16x16.png')}}"> - <title>Cookiecutter Alchemy project for the Pyramid Web Framework</title> + <title>Cookiecutter Starter project for the Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 index d8b0a4232..f2e7283f8 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a Pyramid application generated by<br><span class="font-normal">Cookiecutter</span>.</p> </div> -{% endblock content %}
\ No newline at end of file +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py index ef69ff895..094b2f303 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py @@ -1,12 +1,12 @@ -from pyramid.response import Response from pyramid.view import view_config +from pyramid.response import Response from sqlalchemy.exc import DBAPIError from .. import models -@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +@view_config(route_name='home', renderer='tutorial:templates/mytemplate.jinja2') def my_view(request): try: query = request.dbsession.query(models.MyModel) @@ -21,7 +21,7 @@ Pyramid is having a problem using your SQL database. The problem might be caused by one of the following things: 1. You may need to initialize your database tables with `alembic`. - Check your README.txt for description and try to run it. + Check your README.txt for descriptions and try to run it. 2. Your database server may not be running. Check that the database server referred to by the "sqlalchemy.url" setting in diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/src/installation/.coveragerc b/docs/tutorials/wiki2/src/installation/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/installation/.coveragerc +++ b/docs/tutorials/wiki2/src/installation/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/installation/MANIFEST.in b/docs/tutorials/wiki2/src/installation/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/installation/MANIFEST.in +++ b/docs/tutorials/wiki2/src/installation/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index 564aefb56..f02c4b1b6 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -45,7 +45,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -70,6 +70,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index 29cdda1e1..f8e83f21f 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -39,7 +39,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -64,6 +64,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/installation/pytest.ini b/docs/tutorials/wiki2/src/installation/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/installation/pytest.ini +++ b/docs/tutorials/wiki2/src/installation/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/installation/setup.py b/docs/tutorials/wiki2/src/installation/setup.py index 746012a74..5e7a0111d 100644 --- a/docs/tutorials/wiki2/src/installation/setup.py +++ b/docs/tutorials/wiki2/src/installation/setup.py @@ -9,17 +9,17 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ - 'alembic', 'plaster_pastedeploy', - 'pyramid >= 1.9', - 'pyramid_debugtoolbar', + 'pyramid', 'pyramid_jinja2', + 'pyramid_debugtoolbar', + 'waitress', + 'alembic', 'pyramid_retry', 'pyramid_tm', 'SQLAlchemy', 'transaction', 'zope.sqlalchemy', - 'waitress', ] tests_require = [ @@ -43,7 +43,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={ @@ -55,7 +55,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/installation/tests/__init__.py b/docs/tutorials/wiki2/src/installation/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki2/src/installation/tests/test_it.py index ce650ca7c..ea16534fc 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/installation/tests/test_it.py @@ -1,8 +1,9 @@ import unittest -import transaction from pyramid import testing +import transaction + def dummy_request(dbsession): return testing.DummyRequest(dbsession=dbsession) @@ -13,10 +14,10 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models') + self.config.include('tutorial.models') settings = self.config.get_settings() - from .models import ( + from tutorial.models import ( get_engine, get_session_factory, get_tm_session, @@ -28,11 +29,11 @@ class BaseTest(unittest.TestCase): self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models.meta import Base + from tutorial.models.meta import Base Base.metadata.create_all(self.engine) def tearDown(self): - from .models.meta import Base + from tutorial.models.meta import Base testing.tearDown() transaction.abort() @@ -45,13 +46,13 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models import MyModel + from tutorial.models import MyModel model = MyModel(name='one', value=55) self.session.add(model) def test_passing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') self.assertEqual(info['project'], 'myproj') @@ -60,6 +61,6 @@ class TestMyViewSuccessCondition(BaseTest): class TestMyViewFailureCondition(BaseTest): def test_failing_view(self): - from .views.default import my_view + from tutorial.views.default import my_view info = my_view(dummy_request(self.session)) self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/installation/tutorial/__init__.py b/docs/tutorials/wiki2/src/installation/tutorial/__init__.py index 28bd1f80d..5c2ba5cc0 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/installation/tutorial/pshell.py b/docs/tutorials/wiki2/src/installation/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/404.jinja2 index 1917f83c7..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 index 5d4313fe2..f5a086f0e 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="{{request.static_url('tutorial:static/pyramid-16x16.png')}}"> - <title>Cookiecutter Alchemy project for the Pyramid Web Framework</title> + <title>Cookiecutter Starter project for the Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 index d8b0a4232..f2e7283f8 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a Pyramid application generated by<br><span class="font-normal">Cookiecutter</span>.</p> </div> -{% endblock content %}
\ No newline at end of file +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py index ef69ff895..094b2f303 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py @@ -1,12 +1,12 @@ -from pyramid.response import Response from pyramid.view import view_config +from pyramid.response import Response from sqlalchemy.exc import DBAPIError from .. import models -@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +@view_config(route_name='home', renderer='tutorial:templates/mytemplate.jinja2') def my_view(request): try: query = request.dbsession.query(models.MyModel) @@ -21,7 +21,7 @@ Pyramid is having a problem using your SQL database. The problem might be caused by one of the following things: 1. You may need to initialize your database tables with `alembic`. - Check your README.txt for description and try to run it. + Check your README.txt for descriptions and try to run it. 2. Your database server may not be running. Check that the database server referred to by the "sqlalchemy.url" setting in diff --git a/docs/tutorials/wiki2/src/installation/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/installation/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/src/models/.coveragerc b/docs/tutorials/wiki2/src/models/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/models/.coveragerc +++ b/docs/tutorials/wiki2/src/models/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/models/MANIFEST.in b/docs/tutorials/wiki2/src/models/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/models/MANIFEST.in +++ b/docs/tutorials/wiki2/src/models/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index 564aefb56..f02c4b1b6 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -45,7 +45,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -70,6 +70,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini index 29cdda1e1..f8e83f21f 100644 --- a/docs/tutorials/wiki2/src/models/production.ini +++ b/docs/tutorials/wiki2/src/models/production.ini @@ -39,7 +39,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -64,6 +64,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/models/pytest.ini b/docs/tutorials/wiki2/src/models/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/models/pytest.ini +++ b/docs/tutorials/wiki2/src/models/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py index b9dc9d93f..60234751a 100644 --- a/docs/tutorials/wiki2/src/models/setup.py +++ b/docs/tutorials/wiki2/src/models/setup.py @@ -12,7 +12,7 @@ requires = [ 'alembic', 'bcrypt', 'plaster_pastedeploy', - 'pyramid >= 1.9', + 'pyramid', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', @@ -44,7 +44,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={ @@ -56,7 +56,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/models/tests/__init__.py b/docs/tutorials/wiki2/src/models/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/models/tests/test_it.py b/docs/tutorials/wiki2/src/models/tests/test_it.py new file mode 100644 index 000000000..ea16534fc --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tests/test_it.py @@ -0,0 +1,66 @@ +import unittest + +from pyramid import testing + +import transaction + + +def dummy_request(dbsession): + return testing.DummyRequest(dbsession=dbsession) + + +class BaseTest(unittest.TestCase): + def setUp(self): + self.config = testing.setUp(settings={ + 'sqlalchemy.url': 'sqlite:///:memory:' + }) + self.config.include('tutorial.models') + settings = self.config.get_settings() + + from tutorial.models import ( + get_engine, + get_session_factory, + get_tm_session, + ) + + self.engine = get_engine(settings) + session_factory = get_session_factory(self.engine) + + self.session = get_tm_session(session_factory, transaction.manager) + + def init_database(self): + from tutorial.models.meta import Base + Base.metadata.create_all(self.engine) + + def tearDown(self): + from tutorial.models.meta import Base + + testing.tearDown() + transaction.abort() + Base.metadata.drop_all(self.engine) + + +class TestMyViewSuccessCondition(BaseTest): + + def setUp(self): + super(TestMyViewSuccessCondition, self).setUp() + self.init_database() + + from tutorial.models import MyModel + + model = MyModel(name='one', value=55) + self.session.add(model) + + def test_passing_view(self): + from tutorial.views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info['one'].name, 'one') + self.assertEqual(info['project'], 'myproj') + + +class TestMyViewFailureCondition(BaseTest): + + def test_failing_view(self): + from tutorial.views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/models/tutorial/__init__.py b/docs/tutorials/wiki2/src/models/tutorial/__init__.py index 28bd1f80d..5c2ba5cc0 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/models/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/models/tutorial/pshell.py b/docs/tutorials/wiki2/src/models/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/models/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/404.jinja2 index 1917f83c7..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 index 5d4313fe2..f5a086f0e 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="{{request.static_url('tutorial:static/pyramid-16x16.png')}}"> - <title>Cookiecutter Alchemy project for the Pyramid Web Framework</title> + <title>Cookiecutter Starter project for the Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 index d8b0a4232..f2e7283f8 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a Pyramid application generated by<br><span class="font-normal">Cookiecutter</span>.</p> </div> -{% endblock content %}
\ No newline at end of file +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/models/tutorial/tests.py b/docs/tutorials/wiki2/src/models/tutorial/tests.py deleted file mode 100644 index ce650ca7c..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/tests.py +++ /dev/null @@ -1,65 +0,0 @@ -import unittest -import transaction - -from pyramid import testing - - -def dummy_request(dbsession): - return testing.DummyRequest(dbsession=dbsession) - - -class BaseTest(unittest.TestCase): - def setUp(self): - self.config = testing.setUp(settings={ - 'sqlalchemy.url': 'sqlite:///:memory:' - }) - self.config.include('.models') - settings = self.config.get_settings() - - from .models import ( - get_engine, - get_session_factory, - get_tm_session, - ) - - self.engine = get_engine(settings) - session_factory = get_session_factory(self.engine) - - self.session = get_tm_session(session_factory, transaction.manager) - - def init_database(self): - from .models.meta import Base - Base.metadata.create_all(self.engine) - - def tearDown(self): - from .models.meta import Base - - testing.tearDown() - transaction.abort() - Base.metadata.drop_all(self.engine) - - -class TestMyViewSuccessCondition(BaseTest): - - def setUp(self): - super(TestMyViewSuccessCondition, self).setUp() - self.init_database() - - from .models import MyModel - - model = MyModel(name='one', value=55) - self.session.add(model) - - def test_passing_view(self): - from .views.default import my_view - info = my_view(dummy_request(self.session)) - self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'myproj') - - -class TestMyViewFailureCondition(BaseTest): - - def test_failing_view(self): - from .views.default import my_view - info = my_view(dummy_request(self.session)) - self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/models/tutorial/views/default.py b/docs/tutorials/wiki2/src/models/tutorial/views/default.py index ef69ff895..094b2f303 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/models/tutorial/views/default.py @@ -1,12 +1,12 @@ -from pyramid.response import Response from pyramid.view import view_config +from pyramid.response import Response from sqlalchemy.exc import DBAPIError from .. import models -@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +@view_config(route_name='home', renderer='tutorial:templates/mytemplate.jinja2') def my_view(request): try: query = request.dbsession.query(models.MyModel) @@ -21,7 +21,7 @@ Pyramid is having a problem using your SQL database. The problem might be caused by one of the following things: 1. You may need to initialize your database tables with `alembic`. - Check your README.txt for description and try to run it. + Check your README.txt for descriptions and try to run it. 2. Your database server may not be running. Check that the database server referred to by the "sqlalchemy.url" setting in diff --git a/docs/tutorials/wiki2/src/models/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/models/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/models/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/src/tests/.coveragerc b/docs/tutorials/wiki2/src/tests/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/tests/.coveragerc +++ b/docs/tutorials/wiki2/src/tests/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/tests/MANIFEST.in b/docs/tutorials/wiki2/src/tests/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/tests/MANIFEST.in +++ b/docs/tutorials/wiki2/src/tests/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini index 8fbb5fd38..7fda4cb7b 100644 --- a/docs/tutorials/wiki2/src/tests/development.ini +++ b/docs/tutorials/wiki2/src/tests/development.ini @@ -47,7 +47,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -72,6 +72,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini index 9fef64f83..8e878a707 100644 --- a/docs/tutorials/wiki2/src/tests/production.ini +++ b/docs/tutorials/wiki2/src/tests/production.ini @@ -41,7 +41,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -66,6 +66,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/tests/pytest.ini b/docs/tutorials/wiki2/src/tests/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/tests/pytest.ini +++ b/docs/tutorials/wiki2/src/tests/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/tests/setup.py b/docs/tutorials/wiki2/src/tests/setup.py index f71998afc..500c5e599 100644 --- a/docs/tutorials/wiki2/src/tests/setup.py +++ b/docs/tutorials/wiki2/src/tests/setup.py @@ -13,7 +13,7 @@ requires = [ 'bcrypt', 'docutils', 'plaster_pastedeploy', - 'pyramid >= 1.9', + 'pyramid', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', @@ -45,7 +45,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={ @@ -57,7 +57,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/tests/tests/__init__.py b/docs/tutorials/wiki2/src/tests/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py b/docs/tutorials/wiki2/src/tests/tests/test_functional.py index 0250e71c9..0250e71c9 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_functional.py +++ b/docs/tutorials/wiki2/src/tests/tests/test_functional.py diff --git a/docs/tutorials/wiki2/src/tests/tests/test_initdb.py b/docs/tutorials/wiki2/src/tests/tests/test_initdb.py new file mode 100644 index 000000000..a66945ccc --- /dev/null +++ b/docs/tutorials/wiki2/src/tests/tests/test_initdb.py @@ -0,0 +1,10 @@ +import os +import unittest + + +class TestInitializeDB(unittest.TestCase): + + def test_usage(self): + from tutorial.scripts.initialize_db import main + with self.assertRaises(SystemExit): + main(argv=['foo']) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py b/docs/tutorials/wiki2/src/tests/tests/test_security.py index cbec6420d..9a1455ef9 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_security.py +++ b/docs/tutorials/wiki2/src/tests/tests/test_security.py @@ -8,16 +8,16 @@ class TestMyAuthenticationPolicy(unittest.TestCase): request = DummyRequest() request.user = None - from ..security import MyAuthenticationPolicy + from tutorial.security import MyAuthenticationPolicy policy = MyAuthenticationPolicy(None) self.assertEqual(policy.authenticated_userid(request), None) def test_authenticated_user(self): - from ..models import User + from tutorial.models import User request = DummyRequest() request.user = User() request.user.id = 'foo' - from ..security import MyAuthenticationPolicy + from tutorial.security import MyAuthenticationPolicy policy = MyAuthenticationPolicy(None) self.assertEqual(policy.authenticated_userid(request), 'foo') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py b/docs/tutorials/wiki2/src/tests/tests/test_user_model.py index 9490ac990..21904da6b 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_user_model.py +++ b/docs/tutorials/wiki2/src/tests/tests/test_user_model.py @@ -7,12 +7,12 @@ from pyramid import testing class BaseTest(unittest.TestCase): def setUp(self): - from ..models import get_tm_session + from tutorial.models import get_tm_session self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('..models') - self.config.include('..routes') + self.config.include('tutorial.models') + self.config.include('tutorial.routes') session_factory = self.config.registry['dbsession_factory'] self.session = get_tm_session(session_factory, transaction.manager) @@ -20,7 +20,7 @@ class BaseTest(unittest.TestCase): self.init_database() def init_database(self): - from ..models.meta import Base + from tutorial.models.meta import Base session_factory = self.config.registry['dbsession_factory'] engine = session_factory.kw['bind'] Base.metadata.create_all(engine) @@ -30,7 +30,7 @@ class BaseTest(unittest.TestCase): transaction.abort() def makeUser(self, name, role): - from ..models import User + from tutorial.models import User return User(name=name, role=role) diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_views.py b/docs/tutorials/wiki2/src/tests/tests/test_views.py index 2c945ab33..5c17457dd 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_views.py +++ b/docs/tutorials/wiki2/src/tests/tests/test_views.py @@ -10,12 +10,12 @@ def dummy_request(dbsession): class BaseTest(unittest.TestCase): def setUp(self): - from ..models import get_tm_session + from tutorial.models import get_tm_session self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('..models') - self.config.include('..routes') + self.config.include('tutorial.models') + self.config.include('tutorial.routes') session_factory = self.config.registry['dbsession_factory'] self.session = get_tm_session(session_factory, transaction.manager) @@ -23,7 +23,7 @@ class BaseTest(unittest.TestCase): self.init_database() def init_database(self): - from ..models.meta import Base + from tutorial.models.meta import Base session_factory = self.config.registry['dbsession_factory'] engine = session_factory.kw['bind'] Base.metadata.create_all(engine) @@ -33,20 +33,20 @@ class BaseTest(unittest.TestCase): transaction.abort() def makeUser(self, name, role, password='dummy'): - from ..models import User + from tutorial.models import User user = User(name=name, role=role) user.set_password(password) return user def makePage(self, name, data, creator): - from ..models import Page + from tutorial.models import Page return Page(name=name, data=data, creator=creator) class ViewWikiTests(unittest.TestCase): def setUp(self): self.config = testing.setUp() - self.config.include('..routes') + self.config.include('tutorial.routes') def tearDown(self): testing.tearDown() @@ -67,7 +67,7 @@ class ViewPageTests(BaseTest): return view_page(request) def test_it(self): - from ..routes import PageResource + from tutorial.routes import PageResource # add a page to the db user = self.makeUser('foo', 'editor') @@ -99,8 +99,8 @@ class AddPageTests(BaseTest): return add_page(request) def test_it_pageexists(self): - from ..models import Page - from ..routes import NewPage + from tutorial.models import Page + from tutorial.routes import NewPage request = testing.DummyRequest({'form.submitted': True, 'body': 'Hello yo!'}, dbsession=self.session) @@ -111,7 +111,7 @@ class AddPageTests(BaseTest): self.assertGreater(pagecount, 0) def test_it_notsubmitted(self): - from ..routes import NewPage + from tutorial.routes import NewPage request = dummy_request(self.session) request.user = self.makeUser('foo', 'editor') request.context = NewPage('AnotherPage') @@ -121,8 +121,8 @@ class AddPageTests(BaseTest): 'http://example.com/add_page/AnotherPage') def test_it_submitted(self): - from ..models import Page - from ..routes import NewPage + from tutorial.models import Page + from tutorial.routes import NewPage request = testing.DummyRequest({'form.submitted': True, 'body': 'Hello yo!'}, dbsession=self.session) @@ -139,7 +139,7 @@ class EditPageTests(BaseTest): return edit_page(request) def makeContext(self, page): - from ..routes import PageResource + from tutorial.routes import PageResource return PageResource(page) def test_it_notsubmitted(self): diff --git a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py index 5d4bae3d7..ce2e9f12a 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.include('.security') config.scan() diff --git a/docs/tutorials/wiki2/src/tests/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/tests/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/tests/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/tests/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/tests/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/tests/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/tests/tutorial/pshell.py b/docs/tutorials/wiki2/src/tests/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/tests/tutorial/templates/404.jinja2 index 37b0a16b6..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid tutorial wiki</span> <span class="smaller">(based on TurboGears 20-Minute Wiki)</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py b/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py deleted file mode 100644 index 72fbff04b..000000000 --- a/docs/tutorials/wiki2/src/tests/tutorial/tests/test_initdb.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import unittest - - -class TestInitializeDB(unittest.TestCase): - - def test_usage(self): - from ..scripts.initialize_db import main - with self.assertRaises(SystemExit): - main(argv=['foo']) - - def test_run(self): - from ..scripts.initialize_db import main - main(argv=['foo', 'development.ini']) - self.assertTrue(os.path.exists('tutorial.sqlite')) - os.remove('tutorial.sqlite') diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/auth.py b/docs/tutorials/wiki2/src/tests/tutorial/views/auth.py index 2b993b430..16fa616e5 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/views/auth.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/views/auth.py @@ -11,7 +11,7 @@ from pyramid.view import ( from ..models import User -@view_config(route_name='login', renderer='../templates/login.jinja2') +@view_config(route_name='login', renderer='tutorial:templates/login.jinja2') def login(request): next_url = request.params.get('next', request.referrer) if not next_url: diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py index ad8491b7b..de0bcd816 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/views/default.py @@ -15,7 +15,7 @@ def view_wiki(request): next_url = request.route_url('view_page', pagename='FrontPage') return HTTPFound(location=next_url) -@view_config(route_name='view_page', renderer='../templates/view.jinja2', +@view_config(route_name='view_page', renderer='tutorial:templates/view.jinja2', permission='view') def view_page(request): page = request.context.page @@ -35,7 +35,7 @@ def view_page(request): edit_url = request.route_url('edit_page', pagename=page.name) return dict(page=page, content=content, edit_url=edit_url) -@view_config(route_name='edit_page', renderer='../templates/edit.jinja2', +@view_config(route_name='edit_page', renderer='tutorial:templates/edit.jinja2', permission='edit') def edit_page(request): page = request.context.page @@ -49,7 +49,7 @@ def edit_page(request): save_url=request.route_url('edit_page', pagename=page.name), ) -@view_config(route_name='add_page', renderer='../templates/edit.jinja2', +@view_config(route_name='add_page', renderer='tutorial:templates/edit.jinja2', permission='create') def add_page(request): pagename = request.context.pagename diff --git a/docs/tutorials/wiki2/src/tests/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/tests/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/tests/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/src/views/.coveragerc b/docs/tutorials/wiki2/src/views/.coveragerc index a1d87d03d..5db0e79cf 100644 --- a/docs/tutorials/wiki2/src/views/.coveragerc +++ b/docs/tutorials/wiki2/src/views/.coveragerc @@ -1,3 +1,2 @@ [run] source = tutorial -omit = tutorial/test* diff --git a/docs/tutorials/wiki2/src/views/MANIFEST.in b/docs/tutorials/wiki2/src/views/MANIFEST.in index 05cc195d9..b4624fd1c 100644 --- a/docs/tutorials/wiki2/src/views/MANIFEST.in +++ b/docs/tutorials/wiki2/src/views/MANIFEST.in @@ -1,2 +1,5 @@ include *.txt *.ini *.cfg *.rst recursive-include tutorial *.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/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index 564aefb56..f02c4b1b6 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -45,7 +45,7 @@ listen = localhost:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -70,6 +70,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = INFO +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini index 29cdda1e1..f8e83f21f 100644 --- a/docs/tutorials/wiki2/src/views/production.ini +++ b/docs/tutorials/wiki2/src/views/production.ini @@ -39,7 +39,7 @@ listen = *:6543 ### [loggers] -keys = root, tutorial, sqlalchemy +keys = root, tutorial, sqlalchemy, alembic [handlers] keys = console @@ -64,6 +64,11 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) +[logger_alembic] +level = WARN +handlers = +qualname = alembic + [handler_console] class = StreamHandler args = (sys.stderr,) diff --git a/docs/tutorials/wiki2/src/views/pytest.ini b/docs/tutorials/wiki2/src/views/pytest.ini index a3489cdf8..42c3259f9 100644 --- a/docs/tutorials/wiki2/src/views/pytest.ini +++ b/docs/tutorials/wiki2/src/views/pytest.ini @@ -1,3 +1,6 @@ [pytest] -testpaths = tutorial -python_files = test*.py +addopts = --strict + +testpaths = + tutorial + tests diff --git a/docs/tutorials/wiki2/src/views/setup.py b/docs/tutorials/wiki2/src/views/setup.py index f71998afc..500c5e599 100644 --- a/docs/tutorials/wiki2/src/views/setup.py +++ b/docs/tutorials/wiki2/src/views/setup.py @@ -13,7 +13,7 @@ requires = [ 'bcrypt', 'docutils', 'plaster_pastedeploy', - 'pyramid >= 1.9', + 'pyramid', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', @@ -45,7 +45,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={ @@ -57,7 +57,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', + 'initialize_tutorial_db=tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/views/tests/__init__.py b/docs/tutorials/wiki2/src/views/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tests/__init__.py diff --git a/docs/tutorials/wiki2/src/views/tests/test_it.py b/docs/tutorials/wiki2/src/views/tests/test_it.py new file mode 100644 index 000000000..ea16534fc --- /dev/null +++ b/docs/tutorials/wiki2/src/views/tests/test_it.py @@ -0,0 +1,66 @@ +import unittest + +from pyramid import testing + +import transaction + + +def dummy_request(dbsession): + return testing.DummyRequest(dbsession=dbsession) + + +class BaseTest(unittest.TestCase): + def setUp(self): + self.config = testing.setUp(settings={ + 'sqlalchemy.url': 'sqlite:///:memory:' + }) + self.config.include('tutorial.models') + settings = self.config.get_settings() + + from tutorial.models import ( + get_engine, + get_session_factory, + get_tm_session, + ) + + self.engine = get_engine(settings) + session_factory = get_session_factory(self.engine) + + self.session = get_tm_session(session_factory, transaction.manager) + + def init_database(self): + from tutorial.models.meta import Base + Base.metadata.create_all(self.engine) + + def tearDown(self): + from tutorial.models.meta import Base + + testing.tearDown() + transaction.abort() + Base.metadata.drop_all(self.engine) + + +class TestMyViewSuccessCondition(BaseTest): + + def setUp(self): + super(TestMyViewSuccessCondition, self).setUp() + self.init_database() + + from tutorial.models import MyModel + + model = MyModel(name='one', value=55) + self.session.add(model) + + def test_passing_view(self): + from tutorial.views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info['one'].name, 'one') + self.assertEqual(info['project'], 'myproj') + + +class TestMyViewFailureCondition(BaseTest): + + def test_failing_view(self): + from tutorial.views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/views/tutorial/__init__.py b/docs/tutorials/wiki2/src/views/tutorial/__init__.py index 28bd1f80d..5c2ba5cc0 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/views/tutorial/__init__.py @@ -5,8 +5,8 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ with Configurator(settings=settings) as config: - config.include('pyramid_jinja2') config.include('.models') + config.include('pyramid_jinja2') config.include('.routes') config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/views/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/views/tutorial/alembic/script.py.mako index 2c0156303..535780d13 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/alembic/script.py.mako +++ b/docs/tutorials/wiki2/src/views/tutorial/alembic/script.py.mako @@ -15,10 +15,8 @@ down_revision = ${repr(down_revision)} branch_labels = ${repr(branch_labels)} depends_on = ${repr(depends_on)} - def upgrade(): ${upgrades if upgrades else "pass"} - def downgrade(): ${downgrades if downgrades else "pass"} diff --git a/docs/tutorials/wiki2/src/views/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/views/tutorial/alembic/versions/README.txt index 09ed32c8d..b0d704d6a 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/alembic/versions/README.txt +++ b/docs/tutorials/wiki2/src/views/tutorial/alembic/versions/README.txt @@ -1 +1 @@ -Placeholder for alembic versions
\ No newline at end of file +Placeholder for alembic versions diff --git a/docs/tutorials/wiki2/src/views/tutorial/pshell.py b/docs/tutorials/wiki2/src/views/tutorial/pshell.py index 108c04d5e..b0847ee90 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/pshell.py +++ b/docs/tutorials/wiki2/src/views/tutorial/pshell.py @@ -1,5 +1,6 @@ from . import models + def setup(env): request = env['request'] diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/views/tutorial/templates/404.jinja2 index 37b0a16b6..aaf12413f 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %} <div class="content"> - <h1><span class="font-semi-bold">Pyramid tutorial wiki</span> <span class="smaller">(based on TurboGears 20-Minute Wiki)</span></h1> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter project</span></h1> <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p> </div> {% endblock content %} diff --git a/docs/tutorials/wiki2/src/views/tutorial/tests.py b/docs/tutorials/wiki2/src/views/tutorial/tests.py deleted file mode 100644 index ce650ca7c..000000000 --- a/docs/tutorials/wiki2/src/views/tutorial/tests.py +++ /dev/null @@ -1,65 +0,0 @@ -import unittest -import transaction - -from pyramid import testing - - -def dummy_request(dbsession): - return testing.DummyRequest(dbsession=dbsession) - - -class BaseTest(unittest.TestCase): - def setUp(self): - self.config = testing.setUp(settings={ - 'sqlalchemy.url': 'sqlite:///:memory:' - }) - self.config.include('.models') - settings = self.config.get_settings() - - from .models import ( - get_engine, - get_session_factory, - get_tm_session, - ) - - self.engine = get_engine(settings) - session_factory = get_session_factory(self.engine) - - self.session = get_tm_session(session_factory, transaction.manager) - - def init_database(self): - from .models.meta import Base - Base.metadata.create_all(self.engine) - - def tearDown(self): - from .models.meta import Base - - testing.tearDown() - transaction.abort() - Base.metadata.drop_all(self.engine) - - -class TestMyViewSuccessCondition(BaseTest): - - def setUp(self): - super(TestMyViewSuccessCondition, self).setUp() - self.init_database() - - from .models import MyModel - - model = MyModel(name='one', value=55) - self.session.add(model) - - def test_passing_view(self): - from .views.default import my_view - info = my_view(dummy_request(self.session)) - self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'myproj') - - -class TestMyViewFailureCondition(BaseTest): - - def test_failing_view(self): - from .views.default import my_view - info = my_view(dummy_request(self.session)) - self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/views/tutorial/views/default.py b/docs/tutorials/wiki2/src/views/tutorial/views/default.py index 5e28b64fd..867ba3f6c 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/views/tutorial/views/default.py @@ -19,7 +19,7 @@ def view_wiki(request): next_url = request.route_url('view_page', pagename='FrontPage') return HTTPFound(location=next_url) -@view_config(route_name='view_page', renderer='../templates/view.jinja2') +@view_config(route_name='view_page', renderer='tutorial:templates/view.jinja2') def view_page(request): pagename = request.matchdict['pagename'] page = request.dbsession.query(models.Page).filter_by(name=pagename).first() @@ -41,7 +41,7 @@ def view_page(request): edit_url = request.route_url('edit_page', pagename=page.name) return dict(page=page, content=content, edit_url=edit_url) -@view_config(route_name='edit_page', renderer='../templates/edit.jinja2') +@view_config(route_name='edit_page', renderer='tutorial:templates/edit.jinja2') def edit_page(request): pagename = request.matchdict['pagename'] page = request.dbsession.query(models.Page).filter_by(name=pagename).one() @@ -55,7 +55,7 @@ def edit_page(request): save_url=request.route_url('edit_page', pagename=page.name), ) -@view_config(route_name='add_page', renderer='../templates/edit.jinja2') +@view_config(route_name='add_page', renderer='tutorial:templates/edit.jinja2') def add_page(request): pagename = request.matchdict['pagename'] if request.dbsession.query(models.Page).filter_by(name=pagename).count() > 0: diff --git a/docs/tutorials/wiki2/src/views/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/views/tutorial/views/notfound.py index 69d6e2804..740712d9f 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/views/notfound.py +++ b/docs/tutorials/wiki2/src/views/tutorial/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='tutorial:templates/404.jinja2') def notfound_view(request): request.response.status = 404 return {} diff --git a/docs/tutorials/wiki2/tests.rst b/docs/tutorials/wiki2/tests.rst index 941a50928..c7d1a0f31 100644 --- a/docs/tutorials/wiki2/tests.rst +++ b/docs/tutorials/wiki2/tests.rst @@ -5,18 +5,15 @@ Adding Tests ============ We will now add tests for the models and views as well as a few functional -tests in a new ``tests`` subpackage. Tests ensure that an application works, +tests in a new ``tests`` package. Tests ensure that an application works, and that it continues to work when changes are made in the future. -The file ``tests.py`` was generated from choosing the ``sqlalchemy`` backend -option, but it is a common practice to put tests into a ``tests`` -subpackage, especially as projects grow in size and complexity. Each module in -the test subpackage should contain tests for its corresponding module in our -application. Each corresponding pair of modules should have the same names, -except the test module should have the prefix ``test_``. +The file ``tests/test_it.py`` at the root of our project directory was generated from choosing the ``sqlalchemy`` backend option. +It is a common practice to put tests into a ``tests`` package alongside the application package, especially as projects grow in size and complexity. +Each module in the test package should contain tests for its corresponding module in our application. +Each corresponding pair of modules should have the same names, except the test module should have the prefix ``test_``. -Start by deleting ``tests.py``, then create a new directory to contain our new -tests as well as a new empty file ``tests/__init__.py``. +Start by deleting ``tests/test_it.py``. .. warning:: @@ -47,36 +44,36 @@ user cannot edit pages that it didn't create but the ``editor`` user can, and so on. -View the results of all our edits to ``tests`` subpackage -========================================================= +View the results of all our edits to ``tests`` package +====================================================== -Create ``tutorial/tests/test_views.py`` such that it appears as follows: +Create ``tests/test_views.py`` such that it appears as follows: -.. literalinclude:: src/tests/tutorial/tests/test_views.py +.. literalinclude:: src/tests/tests/test_views.py :linenos: :language: python -Create ``tutorial/tests/test_functional.py`` such that it appears as follows: +Create ``tests/test_functional.py`` such that it appears as follows: -.. literalinclude:: src/tests/tutorial/tests/test_functional.py +.. literalinclude:: src/tests/tests/test_functional.py :linenos: :language: python -Create ``tutorial/tests/test_initdb.py`` such that it appears as follows: +Create ``tests/test_initdb.py`` such that it appears as follows: -.. literalinclude:: src/tests/tutorial/tests/test_initdb.py +.. literalinclude:: src/tests/tests/test_initdb.py :linenos: :language: python -Create ``tutorial/tests/test_security.py`` such that it appears as follows: +Create ``tests/test_security.py`` such that it appears as follows: -.. literalinclude:: src/tests/tutorial/tests/test_security.py +.. literalinclude:: src/tests/tests/test_security.py :linenos: :language: python -Create ``tutorial/tests/test_user_model.py`` such that it appears as follows: +Create ``tests/test_user_model.py`` such that it appears as follows: -.. literalinclude:: src/tests/tutorial/tests/test_user_model.py +.. literalinclude:: src/tests/tests/test_user_model.py :linenos: :language: python @@ -112,7 +109,7 @@ The expected result should look like the following: .. code-block:: text - ................................ - 32 passed in 9.90 seconds + ............................... + 31 passed in 8.85 seconds .. _webtest: https://docs.pylonsproject.org/projects/webtest/en/latest/ diff --git a/pyproject.toml b/pyproject.toml index d8ec559df..6e28b2347 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,12 @@ exclude = ''' [tool.isort] multi_line_output = 3 include_trailing_comma = true -force_grid_wrap = 0 +force_grid_wrap = false combine_as_imports = true +use_parenthesis = true line_length = 79 +force_sort_within_sections = true +no_lines_before = "THIRDPARTY" +sections = "FUTURE,THIRDPARTY,FIRSTPARTY,LOCALFOLDER" +default_section = "THIRDPARTY" +known_first_party = "pyramid" diff --git a/src/pyramid/asset.py b/src/pyramid/asset.py index a32babe6c..b657bf68f 100644 --- a/src/pyramid/asset.py +++ b/src/pyramid/asset.py @@ -1,7 +1,7 @@ import os import pkg_resources -from pyramid.path import package_path, package_name +from pyramid.path import package_name, package_path def resolve_asset_spec(spec, pname='__main__'): diff --git a/src/pyramid/authentication.py b/src/pyramid/authentication.py index 14a4ad210..2d194e309 100644 --- a/src/pyramid/authentication.py +++ b/src/pyramid/authentication.py @@ -1,24 +1,24 @@ +import base64 import binascii -from codecs import utf_8_decode -from codecs import utf_8_encode +from codecs import utf_8_decode, utf_8_encode from collections import namedtuple import hashlib -import base64 import re import time as time_mod from urllib.parse import quote, unquote import warnings - -from zope.interface import implementer - from webob.cookies import CookieProfile +from zope.interface import implementer from pyramid.interfaces import IAuthenticationPolicy, IDebugLogger - from pyramid.security import Authenticated, Everyone - -from pyramid.util import strings_differ, bytes_, ascii_, text_ -from pyramid.util import SimpleSerializer +from pyramid.util import ( + SimpleSerializer, + ascii_, + bytes_, + strings_differ, + text_, +) VALID_TOKEN = re.compile(r"^[A-Za-z][A-Za-z0-9+_-]*$") diff --git a/src/pyramid/authorization.py b/src/pyramid/authorization.py index 498938fd5..b7c5834f9 100644 --- a/src/pyramid/authorization.py +++ b/src/pyramid/authorization.py @@ -1,11 +1,8 @@ from zope.interface import implementer from pyramid.interfaces import IAuthorizationPolicy - from pyramid.location import lineage - from pyramid.security import ACLAllowed, ACLDenied, Allow, Deny, Everyone - from pyramid.util import is_nonstr_iter diff --git a/src/pyramid/config/__init__.py b/src/pyramid/config/__init__.py index 4e22b946e..3d05617ca 100644 --- a/src/pyramid/config/__init__.py +++ b/src/pyramid/config/__init__.py @@ -3,49 +3,20 @@ import logging import os import threading import venusian - from webob.exc import WSGIHTTPException as WebobWSGIHTTPException -from pyramid.interfaces import ( - IDebugLogger, - IExceptionResponse, - PHASE0_CONFIG, - PHASE1_CONFIG, - PHASE2_CONFIG, - PHASE3_CONFIG, -) - from pyramid.asset import resolve_asset_spec - from pyramid.authorization import ACLAuthorizationPolicy - -from pyramid.events import ApplicationCreated - -from pyramid.exceptions import ConfigurationError - -from pyramid.httpexceptions import default_exceptionresponse_view - -from pyramid.path import caller_package, package_of - -from pyramid.registry import Introspectable, Introspector, Registry - -from pyramid.router import Router - -from pyramid.settings import aslist - -from pyramid.threadlocal import manager - -from pyramid.util import WeakOrderedSet, get_callable_name, object_description - -from pyramid.config.actions import action_method, ActionState -from pyramid.config.predicates import not_ - -from pyramid.config.actions import ActionConfiguratorMixin +from pyramid.config.actions import ( + ActionConfiguratorMixin, + ActionState, + action_method, +) from pyramid.config.adapters import AdaptersConfiguratorMixin from pyramid.config.assets import AssetsConfiguratorMixin from pyramid.config.factories import FactoriesConfiguratorMixin from pyramid.config.i18n import I18NConfiguratorMixin -from pyramid.config.predicates import PredicateConfiguratorMixin +from pyramid.config.predicates import PredicateConfiguratorMixin, not_ from pyramid.config.rendering import RenderingConfiguratorMixin from pyramid.config.routes import RoutesConfiguratorMixin from pyramid.config.security import SecurityConfiguratorMixin @@ -54,8 +25,23 @@ from pyramid.config.testing import TestingConfiguratorMixin from pyramid.config.tweens import TweensConfiguratorMixin from pyramid.config.views import ViewsConfiguratorMixin from pyramid.config.zca import ZCAConfiguratorMixin - -from pyramid.path import DottedNameResolver +from pyramid.events import ApplicationCreated +from pyramid.exceptions import ConfigurationError +from pyramid.httpexceptions import default_exceptionresponse_view +from pyramid.interfaces import ( + PHASE0_CONFIG, + PHASE1_CONFIG, + PHASE2_CONFIG, + PHASE3_CONFIG, + IDebugLogger, + IExceptionResponse, +) +from pyramid.path import DottedNameResolver, caller_package, package_of +from pyramid.registry import Introspectable, Introspector, Registry +from pyramid.router import Router +from pyramid.settings import aslist +from pyramid.threadlocal import manager +from pyramid.util import WeakOrderedSet, get_callable_name, object_description _marker = object() diff --git a/src/pyramid/config/actions.py b/src/pyramid/config/actions.py index 29d06d716..7a0ec500a 100644 --- a/src/pyramid/config/actions.py +++ b/src/pyramid/config/actions.py @@ -12,8 +12,7 @@ from pyramid.exceptions import ( ) from pyramid.interfaces import IActionInfo from pyramid.registry import undefer -from pyramid.util import is_nonstr_iter -from pyramid.util import reraise +from pyramid.util import is_nonstr_iter, reraise class ActionConfiguratorMixin(object): diff --git a/src/pyramid/config/adapters.py b/src/pyramid/config/adapters.py index 54c239ab3..867b5d33f 100644 --- a/src/pyramid/config/adapters.py +++ b/src/pyramid/config/adapters.py @@ -1,14 +1,10 @@ -from webob import Response as WebobResponse - from functools import update_wrapper - +from webob import Response as WebobResponse from zope.interface import Interface -from pyramid.interfaces import IResponse, ITraverser, IResourceURL - -from pyramid.util import takes_one_arg - from pyramid.config.actions import action_method +from pyramid.interfaces import IResourceURL, IResponse, ITraverser +from pyramid.util import takes_one_arg class AdaptersConfiguratorMixin(object): diff --git a/src/pyramid/config/assets.py b/src/pyramid/config/assets.py index e505fd204..8257a34a7 100644 --- a/src/pyramid/config/assets.py +++ b/src/pyramid/config/assets.py @@ -1,16 +1,13 @@ import os import pkg_resources import sys - from zope.interface import implementer -from pyramid.interfaces import IPackageOverrides, PHASE1_CONFIG - +from pyramid.config.actions import action_method from pyramid.exceptions import ConfigurationError +from pyramid.interfaces import PHASE1_CONFIG, IPackageOverrides from pyramid.threadlocal import get_current_registry -from pyramid.config.actions import action_method - class OverrideProvider(pkg_resources.DefaultProvider): def __init__(self, module): diff --git a/src/pyramid/config/factories.py b/src/pyramid/config/factories.py index 16211989f..ad64f5aaf 100644 --- a/src/pyramid/config/factories.py +++ b/src/pyramid/config/factories.py @@ -1,21 +1,18 @@ from zope.interface import implementer +from pyramid.config.actions import action_method from pyramid.interfaces import ( IDefaultRootFactory, IExecutionPolicy, + IRequestExtensions, IRequestFactory, IResponseFactory, - IRequestExtensions, IRootFactory, ISessionFactory, ) - from pyramid.router import default_execution_policy from pyramid.traversal import DefaultRootFactory - -from pyramid.util import get_callable_name, InstancePropertyHelper - -from pyramid.config.actions import action_method +from pyramid.util import InstancePropertyHelper, get_callable_name class FactoriesConfiguratorMixin(object): diff --git a/src/pyramid/config/i18n.py b/src/pyramid/config/i18n.py index 92c324ff7..3db0d1bf5 100644 --- a/src/pyramid/config/i18n.py +++ b/src/pyramid/config/i18n.py @@ -1,10 +1,8 @@ -from pyramid.interfaces import ILocaleNegotiator, ITranslationDirectories - +from pyramid.config.actions import action_method from pyramid.exceptions import ConfigurationError +from pyramid.interfaces import ILocaleNegotiator, ITranslationDirectories from pyramid.path import AssetResolver -from pyramid.config.actions import action_method - class I18NConfiguratorMixin(object): @action_method diff --git a/src/pyramid/config/predicates.py b/src/pyramid/config/predicates.py index ffdff5c21..2868ea580 100644 --- a/src/pyramid/config/predicates.py +++ b/src/pyramid/config/predicates.py @@ -2,12 +2,10 @@ from hashlib import md5 from webob.acceptparse import Accept from pyramid.exceptions import ConfigurationError -from pyramid.interfaces import IPredicateList, PHASE1_CONFIG +from pyramid.interfaces import PHASE1_CONFIG, IPredicateList from pyramid.predicates import Notted from pyramid.registry import predvalseq -from pyramid.util import TopologicalSorter -from pyramid.util import is_nonstr_iter, bytes_ - +from pyramid.util import TopologicalSorter, bytes_, is_nonstr_iter MAX_ORDER = 1 << 30 DEFAULT_PHASH = md5().hexdigest() diff --git a/src/pyramid/config/rendering.py b/src/pyramid/config/rendering.py index 7e5b767d9..c1d5e803e 100644 --- a/src/pyramid/config/rendering.py +++ b/src/pyramid/config/rendering.py @@ -1,7 +1,6 @@ -from pyramid.interfaces import IRendererFactory, PHASE1_CONFIG - from pyramid import renderers from pyramid.config.actions import action_method +from pyramid.interfaces import PHASE1_CONFIG, IRendererFactory DEFAULT_RENDERERS = ( ('json', renderers.json_renderer_factory), diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py index 25af9627d..44fbb9c46 100644 --- a/src/pyramid/config/routes.py +++ b/src/pyramid/config/routes.py @@ -2,23 +2,20 @@ import contextlib from urllib.parse import urlparse import warnings +from pyramid.config.actions import action_method +from pyramid.config.predicates import normalize_accept_offer, predvalseq +from pyramid.exceptions import ConfigurationError from pyramid.interfaces import ( + PHASE2_CONFIG, IRequest, IRouteRequest, IRoutesMapper, - PHASE2_CONFIG, ) - -from pyramid.exceptions import ConfigurationError import pyramid.predicates from pyramid.request import route_request_iface from pyramid.urldispatch import RoutesMapper - from pyramid.util import as_sorted_tuple, is_nonstr_iter -from pyramid.config.actions import action_method -from pyramid.config.predicates import normalize_accept_offer, predvalseq - class RoutesConfiguratorMixin(object): @action_method diff --git a/src/pyramid/config/security.py b/src/pyramid/config/security.py index 7d6703b07..182656e7c 100644 --- a/src/pyramid/config/security.py +++ b/src/pyramid/config/security.py @@ -1,23 +1,21 @@ import warnings from zope.interface import implementer +from pyramid.config.actions import action_method +from pyramid.csrf import LegacySessionCSRFStoragePolicy +from pyramid.exceptions import ConfigurationError from pyramid.interfaces import ( - IAuthorizationPolicy, + PHASE1_CONFIG, + PHASE2_CONFIG, IAuthenticationPolicy, + IAuthorizationPolicy, ICSRFStoragePolicy, IDefaultCSRFOptions, IDefaultPermission, ISecurityPolicy, - PHASE1_CONFIG, - PHASE2_CONFIG, ) - -from pyramid.csrf import LegacySessionCSRFStoragePolicy -from pyramid.exceptions import ConfigurationError -from pyramid.util import as_sorted_tuple from pyramid.security import LegacySecurityPolicy - -from pyramid.config.actions import action_method +from pyramid.util import as_sorted_tuple class SecurityConfiguratorMixin(object): diff --git a/src/pyramid/config/testing.py b/src/pyramid/config/testing.py index f8d81f3d3..ea3f92d17 100644 --- a/src/pyramid/config/testing.py +++ b/src/pyramid/config/testing.py @@ -1,13 +1,10 @@ from zope.interface import Interface -from pyramid.interfaces import ITraverser, ISecurityPolicy, IRendererFactory - +from pyramid.config.actions import action_method +from pyramid.interfaces import IRendererFactory, ISecurityPolicy, ITraverser from pyramid.renderers import RendererHelper - from pyramid.traversal import split_path_info -from pyramid.config.actions import action_method - class TestingConfiguratorMixin(object): # testing API diff --git a/src/pyramid/config/tweens.py b/src/pyramid/config/tweens.py index feb4a3230..02255a4b6 100644 --- a/src/pyramid/config/tweens.py +++ b/src/pyramid/config/tweens.py @@ -1,19 +1,15 @@ from zope.interface import implementer -from pyramid.interfaces import ITweens - +from pyramid.config.actions import action_method from pyramid.exceptions import ConfigurationError - -from pyramid.tweens import MAIN, INGRESS, EXCVIEW - +from pyramid.interfaces import ITweens +from pyramid.tweens import EXCVIEW, INGRESS, MAIN from pyramid.util import ( + TopologicalSorter, is_nonstr_iter, is_string_or_iterable, - TopologicalSorter, ) -from pyramid.config.actions import action_method - class TweensConfiguratorMixin(object): def add_tween(self, tween_factory, under=None, over=None): diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py index 3fc6a4a58..2cc5e8144 100644 --- a/src/pyramid/config/views.py +++ b/src/pyramid/config/views.py @@ -1,19 +1,36 @@ import functools import inspect -import posixpath import operator import os -import warnings - +import posixpath from urllib.parse import quote, urljoin, urlparse, urlunparse +import warnings from webob.acceptparse import Accept from zope.interface import Interface, implementedBy, implementer from zope.interface.interfaces import IInterface +from pyramid import renderers +from pyramid.asset import resolve_asset_spec +from pyramid.config.actions import action_method +from pyramid.config.predicates import ( + DEFAULT_PHASH, + MAX_ORDER, + normalize_accept_offer, + predvalseq, + sort_accept_offers, +) +from pyramid.decorator import reify +from pyramid.exceptions import ConfigurationError, PredicateMismatch +from pyramid.httpexceptions import ( + HTTPForbidden, + HTTPNotFound, + default_exceptionresponse_view, +) from pyramid.interfaces import ( + PHASE1_CONFIG, IAcceptOrder, - IExceptionViewClassifier, IException, + IExceptionViewClassifier, IMultiView, IPackageOverrides, IRendererFactory, @@ -24,64 +41,33 @@ from pyramid.interfaces import ( IStaticURLInfo, IView, IViewClassifier, - IViewDerivers, IViewDeriverInfo, + IViewDerivers, IViewMapperFactory, - PHASE1_CONFIG, -) - -from pyramid import renderers - -from pyramid.asset import resolve_asset_spec - -from pyramid.decorator import reify - -from pyramid.exceptions import ConfigurationError, PredicateMismatch - -from pyramid.httpexceptions import ( - HTTPForbidden, - HTTPNotFound, - default_exceptionresponse_view, ) - +import pyramid.predicates from pyramid.registry import Deferred - from pyramid.security import NO_PERMISSION_REQUIRED from pyramid.static import static_view - from pyramid.url import parse_url_overrides - -from pyramid.view import AppendSlashNotFoundViewFactory - from pyramid.util import ( + WIN, + TopologicalSorter, as_sorted_tuple, is_nonstr_iter, - TopologicalSorter, - WIN, ) - -import pyramid.predicates +from pyramid.view import AppendSlashNotFoundViewFactory import pyramid.viewderivers - from pyramid.viewderivers import ( INGRESS, VIEW, + DefaultViewMapper, preserve_view_attrs, - view_description, requestonly, - DefaultViewMapper, + view_description, wraps_view, ) -from pyramid.config.actions import action_method -from pyramid.config.predicates import ( - DEFAULT_PHASH, - MAX_ORDER, - normalize_accept_offer, - predvalseq, - sort_accept_offers, -) - DefaultViewMapper = DefaultViewMapper # bw-compat preserve_view_attrs = preserve_view_attrs # bw-compat requestonly = requestonly # bw-compat diff --git a/src/pyramid/csrf.py b/src/pyramid/csrf.py index f9914e852..8e56c56fc 100644 --- a/src/pyramid/csrf.py +++ b/src/pyramid/csrf.py @@ -1,18 +1,16 @@ from urllib.parse import urlparse import uuid - from webob.cookies import CookieProfile from zope.interface import implementer - from pyramid.exceptions import BadCSRFOrigin, BadCSRFToken from pyramid.interfaces import ICSRFStoragePolicy from pyramid.settings import aslist from pyramid.util import ( SimpleSerializer, + bytes_, is_same_domain, strings_differ, - bytes_, text_, ) diff --git a/src/pyramid/encode.py b/src/pyramid/encode.py index ed8e177b8..b6030ed58 100644 --- a/src/pyramid/encode.py +++ b/src/pyramid/encode.py @@ -1,5 +1,4 @@ -from urllib.parse import quote as _url_quote -from urllib.parse import quote_plus as _quote_plus +from urllib.parse import quote as _url_quote, quote_plus as _quote_plus from pyramid.util import is_nonstr_iter diff --git a/src/pyramid/events.py b/src/pyramid/events.py index fb3730f63..8186cb327 100644 --- a/src/pyramid/events.py +++ b/src/pyramid/events.py @@ -1,14 +1,13 @@ import venusian - -from zope.interface import implementer, Interface +from zope.interface import Interface, implementer from pyramid.interfaces import ( - IContextFound, - INewRequest, - INewResponse, IApplicationCreated, IBeforeRender, IBeforeTraversal, + IContextFound, + INewRequest, + INewResponse, ) diff --git a/src/pyramid/exceptions.py b/src/pyramid/exceptions.py index 92a0098e0..122209d48 100644 --- a/src/pyramid/exceptions.py +++ b/src/pyramid/exceptions.py @@ -1,4 +1,4 @@ -from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound, HTTPForbidden +from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPNotFound NotFound = HTTPNotFound # bw compat Forbidden = HTTPForbidden # bw compat diff --git a/src/pyramid/httpexceptions.py b/src/pyramid/httpexceptions.py index c9fdfe04b..51c2e90a0 100644 --- a/src/pyramid/httpexceptions.py +++ b/src/pyramid/httpexceptions.py @@ -129,13 +129,10 @@ subclasses have one additional keyword argument: ``location``, which indicates the location to which to redirect. """ import json - from string import Template - -from zope.interface import implementer - from webob import html_escape as _html_escape from webob.acceptparse import create_accept_header +from zope.interface import implementer from pyramid.interfaces import IExceptionResponse from pyramid.response import Response diff --git a/src/pyramid/i18n.py b/src/pyramid/i18n.py index a20503be2..b9e00b54b 100644 --- a/src/pyramid/i18n.py +++ b/src/pyramid/i18n.py @@ -1,21 +1,15 @@ import gettext import os - -from translationstring import ( - Translator, - Pluralizer, - TranslationString, # API - TranslationStringFactory, # API -) +from translationstring import Pluralizer, Translator +from translationstring import TranslationString # API +from translationstring import TranslationStringFactory # API from pyramid.decorator import reify - from pyramid.interfaces import ( + ILocaleNegotiator, ILocalizer, ITranslationDirectories, - ILocaleNegotiator, ) - from pyramid.threadlocal import get_current_registry TranslationString = TranslationString # PyFlakes diff --git a/src/pyramid/path.py b/src/pyramid/path.py index 55ed4df2e..e3f9c8c49 100644 --- a/src/pyramid/path.py +++ b/src/pyramid/path.py @@ -2,7 +2,6 @@ from importlib.machinery import SOURCE_SUFFIXES import os import pkg_resources import sys - from zope.interface import implementer from pyramid.interfaces import IAssetDescriptor diff --git a/src/pyramid/predicates.py b/src/pyramid/predicates.py index 32c6a4089..e0bd189c5 100644 --- a/src/pyramid/predicates.py +++ b/src/pyramid/predicates.py @@ -1,13 +1,11 @@ import re from pyramid.exceptions import ConfigurationError - from pyramid.traversal import ( find_interface, - traversal_path, resource_path_tuple, + traversal_path, ) - from pyramid.urldispatch import _compile_route from pyramid.util import as_sorted_tuple, is_nonstr_iter, object_description diff --git a/src/pyramid/registry.py b/src/pyramid/registry.py index 7b2547dd7..680669602 100644 --- a/src/pyramid/registry.py +++ b/src/pyramid/registry.py @@ -1,13 +1,10 @@ import operator import threading - from zope.interface import implementer from zope.interface.registry import Components from pyramid.decorator import reify - -from pyramid.interfaces import IIntrospector, IIntrospectable, ISettings - +from pyramid.interfaces import IIntrospectable, IIntrospector, ISettings from pyramid.path import CALLER_PACKAGE, caller_package diff --git a/src/pyramid/renderers.py b/src/pyramid/renderers.py index 832369fd4..9f6c50936 100644 --- a/src/pyramid/renderers.py +++ b/src/pyramid/renderers.py @@ -2,21 +2,15 @@ from functools import partial import json import os import re - from zope.interface import implementer, providedBy from zope.interface.registry import Components -from pyramid.interfaces import IJSONAdapter, IRendererFactory, IRendererInfo - from pyramid.csrf import get_csrf_token from pyramid.decorator import reify - from pyramid.events import BeforeRender - from pyramid.httpexceptions import HTTPBadRequest - +from pyramid.interfaces import IJSONAdapter, IRendererFactory, IRendererInfo from pyramid.path import caller_package - from pyramid.response import _get_response_factory from pyramid.threadlocal import get_current_registry from pyramid.util import hide_attrs diff --git a/src/pyramid/request.py b/src/pyramid/request.py index 5c68abe69..d65be2a2f 100644 --- a/src/pyramid/request.py +++ b/src/pyramid/request.py @@ -1,27 +1,24 @@ from collections import deque - +from webob import BaseRequest from zope.interface import implementer from zope.interface.interface import InterfaceClass -from webob import BaseRequest - +from pyramid.decorator import reify +from pyramid.i18n import LocalizerRequestMixin from pyramid.interfaces import ( IRequest, IRequestExtensions, IResponse, ISessionFactory, ) - -from pyramid.decorator import reify -from pyramid.i18n import LocalizerRequestMixin from pyramid.response import Response, _get_response_factory -from pyramid.security import SecurityAPIMixin, AuthenticationAPIMixin +from pyramid.security import AuthenticationAPIMixin, SecurityAPIMixin from pyramid.url import URLMethodsMixin from pyramid.util import ( InstancePropertyHelper, InstancePropertyMixin, - text_, bytes_, + text_, ) from pyramid.view import ViewMethodsMixin diff --git a/src/pyramid/response.py b/src/pyramid/response.py index 1ccf4fbdc..03090941d 100644 --- a/src/pyramid/response.py +++ b/src/pyramid/response.py @@ -1,10 +1,9 @@ import mimetypes from os.path import getmtime, getsize - import venusian - from webob import Response as _Response from zope.interface import implementer + from pyramid.interfaces import IResponse, IResponseFactory _BLOCK_SIZE = 4096 * 64 # 256K diff --git a/src/pyramid/router.py b/src/pyramid/router.py index fa1a9ebf7..178c68e87 100644 --- a/src/pyramid/router.py +++ b/src/pyramid/router.py @@ -1,33 +1,29 @@ from zope.interface import implementer, providedBy +from pyramid.events import ( + BeforeTraversal, + ContextFound, + NewRequest, + NewResponse, +) +from pyramid.httpexceptions import HTTPNotFound from pyramid.interfaces import ( IDebugLogger, IExecutionPolicy, IRequest, IRequestExtensions, + IRequestFactory, IRootFactory, - IRouteRequest, IRouter, - IRequestFactory, + IRouteRequest, IRoutesMapper, ITraverser, ITweens, ) - -from pyramid.events import ( - ContextFound, - NewRequest, - NewResponse, - BeforeTraversal, -) - -from pyramid.httpexceptions import HTTPNotFound -from pyramid.request import Request -from pyramid.view import _call_view -from pyramid.request import apply_request_extensions +from pyramid.request import Request, apply_request_extensions from pyramid.threadlocal import RequestContext - from pyramid.traversal import DefaultRootFactory, ResourceTreeTraverser +from pyramid.view import _call_view @implementer(IRouter) diff --git a/src/pyramid/scripting.py b/src/pyramid/scripting.py index cbf9d5e32..abcdd1030 100644 --- a/src/pyramid/scripting.py +++ b/src/pyramid/scripting.py @@ -1,10 +1,7 @@ from pyramid.config import global_registries from pyramid.exceptions import ConfigurationError - from pyramid.interfaces import IRequestFactory, IRootFactory -from pyramid.request import Request -from pyramid.request import apply_request_extensions - +from pyramid.request import Request, apply_request_extensions from pyramid.threadlocal import RequestContext from pyramid.traversal import DefaultRootFactory diff --git a/src/pyramid/scripts/pdistreport.py b/src/pyramid/scripts/pdistreport.py index 3ace9451e..99615c1d5 100644 --- a/src/pyramid/scripts/pdistreport.py +++ b/src/pyramid/scripts/pdistreport.py @@ -1,8 +1,8 @@ -import sys -import platform -import pkg_resources import argparse from operator import itemgetter +import pkg_resources +import platform +import sys def out(*args): # pragma: no cover diff --git a/src/pyramid/scripts/prequest.py b/src/pyramid/scripts/prequest.py index 759978936..b828c9c30 100644 --- a/src/pyramid/scripts/prequest.py +++ b/src/pyramid/scripts/prequest.py @@ -1,12 +1,11 @@ -import base64 import argparse +import base64 import sys import textwrap from urllib.parse import unquote from pyramid.request import Request -from pyramid.scripts.common import get_config_loader -from pyramid.scripts.common import parse_vars +from pyramid.scripts.common import get_config_loader, parse_vars def main(argv=sys.argv, quiet=False): diff --git a/src/pyramid/scripts/proutes.py b/src/pyramid/scripts/proutes.py index 09b550cef..ee3cb0f04 100644 --- a/src/pyramid/scripts/proutes.py +++ b/src/pyramid/scripts/proutes.py @@ -1,21 +1,17 @@ -import fnmatch import argparse +import fnmatch +import re import sys import textwrap -import re - from zope.interface import Interface -from pyramid.paster import bootstrap -from pyramid.interfaces import IRouteRequest from pyramid.config import not_ - -from pyramid.scripts.common import get_config_loader -from pyramid.scripts.common import parse_vars +from pyramid.interfaces import IRouteRequest +from pyramid.paster import bootstrap +from pyramid.scripts.common import get_config_loader, parse_vars from pyramid.static import static_view from pyramid.view import _find_views - PAD = 3 ANY_KEY = '*' UNKNOWN_KEY = '<unknown>' diff --git a/src/pyramid/scripts/pserve.py b/src/pyramid/scripts/pserve.py index 350ab4d6d..6e8d0b599 100644 --- a/src/pyramid/scripts/pserve.py +++ b/src/pyramid/scripts/pserve.py @@ -9,6 +9,7 @@ # lib/site.py import argparse +import hupper import os import re import sys @@ -17,11 +18,8 @@ import threading import time import webbrowser -import hupper - -from pyramid.scripts.common import get_config_loader -from pyramid.scripts.common import parse_vars from pyramid.path import AssetResolver +from pyramid.scripts.common import get_config_loader, parse_vars from pyramid.settings import aslist diff --git a/src/pyramid/scripts/pshell.py b/src/pyramid/scripts/pshell.py index a9f02e408..2f2939e99 100644 --- a/src/pyramid/scripts/pshell.py +++ b/src/pyramid/scripts/pshell.py @@ -1,19 +1,15 @@ +import argparse from code import interact from contextlib import contextmanager -import argparse import os +import pkg_resources import sys import textwrap -import pkg_resources -from pyramid.util import DottedNameResolver -from pyramid.util import make_contextmanager from pyramid.paster import bootstrap - +from pyramid.scripts.common import get_config_loader, parse_vars from pyramid.settings import aslist - -from pyramid.scripts.common import get_config_loader -from pyramid.scripts.common import parse_vars +from pyramid.util import DottedNameResolver, make_contextmanager def main(argv=sys.argv, quiet=False): diff --git a/src/pyramid/scripts/ptweens.py b/src/pyramid/scripts/ptweens.py index e6a5c5ac7..f90e0967f 100644 --- a/src/pyramid/scripts/ptweens.py +++ b/src/pyramid/scripts/ptweens.py @@ -3,12 +3,9 @@ import sys import textwrap from pyramid.interfaces import ITweens - -from pyramid.tweens import MAIN -from pyramid.tweens import INGRESS -from pyramid.paster import bootstrap -from pyramid.paster import setup_logging +from pyramid.paster import bootstrap, setup_logging from pyramid.scripts.common import parse_vars +from pyramid.tweens import INGRESS, MAIN def main(argv=sys.argv, quiet=False): diff --git a/src/pyramid/scripts/pviews.py b/src/pyramid/scripts/pviews.py index d2a4bfa40..ac7725c99 100644 --- a/src/pyramid/scripts/pviews.py +++ b/src/pyramid/scripts/pviews.py @@ -3,8 +3,7 @@ import sys import textwrap from pyramid.interfaces import IMultiView -from pyramid.paster import bootstrap -from pyramid.paster import setup_logging +from pyramid.paster import bootstrap, setup_logging from pyramid.request import Request from pyramid.scripts.common import parse_vars from pyramid.view import _find_views diff --git a/src/pyramid/security.py b/src/pyramid/security.py index dc4713368..c0d01e0a7 100644 --- a/src/pyramid/security.py +++ b/src/pyramid/security.py @@ -1,15 +1,14 @@ -from zope.interface import implementer, providedBy from zope.deprecation import deprecated +from zope.interface import implementer, providedBy from pyramid.interfaces import ( - ISecurityPolicy, IAuthenticationPolicy, IAuthorizationPolicy, ISecuredView, + ISecurityPolicy, IView, IViewClassifier, ) - from pyramid.threadlocal import get_current_registry Everyone = 'system.Everyone' diff --git a/src/pyramid/session.py b/src/pyramid/session.py index 10e1ea313..e683fd77a 100644 --- a/src/pyramid/session.py +++ b/src/pyramid/session.py @@ -2,17 +2,13 @@ import binascii import os import pickle import time - +from webob.cookies import JSONSerializer, SignedSerializer from zope.deprecation import deprecated from zope.interface import implementer -from webob.cookies import JSONSerializer, SignedSerializer - from pyramid.csrf import check_csrf_origin, check_csrf_token - from pyramid.interfaces import ISession - -from pyramid.util import text_, bytes_ +from pyramid.util import bytes_, text_ def manage_accessed(wrapped): diff --git a/src/pyramid/static.py b/src/pyramid/static.py index 499706554..d71fa750b 100644 --- a/src/pyramid/static.py +++ b/src/pyramid/static.py @@ -3,19 +3,13 @@ from functools import lru_cache import json import mimetypes import os - -from os.path import getmtime, getsize, normcase, normpath, join, isdir, exists - +from os.path import exists, getmtime, getsize, isdir, join, normcase, normpath from pkg_resources import resource_exists, resource_filename, resource_isdir from pyramid.asset import abspath_from_asset_spec, resolve_asset_spec - -from pyramid.httpexceptions import HTTPNotFound, HTTPMovedPermanently - +from pyramid.httpexceptions import HTTPMovedPermanently, HTTPNotFound from pyramid.path import caller_package - -from pyramid.response import _guess_type, FileResponse - +from pyramid.response import FileResponse, _guess_type from pyramid.traversal import traversal_path_info diff --git a/src/pyramid/testing.py b/src/pyramid/testing.py index 251e1fcc2..af02872dd 100644 --- a/src/pyramid/testing.py +++ b/src/pyramid/testing.py @@ -1,30 +1,23 @@ +from contextlib import contextmanager import copy import os -from contextlib import contextmanager - from webob.acceptparse import create_accept_header - -from zope.interface import implementer, alsoProvides - -from pyramid.interfaces import IRequest, ISession +from zope.interface import alsoProvides, implementer from pyramid.config import Configurator from pyramid.decorator import reify +from pyramid.i18n import LocalizerRequestMixin +from pyramid.interfaces import IRequest, ISession from pyramid.path import caller_package -from pyramid.response import _get_response_factory from pyramid.registry import Registry - -from pyramid.security import SecurityAPIMixin, AuthenticationAPIMixin - -from pyramid.threadlocal import get_current_registry, manager - -from pyramid.i18n import LocalizerRequestMixin from pyramid.request import CallbackMethodsMixin +from pyramid.response import _get_response_factory +from pyramid.security import AuthenticationAPIMixin, SecurityAPIMixin +from pyramid.threadlocal import get_current_registry, manager from pyramid.url import URLMethodsMixin -from pyramid.util import InstancePropertyMixin, PYPY, text_ +from pyramid.util import PYPY, InstancePropertyMixin, text_ from pyramid.view import ViewMethodsMixin - _marker = object() diff --git a/src/pyramid/traversal.py b/src/pyramid/traversal.py index 811c0881b..cfa29f279 100644 --- a/src/pyramid/traversal.py +++ b/src/pyramid/traversal.py @@ -1,18 +1,16 @@ from functools import lru_cache from urllib.parse import unquote_to_bytes - from zope.interface import implementer from zope.interface.interfaces import IInterface +from pyramid.encode import url_quote +from pyramid.exceptions import URLDecodeError from pyramid.interfaces import ( - IResourceURL, + VH_ROOT_KEY, IRequestFactory, + IResourceURL, ITraverser, - VH_ROOT_KEY, ) - -from pyramid.encode import url_quote -from pyramid.exceptions import URLDecodeError from pyramid.location import lineage from pyramid.threadlocal import get_current_registry from pyramid.util import ascii_, is_nonstr_iter, text_ diff --git a/src/pyramid/url.py b/src/pyramid/url.py index 22551a349..b79604d96 100644 --- a/src/pyramid/url.py +++ b/src/pyramid/url.py @@ -3,19 +3,17 @@ from functools import lru_cache import os -from pyramid.interfaces import IResourceURL, IRoutesMapper, IStaticURLInfo - from pyramid.encode import url_quote, urlencode +from pyramid.interfaces import IResourceURL, IRoutesMapper, IStaticURLInfo from pyramid.path import caller_package from pyramid.threadlocal import get_current_registry -from pyramid.util import bytes_ - from pyramid.traversal import ( - ResourceURL, - quote_path_segment, PATH_SAFE, PATH_SEGMENT_SAFE, + ResourceURL, + quote_path_segment, ) +from pyramid.util import bytes_ QUERY_SAFE = "/?:@!$&'()*+,;=" # RFC 3986 ANCHOR_SAFE = QUERY_SAFE diff --git a/src/pyramid/urldispatch.py b/src/pyramid/urldispatch.py index 73b7be9f3..920aeffb5 100644 --- a/src/pyramid/urldispatch.py +++ b/src/pyramid/urldispatch.py @@ -1,12 +1,9 @@ import re from zope.interface import implementer -from pyramid.interfaces import IRoutesMapper, IRoute - from pyramid.exceptions import URLDecodeError - -from pyramid.traversal import quote_path_segment, split_path_info, PATH_SAFE - +from pyramid.interfaces import IRoute, IRoutesMapper +from pyramid.traversal import PATH_SAFE, quote_path_segment, split_path_info from pyramid.util import is_nonstr_iter, text_ _marker = object() diff --git a/src/pyramid/view.py b/src/pyramid/view.py index 201e8af7c..3253924da 100644 --- a/src/pyramid/view.py +++ b/src/pyramid/view.py @@ -1,33 +1,26 @@ +import inspect import itertools import sys -import inspect - import venusian - from zope.interface import providedBy -from pyramid.interfaces import ( - IRoutesMapper, - IMultiView, - ISecuredView, - IView, - IViewClassifier, - IRequest, - IExceptionViewClassifier, -) - from pyramid.exceptions import ConfigurationError, PredicateMismatch - from pyramid.httpexceptions import ( HTTPNotFound, HTTPTemporaryRedirect, default_exceptionresponse_view, ) - +from pyramid.interfaces import ( + IExceptionViewClassifier, + IMultiView, + IRequest, + IRoutesMapper, + ISecuredView, + IView, + IViewClassifier, +) from pyramid.threadlocal import get_current_registry, manager - -from pyramid.util import hide_attrs -from pyramid.util import reraise as reraise_ +from pyramid.util import hide_attrs, reraise as reraise_ _marker = object() diff --git a/src/pyramid/viewderivers.py b/src/pyramid/viewderivers.py index 7c28cbf85..d91295143 100644 --- a/src/pyramid/viewderivers.py +++ b/src/pyramid/viewderivers.py @@ -1,31 +1,28 @@ import inspect - from zope.interface import implementer, provider -from pyramid.security import NO_PERMISSION_REQUIRED +from pyramid import renderers from pyramid.csrf import check_csrf_origin, check_csrf_token -from pyramid.response import Response - +from pyramid.exceptions import ConfigurationError +from pyramid.httpexceptions import HTTPForbidden from pyramid.interfaces import ( + IDebugLogger, IDefaultCSRFOptions, IDefaultPermission, - IDebugLogger, IResponse, ISecurityPolicy, IViewMapper, IViewMapperFactory, ) - -from pyramid.exceptions import ConfigurationError -from pyramid.httpexceptions import HTTPForbidden +from pyramid.response import Response +from pyramid.security import NO_PERMISSION_REQUIRED from pyramid.util import ( - object_description, - takes_one_arg, is_bound_method, is_unbound_method, + object_description, + takes_one_arg, ) from pyramid.view import render_view_to_response -from pyramid import renderers def view_description(view): diff --git a/src/pyramid/wsgi.py b/src/pyramid/wsgi.py index b3f3803e4..5aec62b77 100644 --- a/src/pyramid/wsgi.py +++ b/src/pyramid/wsgi.py @@ -1,4 +1,5 @@ from functools import wraps + from pyramid.request import call_app_with_subpath_as_path_info diff --git a/tests/pkgs/conflictapp/__init__.py b/tests/pkgs/conflictapp/__init__.py index 840813994..ba3e72fc8 100644 --- a/tests/pkgs/conflictapp/__init__.py +++ b/tests/pkgs/conflictapp/__init__.py @@ -1,6 +1,6 @@ -from pyramid.response import Response from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy +from pyramid.response import Response def aview(request): diff --git a/tests/pkgs/defpermbugapp/__init__.py b/tests/pkgs/defpermbugapp/__init__.py index af78404ae..fe8611870 100644 --- a/tests/pkgs/defpermbugapp/__init__.py +++ b/tests/pkgs/defpermbugapp/__init__.py @@ -1,4 +1,5 @@ from webob import Response + from pyramid.security import NO_PERMISSION_REQUIRED from pyramid.view import view_config diff --git a/tests/pkgs/eventonly/__init__.py b/tests/pkgs/eventonly/__init__.py index c48b539a1..35d83838f 100644 --- a/tests/pkgs/eventonly/__init__.py +++ b/tests/pkgs/eventonly/__init__.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.events import subscriber +from pyramid.view import view_config class Yup(object): diff --git a/tests/pkgs/exceptionviewapp/views.py b/tests/pkgs/exceptionviewapp/views.py index ca2c4fffb..7985d0b94 100644 --- a/tests/pkgs/exceptionviewapp/views.py +++ b/tests/pkgs/exceptionviewapp/views.py @@ -1,7 +1,9 @@ from webob import Response -from .models import AnException + from pyramid.httpexceptions import HTTPBadRequest +from .models import AnException + def no(request): return Response('no') diff --git a/tests/pkgs/fixtureapp/views.py b/tests/pkgs/fixtureapp/views.py index 78df81c6f..c955a220d 100644 --- a/tests/pkgs/fixtureapp/views.py +++ b/tests/pkgs/fixtureapp/views.py @@ -1,5 +1,6 @@ -from zope.interface import Interface from webob import Response +from zope.interface import Interface + from pyramid.httpexceptions import HTTPForbidden diff --git a/tests/pkgs/forbiddenapp/__init__.py b/tests/pkgs/forbiddenapp/__init__.py index 79670dd32..4ae265a96 100644 --- a/tests/pkgs/forbiddenapp/__init__.py +++ b/tests/pkgs/forbiddenapp/__init__.py @@ -1,4 +1,5 @@ from webob import Response + from pyramid.httpexceptions import HTTPForbidden from pyramid.util import bytes_ diff --git a/tests/pkgs/forbiddenview/__init__.py b/tests/pkgs/forbiddenview/__init__.py index 4c78d961c..405869763 100644 --- a/tests/pkgs/forbiddenview/__init__.py +++ b/tests/pkgs/forbiddenview/__init__.py @@ -1,7 +1,7 @@ -from pyramid.view import forbidden_view_config, view_config -from pyramid.response import Response from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy +from pyramid.response import Response +from pyramid.view import forbidden_view_config, view_config @forbidden_view_config(route_name='foo') diff --git a/tests/pkgs/legacysecurityapp/__init__.py b/tests/pkgs/legacysecurityapp/__init__.py index 12fb6104e..abfef1cc5 100644 --- a/tests/pkgs/legacysecurityapp/__init__.py +++ b/tests/pkgs/legacysecurityapp/__init__.py @@ -1,5 +1,5 @@ -from pyramid.response import Response from pyramid.authentication import RemoteUserAuthenticationPolicy +from pyramid.response import Response from pyramid.security import Allowed, Denied diff --git a/tests/pkgs/notfoundview/__init__.py b/tests/pkgs/notfoundview/__init__.py index f606ec671..0eec3192c 100644 --- a/tests/pkgs/notfoundview/__init__.py +++ b/tests/pkgs/notfoundview/__init__.py @@ -1,5 +1,5 @@ -from pyramid.view import notfound_view_config, view_config from pyramid.response import Response +from pyramid.view import notfound_view_config, view_config @notfound_view_config(route_name='foo', append_slash=True) diff --git a/tests/pkgs/permbugapp/__init__.py b/tests/pkgs/permbugapp/__init__.py index 72b5d9c17..594acc8d6 100644 --- a/tests/pkgs/permbugapp/__init__.py +++ b/tests/pkgs/permbugapp/__init__.py @@ -1,6 +1,7 @@ from html import escape -from pyramid.security import view_execution_permitted + from pyramid.response import Response +from pyramid.security import view_execution_permitted def x_view(request): # pragma: no cover diff --git a/tests/test_asset.py b/tests/test_asset.py index 55a3c0336..84c30b33f 100644 --- a/tests/test_asset.py +++ b/tests/test_asset.py @@ -1,5 +1,5 @@ -import unittest import os +import unittest here = os.path.abspath(os.path.dirname(__file__)) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index e0f5a7963..ec3aef4ef 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -1,8 +1,9 @@ from http.cookies import SimpleCookie import unittest import warnings + from pyramid import testing -from pyramid.util import text_, bytes_ +from pyramid.util import bytes_, text_ class TestCallbackAuthenticationPolicyDebugging(unittest.TestCase): diff --git a/tests/test_config/__init__.py b/tests/test_config/__init__.py index ac1f19667..99677ebc5 100644 --- a/tests/test_config/__init__.py +++ b/tests/test_config/__init__.py @@ -1,7 +1,6 @@ # package from functools import partial -from zope.interface import implementer -from zope.interface import Interface +from zope.interface import Interface, implementer class IFactory(Interface): diff --git a/tests/test_config/pkgs/scannable/__init__.py b/tests/test_config/pkgs/scannable/__init__.py index 585f4357b..e0042a5cc 100644 --- a/tests/test_config/pkgs/scannable/__init__.py +++ b/tests/test_config/pkgs/scannable/__init__.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.renderers import null_renderer +from pyramid.view import view_config @view_config(renderer=null_renderer) diff --git a/tests/test_config/pkgs/scannable/another.py b/tests/test_config/pkgs/scannable/another.py index e8b71e5e3..31e7f5128 100644 --- a/tests/test_config/pkgs/scannable/another.py +++ b/tests/test_config/pkgs/scannable/another.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.renderers import null_renderer +from pyramid.view import view_config @view_config(name='another', renderer=null_renderer) diff --git a/tests/test_config/pkgs/scannable/pod/notinit.py b/tests/test_config/pkgs/scannable/pod/notinit.py index 03c93857f..bb1412722 100644 --- a/tests/test_config/pkgs/scannable/pod/notinit.py +++ b/tests/test_config/pkgs/scannable/pod/notinit.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.renderers import null_renderer +from pyramid.view import view_config @view_config(name='pod_notinit', renderer=null_renderer) diff --git a/tests/test_config/pkgs/scannable/subpackage/__init__.py b/tests/test_config/pkgs/scannable/subpackage/__init__.py index f89ca33f7..c22d48150 100644 --- a/tests/test_config/pkgs/scannable/subpackage/__init__.py +++ b/tests/test_config/pkgs/scannable/subpackage/__init__.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.renderers import null_renderer +from pyramid.view import view_config @view_config(name='subpackage_init', renderer=null_renderer) diff --git a/tests/test_config/pkgs/scannable/subpackage/notinit.py b/tests/test_config/pkgs/scannable/subpackage/notinit.py index 65c2a4929..10c35ab7b 100644 --- a/tests/test_config/pkgs/scannable/subpackage/notinit.py +++ b/tests/test_config/pkgs/scannable/subpackage/notinit.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.renderers import null_renderer +from pyramid.view import view_config @view_config(name='subpackage_notinit', renderer=null_renderer) diff --git a/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py b/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py index ec4bab818..a2fcf2af8 100644 --- a/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py +++ b/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py @@ -1,5 +1,5 @@ -from pyramid.view import view_config from pyramid.renderers import null_renderer +from pyramid.view import view_config @view_config(name='subsubpackage_init', renderer=null_renderer) diff --git a/tests/test_config/test_actions.py b/tests/test_config/test_actions.py index a72d0d7b1..aa86f3792 100644 --- a/tests/test_config/test_actions.py +++ b/tests/test_config/test_actions.py @@ -1,8 +1,9 @@ import unittest -from pyramid.exceptions import ConfigurationConflictError -from pyramid.exceptions import ConfigurationExecutionError - +from pyramid.exceptions import ( + ConfigurationConflictError, + ConfigurationExecutionError, +) from pyramid.interfaces import IRequest diff --git a/tests/test_config/test_assets.py b/tests/test_config/test_assets.py index 875846dbd..cfd786c5d 100644 --- a/tests/test_config/test_assets.py +++ b/tests/test_config/test_assets.py @@ -1,5 +1,6 @@ import os.path import unittest + from pyramid.testing import cleanUp # we use this folder diff --git a/tests/test_config/test_init.py b/tests/test_config/test_init.py index 5ca33178a..ebcd78bb6 100644 --- a/tests/test_config/test_init.py +++ b/tests/test_config/test_init.py @@ -1,17 +1,20 @@ import os import unittest -from . import dummy_tween_factory -from . import dummy_include -from . import dummy_extend -from . import dummy_extend2 -from . import DummyContext - -from pyramid.exceptions import ConfigurationExecutionError -from pyramid.exceptions import ConfigurationConflictError - +from pyramid.exceptions import ( + ConfigurationConflictError, + ConfigurationExecutionError, +) from pyramid.interfaces import IRequest +from . import ( + DummyContext, + dummy_extend, + dummy_extend2, + dummy_include, + dummy_tween_factory, +) + class ConfiguratorTests(unittest.TestCase): def _makeOne(self, *arg, **kw): diff --git a/tests/test_config/test_routes.py b/tests/test_config/test_routes.py index a75fdd776..bbafa8784 100644 --- a/tests/test_config/test_routes.py +++ b/tests/test_config/test_routes.py @@ -1,10 +1,10 @@ import unittest import warnings -from . import dummyfactory -from . import DummyContext from pyramid.util import text_ +from . import DummyContext, dummyfactory + class RoutesConfiguratorMixinTests(unittest.TestCase): def _makeOne(self, *arg, **kw): diff --git a/tests/test_config/test_security.py b/tests/test_config/test_security.py index 9a9ea9f7e..6c73ead1e 100644 --- a/tests/test_config/test_security.py +++ b/tests/test_config/test_security.py @@ -1,7 +1,6 @@ import unittest -from pyramid.exceptions import ConfigurationExecutionError -from pyramid.exceptions import ConfigurationError +from pyramid.exceptions import ConfigurationError, ConfigurationExecutionError class ConfiguratorSecurityMethodsTests(unittest.TestCase): diff --git a/tests/test_config/test_testing.py b/tests/test_config/test_testing.py index efbe28f66..e379e41bc 100644 --- a/tests/test_config/test_testing.py +++ b/tests/test_config/test_testing.py @@ -1,8 +1,9 @@ import unittest from zope.interface import implementer -from pyramid.security import SecurityAPIMixin, AuthenticationAPIMixin +from pyramid.security import AuthenticationAPIMixin, SecurityAPIMixin from pyramid.util import text_ + from . import IDummy diff --git a/tests/test_config/test_tweens.py b/tests/test_config/test_tweens.py index 805310c9a..ff75461c3 100644 --- a/tests/test_config/test_tweens.py +++ b/tests/test_config/test_tweens.py @@ -1,10 +1,9 @@ import unittest -from . import dummy_tween_factory -from . import dummy_tween_factory2 - from pyramid.exceptions import ConfigurationConflictError +from . import dummy_tween_factory, dummy_tween_factory2 + class TestTweensConfiguratorMixin(unittest.TestCase): def _makeOne(self, *arg, **kw): diff --git a/tests/test_config/test_views.py b/tests/test_config/test_views.py index 353749ed6..3aecc721a 100644 --- a/tests/test_config/test_views.py +++ b/tests/test_config/test_views.py @@ -4,14 +4,15 @@ import warnings from zope.interface import implementer from pyramid import testing -from pyramid.exceptions import ConfigurationError -from pyramid.exceptions import ConfigurationExecutionError -from pyramid.exceptions import ConfigurationConflictError -from pyramid.interfaces import IResponse, IRequest, IMultiView +from pyramid.exceptions import ( + ConfigurationConflictError, + ConfigurationError, + ConfigurationExecutionError, +) +from pyramid.interfaces import IMultiView, IRequest, IResponse from pyramid.util import text_ -from . import IDummy -from . import dummy_view +from . import IDummy, dummy_view class TestViewsConfigurationMixin(unittest.TestCase): diff --git a/tests/test_encode.py b/tests/test_encode.py index 4df08d509..ede6e9050 100644 --- a/tests/test_encode.py +++ b/tests/test_encode.py @@ -1,4 +1,5 @@ import unittest + from pyramid.util import text_ diff --git a/tests/test_events.py b/tests/test_events.py index 25ed5fc0d..b344738a3 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1,4 +1,5 @@ import unittest + from pyramid import testing diff --git a/tests/test_i18n.py b/tests/test_i18n.py index 78891200d..4ac6bd4e2 100644 --- a/tests/test_i18n.py +++ b/tests/test_i18n.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import os import unittest + from pyramid import testing here = os.path.dirname(__file__) diff --git a/tests/test_location.py b/tests/test_location.py index 163bb85aa..86fb8bfa8 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -1,5 +1,6 @@ import unittest from zope.interface import implementer + from pyramid.interfaces import ILocation diff --git a/tests/test_paster.py b/tests/test_paster.py index dd53195c7..ef2571471 100644 --- a/tests/test_paster.py +++ b/tests/test_paster.py @@ -1,5 +1,6 @@ import os import unittest + from .test_scripts.dummy import DummyLoader here = os.path.dirname(__file__) diff --git a/tests/test_path.py b/tests/test_path.py index da7cd64e1..e9fe94fe2 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -1,5 +1,5 @@ -import unittest import os +import unittest here = os.path.abspath(os.path.dirname(__file__)) diff --git a/tests/test_predicates.py b/tests/test_predicates.py index c0a6c59ec..b0ee65bcf 100644 --- a/tests/test_predicates.py +++ b/tests/test_predicates.py @@ -1,7 +1,6 @@ import unittest from pyramid import testing - from pyramid.util import text_ diff --git a/tests/test_registry.py b/tests/test_registry.py index aee4f0e15..81443ce47 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -1,6 +1,5 @@ import unittest -from zope.interface import Interface -from zope.interface import implementer +from zope.interface import Interface, implementer class TestRegistry(unittest.TestCase): diff --git a/tests/test_request.py b/tests/test_request.py index 1a10a8509..bbf6aa47c 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -1,8 +1,8 @@ import unittest -from pyramid import testing -from pyramid.security import SecurityAPIMixin, AuthenticationAPIMixin -from pyramid.util import text_, bytes_ +from pyramid import testing +from pyramid.security import AuthenticationAPIMixin, SecurityAPIMixin +from pyramid.util import bytes_, text_ class TestRequest(unittest.TestCase): diff --git a/tests/test_response.py b/tests/test_response.py index b63ccc6b1..4371d867f 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -2,6 +2,7 @@ import io import mimetypes import os import unittest + from pyramid import testing diff --git a/tests/test_scripts/dummy.py b/tests/test_scripts/dummy.py index bb3475d39..4a848e043 100644 --- a/tests/test_scripts/dummy.py +++ b/tests/test_scripts/dummy.py @@ -1,4 +1,5 @@ from zope.interface import implementer + from pyramid.interfaces import IMultiView diff --git a/tests/test_scripts/test_prequest.py b/tests/test_scripts/test_prequest.py index aadde719a..2214f6350 100644 --- a/tests/test_scripts/test_prequest.py +++ b/tests/test_scripts/test_prequest.py @@ -1,5 +1,6 @@ from io import StringIO import unittest + from . import dummy diff --git a/tests/test_scripts/test_proutes.py b/tests/test_scripts/test_proutes.py index b5a083272..6ba02a7d4 100644 --- a/tests/test_scripts/test_proutes.py +++ b/tests/test_scripts/test_proutes.py @@ -1,5 +1,6 @@ import os import unittest + from . import dummy diff --git a/tests/test_scripts/test_pserve.py b/tests/test_scripts/test_pserve.py index f19ba81df..7bf962f9e 100644 --- a/tests/test_scripts/test_pserve.py +++ b/tests/test_scripts/test_pserve.py @@ -1,8 +1,8 @@ from io import StringIO import os import unittest -from . import dummy +from . import dummy here = os.path.abspath(os.path.dirname(__file__)) diff --git a/tests/test_scripts/test_pshell.py b/tests/test_scripts/test_pshell.py index 6beaacda6..10a9cd593 100644 --- a/tests/test_scripts/test_pshell.py +++ b/tests/test_scripts/test_pshell.py @@ -1,5 +1,6 @@ import os import unittest + from . import dummy diff --git a/tests/test_scripts/test_ptweens.py b/tests/test_scripts/test_ptweens.py index ee50887f6..808bc64b6 100644 --- a/tests/test_scripts/test_ptweens.py +++ b/tests/test_scripts/test_ptweens.py @@ -1,4 +1,5 @@ import unittest + from . import dummy diff --git a/tests/test_scripts/test_pviews.py b/tests/test_scripts/test_pviews.py index c8d29113f..b462b6f28 100644 --- a/tests/test_scripts/test_pviews.py +++ b/tests/test_scripts/test_pviews.py @@ -1,4 +1,5 @@ import unittest + from . import dummy diff --git a/tests/test_session.py b/tests/test_session.py index 582a7ed4a..8f646658e 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -2,6 +2,7 @@ import base64 import json import pickle import unittest + from pyramid import testing diff --git a/tests/test_testing.py b/tests/test_testing.py index 31c33cafe..dbda76454 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -1,7 +1,7 @@ import unittest from zope.component import getSiteManager -from zope.interface import Interface -from zope.interface import implementer +from zope.interface import Interface, implementer + from pyramid import testing diff --git a/tests/test_threadlocal.py b/tests/test_threadlocal.py index 487c7f4f2..609041882 100644 --- a/tests/test_threadlocal.py +++ b/tests/test_threadlocal.py @@ -1,6 +1,7 @@ -from pyramid import testing import unittest +from pyramid import testing + class TestThreadLocalManager(unittest.TestCase): def setUp(self): diff --git a/tests/test_traversal.py b/tests/test_traversal.py index fdb0bcbb7..8d679b1f7 100644 --- a/tests/test_traversal.py +++ b/tests/test_traversal.py @@ -3,7 +3,6 @@ import unittest from urllib.parse import quote from pyramid.testing import cleanUp - from pyramid.util import text_ diff --git a/tests/test_tweens.py b/tests/test_tweens.py index 054f4360d..aee1ae7cc 100644 --- a/tests/test_tweens.py +++ b/tests/test_tweens.py @@ -1,4 +1,5 @@ import unittest + from pyramid import testing diff --git a/tests/test_url.py b/tests/test_url.py index c5c0ca09f..b61b15d82 100644 --- a/tests/test_url.py +++ b/tests/test_url.py @@ -2,7 +2,6 @@ import os import unittest from pyramid import testing - from pyramid.util import WIN, text_ diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index 5d77042ae..5c48bea01 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -1,4 +1,5 @@ import unittest + from pyramid import testing from pyramid.util import text_ diff --git a/tests/test_util.py b/tests/test_util.py index 84bc9379f..293036c10 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -1,6 +1,7 @@ import sys import unittest -from pyramid.util import text_, bytes_ + +from pyramid.util import bytes_, text_ class Test_InstancePropertyHelper(unittest.TestCase): diff --git a/tests/test_view.py b/tests/test_view.py index 5411e57c0..710fba76c 100644 --- a/tests/test_view.py +++ b/tests/test_view.py @@ -1,11 +1,9 @@ -import unittest -from zope.interface import Interface -from zope.interface import implementer import sys +import unittest +from zope.interface import Interface, implementer from pyramid import testing -from pyramid.interfaces import IRequest -from pyramid.interfaces import IResponse +from pyramid.interfaces import IRequest, IResponse class BaseTest(object): diff --git a/tests/test_viewderivers.py b/tests/test_viewderivers.py index 3b5349094..0e2881683 100644 --- a/tests/test_viewderivers.py +++ b/tests/test_viewderivers.py @@ -3,7 +3,7 @@ from zope.interface import implementer from pyramid import testing from pyramid.exceptions import ConfigurationError -from pyramid.interfaces import IResponse, IRequest +from pyramid.interfaces import IRequest, IResponse class TestDeriveView(unittest.TestCase): @@ -19,12 +19,14 @@ setenv = skip_install = true commands = flake8 src/pyramid tests setup.py + isort --check -rc src/pyramid tests setup.py black --check --diff src/pyramid tests setup.py python setup.py check -r -s -m check-manifest deps = flake8 black + isort readme_renderer check-manifest @@ -53,12 +55,14 @@ deps = setenv = COVERAGE_FILE=.coverage -[testenv:black] +[testenv:format] skip_install = true commands = + isort -rc src/pyramid tests setup.py black src/pyramid tests setup.py deps = black + isort [testenv:build] skip_install = true |
