Giter Site home page Giter Site logo

bbangert / routes Goto Github PK

View Code? Open in Web Editor NEW
165.0 165.0 60.0 1.24 MB

Routes is a Python URL recognition and generation system similar to the Rails routing system. Routes makes it easy to create pretty and concise URL's that are RESTful with little effort.

Home Page: http://routes.readthedocs.org

License: MIT License

Python 100.00%

routes's Introduction

routes's People

Contributors

aib avatar alex avatar alsanchez avatar anandanvivopenstack avatar asplake avatar bbangert avatar floppym avatar frewsxcv avatar gawel avatar huanghao avatar hub-cap avatar kapyshin avatar lmacken avatar marc1n avatar mcdonc avatar mikeorr avatar mnaberez avatar phillbaker avatar pjenvey avatar samdphillips avatar sdague avatar sixohsix avatar stephenfin avatar stmcginnis avatar the-code-robot avatar uralbash avatar uvnikita avatar vstinner avatar webknjaz avatar yoriksar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

routes's Issues

repoze.lru not installed automatically

Is there a reason why there is no requirements.txt file for this repo? I'm using routes, but when I try install using pip, it does not install the repoze.lru package and my application naturally fails. I'm currently getting around this by adding repoze.lru in my own requirements file, but upstream would be more simple :)

HTTP_X_FORWARDED_HOST is assumed to be a single host

In cache_hostinfo() HTTP_X_FORWARDED_HOST is parsed as a normal host. If the application is behind more than one proxy it appears that this can be a comma-separated list of hosts.

In this case invalid urls are returned.

Unclear how to determine allowed methods per URL, so hard to make a 405

When a URL exists, but does not support a particular method (e.g. DELETE) the correct response is to return an HTTP 405 response code. Routes doesn't make this immediately easy. By default a mapping that does not match just returns None with no indication that it was because of a failed condition after an initial path match. So what I've had to come up with is something like the following test, which seems cumbersome. Is there a better way?

from routes import Mapper, middleware

def test_405():
    map = Mapper()
    map.connect(
        '/controller/{id}', action='get_handler',
        conditions=dict(method=['GET', 'HEAD']))
    map.connect('/controller/{id}', action='post_handler',
        conditions=dict(method=['POST']))
    map.connect('/controller/{id}', action='405_handler')

    environ = {
        'PATH_INFO': '/controller/cow',
        'REQUEST_METHOD': 'GET',
        'SERVER_NAME': 'example.com',
        'SERVER_PORT': '80',
        'wsgi.url_scheme': 'http',
    }

    result = map.match(environ=environ)
    assert result['action'] == 'get_handler'

    environ['REQUEST_METHOD'] = 'POST'
    result = map.match(environ=environ)
    assert result['action'] == 'post_handler'

    environ['REQUEST_METHOD'] = 'PUT'
    result = map.match(environ=environ)
    assert result['action'] == '405_handler'

    environ['PATH_INFO'] = '/missed/url'
    result = map.match(environ=environ)
    assert result is None

Should not be using a universal wheel

Since the build process runs 2to3 automatically instead of the code working on either Python 2 or Python 3, a wheel built on either version won't run on the other; it's inappropriate for setup.cfg to declare a universal wheel should be built.

(pip will cache a wheel built on 2 and try to use it on 3, which will fail horribly)

routes.middleware not Python 2.x compatible (ImportError: No module named request)

New in routes 2.1...

Python 2.7.6 (default, Mar 22 2014, 15:40:47) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import routes.middleware
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/scratch/routes/local/lib/python2.7/site-packages/routes/__init__.py", line 145, in <module>
    from routes.mapper import Mapper
  File "/scratch/routes/local/lib/python2.7/site-packages/routes/mapper.py", line 8, in <module>
    from routes.util import (
  File "/scratch/routes/local/lib/python2.7/site-packages/routes/util.py", line 10, in <module>
    import urllib.request, urllib.parse, urllib.error
ImportError: No module named request

It looks like util.py assumes a Py3K urllib rather than using urllib2.Requests here?

Can't print a `Mapper` object

While fixing #11 a bug was introduced.

table = [('Route name', 'Methods', 'Path', 'Controller', 'action')] + \
        [(r.name or '', format_methods(r), r.routepath or '',
          r.defaults.get('controller', ''), r.defaults.get('action', ''))
         for r in self.matchlist]

widths = [max(len(row[col]) for row in table)
          for col in range(len(table[0]))]

While iterating over all the rows and all the columns of the table, a call to len(r.defaults.get('controller', '')) is going to be made. But r.defaults.get('controller', '') is an instance of a class that doesn't have to have a __len__ method. So this code will fail with TypeError: object of type 'ResourceV21' has no len().

Package installation fails where system preferred locale encoding is ASCII.

Due to the presence of a non ASCII character in the CHANGELOG.rst file, installation of the package can fail under Python 3 if the system default encoding for Python is ASCII.

Downloading/unpacking routes
  Running setup.py egg_info for package routes
    Traceback (most recent call last):
      File "<string>", line 16, in <module>
      File "/data/tests/component_cornice/.tox-0016/py33-with-extensions/build/routes/setup.py", line 9, in <module>
        CHANGES = open(os.path.join(here, 'CHANGELOG.rst')).read()
      File "/data/tests/component_cornice/.tox-0016/py33-with-extensions/lib/python3.3/encodings/ascii.py", line 26, in decode
        return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 162: ordinal not in range(128)
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):

  File "<string>", line 16, in <module>

  File "/data/tests/component_cornice/.tox-0016/py33-with-extensions/build/routes/setup.py", line 9, in <module>

    CHANGES = open(os.path.join(here, 'CHANGELOG.rst')).read()

  File "/data/tests/component_cornice/.tox-0016/py33-with-extensions/lib/python3.3/encodings/ascii.py", line 26, in decode

    return codecs.ascii_decode(input, self.errors)[0]

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 162: ordinal not in range(128)

