Steve Piercy
2013-03-21 a17c712f7f836b3506be069f60ee9ed8a8edb42b
Merge remote-tracking branch 'upstream/master'

Conflicts:
docs/tutorials/wiki2/installation.rst
1 files added
13 files modified
150 ■■■■ changed files
CHANGES.txt 8 ●●●●● patch | view | raw | blame | history
CONTRIBUTORS.txt 2 ●●●●● patch | view | raw | blame | history
docs/api/paster.rst 2 ●●● patch | view | raw | blame | history
docs/conf.py 11 ●●●● patch | view | raw | blame | history
docs/narr/router.rst 2 ●●● patch | view | raw | blame | history
docs/narr/urldispatch.rst 7 ●●●●● patch | view | raw | blame | history
docs/narr/viewconfig.rst 4 ●●●● patch | view | raw | blame | history
docs/tutorials/wiki2/basiclayout.rst 6 ●●●● patch | view | raw | blame | history
docs/tutorials/wiki2/definingmodels.rst 11 ●●●● patch | view | raw | blame | history
docs/tutorials/wiki2/installation.rst 18 ●●●●● patch | view | raw | blame | history
pyramid/paster.py 22 ●●●●● patch | view | raw | blame | history
pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py 9 ●●●●● patch | view | raw | blame | history
pyramid/tests/fixtures/dummy.ini 4 ●●●● patch | view | raw | blame | history
pyramid/tests/test_paster.py 44 ●●●● patch | view | raw | blame | history
CHANGES.txt
@@ -21,6 +21,14 @@
  define how to properly handle IPv6. See
  https://github.com/Pylons/pyramid/issues/831.
- Make it possible to use variable arguments via
  ``pyramid.paster.get_appsettings``. This also allowed the generated
  ``initialize_db`` script from the ``alchemy`` scaffold to grow support
  for options in the form ``a=1 b=2`` so you can fill in
  values in a parameterized ``.ini`` file, e.g.
  ``initialize_myapp_db etc/development.ini a=1 b=2``.
  See https://github.com/Pylons/pyramid/pull/911
Bug Fixes
---------
CONTRIBUTORS.txt
@@ -194,3 +194,5 @@
- John Anderson, 2012/11/14
- Bert JW Regeer, 2013/02/01
- Georges Dubus, 2013/03/21
docs/api/paster.rst
@@ -9,6 +9,6 @@
    .. autofunction:: get_app(config_uri, name=None, options=None)
    .. autofunction:: get_appsettings(config_uri, name=None)
    .. autofunction:: get_appsettings(config_uri, name=None, options=None)
    .. autofunction:: setup_logging(config_uri)
docs/conf.py
@@ -55,13 +55,14 @@
# Looks for objects in external projects
intersphinx_mapping = {
     'who': ('http://docs.repoze.org/who/2.0', None),
     'python': ('http://docs.python.org', None),
     'python3': ('http://docs.python.org/3', None),
     'tstring':
    'sqla': ('http://docs.sqlalchemy.org/en/latest', None),
    'who': ('http://docs.repoze.org/who/latest', None),
    'python': ('http://docs.python.org', None),
    'python3': ('http://docs.python.org/3', None),
    'tstring':
        ('http://docs.pylonsproject.org/projects/translationstring/en/latest',
          None),
     'venusian':
    'venusian':
        ('http://docs.pylonsproject.org/projects/venusian/en/latest', None),
}
docs/narr/router.rst
@@ -46,7 +46,7 @@
   :class:`~pyramid.interfaces.IRoute` object representing the route which
   matched.  The root object associated with the route found is also
   generated: if the :term:`route configuration` which matched has an
   associated a ``factory`` argument, this factory is used to generate the
   associated ``factory`` argument, this factory is used to generate the
   root object, otherwise a default :term:`root factory` is used.
