diff options
| author | Chris McDonough <chrism@plope.com> | 2014-05-05 23:48:51 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2014-05-05 23:48:51 -0400 |
| commit | 0caac0a0af78cd55df2e1f3c3c7fc5171dbfe849 (patch) | |
| tree | a624aa38b3db1f7de58bb8bf9aaff4583cec28fd | |
| parent | ba85e591d563ed654f492f7cab5ca492a32a86d7 (diff) | |
| parent | 0117573edbc5dff565868187f8841859b3e36a51 (diff) | |
| download | pyramid-0caac0a0af78cd55df2e1f3c3c7fc5171dbfe849.tar.gz pyramid-0caac0a0af78cd55df2e1f3c3c7fc5171dbfe849.tar.bz2 pyramid-0caac0a0af78cd55df2e1f3c3c7fc5171dbfe849.zip | |
Merge branch 'master' into redundant_totuorial_logging_config
36 files changed, 213 insertions, 721 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 434eab898..264497f5b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,15 +1,27 @@ -Unreleased -========== +Next release +============ -- Avoid crash in ``pserve --reload`` under Py3k, when iterating over posiibly +- ... + +1.5 (2014-04-08) +================ + +- Avoid crash in ``pserve --reload`` under Py3k, when iterating over possibly mutated ``sys.modules``. +- ``UnencryptedCookieSessionFactoryConfig`` failed if the secret contained + higher order characters. See https://github.com/Pylons/pyramid/issues/1246 + - Fixed a bug in ``UnencryptedCookieSessionFactoryConfig`` and ``SignedCookieSessionFactory`` where ``timeout=None`` would cause a new session to always be created. Also in ``SignedCookieSessionFactory`` a ``reissue_time=None`` would cause an exception when modifying the session. See https://github.com/Pylons/pyramid/issues/1247 +- Updated docs and scaffolds to keep in step with new 2.0 release of + ``Lingua``. This included removing all ``setup.cfg`` files from scaffolds + and documentation environments. + 1.5b1 (2014-02-08) ================== diff --git a/docs/conf.py b/docs/conf.py index a447c9968..eba776628 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -138,17 +138,21 @@ if book: # Add and use Pylons theme if 'sphinx-build' in ' '.join(sys.argv): # protect against dumb importers from subprocess import call, Popen, PIPE - - p = Popen('which git', shell=True, stdout=PIPE) cwd = os.getcwd() - _themes = os.path.join(cwd, '_themes') + p = Popen('which git', shell=True, stdout=PIPE) + here = os.path.abspath(os.path.dirname(__file__)) + parent = os.path.abspath(os.path.dirname(here)) + _themes = os.path.join(here, '_themes') git = p.stdout.read().strip() - if not os.listdir(_themes): - call([git, 'submodule', '--init']) - else: - call([git, 'submodule', 'update']) - - sys.path.append(os.path.abspath('_themes')) + try: + os.chdir(parent) + if not os.listdir(_themes): + call([git, 'submodule', '--init']) + else: + call([git, 'submodule', 'update']) + sys.path.append(_themes) + finally: + os.chdir(cwd) html_theme_path = ['_themes'] html_theme = 'pyramid' diff --git a/docs/glossary.rst b/docs/glossary.rst index 0e340491b..2cc461a77 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -801,8 +801,9 @@ Glossary application. Lingua - A package by Wichert Akkerman which provides :term:`Babel` message - extractors for Python source files and Chameleon ZPT template files. + A package by Wichert Akkerman which provides the ``pot-create`` + command to extract translateable messages from Python sources + and Chameleon ZPT template files. Message Identifier A string used as a translation lookup key during localization. diff --git a/docs/narr/MyProject/setup.cfg b/docs/narr/MyProject/setup.cfg deleted file mode 100644 index 332e80a60..000000000 --- a/docs/narr/MyProject/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = myproject -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = myproject/locale -domain = MyProject -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = myproject/locale/MyProject.pot -width = 80 - -[init_catalog] -domain = MyProject -input_file = myproject/locale/MyProject.pot -output_dir = myproject/locale - -[update_catalog] -domain = MyProject -input_file = myproject/locale/MyProject.pot -output_dir = myproject/locale -previous = true diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 5f50ca212..1de2c8941 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -245,88 +245,70 @@ GNU gettext uses three types of files in the translation framework, A ``.po`` file is turned into a machine-readable binary file, which is the ``.mo`` file. Compiling the translations to machine code - makes the localized program run faster. + makes the localized program start faster. The tools for working with :term:`gettext` translation files related to a -:app:`Pyramid` application is :term:`Babel` and :term:`Lingua`. Lingua is a -Babel extension that provides support for scraping i18n references out of -Python and Chameleon files. +:app:`Pyramid` application are :term:`Lingua` and :term:`Gettext`. Lingua +can scrape i18n references out of Python and Chameleon files and create +the ``.pot`` file. Gettext includes ``msgmerge`` tool to update a ``.po`` file +from an updated ``.pot`` file and ``msgfmt`` to compile ``.po`` files to +``.mo`` files. .. index:: - single: Babel + single: Gettext single: Lingua .. _installing_babel: -Installing Babel and Lingua -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Installing Lingua and Gettext +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In order for the commands related to working with ``gettext`` translation -files to work properly, you will need to have :term:`Babel` and -:term:`Lingua` installed into the same environment in which :app:`Pyramid` is +files to work properly, you will need to have :term:`Lingua` and +:term:`Gettext` installed into the same environment in which :app:`Pyramid` is installed. Installation on UNIX ++++++++++++++++++++ -If the :term:`virtualenv` into which you've installed your :app:`Pyramid` -application lives in ``/my/virtualenv``, you can install Babel and Lingua -like so: +Gettext is often already installed on UNIX systems. You can check if it is +installed by testing if the ``msgfmt`` command is available. If it is not +available you can install it through the packaging system from your OS; +the package name is almost always ``gettext``. For example on a Debian or +Ubuntu system run this command: .. code-block:: text - $ cd /my/virtualenv - $ $VENV/bin/easy_install Babel lingua + $ sudo apt-get install gettext -Installation on Windows -+++++++++++++++++++++++ - -If the :term:`virtualenv` into which you've installed your :app:`Pyramid` -application lives in ``C:\my\virtualenv``, you can install Babel and Lingua +Installing Lingua is done with the Python packaging tools. If the +:term:`virtualenv` into which you've installed your :app:`Pyramid` application +lives in ``/my/virtualenv``, you can install Lingua like so: .. code-block:: text - C> %VENV%\Scripts\easy_install Babel lingua + $ cd /my/virtualenv + $ $VENV/bin/easy_install lingua -.. index:: - single: Babel; message extractors - single: Lingua +Installation on Windows ++++++++++++++++++++++++ -Changing the ``setup.py`` -+++++++++++++++++++++++++ +There are several ways to install Gettext on Windows: it is included in the +`Cygwin <http://www.cygwin.com/>`_ collection, or you can use the `installer +from the GnuWin32 <http://gnuwin32.sourceforge.net/packages/gettext.htm>`_ +or compile it yourself. Make sure the installation path is added to your +``$PATH``. -You need to add a few boilerplate lines to your application's ``setup.py`` -file in order to properly generate :term:`gettext` files from your -application. -.. note:: See :ref:`project_narr` to learn about the - composition of an application's ``setup.py`` file. +Installing Lingua is done with the Python packaging tools. If the +:term:`virtualenv` into which you've installed your :app:`Pyramid` application +lives in ``C:\my\virtualenv``, you can install Lingua like so: -In particular, add the ``Babel`` and ``lingua`` distributions to the -``install_requires`` list and insert a set of references to :term:`Babel` -*message extractors* within the call to :func:`setuptools.setup` inside your -application's ``setup.py`` file: +.. code-block:: text -.. code-block:: python - :linenos: + C> %VENV%\Scripts\easy_install lingua - setup(name="mypackage", - # ... - install_requires = [ - # ... - 'Babel', - 'lingua', - ], - message_extractors = { '.': [ - ('**.py', 'lingua_python', None ), - ('**.pt', 'lingua_xml', None ), - ]}, - ) - -The ``message_extractors`` stanza placed into the ``setup.py`` file causes -the :term:`Babel` message catalog extraction machinery to also consider -``*.pt`` files when doing message id extraction. .. index:: pair: extracting; messages @@ -336,90 +318,20 @@ the :term:`Babel` message catalog extraction machinery to also consider Extracting Messages from Code and Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once Babel and Lingua are installed and your application's ``setup.py`` file -has the correct message extractor references, you may extract a message -catalog template from the code and :term:`Chameleon` templates which reside -in your :app:`Pyramid` application. You run a ``setup.py`` command to -extract the messages: +Once Lingua is installed you may extract a message catalog template from the +code and :term:`Chameleon` templates which reside in your :app:`Pyramid` +application. You run a ``pot-create`` command to extract the messages: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives $ mkdir -p myapplication/locale - $ $VENV/bin/python setup.py extract_messages + $ $VENV/bin/pot-create src > myapplication/locale/myapplication.pot The message catalog ``.pot`` template will end up in: ``myapplication/locale/myapplication.pot``. -.. index:: - single: translation domains - -Translation Domains -+++++++++++++++++++ - -The name ``myapplication`` above in the filename ``myapplication.pot`` -denotes the :term:`translation domain` of the translations that must -be performed to localize your application. By default, the -translation domain is the :term:`project` name of your -:app:`Pyramid` application. - -To change the translation domain of the extracted messages in your project, -edit the ``setup.cfg`` file of your application, The default ``setup.cfg`` -file of a ``pcreate`` -generated :app:`Pyramid` application has stanzas in it -that look something like the following: - -.. code-block:: ini - :linenos: - - [compile_catalog] - directory = myproject/locale - domain = MyProject - statistics = true - - [extract_messages] - add_comments = TRANSLATORS: - output_file = myproject/locale/MyProject.pot - width = 80 - - [init_catalog] - domain = MyProject - input_file = myproject/locale/MyProject.pot - output_dir = myproject/locale - - [update_catalog] - domain = MyProject - input_file = myproject/locale/MyProject.pot - output_dir = myproject/locale - previous = true - -In the above example, the project name is ``MyProject``. To indicate -that you'd like the domain of your translations to be ``mydomain`` -instead, change the ``setup.cfg`` file stanzas to look like so: - -.. code-block:: ini - :linenos: - - [compile_catalog] - directory = myproject/locale - domain = mydomain - statistics = true - - [extract_messages] - add_comments = TRANSLATORS: - output_file = myproject/locale/mydomain.pot - width = 80 - - [init_catalog] - domain = mydomain - input_file = myproject/locale/mydomain.pot - output_dir = myproject/locale - - [update_catalog] - domain = mydomain - input_file = myproject/locale/mydomain.pot - output_dir = myproject/locale - previous = true .. index:: pair: initializing; message catalog @@ -432,15 +344,17 @@ Once you've extracted messages into a ``.pot`` file (see in the ``.pot`` file, you need to generate at least one ``.po`` file. A ``.po`` file represents translations of a particular set of messages to a particular locale. Initialize a ``.po`` file for a specific -locale from a pre-generated ``.pot`` template by using the ``setup.py -init_catalog`` command: +locale from a pre-generated ``.pot`` template by using the ``msginit`` +command from Gettext: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $VENV/bin/python setup.py init_catalog -l es + $ cd myapplication/locale + $ mkdir -p es/LC_MESSAGES + $ msginit -l es es/LC_MESSAGES/myapplication.po -By default, the message catalog ``.po`` file will end up in: +This will create a new the message catalog ``.po`` file will in: ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. @@ -465,12 +379,13 @@ files based on changes to the ``.pot`` file, so that the new and changed messages can also be translated or re-translated. First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. -Then use the ``setup.py update_catalog`` command. +Then use the ``msgmerge`` command from Gettext. .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $VENV/bin/python setup.py update_catalog + $ cd myapplication/locale + $ msgmerge --update es/LC_MESSAGES/myapplication.po myapplication.pot .. index:: pair: compiling; message catalog @@ -481,12 +396,13 @@ Compiling a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Finally, to prepare an application for performing actual runtime -translations, compile ``.po`` files to ``.mo`` files: +translations, compile ``.po`` files to ``.mo`` files use the ``msgfmt`` +command from Gettext: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $VENV/bin/python setup.py compile_catalog + $ msgfmt myapplication/locale/*/LC_MESSAGES/*.po This will create a ``.mo`` file for each ``.po`` file in your application. As long as the :term:`translation directory` in which diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 62b91de0e..0ada1a379 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -476,24 +476,23 @@ structure: .. code-block:: text MyProject/ - ├── CHANGES.txt - ├── MANIFEST.in - ├── README.txt - ├── development.ini - ├── myproject - │ ├── __init__.py - │ ├── static - │ │ ├── pyramid-16x16.png - │ │ ├── pyramid.png - │ │ ├── theme.css - │ │ └── theme.min.css - │ ├── templates - │ │ └── mytemplate.pt - │ ├── tests.py - │ └── views.py - ├── production.ini - ├── setup.cfg - └── setup.py + |-- CHANGES.txt + |-- development.ini + |-- MANIFEST.in + |-- myproject + | |-- __init__.py + | |-- static + | | |-- pyramid-16x16.png + | | |-- pyramid.png + | | |-- theme.css + | | `-- theme.min.css + | |-- templates + | | `-- mytemplate.pt + | |-- tests.py + | `-- views.py + |-- production.ini + |-- README.txt + `-- setup.py The ``MyProject`` :term:`Project` --------------------------------- @@ -515,9 +514,6 @@ describe, run, and test your application. #. ``production.ini`` is a :term:`PasteDeploy` configuration file that can be used to execute your application in a production configuration. -#. ``setup.cfg`` is a :term:`setuptools` configuration file used by - ``setup.py``. - #. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files should be included in a source distribution of the package when ``python setup.py sdist`` is run. @@ -746,24 +742,6 @@ named ``MyProject-0.1.tar.gz``. You can send this tarball to other people who want to install and use your application. .. index:: - single: setup.cfg - -``setup.cfg`` -~~~~~~~~~~~~~ - -The ``setup.cfg`` file is a :term:`setuptools` configuration file. It -contains various settings related to testing and internationalization: - -Our generated ``setup.cfg`` looks like this: - -.. literalinclude:: MyProject/setup.cfg - :language: guess - :linenos: - -The values in the default setup file allow various commonly-used -internationalization commands and testing commands to work more smoothly. - -.. index:: single: package The ``myproject`` :term:`Package` diff --git a/docs/quick_tour/awesome/setup.cfg b/docs/quick_tour/awesome/setup.cfg deleted file mode 100644 index b1cd90d2c..000000000 --- a/docs/quick_tour/awesome/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = awesome -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = awesome/locale -domain = awesome -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = awesome/locale/awesome.pot -width = 80 -mapping_file = message-extraction.ini - -[init_catalog] -domain = awesome -input_file = awesome/locale/awesome.pot -output_dir = awesome/locale - -[update_catalog] -domain = awesome -input_file = awesome/locale/awesome.pot -output_dir = awesome/locale -previous = true diff --git a/docs/quick_tour/package/setup.cfg b/docs/quick_tour/package/setup.cfg deleted file mode 100644 index 186e796fc..000000000 --- a/docs/quick_tour/package/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = hello_world -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = hello_world/locale -domain = hello_world -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = hello_world/locale/hello_world.pot -width = 80 -mapping_file = message-extraction.ini - -[init_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale - -[update_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale -previous = true diff --git a/docs/quick_tour/sqla_demo/setup.cfg b/docs/quick_tour/sqla_demo/setup.cfg deleted file mode 100644 index 9f91cd122..000000000 --- a/docs/quick_tour/sqla_demo/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=sqla_demo -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = sqla_demo/locale -domain = sqla_demo -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = sqla_demo/locale/sqla_demo.pot -width = 80 - -[init_catalog] -domain = sqla_demo -input_file = sqla_demo/locale/sqla_demo.pot -output_dir = sqla_demo/locale - -[update_catalog] -domain = sqla_demo -input_file = sqla_demo/locale/sqla_demo.pot -output_dir = sqla_demo/locale -previous = true diff --git a/docs/quick_tutorial/hello_world.rst b/docs/quick_tutorial/hello_world.rst index 86e1319f0..1a9ba4c9d 100644 --- a/docs/quick_tutorial/hello_world.rst +++ b/docs/quick_tutorial/hello_world.rst @@ -96,13 +96,13 @@ Extra Credit .. code-block:: python - print ('Starting up server on http://localhost:6547') + print('Incoming request') ...instead of: .. code-block:: python - print 'Starting up server on http://localhost:6547' + print 'Incoming request' #. What happens if you return a string of HTML? A sequence of integers? diff --git a/docs/quick_tutorial/hello_world/app.py b/docs/quick_tutorial/hello_world/app.py index 210075023..0a95f9ad3 100644 --- a/docs/quick_tutorial/hello_world/app.py +++ b/docs/quick_tutorial/hello_world/app.py @@ -4,7 +4,7 @@ from pyramid.response import Response def hello_world(request): - print ('Incoming request') + print('Incoming request') return Response('<body><h1>Hello World!</h1></body>') @@ -14,4 +14,4 @@ if __name__ == '__main__': config.add_view(hello_world, route_name='hello') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) - server.serve_forever()
\ No newline at end of file + server.serve_forever() diff --git a/docs/quick_tutorial/scaffolds.rst b/docs/quick_tutorial/scaffolds.rst index 8ca2d27df..4f2694100 100644 --- a/docs/quick_tutorial/scaffolds.rst +++ b/docs/quick_tutorial/scaffolds.rst @@ -63,11 +63,11 @@ Steps On startup, ``pserve`` logs some output: - .. code-block:: bash + .. code-block:: bash - Starting subprocess with file monitor - Starting server in PID 72213. - Starting HTTP server on http://0.0.0.0:6543 + Starting subprocess with file monitor + Starting server in PID 72213. + Starting HTTP server on http://0.0.0.0:6543 #. Open http://localhost:6543/ in your browser. diff --git a/docs/quick_tutorial/scaffolds/setup.cfg b/docs/quick_tutorial/scaffolds/setup.cfg deleted file mode 100644 index c980261e3..000000000 --- a/docs/quick_tutorial/scaffolds/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = scaffolds -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = scaffolds/locale -domain = scaffolds -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = scaffolds/locale/scaffolds.pot -width = 80 - -[init_catalog] -domain = scaffolds -input_file = scaffolds/locale/scaffolds.pot -output_dir = scaffolds/locale - -[update_catalog] -domain = scaffolds -input_file = scaffolds/locale/scaffolds.pot -output_dir = scaffolds/locale -previous = true diff --git a/docs/tutorials/wiki/src/authorization/setup.cfg b/docs/tutorials/wiki/src/authorization/setup.cfg deleted file mode 100644 index 3d7ea6e23..000000000 --- a/docs/tutorials/wiki/src/authorization/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true - diff --git a/docs/tutorials/wiki/src/basiclayout/setup.cfg b/docs/tutorials/wiki/src/basiclayout/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/wiki/src/basiclayout/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/wiki/src/models/setup.cfg b/docs/tutorials/wiki/src/models/setup.cfg deleted file mode 100644 index 3d7ea6e23..000000000 --- a/docs/tutorials/wiki/src/models/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true - diff --git a/docs/tutorials/wiki/src/tests/setup.cfg b/docs/tutorials/wiki/src/tests/setup.cfg deleted file mode 100644 index 3d7ea6e23..000000000 --- a/docs/tutorials/wiki/src/tests/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true - diff --git a/docs/tutorials/wiki/src/views/setup.cfg b/docs/tutorials/wiki/src/views/setup.cfg deleted file mode 100644 index 3d7ea6e23..000000000 --- a/docs/tutorials/wiki/src/views/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true - diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 1e5d0dcbf..2e35574fd 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -207,6 +207,21 @@ routes: :linenos: :language: python +.. note:: The preceding lines must be added *before* the following + ``view_page`` route definition: + + .. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 32 + :linenos: + :language: python + + This is because ``view_page``'s route definition uses a catch-all + "replacement marker" ``/{pagename}`` (see :ref:`route_pattern_syntax`) + which will catch any route that was not already caught by any + route listed above it in ``__init__.py``. Hence, for ``login`` and + ``logout`` views to have the opportunity of being matched + (or "caught"), they must be above ``/{pagename}``. + Add Login and Logout Views ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/tutorials/wiki2/src/authorization/setup.cfg b/docs/tutorials/wiki2/src/authorization/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/wiki2/src/authorization/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.cfg b/docs/tutorials/wiki2/src/basiclayout/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/wiki2/src/models/setup.cfg b/docs/tutorials/wiki2/src/models/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/wiki2/src/models/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/wiki2/src/tests/setup.cfg b/docs/tutorials/wiki2/src/tests/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/wiki2/src/tests/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/tutorials/wiki2/src/views/setup.cfg b/docs/tutorials/wiki2/src/views/setup.cfg deleted file mode 100644 index 23b2ad983..000000000 --- a/docs/tutorials/wiki2/src/views/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true diff --git a/docs/whatsnew-1.5.rst b/docs/whatsnew-1.5.rst index 2f73af661..65e8393f8 100644 --- a/docs/whatsnew-1.5.rst +++ b/docs/whatsnew-1.5.rst @@ -511,6 +511,9 @@ Scaffolding Enhancements - All scaffolds have a new HTML + CSS theme. +- Updated docs and scaffolds to keep in step with new 2.0 release of + ``Lingua``. This included removing all ``setup.cfg`` files from scaffolds + and documentation environments. Dependency Changes ------------------ diff --git a/pyramid/scaffolds/alchemy/setup.cfg_tmpl b/pyramid/scaffolds/alchemy/setup.cfg_tmpl deleted file mode 100644 index 5bec29823..000000000 --- a/pyramid/scaffolds/alchemy/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package={{package}} -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/pyramid/scaffolds/starter/setup.cfg_tmpl b/pyramid/scaffolds/starter/setup.cfg_tmpl deleted file mode 100644 index 04c738049..000000000 --- a/pyramid/scaffolds/starter/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = {{package}} -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/pyramid/scaffolds/tests.py b/pyramid/scaffolds/tests.py index d913d022a..dfbf9b6cf 100644 --- a/pyramid/scaffolds/tests.py +++ b/pyramid/scaffolds/tests.py @@ -1,6 +1,5 @@ import sys import os -import pkg_resources import shutil import subprocess import tempfile @@ -26,7 +25,8 @@ class TemplateTest(object): self.old_cwd = os.getcwd() self.directory = tempfile.mkdtemp() self.make_venv(self.directory) - os.chdir(pkg_resources.get_distribution('pyramid').location) + here = os.path.abspath(os.path.dirname(__file__)) + os.chdir(os.path.dirname(os.path.dirname(here))) subprocess.check_call( [os.path.join(self.directory, 'bin', 'python'), 'setup.py', 'develop']) diff --git a/pyramid/scaffolds/zodb/setup.cfg_tmpl b/pyramid/scaffolds/zodb/setup.cfg_tmpl deleted file mode 100644 index 5bec29823..000000000 --- a/pyramid/scaffolds/zodb/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package={{package}} -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/pyramid/session.py b/pyramid/session.py index 56d99e9de..a95c3f258 100644 --- a/pyramid/session.py +++ b/pyramid/session.py @@ -58,7 +58,12 @@ def signed_serialize(data, secret): response.set_cookie('signed_cookie', cookieval) """ pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) - sig = hmac.new(bytes_(secret), pickled, hashlib.sha1).hexdigest() + try: + # bw-compat with pyramid <= 1.5b1 where latin1 is the default + secret = bytes_(secret) + except UnicodeEncodeError: + secret = bytes_(secret, 'utf-8') + sig = hmac.new(secret, pickled, hashlib.sha1).hexdigest() return sig + native_(base64.b64encode(pickled)) def signed_deserialize(serialized, secret, hmac=hmac): @@ -82,7 +87,12 @@ def signed_deserialize(serialized, secret, hmac=hmac): # Badly formed data can make base64 die raise ValueError('Badly formed base64 data: %s' % e) - sig = bytes_(hmac.new(bytes_(secret), pickled, hashlib.sha1).hexdigest()) + try: + # bw-compat with pyramid <= 1.5b1 where latin1 is the default + secret = bytes_(secret) + except UnicodeEncodeError: + secret = bytes_(secret, 'utf-8') + sig = bytes_(hmac.new(secret, pickled, hashlib.sha1).hexdigest()) # Avoid timing attacks (see # http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf) diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index 9d3a9e004..35648ed38 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -640,6 +640,48 @@ class RendererScanAppTest(IntegrationBase, unittest.TestCase): res = testapp.get('/two', status=200) self.assertTrue(b'Two!' in res.body) +class UnicodeInURLTest(unittest.TestCase): + def _makeConfig(self): + from pyramid.config import Configurator + config = Configurator() + return config + + def _makeTestApp(self, config): + from webtest import TestApp + app = config.make_wsgi_app() + return TestApp(app) + + def test_unicode_in_url_404(self): + request_path = '/avalia%C3%A7%C3%A3o_participante' + request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') + + config = self._makeConfig() + testapp = self._makeTestApp(config) + + res = testapp.get(request_path, status=404) + + # Pyramid default 404 handler outputs: + # u'404 Not Found\n\nThe resource could not be found.\n\n\n' + # u'/avalia\xe7\xe3o_participante\n\n' + self.assertTrue(request_path_unicode in res.text) + + def test_unicode_in_url_200(self): + request_path = '/avalia%C3%A7%C3%A3o_participante' + request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') + + def myview(request): + return 'XXX' + + config = self._makeConfig() + config.add_route('myroute', request_path_unicode) + config.add_view(myview, route_name='myroute', renderer='json') + testapp = self._makeTestApp(config) + + res = testapp.get(request_path, status=200) + + self.assertEqual(res.text, '"XXX"') + + class AcceptContentTypeTest(unittest.TestCase): def setUp(self): def hello_view(request): diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/setup.cfg_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/setup.cfg_tmpl deleted file mode 100644 index 04c738049..000000000 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/setup.cfg_tmpl +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = {{package}} -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = {{package}}/locale -domain = {{project}} -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = {{package}}/locale/{{project}}.pot -width = 80 - -[init_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale - -[update_catalog] -domain = {{project}} -input_file = {{package}}/locale/{{project}}.pot -output_dir = {{package}}/locale -previous = true diff --git a/pyramid/tests/test_session.py b/pyramid/tests/test_session.py index 1aaa7a2ba..35c234e99 100644 --- a/pyramid/tests/test_session.py +++ b/pyramid/tests/test_session.py @@ -544,7 +544,7 @@ def serialize(data, secret): from pyramid.compat import native_ from pyramid.compat import pickle pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) - sig = hmac.new(bytes_(secret), pickled, sha1).hexdigest() + sig = hmac.new(bytes_(secret, 'utf-8'), pickled, sha1).hexdigest() return sig + native_(base64.b64encode(pickled)) class Test_signed_serialize(unittest.TestCase): @@ -556,6 +556,18 @@ class Test_signed_serialize(unittest.TestCase): expected = serialize('123', 'secret') result = self._callFUT('123', 'secret') self.assertEqual(result, expected) + + def test_it_with_highorder_secret(self): + secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8') + expected = serialize('123', secret) + result = self._callFUT('123', secret) + self.assertEqual(result, expected) + + def test_it_with_latin1_secret(self): + secret = b'La Pe\xc3\xb1a' + expected = serialize('123', secret) + result = self._callFUT('123', secret.decode('latin-1')) + self.assertEqual(result, expected) class Test_signed_deserialize(unittest.TestCase): def _callFUT(self, serialized, secret, hmac=None): @@ -587,6 +599,19 @@ class Test_signed_deserialize(unittest.TestCase): serialized = 'bad' + serialize('123', 'secret') self.assertRaises(ValueError, self._callFUT, serialized, 'secret') + def test_it_with_highorder_secret(self): + secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8') + serialized = serialize('123', secret) + result = self._callFUT(serialized, secret) + self.assertEqual(result, '123') + + # bwcompat with pyramid <= 1.5b1 where latin1 is the default + def test_it_with_latin1_secret(self): + secret = b'La Pe\xc3\xb1a' + serialized = serialize('123', secret) + result = self._callFUT(serialized, secret.decode('latin-1')) + self.assertEqual(result, '123') + class Test_check_csrf_token(unittest.TestCase): def _callFUT(self, *args, **kwargs): from ..session import check_csrf_token @@ -11,3 +11,7 @@ cover-erase=1 [aliases] dev = develop easy_install pyramid[testing] docs = develop easy_install pyramid[docs] + +[bdist_wheel] +universal = 1 + @@ -68,7 +68,7 @@ testing_extras = tests_require + [ ] setup(name='pyramid', - version='1.5b1', + version='1.6dev', description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ @@ -79,6 +79,7 @@ setup(name='pyramid', "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Framework :: Pyramid", @@ -1,6 +1,6 @@ [tox] envlist = - py26,py27,py32,py33,pypy,cover + py26,py27,py32,py33,py34,pypy,cover [testenv] commands = |