This appears to correspond to 'á' in 'Alejandro Sánchez'.

2.5.1: sphinx error

Looks like new sphish shoes some errors on generate documentation

+ /usr/bin/python3 setup.py build_sphinx -b man --build-dir build/sphinx
running build_sphinx
Running Sphinx v4.3.1

Configuration error:
There is a syntax error in your configuration file: (unicode error) 'unicodeescape' codec can't decode bytes in position 1-2: truncated \uXXXX escape (conf.py, line 163)

Optional parts count towards 100 capturing group python re limit in Routes master regex

Python re has limit of 100 capturing groups per expression. Mostly Routes (1.13 at the moment) uses anonymous groups which don't count towards the limit. However it doesn't do so in all the cases. Particularly an optional URL part is wrapped in capturing group which counts and Routes fails with re group limit assertion.

The group is created at line 455 in route.py. Fixing group to anonymous solves the issue. There are another two non-anonymous groups in adjacent if branches which should probably use anonymous groups as well.

Here's the patch: https://gist.github.com/saaj/7154231.

About Version 2.4.1

Update the version. The current version has not been updated for more than three years.
I think it's not active at the moment. If it goes on like this, it will affect the usage. Thank you.

Incorrect wheel for py3k

Hi @bbangert,
when I'm trying to install Routes==2.0 with pip under python 3 I get following error (from pip.log):

Cleaning up...
  Removing temporary dir /home/wk/private/work/source/cherrypy/.tox/py33/build...
Routes is in an unsupported or invalid wheel
Exception information:
Traceback (most recent call last):
  File "/home/wk/private/work/source/cherrypy/.tox/py33/lib/python3.3/site-packages/pip/basecommand.py", line 122, in main
    status = self.run(options, args)
  File "/home/wk/private/work/source/cherrypy/.tox/py33/lib/python3.3/site-packages/pip/commands/install.py", line 283, in run
    requirement_set.install(install_options, global_options, root=options.root_path)
  File "/home/wk/private/work/source/cherrypy/.tox/py33/lib/python3.3/site-packages/pip/req.py", line 1435, in install
    requirement.install(install_options, global_options, *args, **kwargs)
  File "/home/wk/private/work/source/cherrypy/.tox/py33/lib/python3.3/site-packages/pip/req.py", line 669, in install
    pip.wheel.check_compatibility(version, self.name)
  File "/home/wk/private/work/source/cherrypy/.tox/py33/lib/python3.3/site-packages/pip/wheel.py", line 438, in check_compatibility
    "%s is in an unsupported or invalid wheel" % name
pip.exceptions.UnsupportedWheel: Routes is in an unsupported or invalid wheel

The snippet (from site-packages/pip/wheel.py) which generates the exception is

def check_compatibility(version, name):
    """
    Raises errors or warns if called with an incompatible Wheel-Version.

    Pip should refuse to install a Wheel-Version that's a major series
    ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when
    installing a version only minor version ahead (e.g 1.2 > 1.1).

    version: a 2-tuple representing a Wheel-Version (Major, Minor)
    name: name of wheel or package to raise exception about

    :raises UnsupportedWheel: when an incompatible Wheel-Version is given
    """
    if not version:
        raise UnsupportedWheel(
            "%s is in an unsupported or invalid wheel" % name
        )
    if version[0] > VERSION_COMPATIBLE[0]:
        raise UnsupportedWheel(
            "%s's Wheel-Version (%s) is not compatible with this version "
            "of pip" % (name, '.'.join(map(str, version)))
        )
    elif version > VERSION_COMPATIBLE:
        logger.warn('Installing from a newer Wheel-Version (%s)'
                    % '.'.join(map(str, version)))

So I guess it should be repackaged.