#. If a route match was *not* found, and a ``root_factory`` argument was
docs/narr/urldispatch.rst
@@ -16,12 +16,13 @@
High-Level Operational Overview
-------------------------------
If route configuration is present in an application, the :app:`Pyramid`
If any route configuration is present in an application, the :app:`Pyramid`
:term:`Router` checks every incoming request against an ordered set of URL
matching patterns present in a *route map*.
If any route pattern matches the information in the :term:`request`,
:app:`Pyramid` will invoke :term:`view lookup` to find a matching view.
:app:`Pyramid` will invoke the :term:`view lookup` process to find a
matching view.
If no route pattern in the route map matches the information in the
:term:`request` provided in your application, :app:`Pyramid` will fail over
@@ -81,7 +82,7 @@
Note that we don't call :meth:`~pyramid.config.Configurator.add_view` in this
setup code.  However, the above :term:`scan` execution
``config.scan('mypackage')`` will pick up all :term:`configuration
``config.scan('mypackage')`` will pick up each :term:`configuration
decoration`, including any objects decorated with the
:class:`pyramid.view.view_config` decorator in the ``mypackage`` Python
package.  For example, if you have a ``views.py`` in your package, a scan will
docs/narr/viewconfig.rst
@@ -62,9 +62,9 @@
:term:`View predicate` attributes are an important part of view configuration
that enables the :term:`view lookup` subsystem to find and invoke the
appropriate view.  The greater number of predicate attributes possessed by a
appropriate view.  The greater the number of predicate attributes possessed by a
view's configuration, the more specific the circumstances need to be before
the registered view callable will be invoked.  The fewer number of predicates
the registered view callable will be invoked.  The fewer the number of predicates
which are supplied to a particular view configuration, the more likely it is
that the associated view callable will be invoked.  A view with five
predicates will always be found and evaluated before a view with two, for
docs/tutorials/wiki2/basiclayout.rst
@@ -43,9 +43,9 @@
application.  (See :ref:`startup_chapter` for more about ``pserve``.)
The main function first creates a :term:`SQLAlchemy` database engine using
``engine_from_config`` from the ``sqlalchemy.`` prefixed settings in the
``development.ini`` file's ``[app:main]`` section.  This will be a URI
(something like ``sqlite://``):
:func:`sqlalchemy.engine_from_config` from the ``sqlalchemy.`` prefixed
settings in the ``development.ini`` file's ``[app:main]`` section.
This will be a URI (something like ``sqlite://``):
   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :lines: 13
docs/tutorials/wiki2/definingmodels.rst
@@ -34,7 +34,7 @@
Then, we added a ``Page`` class.  Because this is a SQLAlchemy application,
this class inherits from an instance of
:class:`sqlalchemy.ext.declarative.declarative_base`.
:func:`sqlalchemy.ext.declarative.declarative_base`.
.. literalinclude:: src/models/tutorial/models.py
   :pyobject: Page
@@ -45,9 +45,10 @@
``__tablename__`` which equals the string ``'pages'``.  This means that
SQLAlchemy will store our wiki data in a SQL table named ``pages``.  Our
``Page`` class will also have class-level attributes named ``id``, ``name`` and
``data`` (all instances of :class:`sqlalchemy.Column`).  These will map to
columns in the ``pages`` table.  The ``id`` attribute will be the primary key
in the table.  The ``name`` attribute will be a text attribute, each value of
``data`` (all instances of :class:`sqlalchemy.schema.Column`).
These will map to columns in the ``pages`` table.
The ``id`` attribute will be the primary key in the table.
The ``name`` attribute will be a text attribute, each value of
which needs to be unique within the column.  The ``data`` attribute is a text
attribute that will hold the body of each page.
@@ -76,8 +77,6 @@
Installing the Project and re-initializing the Database
-------------------------------------------------------
Redo the steps in :ref:`installing_project_in_dev_mode`.
Because our model has changed, in order to reinitialize the database, we need
to rerun the ``initialize_tutorial_db`` command to pick up the changes you've made
docs/tutorials/wiki2/installation.rst
@@ -70,6 +70,7 @@
Install SQLite3 and Its Development Packages
--------------------------------------------
<<<<<<< HEAD
If you used a package manager to install your Python or if you compiled
your Python from source, then you must install SQLite3 and its
development packages.  If you downloaded your Python as an installer
@@ -78,23 +79,40 @@
If you need to install the SQLite3 packages, then, for example, using
the Debian system and apt-get, the command would be the following:
=======
Install SQLite3 and its development packages if you don't already
have them installed.  Usually this is via your system's package
manager. On a Debian system, this would be:
>>>>>>> upstream/master
   .. code-block:: text
      $ sudo apt-get install libsqlite3-dev
<<<<<<< HEAD
Change Directory to Your Virtual Python Environment
---------------------------------------------------
Change directory to the ``pyramidtut`` directory.
**On UNIX:**
=======
Entering the virtualenv
-----------------------
Do not forget to switch to the ``pyramidtut`` directory.
In order to do so, run this command if you are on Unix:
>>>>>>> upstream/master
   .. code-block:: text
      $ cd pyramidtut
<<<<<<< HEAD
**On Windows**
=======
And run this if you are on Windows:
>>>>>>> upstream/master
   .. code-block:: text
pyramid/paster.py
@@ -23,18 +23,22 @@
    path, section = _getpathsec(config_uri, name)
    config_name = 'config:%s' % path
    here_dir = os.getcwd()
    if options:
        kw = {'global_conf': options}
    else:
        kw = {}
    app = loadapp(config_name, name=section, relative_to=here_dir, **kw)
    app = loadapp(
        config_name,
        name=section,
        relative_to=here_dir,
        global_conf=options)
    return app
def get_appsettings(config_uri, name=None, appconfig=appconfig):
def get_appsettings(config_uri, name=None, options=None, appconfig=appconfig):
    """ Return a dictionary representing the key/value pairs in an ``app``
    section within the file represented by ``config_uri``.
    ``options``, if passed, should be a dictionary used as variable assignments
    like ``{'http_port': 8080}``.  This is useful if e.g. ``%(http_port)s`` is
    used in the config file.
    If the ``name`` is None, this will attempt to parse the name from
    the ``config_uri`` string expecting the format ``inifile#name``.
@@ -42,7 +46,11 @@
    path, section = _getpathsec(config_uri, name)
    config_name = 'config:%s' % path
    here_dir = os.getcwd()
    return appconfig(config_name, name=section, relative_to=here_dir)
    return appconfig(
        config_name,
        name=section,
        relative_to=here_dir,
        global_conf=options)
def setup_logging(config_uri, fileConfig=fileConfig,
                  configparser=configparser):
pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
@@ -9,6 +9,8 @@
    setup_logging,
    )
from pyramid.scripts.common import parse_vars
from ..models import (
    DBSession,
    MyModel,
@@ -18,17 +20,18 @@
def usage(argv):
    cmd = os.path.basename(argv[0])
    print('usage: %s <config_uri>\n'
    print('usage: %s <config_uri> [var=value]\n'
          '(example: "%s development.ini")' % (cmd, cmd))
    sys.exit(1)
def main(argv=sys.argv):
    if len(argv) != 2:
    if len(argv) < 2:
        usage(argv)
    config_uri = argv[1]
    options = parse_vars(argv[2:])
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    settings = get_appsettings(config_uri, options=options)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
pyramid/tests/fixtures/dummy.ini
New file
@@ -0,0 +1,4 @@
[app:myapp]
use = call:pyramid.tests.test_paster:make_dummyapp
foo = %(bar)s
pyramid/tests/test_paster.py
@@ -1,12 +1,12 @@
import os
import unittest
here = os.path.dirname(__file__)
class Test_get_app(unittest.TestCase):
    def _callFUT(self, config_file, section_name, options=None, loadapp=None):
    def _callFUT(self, config_file, section_name, **kw):
        from pyramid.paster import get_app
        return get_app(
            config_file, section_name, options=options, loadapp=loadapp
            )
        return get_app(config_file, section_name, **kw)
    def test_it(self):
        app = DummyApp()
@@ -55,15 +55,23 @@
        self.assertEqual(loadapp.kw, {'global_conf':options})
        self.assertEqual(result, app)
    def test_it_with_dummyapp_requiring_options(self):
        options = {'bar': 'baz'}
        app = self._callFUT(
            os.path.join(here, 'fixtures', 'dummy.ini'),
            'myapp', options=options)
        self.assertEqual(app.settings['foo'], 'baz')
class Test_get_appsettings(unittest.TestCase):
    def _callFUT(self, config_file, section_name, appconfig):
    def _callFUT(self, config_file, section_name, **kw):
        from pyramid.paster import get_appsettings
        return get_appsettings(config_file, section_name, appconfig)
        return get_appsettings(config_file, section_name, **kw)
    def test_it(self):
        values = {'a':1}
        appconfig = DummyLoadWSGI(values)
        result = self._callFUT('/foo/bar/myapp.ini', 'myapp', appconfig)
        result = self._callFUT('/foo/bar/myapp.ini', 'myapp',
                               appconfig=appconfig)
        self.assertEqual(appconfig.config_name, 'config:/foo/bar/myapp.ini')
        self.assertEqual(appconfig.section_name, 'myapp')
        self.assertEqual(appconfig.relative_to, os.getcwd())
@@ -72,7 +80,8 @@
    def test_it_with_hash(self):
        values = {'a':1}
        appconfig = DummyLoadWSGI(values)
        result = self._callFUT('/foo/bar/myapp.ini#myapp', None, appconfig)
        result = self._callFUT('/foo/bar/myapp.ini#myapp', None,
                               appconfig=appconfig)
        self.assertEqual(appconfig.config_name, 'config:/foo/bar/myapp.ini')
        self.assertEqual(appconfig.section_name, 'myapp')
        self.assertEqual(appconfig.relative_to, os.getcwd())
@@ -81,11 +90,19 @@
    def test_it_with_hash_and_name_override(self):
        values = {'a':1}
        appconfig = DummyLoadWSGI(values)
        result = self._callFUT('/foo/bar/myapp.ini#myapp', 'yourapp', appconfig)
        result = self._callFUT('/foo/bar/myapp.ini#myapp', 'yourapp',
                               appconfig=appconfig)
        self.assertEqual(appconfig.config_name, 'config:/foo/bar/myapp.ini')
        self.assertEqual(appconfig.section_name, 'yourapp')
        self.assertEqual(appconfig.relative_to, os.getcwd())
        self.assertEqual(result, values)
    def test_it_with_dummyapp_requiring_options(self):
        options = {'bar': 'baz'}
        result = self._callFUT(
            os.path.join(here, 'fixtures', 'dummy.ini'),
            'myapp', options=options)
        self.assertEqual(result['foo'], 'baz')
class Test_setup_logging(unittest.TestCase):
    def _callFUT(self, config_file):
@@ -165,6 +182,12 @@
    def __init__(self):
        self.registry = dummy_registry
def make_dummyapp(global_conf, **settings):
    app = DummyApp()
    app.settings = settings
    app.global_conf = global_conf
    return app
class DummyRequest:
    application_url = 'http://example.com:5432'
    script_name = ''
@@ -181,6 +204,3 @@
class DummyConfigParserModule(object):
    ConfigParser = DummyConfigParser