Tests passing on Python3, basic support for TurboGears2 running on Python3
This commit is contained in:
parent
c0474f4b9c
commit
a555449578
@ -3,6 +3,11 @@ This module implements the :class:`DispatchState` class
|
||||
"""
|
||||
from crank.util import Path
|
||||
|
||||
try:
|
||||
string_type = basestring
|
||||
except NameError: # pragma: no cover
|
||||
string_type = str
|
||||
|
||||
class DispatchState(object):
|
||||
"""
|
||||
This class keeps around all the pertainent info for the state
|
||||
@ -29,7 +34,7 @@ class DispatchState(object):
|
||||
path = request.path_info[1:]
|
||||
|
||||
path = path.split('/')
|
||||
elif isinstance(path, basestring):
|
||||
elif isinstance(path, string_type):
|
||||
path = path.split('/')
|
||||
try:
|
||||
if not path[0]:
|
||||
|
@ -6,8 +6,8 @@ combines controller decoration for TG-Controller behavior.
|
||||
"""
|
||||
from inspect import ismethod
|
||||
from webob.exc import HTTPMethodNotAllowed
|
||||
from util import get_argspec, method_matches_args
|
||||
from objectdispatcher import ObjectDispatcher
|
||||
from crank.util import get_argspec, method_matches_args
|
||||
from crank.objectdispatcher import ObjectDispatcher
|
||||
|
||||
class RestDispatcher(ObjectDispatcher):
|
||||
"""Defines a restful interface for a set of HTTP verbs.
|
||||
|
@ -5,7 +5,7 @@ Copyright (c) Chrispther Perkins
|
||||
MIT License
|
||||
"""
|
||||
|
||||
import collections
|
||||
import collections, sys
|
||||
|
||||
__all__ = [
|
||||
'get_argspec', 'get_params_with_argspec', 'remove_argspec_params_from_params', 'method_matches_args',
|
||||
@ -146,6 +146,7 @@ def method_matches_args(method, params, remainder, lax_params=False):
|
||||
|
||||
return False
|
||||
|
||||
_PY3 = bool(sys.version_info[0] == 3)
|
||||
|
||||
class Path(collections.deque):
|
||||
def __init__(self, value=None, separator='/'):
|
||||
@ -160,7 +161,12 @@ class Path(collections.deque):
|
||||
separator = self.separator
|
||||
self.clear()
|
||||
|
||||
if isinstance(value, (str, unicode)):
|
||||
if _PY3: # pragma: no cover
|
||||
string_types = str
|
||||
else: # pragma: no cover
|
||||
string_types = basestring
|
||||
|
||||
if isinstance(value, string_types):
|
||||
self.extend(value.split(separator))
|
||||
return
|
||||
|
||||
@ -172,18 +178,19 @@ class Path(collections.deque):
|
||||
def __str__(self):
|
||||
return str(self.separator).join(self)
|
||||
|
||||
def __unicode__(self):
|
||||
def __unicode__(self): # pragma: no cover
|
||||
#unused on PY3
|
||||
return unicode(self.separator).join(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Path %r>" % super(Path, self).__repr__()
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(type(other)(self), other)
|
||||
def __eq__(self, other):
|
||||
return type(other)(self) == other
|
||||
|
||||
def __getitem__(self, i):
|
||||
try:
|
||||
return super(Path, self).__getitem__(i)
|
||||
|
||||
except TypeError:
|
||||
return Path([self[i] for i in xrange(*i.indices(len(self)))])
|
||||
return Path([self[i] for i in range(*i.indices(len(self)))])
|
||||
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
@ -1,9 +1,16 @@
|
||||
# encoding: utf-8
|
||||
import sys
|
||||
from nose.tools import raises
|
||||
from crank.objectdispatcher import *
|
||||
from crank.dispatchstate import DispatchState
|
||||
from webob.exc import HTTPNotFound
|
||||
|
||||
_PY3 = bool(sys.version_info[0] == 3)
|
||||
if _PY3:
|
||||
def u(s): return s
|
||||
else:
|
||||
def u(s): return s.decode('utf-8')
|
||||
|
||||
class MockRequest(object):
|
||||
|
||||
def __init__(self, path_info, params=None):
|
||||
@ -125,7 +132,7 @@ class TestDispatcher:
|
||||
assert state.method.__name__ == '_default', state.method
|
||||
|
||||
def test_dispatch_default_with_unicode(self):
|
||||
req = MockRequest('/', params={u'å':u'ß'})
|
||||
req = MockRequest('/', params={u('å'):u('ß')})
|
||||
state = DispatchState(req)
|
||||
state = self.dispatcher._dispatch(state)
|
||||
assert state.method.__name__ == '_default', state.method
|
||||
@ -137,7 +144,7 @@ class TestDispatcher:
|
||||
assert state.method.__name__ == 'no_args', state.method
|
||||
|
||||
def test_controller_method_with_unicode_args(self):
|
||||
req = MockRequest(u'/with_args/å/ß')
|
||||
req = MockRequest(u('/with_args/å/ß'))
|
||||
state = DispatchState(req)
|
||||
state = self.dispatcher._dispatch(state)
|
||||
assert state.method.__name__ == 'with_args', state.method
|
||||
|
@ -1,8 +1,13 @@
|
||||
# encoding: utf-8
|
||||
|
||||
import sys
|
||||
from nose.tools import raises
|
||||
from crank.util import *
|
||||
from inspect import ArgSpec
|
||||
|
||||
_PY3 = bool(sys.version_info[0] == 3)
|
||||
if _PY3:
|
||||
def u(s): return s
|
||||
else:
|
||||
def u(s): return s.decode('utf-8')
|
||||
|
||||
def mock_f(self, a, b, c=None, d=50, *args, **kw):
|
||||
pass
|
||||
@ -169,18 +174,21 @@ def test_path_unicode():
|
||||
|
||||
cases = [
|
||||
('/', "/"),
|
||||
(u'/©', u'/©'),
|
||||
(u'/©/™', u'/©/™'),
|
||||
(u'/©/™/', u'/©/™/'),
|
||||
((u'¡', ), u'¡'),
|
||||
(('foo', u'¡'), u'foo/¡')
|
||||
(u('/©'), u('/©')),
|
||||
(u('/©/™'), u('/©/™')),
|
||||
(u('/©/™/'), u('/©/™/')),
|
||||
((u('¡'), ), u('¡')),
|
||||
(('foo', u('¡')), u('foo/¡'))
|
||||
]
|
||||
|
||||
for case, expected in cases:
|
||||
instance = MockOb()
|
||||
instance.path = case
|
||||
|
||||
yield assert_path, instance, expected, unicode
|
||||
|
||||
if _PY3:
|
||||
yield assert_path, instance, expected, str
|
||||
else:
|
||||
yield assert_path, instance, expected, unicode
|
||||
|
||||
def test_path_slicing():
|
||||
class MockOb(object):
|
||||
@ -199,4 +207,4 @@ def test_path_comparison():
|
||||
assert Path('/foo') == ('', 'foo'), 'tuple comparison'
|
||||
assert Path('/foo') == ['', 'foo'], 'list comparison'
|
||||
assert Path('/foo') == '/foo', 'string comparison'
|
||||
assert Path(u'/föö') == u'/föö', 'string comparison'
|
||||
assert Path(u('/föö')) == u('/föö'), 'string comparison'
|
||||
|
Loading…
x
Reference in New Issue
Block a user