P.S. Attempt to install it from git (./.tox/py33/bin/pip install git+https://github.com/bbangert/routes.git) succeeds. I faced this issue while running tox in cherrypy repo.

PyPi 2.3.1 and 2.4 packages missing

$ pip install -I Routes==2.3.1
Could not find a version that satisfies the requirement Routes==2.3.1 (from versions: 1.5, 1.5.1, 1.5.2, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.7, 1.7.1, 1.7.2, 1.7.3, 1.8, 1.9, 1.9.1, 1.9.2, 1.10, 1.10.1, 1.10.2, 1.10.3, 1.11, 1.12, 1.12.1, 1.12.3, 1.13, 2.0, 2.1, 2.2, 2.3)                                                                                                                                                                                                                
No matching distribution found for Routes==2.3.1
$ pip install -I Routes==2.4
Could not find a version that satisfies the requirement Routes==2.4 (from versions: 1.5, 1.5.1, 1.5.2, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.7, 1.7.1, 1.7.2, 1.7.3, 1.8, 1.9, 1.9.1, 1.9.2, 1.10, 1.10.1, 1.10.2, 1.10.3, 1.11, 1.12, 1.12.1, 1.12.3, 1.13, 2.0, 2.1, 2.2, 2.3)                                                                                                                                                                                                                  
No matching distribution found for Routes==2.4

Python 3 Support

Hello,

Are there any plans to add support for python 3? Now that Python 3.3 is close to release, I'd love to be able to use routes with it.

Thanks!

CHANGELOG.rst isn't included in the released package and installation fails

Trying to install from sources raises an error while setup.py is being executed. See complete log below:

$ pip install Routes
Downloading/unpacking Routes
  Downloading Routes-2.0.tar.gz (192kB): 192kB downloaded
  Running setup.py egg_info for package Routes
    Traceback (most recent call last):
      File "<string>", line 16, in <module>
      File "/home/freyes/.virtualenvs/oslo/build/Routes/setup.py", line 9, in <module>
        CHANGES = open(os.path.join(here, 'CHANGELOG.rst')).read()
    IOError: [Errno 2] No such file or directory: '/home/freyes/.virtualenvs/oslo/build/Routes/CHANGELOG.rst'
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):

  File "<string>", line 16, in <module>

  File "/home/freyes/.virtualenvs/oslo/build/Routes/setup.py", line 9, in <module>

    CHANGES = open(os.path.join(here, 'CHANGELOG.rst')).read()

IOError: [Errno 2] No such file or directory: '/home/freyes/.virtualenvs/oslo/build/Routes/CHANGELOG.rst'

Matching a url to Mapper with the methods=["GET"]

I am implementing Routes into a micro framework for a web 3200 class. Anyhow the problem is that if I write the Mapper with a url map such as:

/api/{filename}/{id}

For my match function I need to pass in the method like "GET" or "POST" and make sure it exists else I need to raise a ValueError. Is there a native way of doing this?

Change in order of route matching from #89

I believe #89 introduced coder that results in a different ordering for routes being matched. I think a reproducible case would be:

mapper.connect("Foo action", "/api/{version}/foo/action", controller=controller, action=an_action, conditions={"method": ["GET"]}, requirements={"version": V1_REGEX})
mapper.connect("Get foo", "/api/v1/foo/{foo_id}", controller=controller, action=get_action, conditions={"method": ["GET"]}, requirements={})

Although the 2nd path is registered second, because it has a longer static prefix it will match first. Previously, routes would have been guaranteed to match in the order that they were registered. There are workarounds (e.g. ensure routes use the same prefix), however, this is unexpected.

I don't have a concrete suggestion for fixing this optimization at the moment, other than limiting its scope to specific instances of route lists where these overlaps do not occur.

For the time being, would it be possible to revert #89?

Wrong error code returned

