summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-02-29 10:02:08 -0500
committerChris McDonough <chrism@plope.com>2012-02-29 10:02:08 -0500
commit17a618c2c8d39147dd053221aa5dcf22c80ae6c2 (patch)
treeb71962cfbf1ea7106bb5d93fc4b0a8e634fa7e2b
parent25d7c28c6830d7f55b206b0467cd987e77f07515 (diff)
parent28c3135c6dab669bc4bace40cd7f8f22c0a8f997 (diff)
downloadpyramid-17a618c2c8d39147dd053221aa5dcf22c80ae6c2.tar.gz
pyramid-17a618c2c8d39147dd053221aa5dcf22c80ae6c2.tar.bz2
pyramid-17a618c2c8d39147dd053221aa5dcf22c80ae6c2.zip
Merge branch 'master' into 1.3-branch
-rw-r--r--CHANGES.txt7
-rw-r--r--pyramid/compat.py6
-rw-r--r--pyramid/config/views.py17
-rw-r--r--pyramid/scripts/pserve.py5
-rw-r--r--pyramid/tests/fixtures/static/index.html2
-rw-r--r--pyramid/tests/test_config/test_assets.py29
-rw-r--r--pyramid/tests/test_integration.py32
-rw-r--r--pyramid/tests/test_paster.py14
-rw-r--r--pyramid/tests/test_scaffolds/test_copydir.py4
-rw-r--r--pyramid/tests/test_scripts/test_common.py8
-rw-r--r--pyramid/tests/test_scripts/test_pserve.py28
-rw-r--r--pyramid/tests/test_url.py12
12 files changed, 95 insertions, 69 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 84de3c642..284c45ae4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,13 @@ Bug Fixes
the documentation as an API method was a mistake, and it has been renamed
to something private.
+- When a static view was registered using an absolute filesystem path on
+ Windows, the ``request.static_url`` function did not work to generate URLs
+ to its resources. Symptom: "No static URL definition matching
+ c:\foo\bar\baz".
+
+- Make all tests pass on Windows XP.
+
- Bug in ACL authentication checking on Python 3: the ``permits`` and
``principals_allowed_by_permission`` method of
``pyramid.authorization.ACLAuthenticationPolicy`` could return an
diff --git a/pyramid/compat.py b/pyramid/compat.py
index 948a1c3be..3459e0b02 100644
--- a/pyramid/compat.py
+++ b/pyramid/compat.py
@@ -1,6 +1,12 @@
+import platform
import sys
import types
+if platform.system() == 'Windows': # pragma: no cover
+ WIN = True
+else: # pragma: no cover
+ WIN = False
+
try: # pragma: no cover
import __pypy__
PYPY = True
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index b4216c220..1baaefcb6 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -1,5 +1,6 @@
import inspect
import operator
+import os
from functools import wraps
from zope.interface import (
@@ -39,6 +40,7 @@ from pyramid.compat import (
urlparse,
im_func,
url_quote,
+ WIN,
)
from pyramid.exceptions import (
@@ -1526,8 +1528,8 @@ class ViewsConfiguratorMixin(object):
some URL is visited; :meth:`pyramid.request.Request.static_url`
generates a URL to that asset.
- The ``name`` argument to ``add_static_view`` is usually a :term:`view
- name`. When this is the case, the
+ The ``name`` argument to ``add_static_view`` is usually a simple URL
+ prefix (e.g. ``'images'``). When this is the case, the
:meth:`pyramid.request.Request.static_url` API will generate a URL
which points to a Pyramid view, which will serve up a set of assets
that live in the package itself. For example:
@@ -1586,7 +1588,6 @@ class ViewsConfiguratorMixin(object):
if info is None:
info = StaticURLInfo()
self.registry.registerUtility(info, IStaticURLInfo)
-
info.add(self, name, spec, **kw)
def isexception(o):
@@ -1617,6 +1618,8 @@ class StaticURLInfo(object):
for (url, spec, route_name) in self._get_registrations(registry):
if path.startswith(spec):
subpath = path[len(spec):]
+ if WIN: # pragma: no cover
+ subpath = subpath.replace('\\', '/') # windows
if url is None:
kw['subpath'] = subpath
return request.route_url(route_name, **kw)
@@ -1632,8 +1635,12 @@ class StaticURLInfo(object):
# appending a slash here if the spec doesn't have one is
# required for proper prefix matching done in ``generate``
# (``subpath = path[len(spec):]``).
- if not spec.endswith('/'):
- spec = spec + '/'
+ if os.path.isabs(spec):
+ sep = os.sep
+ else:
+ sep = '/'
+ if not spec.endswith(sep):
+ spec = spec + sep
# we also make sure the name ends with a slash, purely as a
# convenience: a name that is a url is required to end in a
diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py
index c2df7162f..2bea7376a 100644
--- a/pyramid/scripts/pserve.py
+++ b/pyramid/scripts/pserve.py
@@ -581,11 +581,14 @@ class LazyWriter(object):
self.lock.release()
return self.fileobj
- def __del__(self):
+ def close(self):
fileobj = self.fileobj
if fileobj is not None:
fileobj.close()
+ def __del__(self):
+ self.close()
+
def write(self, text):
fileobj = self.open()
fileobj.write(text)
diff --git a/pyramid/tests/fixtures/static/index.html b/pyramid/tests/fixtures/static/index.html
index 6498787a5..0470710b2 100644
--- a/pyramid/tests/fixtures/static/index.html
+++ b/pyramid/tests/fixtures/static/index.html
@@ -1 +1 @@
-<html>static</html>
+<html>static</html> \ No newline at end of file
diff --git a/pyramid/tests/test_config/test_assets.py b/pyramid/tests/test_config/test_assets.py
index 627eefba7..5fe02c358 100644
--- a/pyramid/tests/test_config/test_assets.py
+++ b/pyramid/tests/test_config/test_assets.py
@@ -163,9 +163,8 @@ class TestOverrideProvider(unittest.TestCase):
import pyramid.tests.test_config
provider = self._makeOne(pyramid.tests.test_config)
here = os.path.dirname(os.path.abspath(__file__))
- expected = read_(os.path.join(here, resource_name))
with provider.get_resource_stream(None, resource_name) as result:
- self.assertEqual(result.read().replace(b'\r', b''), expected)
+ _assertBody(result.read(), os.path.join(here, resource_name))
def test_get_resource_string_no_overrides(self):
import os
@@ -173,9 +172,8 @@ class TestOverrideProvider(unittest.TestCase):
import pyramid.tests.test_config
provider = self._makeOne(pyramid.tests.test_config)
here = os.path.dirname(os.path.abspath(__file__))
- expected = read_(os.path.join(here, resource_name))
result = provider.get_resource_string(None, resource_name)
- self.assertEqual(result.replace(b'\r', b''), expected)
+ _assertBody(result, os.path.join(here, resource_name))
def test_has_resource_no_overrides(self):
resource_name = 'test_assets.py'
@@ -221,9 +219,8 @@ class TestOverrideProvider(unittest.TestCase):
import pyramid.tests.test_config
provider = self._makeOne(pyramid.tests.test_config)
here = os.path.dirname(os.path.abspath(__file__))
- expected = read_(os.path.join(here, resource_name))
with provider.get_resource_stream(None, resource_name) as result:
- self.assertEqual(result.read(), expected)
+ _assertBody(result.read(), os.path.join(here, resource_name))
def test_get_resource_string_override_returns_None(self):
overrides = DummyOverrides(None)
@@ -233,9 +230,8 @@ class TestOverrideProvider(unittest.TestCase):
import pyramid.tests.test_config
provider = self._makeOne(pyramid.tests.test_config)
here = os.path.dirname(os.path.abspath(__file__))
- expected = read_(os.path.join(here, resource_name))
result = provider.get_resource_string(None, resource_name)
- self.assertEqual(result, expected)
+ _assertBody(result, os.path.join(here, resource_name))
def test_has_resource_override_returns_None(self):
overrides = DummyOverrides(None)
@@ -420,10 +416,8 @@ class TestPackageOverrides(unittest.TestCase):
po = self._makeOne(package)
po.overrides= overrides
here = os.path.dirname(os.path.abspath(__file__))
- expected = read_(os.path.join(here, 'test_assets.py'))
with po.get_stream('whatever') as stream:
- self.assertEqual(stream.read().replace(b'\r', b''),
- expected)
+ _assertBody(stream.read(), os.path.join(here, 'test_assets.py'))
def test_get_stream_file_doesnt_exist(self):
overrides = [ DummyOverride(None), DummyOverride(
@@ -441,9 +435,8 @@ class TestPackageOverrides(unittest.TestCase):
po = self._makeOne(package)
po.overrides= overrides
here = os.path.dirname(os.path.abspath(__file__))
- expected = read_(os.path.join(here, 'test_assets.py'))
- self.assertEqual(po.get_string('whatever').replace(b'\r', b''),
- expected)
+ _assertBody(po.get_string('whatever'),
+ os.path.join(here, 'test_assets.py'))
def test_get_string_file_doesnt_exist(self):
overrides = [ DummyOverride(None), DummyOverride(
@@ -595,3 +588,11 @@ def read_(src):
contents = f.read()
return contents
+def _assertBody(body, filename):
+ # strip both \n and \r for windows
+ body = body.replace(b'\r', b'')
+ body = body.replace(b'\n', b'')
+ data = read_(filename)
+ data = data.replace(b'\r', b'')
+ data = data.replace(b'\n', b'')
+ assert(body == data)
diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py
index 85a68ab25..590ba0760 100644
--- a/pyramid/tests/test_integration.py
+++ b/pyramid/tests/test_integration.py
@@ -3,6 +3,7 @@
import datetime
import locale
import os
+import platform
import unittest
from pyramid.wsgi import wsgiapp
@@ -81,8 +82,10 @@ class TestStaticAppBase(IntegrationBase):
res = self.testapp.get('/static/.hiddenfile', status=200)
_assertBody(res.body, os.path.join(here, 'fixtures/static/.hiddenfile'))
- if defaultlocale is not None:
- # These tests are expected to fail on LANG=C systems
+ if defaultlocale is not None and platform.system() == 'Linux':
+ # These tests are expected to fail on LANG=C systems due to decode
+ # errors and on non-Linux systems due to git highchar handling
+ # vagaries
def test_highchars_in_pathelement(self):
url = url_quote('/static/héhé/index.html')
res = self.testapp.get(url, status=200)
@@ -140,7 +143,7 @@ class TestStaticAppBase(IntegrationBase):
def test_range_tilend(self):
self.testapp.extra_environ = {'HTTP_RANGE':'bytes=-5'}
res = self.testapp.get('/static/index.html', status=206)
- self.assertEqual(res.body, b'tml>\n')
+ self.assertEqual(res.body, b'html>')
def test_range_notbytes(self):
self.testapp.extra_environ = {'HTTP_RANGE':'kHz=-5'}
@@ -240,9 +243,8 @@ class TestStaticPermApp(IntegrationBase, unittest.TestCase):
root_factory = 'pyramid.tests.pkgs.staticpermapp:RootFactory'
def test_allowed(self):
result = self.testapp.get('/allowed/index.html', status=200)
- self.assertEqual(
- result.body.replace(b'\r', b''),
- read_(os.path.join(here, 'fixtures/static/index.html')))
+ _assertBody(result.body,
+ os.path.join(here, 'fixtures/static/index.html'))
def test_denied_via_acl_global_root_factory(self):
self.testapp.extra_environ = {'REMOTE_USER':'bob'}
@@ -251,9 +253,8 @@ class TestStaticPermApp(IntegrationBase, unittest.TestCase):
def test_allowed_via_acl_global_root_factory(self):
self.testapp.extra_environ = {'REMOTE_USER':'fred'}
result = self.testapp.get('/protected/index.html', status=200)
- self.assertEqual(
- result.body.replace(b'\r', b''),
- read_(os.path.join(here, 'fixtures/static/index.html')))
+ _assertBody(result.body,
+ os.path.join(here, 'fixtures/static/index.html'))
def test_denied_via_acl_local_root_factory(self):
self.testapp.extra_environ = {'REMOTE_USER':'fred'}
@@ -262,9 +263,8 @@ class TestStaticPermApp(IntegrationBase, unittest.TestCase):
def test_allowed_via_acl_local_root_factory(self):
self.testapp.extra_environ = {'REMOTE_USER':'bob'}
result = self.testapp.get('/factory_protected/index.html', status=200)
- self.assertEqual(
- result.body.replace(b'\r', b''),
- read_(os.path.join(here, 'fixtures/static/index.html')))
+ _assertBody(result.body,
+ os.path.join(here, 'fixtures/static/index.html'))
class TestCCBug(IntegrationBase, unittest.TestCase):
# "unordered" as reported in IRC by author of
@@ -621,5 +621,11 @@ def _assertBody(body, filename):
if defaultlocale is None: # pragma: no cover
# If system locale does not have an encoding then default to utf-8
filename = filename.encode('utf-8')
- assert(body.replace(b'\r', b'') == read_(filename))
+ # strip both \n and \r for windows
+ body = body.replace(b'\r', b'')
+ body = body.replace(b'\n', b'')
+ data = read_(filename)
+ data = data.replace(b'\r', b'')
+ data = data.replace(b'\n', b'')
+ assert(body == data)
diff --git a/pyramid/tests/test_paster.py b/pyramid/tests/test_paster.py
index 5901c0416..d94b46a9f 100644
--- a/pyramid/tests/test_paster.py
+++ b/pyramid/tests/test_paster.py
@@ -1,3 +1,4 @@
+import os
import unittest
class Test_get_app(unittest.TestCase):
@@ -6,7 +7,6 @@ class Test_get_app(unittest.TestCase):
return get_app(config_file, section_name, loadapp)
def test_it(self):
- import os
app = DummyApp()
loadapp = DummyLoadWSGI(app)
result = self._callFUT('/foo/bar/myapp.ini', 'myapp', loadapp)
@@ -16,7 +16,6 @@ class Test_get_app(unittest.TestCase):
self.assertEqual(result, app)
def test_it_with_hash(self):
- import os
app = DummyApp()
loadapp = DummyLoadWSGI(app)
result = self._callFUT('/foo/bar/myapp.ini#myapp', None, loadapp)
@@ -26,7 +25,6 @@ class Test_get_app(unittest.TestCase):
self.assertEqual(result, app)
def test_it_with_hash_and_name_override(self):
- import os
app = DummyApp()
loadapp = DummyLoadWSGI(app)
result = self._callFUT('/foo/bar/myapp.ini#myapp', 'yourapp', loadapp)
@@ -41,7 +39,6 @@ class Test_get_appsettings(unittest.TestCase):
return get_appsettings(config_file, section_name, appconfig)
def test_it(self):
- import os
values = {'a':1}
appconfig = DummyLoadWSGI(values)
result = self._callFUT('/foo/bar/myapp.ini', 'myapp', appconfig)
@@ -51,7 +48,6 @@ class Test_get_appsettings(unittest.TestCase):
self.assertEqual(result, values)
def test_it_with_hash(self):
- import os
values = {'a':1}
appconfig = DummyLoadWSGI(values)
result = self._callFUT('/foo/bar/myapp.ini#myapp', None, appconfig)
@@ -61,7 +57,6 @@ class Test_get_appsettings(unittest.TestCase):
self.assertEqual(result, values)
def test_it_with_hash_and_name_override(self):
- import os
values = {'a':1}
appconfig = DummyLoadWSGI(values)
result = self._callFUT('/foo/bar/myapp.ini#myapp', 'yourapp', appconfig)
@@ -78,9 +73,10 @@ class Test_setup_logging(unittest.TestCase):
def test_it(self):
config_file, dict = self._callFUT('/abc')
- self.assertEqual(config_file, '/abc')
- self.assertEqual(dict['__file__'], '/abc')
- self.assertEqual(dict['here'], '/')
+ # os.path.abspath is a sop to Windows
+ self.assertEqual(config_file, os.path.abspath('/abc'))
+ self.assertEqual(dict['__file__'], os.path.abspath('/abc'))
+ self.assertEqual(dict['here'], os.path.abspath('/'))
def fileConfig(self, config_file, dict):
return config_file, dict
diff --git a/pyramid/tests/test_scaffolds/test_copydir.py b/pyramid/tests/test_scaffolds/test_copydir.py
index 01f9b19ff..42edd9d23 100644
--- a/pyramid/tests/test_scaffolds/test_copydir.py
+++ b/pyramid/tests/test_scaffolds/test_copydir.py
@@ -30,7 +30,7 @@ class Test_copy_dir(unittest.TestCase):
1, False,
template_renderer=dummy_template_renderer)
result = self.out.getvalue()
- self.assertTrue('Creating %s/mypackage/' % self.dirname in result)
+ self.assertTrue('Creating' in result)
self.assertTrue(
'Copying fixture_scaffold/+package+/__init__.py_tmpl to' in result)
source = pkg_resources.resource_filename(
@@ -52,7 +52,7 @@ class Test_copy_dir(unittest.TestCase):
1, False,
template_renderer=dummy_template_renderer)
result = self.out.getvalue()
- self.assertTrue('Creating %s/mypackage/' % self.dirname in result)
+ self.assertTrue('Creating' in result)
self.assertTrue('Copying __init__.py_tmpl to' in result)
source = pkg_resources.resource_filename(
'pyramid.tests.test_scaffolds',
diff --git a/pyramid/tests/test_scripts/test_common.py b/pyramid/tests/test_scripts/test_common.py
index c62483fdc..c3c792ca4 100644
--- a/pyramid/tests/test_scripts/test_common.py
+++ b/pyramid/tests/test_scripts/test_common.py
@@ -1,3 +1,4 @@
+import os
import unittest
class Test_logging_file_config(unittest.TestCase):
@@ -8,9 +9,10 @@ class Test_logging_file_config(unittest.TestCase):
def test_it(self):
config_file, dict = self._callFUT('/abc')
- self.assertEqual(config_file, '/abc')
- self.assertEqual(dict['__file__'], '/abc')
- self.assertEqual(dict['here'], '/')
+ # use of os.path.abspath here is a sop to Windows
+ self.assertEqual(config_file, os.path.abspath('/abc'))
+ self.assertEqual(dict['__file__'], os.path.abspath('/abc'))
+ self.assertEqual(dict['here'], os.path.abspath('/'))
def fileConfig(self, config_file, dict):
return config_file, dict
diff --git a/pyramid/tests/test_scripts/test_pserve.py b/pyramid/tests/test_scripts/test_pserve.py
index d19eb6901..e21a703d9 100644
--- a/pyramid/tests/test_scripts/test_pserve.py
+++ b/pyramid/tests/test_scripts/test_pserve.py
@@ -1,5 +1,6 @@
import unittest
import os
+import tempfile
class TestPServeCommand(unittest.TestCase):
def setUp(self):
@@ -41,19 +42,14 @@ class TestPServeCommand(unittest.TestCase):
self.out_.getvalue(),'Not a valid PID file in %s' % path)
def test_run_stop_daemon_invalid_pid_in_file(self):
- import tempfile
- tmp = tempfile.NamedTemporaryFile()
- tmp.write(b'9999999')
- tmp.flush()
- tmpname = tmp.name
- inst = self._makeOne('--stop-daemon', '--pid-file=%s' % tmpname)
+ fn = tempfile.mktemp()
+ with open(fn, 'wb') as tmp:
+ tmp.write(b'9999999')
+ tmp.close()
+ inst = self._makeOne('--stop-daemon', '--pid-file=%s' % fn)
inst.run()
- try:
- tmp.close()
- except:
- pass
self.assertEqual(self.out_.getvalue(),
- 'PID in %s is not valid (deleting)' % tmpname)
+ 'PID in %s is not valid (deleting)' % fn)
def test_parse_vars_good(self):
vars = ['a=1', 'b=2']
@@ -81,18 +77,16 @@ class TestLazyWriter(unittest.TestCase):
return LazyWriter(filename, mode)
def test_open(self):
- import tempfile
filename = tempfile.mktemp()
try:
inst = self._makeOne(filename)
fp = inst.open()
self.assertEqual(fp.name, filename)
- fp.close()
finally:
+ fp.close()
os.remove(filename)
def test_write(self):
- import tempfile
filename = tempfile.mktemp()
try:
inst = self._makeOne(filename)
@@ -101,10 +95,10 @@ class TestLazyWriter(unittest.TestCase):
with open(filename) as f:
data = f.read()
self.assertEqual(data, 'hello')
+ inst.close()
os.remove(filename)
def test_writeline(self):
- import tempfile
filename = tempfile.mktemp()
try:
inst = self._makeOne(filename)
@@ -113,18 +107,18 @@ class TestLazyWriter(unittest.TestCase):
with open(filename) as f:
data = f.read()
self.assertEqual(data, 'hello')
+ inst.close()
os.remove(filename)
def test_flush(self):
- import tempfile
filename = tempfile.mktemp()
try:
inst = self._makeOne(filename)
inst.flush()
fp = inst.fileobj
self.assertEqual(fp.name, filename)
- fp.close()
finally:
+ fp.close()
os.remove(filename)
class Test__methodwrapper(unittest.TestCase):
diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py
index 7f002cbd6..0dff1e648 100644
--- a/pyramid/tests/test_url.py
+++ b/pyramid/tests/test_url.py
@@ -1,3 +1,4 @@
+import os
import unittest
import warnings
@@ -8,6 +9,7 @@ from pyramid.testing import (
from pyramid.compat import (
text_,
native_,
+ WIN,
)
class TestURLMethodsMixin(unittest.TestCase):
@@ -516,7 +518,7 @@ class TestURLMethodsMixin(unittest.TestCase):
abspath = makeabs('static', 'foo.css')
result = request.static_url(abspath)
self.assertEqual(result, 'abc')
- self.assertEqual(info.args, ('/static/foo.css', request, {}))
+ self.assertEqual(info.args, (makeabs('static', 'foo.css'), request, {}))
request = self._makeOne()
def test_static_url_found_rel(self):
@@ -576,7 +578,7 @@ class TestURLMethodsMixin(unittest.TestCase):
abspath = makeabs('static', 'foo.css')
result = request.static_path(abspath)
self.assertEqual(result, 'abc')
- self.assertEqual(info.args, ('/static/foo.css', request,
+ self.assertEqual(info.args, (makeabs('static', 'foo.css'), request,
{'_app_url':'/foo'})
)
@@ -986,5 +988,7 @@ class DummyStaticURLInfo:
return self.result
def makeabs(*elements):
- import os
- return os.path.sep + os.path.sep.join(elements)
+ if WIN: # pragma: no cover
+ return r'c:\\' + os.path.sep.join(elements)
+ else:
+ return os.path.sep + os.path.sep.join(elements)