When using an undefined method (i.e. the used method's name is not in the list of methods assigned to the method key in the dictionary passed to conditions in a connect fcn call) the error returned is 404 Not Found while it should be 405 Method Not Allowed.

Documentation Problems

There are two noticeable problems with the documentation:

1/ Use of keywords as variables, e.g.: map = Mapping... this can cause some obscure bugs if duplicated.
2/ No links to bug tracker, contacts, etc.

Unable to create a URL with either "host", "anchor" or "protocol" as a parameter

Hi,

I think commit d1d1742 made it impossible to create an URL with a parameter named "host", "anchor" or "protocol" due to the changes in routes/util.py.

Before that commit, it was possible to call an URLGenerator like so:

URLGenerator(mapper, environ)("/foo", host_="bar")

to get this kind of URL: "/foo?host=bar"

(the "_" is necessary because a parameter named "host" would simply replace the FQDN, creating a URL such as "http://bar/foo")

Is there a new mechanism that allows passing a parameter with one of the three names above or is this a regression?

Need more info in mapper print

It is still tricky to understand the complete routing from the print function. Can we propose two additional columns in mapper.py Mapper.str:

table = [('Route name', 'Methods', 'Path', 'Controller', 'action')] +
[(r.name or '', format_methods(r), r.routepath or '',r.defaults.get('controller'), r.defaults.get('action'))
for r in self.matchlist]

Thanks!

Invalid escape sequences when running under py36

Python 3.6 is more strict about allowing escape characters in normal strings. This most often occurs with regex strings and results in warning messages such as the following:

routes/mapper.py:410: DeprecationWarning: invalid escape sequence .

In most cases this is just a matter of changing from a regular string ("") to a raw string (r"").

Parent resources with hyphens cannot add sub resource through mapper.resource

It seems that mapper.resource does not function correctly when specifying a parent resource that has a hyphen in the name.

 mapper.resource("my-type", "my-types",
                        controller=my_controller,
                        collection={"detail": "GET", "default": "GET"},
                        member={"action": "POST"})

mapper.resource("spec", "spec",
                        controller=my_controller,
                        parent_resource=dict(member_name="my-type", collection_name="my-types"))

mapper.routematch("/my-types/blah-id/spec") <-- this returns None

If i change it to:

 mapper.resource("mytype", "mytypes",
                        controller=my_controller,
                        collection={"detail": "GET", "default": "GET"},
                        member={"action": "POST"})

mapper.resource("spec", "spec",
                        controller=my_controller,
                        parent_resource=dict(member_name="mytype", collection_name="mytypes"))

mapper.routematch("/mytypes/blah-id/spec") <-- this returns the Resource

I can get around this by instead doing

 mapper.resource("my-type", "my-types",
                        controller=my_controller,
                        collection={"detail": "GET", "default": "GET"},
                        member={"action": "POST"})

mapper.connect("spec", "/mytypes/{id}/spec",
                          controller=my_controller,
                          action="index",
                          conditions={"method": ["GET"]})

ASCII characters limitations

if not ascii_characters(url) and url is not None:

    if not ascii_characters(url) and url is not None:
        raise GenerationException("url_for can only return a string, got "
                        "unicode instead: %s" % url)

What's the problem to generate none ascii routes?

Needless modules/lru.rst

modules/lru.rst refers to non-existent routes.lru module, which results in ImportError shown during building documentation:

$ cd docs
$ PYTHONPATH=".." make html
mkdir -p _build/html _build/doctrees
sphinx-build -b html -d _build/doctrees   . _build/html
Running Sphinx v1.2b3
loading pickled environment... not yet created
building [html]: targets for 17 source files that are out of date
updating environment: 17 added, 0 changed, 0 removed
reading sources... [100%] uni_redirect_rest                                                                                                                  
/tmp/routes/docs/modules/lru.rst:4: WARNING: autodoc: failed to import module u'routes.lru'; the following exception was raised:
Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/sphinx/ext/autodoc.py", line 335, in import_object
    __import__(self.modname)
ImportError: No module named lru
/tmp/routes/docs/modules/lru.rst:9: WARNING: don't know which module to import for autodocumenting u'LRUCache' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
looking for now-outdated files... none found
pickling environment... done
checking consistency... /tmp/routes/docs/todo.rst:: WARNING: document isn't included in any toctree
done
preparing documents... done
writing output... [100%] uni_redirect_rest                                                                                                                   
writing additional files... genindex py-modindex search
copying static files... done
copying extra files... dumping search index... done
dumping object inventory... done
build succeeded, 3 warnings.

Build finished. The HTML pages are in _build/html.

无法识别前缀

API为/v3/test 无法匹配到/{prefix}/v3/test的路由 以变量为首的路由无法匹配

2.5.1: pytest warnings

I'm trying to package your module as an rpm package. So I'm using the typical build, install and test cycle used on building packages from non-root account.

  • "setup.py build"
  • "setup.py install --root </install/prefix>"
  • "pytest with PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>

Here are pytest warnings:

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-routes-2.5.1-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-routes-2.5.1-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
benchmark: 3.4.1 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
Using --randomly-seed=3825766791
rootdir: /home/tkloczko/rpmbuild/BUILD/routes-2.5.1
plugins: shutil-1.7.0, virtualenv-1.7.0, mock-3.6.1, cov-2.12.1, anyio-3.3.4, forked-1.3.0, xdist-2.3.0, flaky-3.7.0, tornasync-0.6.0.post2, console-scripts-1.2.0, trio-0.7.0, timeout-2.0.1, asyncio-0.16.0, freezegun-0.4.2, flake8-1.0.7, pyfakefs-4.5.3, hypothesis-6.29.3, benchmark-3.4.1, profiling-1.7.0, datadir-1.3.1, regressions-2.2.0, randomly-3.8.0, rerunfailures-9.1.1, yagot-0.5.0, requests-mock-1.9.3, django-4.5.1
collected 211 items

tests/test_functional/test_submapper.py ............                                                                                                                 [  5%]
tests/test_functional/test_generation.py .................................................                                                                           [ 28%]
tests/test_functional/test_recognition.py ..........................................................                                                                 [ 56%]
tests/test_functional/test_resources.py ...........                                                                                                                  [ 61%]
tests/test_functional/test_nonminimization.py .........                                                                                                              [ 65%]
tests/test_functional/test_middleware.py .......                                                                                                                     [ 69%]
tests/test_functional/test_utils.py .........................................                                                                                        [ 88%]
tests/test_functional/test_explicit_use.py .............                                                                                                             [ 94%]
tests/test_units/test_base.py ..                                                                                                                                     [ 95%]
tests/test_units/test_mapper_str.py .                                                                                                                                [ 96%]
tests/test_units/test_environment.py .                                                                                                                               [ 96%]
tests/test_units/test_route_escapes.py .......                                                                                                                       [100%]

============================================================================= warnings summary =============================================================================
tests/test_functional/test_generation.py:204
tests/test_functional/test_generation.py:204
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:204: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_generation.py:219
tests/test_functional/test_generation.py:219
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:219: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_generation.py:245
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:245: DeprecationWarning: invalid escape sequence \d
    m.connect('articles/page/:page', controller='articles', action='index', requirements = {'page':'\d+'})

tests/test_functional/test_generation.py:248
tests/test_functional/test_generation.py:248
tests/test_functional/test_generation.py:248
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:248: DeprecationWarning: invalid escape sequence \d
    requirements = {'year':'\d{4}', 'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_generation.py:284
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:284: DeprecationWarning: invalid escape sequence \d
    m.connect('articles/page/:(page).myt', controller='articles', action='index', requirements = {'page':'\d+'})

tests/test_functional/test_generation.py:287
tests/test_functional/test_generation.py:287
tests/test_functional/test_generation.py:287
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:287: DeprecationWarning: invalid escape sequence \d
    requirements = {'year':'\d{4}', 'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_generation.py:323
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:323: DeprecationWarning: invalid escape sequence \d
    m.connect('articles/page/:page', controller='articles', action='index', requirements = {'page':'\d+'})

tests/test_functional/test_generation.py:326
tests/test_functional/test_generation.py:326
tests/test_functional/test_generation.py:326
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:326: DeprecationWarning: invalid escape sequence \d
    requirements = {'year':'\d{4}', 'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_generation.py:497
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:497: DeprecationWarning: invalid escape sequence \d
    m.connect('test/:year', controller='post', action='show', year=None, requirements = {'year':'\d{4}'})

tests/test_functional/test_generation.py:673
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:673: DeprecationWarning: invalid escape sequence \d
    m.connect('articles/page/:page', controller='articles', action='index', requirements = {'page':'\d+'})

tests/test_functional/test_generation.py:676
tests/test_functional/test_generation.py:676
tests/test_functional/test_generation.py:676
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_generation.py:676: DeprecationWarning: invalid escape sequence \d
    requirements = {'year':'\d{4}', 'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_nonminimization.py:91
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_nonminimization.py:91: DeprecationWarning: invalid escape sequence \d
    m.connect('/{controller}/{action}/{id:\d\d}')

tests/test_functional/test_recognition.py:212
tests/test_functional/test_recognition.py:212
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:212: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_recognition.py:228
tests/test_functional/test_recognition.py:228
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:228: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_recognition.py:245
tests/test_functional/test_recognition.py:245
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:245: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_recognition.py:261
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:261: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}'})

tests/test_functional/test_recognition.py:262
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:262: DeprecationWarning: invalid escape sequence \d
    m.connect('view/:id/:controller', controller='blog', id=2, action='view', requirements={'id':'\d{1,2}'})

tests/test_functional/test_recognition.py:276
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:276: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}'})

tests/test_functional/test_recognition.py:277
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:277: DeprecationWarning: invalid escape sequence \d
    m.connect('view/:(id)/:(controller)', controller='blog', id=2, action='view', requirements={'id':'\d{1,2}'})

tests/test_functional/test_recognition.py:291
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:291: DeprecationWarning: invalid escape sequence \d
    m.connect(path, id=2, action='view', requirements={'id':'\d{1,2}'})

tests/test_functional/test_recognition.py:305
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:305: DeprecationWarning: invalid escape sequence \d
    m.connect(path, controller='blog', id=2, action='view', requirements={'id':'\d{1,2}'})

tests/test_functional/test_recognition.py:929
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:929: DeprecationWarning: invalid escape sequence \d
    m.connect('articles/page/:page', controller='articles', action='index', requirements = {'page':'\d+'})

tests/test_functional/test_recognition.py:932
tests/test_functional/test_recognition.py:932
tests/test_functional/test_recognition.py:932
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_recognition.py:932: DeprecationWarning: invalid escape sequence \d
    requirements = {'year':'\d{4}', 'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_resources.py:144
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:144: DeprecationWarning: invalid escape sequence \.
    test_path('/people/2\.13', 'PUT')

tests/test_functional/test_resources.py:145
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:145: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'2\.13'}

tests/test_functional/test_resources.py:146
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:146: DeprecationWarning: invalid escape sequence \.
    test_path('/people/2\.13.xml', 'PUT')

tests/test_functional/test_resources.py:147
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:147: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'2\.13', 'format':'xml'}

tests/test_functional/test_resources.py:148
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:148: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.name', 'PUT')

tests/test_functional/test_resources.py:149
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:149: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.name'}

tests/test_functional/test_resources.py:150
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:150: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.\.\.name', 'PUT')

tests/test_functional/test_resources.py:151
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:151: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.\.\.name'}

tests/test_functional/test_resources.py:152
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:152: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.name\.has\.dots', 'PUT')

tests/test_functional/test_resources.py:153
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:153: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.name\.has\.dots'}

tests/test_functional/test_resources.py:154
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:154: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.name\.is\.something.xml', 'PUT')

tests/test_functional/test_resources.py:155
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:155: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.name\.is\.something', 'format':'xml'}

tests/test_functional/test_resources.py:156
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:156: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.name\.ends\.with\.dot\..xml', 'PUT')

tests/test_functional/test_resources.py:157
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:157: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.name\.ends\.with\.dot\.', 'format':'xml'}

tests/test_functional/test_resources.py:158
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:158: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.name\.ends\.with\.dot\.', 'PUT')

tests/test_functional/test_resources.py:159
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:159: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.name\.ends\.with\.dot\.'}

tests/test_functional/test_resources.py:160
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:160: DeprecationWarning: invalid escape sequence \.
    test_path('/people/\.user\.name\.starts\.with\.dot', 'PUT')

tests/test_functional/test_resources.py:161
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:161: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'\.user\.name\.starts\.with\.dot'}

tests/test_functional/test_resources.py:162
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:162: DeprecationWarning: invalid escape sequence \.
    test_path('/people/user\.name.json', 'PUT')

tests/test_functional/test_resources.py:163
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_resources.py:163: DeprecationWarning: invalid escape sequence \.
    assert con.mapper_dict == {'controller':'people', 'action':'update', 'id':'user\.name', 'format':'json'}

tests/test_functional/test_submapper.py:10
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_submapper.py:10: DeprecationWarning: invalid escape sequence \d
    c = m.submapper(path_prefix='/entries', requirements=dict(id='\d+'))

tests/test_functional/test_submapper.py:26
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_submapper.py:26: DeprecationWarning: invalid escape sequence \d
    requirements=dict(id='\d+'))

tests/test_functional/test_submapper.py:161
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_submapper.py:161: DeprecationWarning: invalid escape sequence \d
    requirement=dict(id='\d+')

tests/test_functional/test_utils.py:13
tests/test_functional/test_utils.py:13
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_utils.py:13: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_utils.py:761
tests/test_functional/test_utils.py:761
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_utils.py:761: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_functional/test_utils.py:977
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_utils.py:977: DeprecationWarning: invalid escape sequence \d
    m.connect('articles/page/:page', controller='articles', action='index', requirements = {'page':'\d+'})

tests/test_functional/test_utils.py:980
tests/test_functional/test_utils.py:980
tests/test_functional/test_utils.py:980
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_functional/test_utils.py:980: DeprecationWarning: invalid escape sequence \d
    requirements = {'year':'\d{4}', 'month':'\d{1,2}','day':'\d{1,2}'})

tests/test_units/test_environment.py:9
tests/test_units/test_environment.py:9
  /home/tkloczko/rpmbuild/BUILD/routes-2.5.1/tests/test_units/test_environment.py:9: DeprecationWarning: invalid escape sequence \d
    requirements={'month':'\d{1,2}','day':'\d{1,2}'})

-- Docs: https://docs.pytest.org/en/stable/warnings.html
===================================================================== 211 passed, 71 warnings in 5.07s =====================================================================

Duplicated code of URL generation

In util.py module there are url_for() function and URLGenerator.call method each has over 100 lines of complicated code which does almost exactly the same thing. It's ugly!

One of bad consequences of this is that it is hard to answer if I can safely replace "pylons.url(...)" (URLGenerator instance call) with "paste.url_for(...)" (url_for function call) in my pylons application?

escaping colon as part of the path

I understand it's very non-standard, but I need colons as fixed parts of my mapping

I'd like my code to look like this:

m.connect('/id/foo:{fooId}'), controller='getFoo')
m.connect('/id/bar:{barId}'), controller='getBar')

Right now I'm getting the error bad character in group name '{fooId}'

Is it doable?

Errors in example on documentation front page.

The documentation front page on Read the Docs contains an example of routes usage but this example contains two errors.


First, the following snippet is missing a double-quote before the comma:

 map.connect(None, "/error/{action}/{id}, controller="error")

It probably should read like the following (note that this will fix the syntax highlighting):

 map.connect(None, "/error/{action}/{id}", controller="error")

Second, the following snippet should probably read 'controller': 'error' to match the mapping.

# result == {'controller': 'main', 'action': 'myapp', 'id': '4'}

It should read like the following since it matches the map.connect(..., controller="error") pattern.

# result == {'controller': 'error', 'action': 'myapp', 'id': '4'}

On a side note, it might be interesting to explain why the action is set to myapp, perhaps this is the default?

doc build fails

Here are at least 2 ways the doc build fails in 2 versions;

'/path/to/Routes-2.1/docs/ $ make -C docs/ html
make: Entering directory '/path/to/Routes-2.1/docs/
mkdir -p _build/html _build/doctrees
sphinx-build -b html -d _build/doctrees   . _build/html
Running Sphinx v1.3
loading pickled environment... not yet created
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 16 source files that are out of date
updating environment: 16 added, 0 changed, 0 removed
reading sources... [100%] uni_redirect_rest                                                                                 
/mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs/index.rst:51: ERROR: Unknown target name: "github issue tracker <https://github.com/bbangert/routes/issues".
/mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs/todo.rst:5: SEVERE: Problems with "include" directive path:
InputError: [Errno 2] No such file or directory: '../TODO'.
looking for now-outdated files... none found
pickling environment... done
checking consistency... /mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs/todo.rst:: WARNING: document isn't included in any toctree
done
preparing documents... 
Theme error:
unsupported theme option 'relbarlinkcolor' given
Makefile:29: recipe for target 'html' failed
make: *** [html] Error 1
make: Leaving directory '/mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs'

ditto Routes-2.0.

from an ebuild;

~/cvsPortage/gentoo-x86/dev-python/routes $ USE=doc ebuild routes-2.1.ebuild clean compile

reading sources... [ 93%] todo
reading sources... [100%] uni_redirect_rest

/mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs/index.rst:51: ERROR: Unknown target name: "github issue tracker <https://github.com/bbangert/routes/issues".
/mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs/todo.rst:5: SEVERE: Problems with "include" directive path:
InputError: [Errno 2] No such file or directory: '../TODO'.
looking for now-outdated files... none found
pickling environment... done
checking consistency... /mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs/todo.rst:: WARNING: document isn't included in any toctree
done
preparing documents... 
Theme error:
unsupported theme option 'relbarlinkcolor' given
Makefile:29: recipe for target 'html' failed
make: *** [html] Error 1
make: Leaving directory '/mnt/gen2/TmpDir/portage/dev-python/routes-2.1/work/Routes-2.1/docs'
 * ERROR: dev-python/routes-2.1::gentoo failed (compile phase):
 *   emake failed

ditto routes-2.0.ebuild

Release new version

I want to know the release time of version 2.5.0. Please let me know. Thank you. This is because version 2.4.1 has been released for a long time.

Routes 2.3 changes API for SubMapper.connect()

In OpenStack Neutron (and other projects) we call SubMapper.connect() with a single argument. See
https://github.com/openstack/neutron/blob/stable/kilo/neutron/api/extensions.py#L293

As of Routes 2.3 this now generates a traceback. See
http://logs.openstack.org/95/293195/5/check/gate-tempest-dsvm-neutron-full-kilo/d5c1fd1/logs/screen-q-svc.txt.gz#_2016-03-28_21_10_22_791

This is because 0a41700 made is mandatory to pass 2 args into connect

0a41700#diff-b54de741c3f86d76eb4bce4a223054aaR168

Was that patch a deliberate API break?
Is there any possibility of releasing 2.3.1 with the old behavior?

repeating a variable in a path/pattern fails

Using the same variable name in a path mutiple times fails:

import routes
m = routes.Mapper()
m.connect("/redfish/v1/Systems/{ComputerSystemId}/Memory/{MemoryId}/Oem/Dell/DellMemory/{MemoryId}")
m.routematch("/redfish/v1/Systems/1/Memory/0/Oem/Dell/DellMemory/0")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "~/venv//lib/python3.10/site-packages/routes/mapper.py", line 761, in routematch
    result = self._match(url, environ)
  File "~/venv//lib/python3.10/site-packages/routes/mapper.py", line 672, in _match
    self.create_regs()
  File "~/venv//lib/python3.10/site-packages/routes/mapper.py", line 612, in create_regs
    self._create_regs(*args, **kwargs)
  File "~/venv//lib/python3.10/site-packages/routes/mapper.py", line 630, in _create_regs
    route.makeregexp(clist)
  File "~/venv//lib/python3.10/site-packages/routes/route.py", line 315, in makeregexp
    self.regmatch = re.compile(reg)
  File "/usr/lib/python3.10/re.py", line 251, in compile
    return _compile(pattern, flags)
  File "/usr/lib/python3.10/re.py", line 303, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib/python3.10/sre_compile.py", line 788, in compile
    p = sre_parse.parse(p, flags)
  File "/usr/lib/python3.10/sre_parse.py", line 955, in parse
    p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)
  File "/usr/lib/python3.10/sre_parse.py", line 444, in _parse_sub
    itemsappend(_parse(source, state, verbose, nested + 1,
  File "/usr/lib/python3.10/sre_parse.py", line 838, in _parse
    raise source.error(err.msg, len(name) + 1) from None
re.error: redefinition of group name 'MemoryId' as group 3; was group 2 at position 102

basic map.connect(None, "/{controller}/{action}/{id}") fails?

I have to use the basic mapping method for a dynamic controller and this simple documentation example fails (python3.2):

from routes import Mapper
map = Mapper()
map.connect(None, "/{controller}/{action}/{id}")
map.create_regs()

print(map.match("/ctl/act/1"))
>> None

Normally this should return:

{"controller" : "ctl", "action" : "act", "id" : "1"}

Any help is appreciated, thanks.

Need a new release 2.2 to get the Python 3 fix

Hi,

My pull request #44 was accepted, but there is not release including this fix yet. So I'm still unable to install Routes on Python 3 (because of the new cache of wheels of pip 7). Please release a new version including this fix. Thanks ;-)

Victor

middleware uses webob, which is not a declared dependency

$ ../venvs/virtualenv/bin/virtualenv routes 
Using real prefix '/usr'
New python executable in routes/bin/python
Installing setuptools, pip...done.
$ routes/bin/pip install -U routes
Collecting routes
  Downloading Routes-2.1.tar.gz (179kB)
    100% |################################| 180kB 777kB/s 
Collecting repoze.lru>=0.3 (from routes)
  Downloading repoze.lru-0.6.tar.gz
Installing collected packages: repoze.lru, routes
  Running setup.py install for repoze.lru
    Skipping installation of /scratch/routes/lib/python2.7/site-packages/repoze/__init__.py (namespace package)
    Installing /scratch/routes/lib/python2.7/site-packages/repoze.lru-0.6-py2.7-nspkg.pth
  Running setup.py install for routes
Successfully installed repoze.lru-0.6 routes-2.1
$ routes/bin/python
Python 2.7.6 (default, Mar 22 2014, 15:40:47) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import routes.middleware
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/scratch/routes/local/lib/python2.7/site-packages/routes/middleware.py", line 5, in <module>
    from webob import Request
ImportError: No module named webob

Since you've defined webob in your setup.py tests_require and also manually install it in your .travis.yml your testsuite doesn't notice this, but it definitely appears to me to be an actual requirement.

docs: using routes without a framework

Hi All,

I want to use the routes package in a context of AWS Lambda function.

Say I want to have the following 2 routes.

from routes import Mapper

uuid_pattern = r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"

def setup_router() -> Mapper:
    router = Mapper()
    router.connect("/api/project/{id}", requirements={"id": uuid_pattern})
    router.connect("/api/projects")
    return router

When a request GET /api/project/956aad40-e250-48e5-8a9a-3d342c8d739a, I want the first route to intercept and then trigger the execution of handle_get_project(id: str). If it is GET /api/projects, then handle_get_projects(). If none matches, then handle_catch_all()

My guess is that I use the following. However, I do I instruct the Mapper to trigger a function?

router.match(event["path"])

What is the usage pattern for the above scenario?

delete "master" branch

This repo has two branches, master and main.

main is now a few commits ahead of master. Would you please delete master to reduce confusion?

Support protocol-relative URLs

Currently, it's impossible to create a URL like //www.google.com. Looking into the code, I found out:

# https://github.com/bbangert/routes/blob/master/routes/util.py#L259-L262
if not protocol:
    protocol = config.protocol
if url is not None:
    url = protocol + '://' + host + url

That could be changed to accept that if protocol == '', then we create a protocol-relative URL.

What do you think, @bbangert? I'd be happy to submit a pull request if you agree.

Incorrect cached value returned by mapper.generate

It appears as if the Routes Mapper .generate() is returning cached values inappropriately by not distinguishing requests respecting SCRIPT_NAME. Here's a simple example reproducing the issue:

>>> import routes
>>> m = routes.Mapper()
>>> m.connect("foo", "/", controller="main", action="index")
>>> m.generate(controller='main', action='index')
'/'
>>> m.urlcache.clear()
>>> m.generate(controller='main', action='index', _environ=dict(SCRIPT_NAME='/bar'))
'/bar/'
>>> m.generate(controller='main', action='index')
'/bar/'
>>> m.urlcache.clear()
>>> m.generate(controller='main', action='index')
'/'

The salient point here is that m.generate should return '/' for both the first and third requests, but due to the cache resolving both with and without regard to SCRIPT_NAME, the cache will map both flavors to the first one found.

I believe the issue lies in in this line.

This issue is a blocker for CherryPy issue 1208.

The parent_resource of parent_resouce

Code:

    mapper.resource("network", "networks",
                    controller=NetworkController.gen_controller(conf),
                    member={'action': 'POST'})

    mapper.resource("subnet", "subnets",
                    controller=SubnetController.gen_controller(conf),
                    member={'action': 'POST'},
                    parent_resource=dict(member_name='network',
                                         collection_name='networks'))

    mapper.resource("port", "ports",
                    controller=PortController.gen_controller(conf),
                    member={'action': 'POST'},
                    parent_resource=dict(member_name='network_subnet',
                                         collection_name='subnets'))

The ports cannot be found as resouce

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.