Merging pecan-env into master

This commit is contained in:
Yoann Roman
2011-03-08 13:37:36 -05:00
10 changed files with 340 additions and 187 deletions

1
.gitignore vendored
View File

@@ -17,3 +17,4 @@ pip-log.txt
# Unit test / coverage reports
.coverage
.tox
htmlcov

View File

@@ -25,8 +25,6 @@ def proxy(key):
class ObjectProxy(object):
def __getattr__(self, attr):
obj = getattr(state, key)
if attr == 'validation_errors':
return getattr(obj, attr, {})
return getattr(obj, attr)
def __setattr__(self, attr, value):
obj = getattr(state, key)
@@ -50,9 +48,10 @@ def override_template(template, content_type=None):
:param content_type: a valid MIME type to use for the response.
'''
request.override_template = template
request.pecan['override_template'] = template
if content_type:
request.override_content_type = content_type
request.pecan['override_content_type'] = content_type
def abort(status_code=None, detail='', headers=None, comment=None):
'''
@@ -98,11 +97,9 @@ def error_for(field):
:param field: The name of the field to get the error for.
'''
if not request.validation_errors:
return ''
return request.validation_errors.get(field, '')
return request.pecan['validation_errors'].get(field, '')
def static(name, value):
'''
When using ``htmlfill`` validation support, this function indicates
@@ -129,16 +126,7 @@ def render(template, namespace):
:param namespace: The namespace to use for rendering the template, as a dictionary.
'''
renderer = state.app.renderers.get(state.app.default_renderer, state.app.template_path)
if template == 'json':
renderer = state.app.renderers.get('json', state.app.template_path)
else:
namespace['error_for'] = error_for
namespace['static'] = static
if ':' in template:
renderer = state.app.renderers.get(template.split(':')[0], state.app.template_path)
template = template.split(':')[1]
return renderer.render(template, namespace)
return state.app.render(template, namespace)
class ValidationException(ForwardRequestException):
@@ -156,10 +144,10 @@ class ValidationException(ForwardRequestException):
location = cfg['error_handler']
if callable(location):
location = location()
merge_dicts(request.validation_errors, errors)
merge_dicts(request.pecan['validation_errors'], errors)
if 'pecan.params' not in request.environ:
request.environ['pecan.params'] = dict(request.str_params)
request.environ['pecan.validation_errors'] = request.validation_errors
request.environ['pecan.validation_errors'] = request.pecan['validation_errors']
if cfg.get('htmlfill') is not None:
request.environ['pecan.htmlfill'] = cfg['htmlfill']
request.environ['REQUEST_METHOD'] = 'GET'
@@ -214,7 +202,11 @@ class Pecan(object):
except NonCanonicalPath, e:
if self.force_canonical and not _cfg(e.controller).get('accept_noncanonical', False):
if request.method == 'POST':
raise RuntimeError, "You have POSTed to a URL '%s' which requires a slash. Most browsers will not maintain POST data when redirected. Please update your code to POST to '%s/' or set force_canonical to False" % (request.routing_path, request.routing_path)
raise RuntimeError, "You have POSTed to a URL '%s' which '\
'requires a slash. Most browsers will not maintain '\
'POST data when redirected. Please update your code '\
'to POST to '%s/' or set force_canonical to False" % \
(request.pecan['routing_path'], request.pecan['routing_path'])
raise exc.HTTPFound(add_slash=True)
return e.controller, e.remainder
@@ -265,9 +257,9 @@ class Pecan(object):
args.append(im_self)
# grab the routing args from nested REST controllers
if hasattr(request, 'routing_args'):
remainder = request.routing_args + list(remainder)
delattr(request, 'routing_args')
if 'routing_args' in request.pecan:
remainder = request.pecan['routing_args'] + list(remainder)
del request.pecan['routing_args']
# handle positional arguments
if valid_args and remainder:
@@ -304,6 +296,18 @@ class Pecan(object):
return args, kwargs
def render(self, template, namespace):
renderer = self.renderers.get(self.default_renderer, self.template_path)
if template == 'json':
renderer = self.renderers.get('json', self.template_path)
else:
namespace['error_for'] = error_for
namespace['static'] = static
if ':' in template:
renderer = self.renderers.get(template.split(':')[0], self.template_path)
template = template.split(':')[1]
return renderer.render(template, namespace)
def validate(self, schema, params, json=False, error_handler=None,
htmlfill=None, variable_decode=None):
'''
@@ -318,7 +322,6 @@ class Pecan(object):
:param variable_decode: Indicates whether or not to decode variables when using htmlfill.
'''
request.validation_errors = {}
try:
to_validate = params
if json:
@@ -331,7 +334,7 @@ class Pecan(object):
if variable_decode is not None:
kwargs['encode_variables'] = True
kwargs.update(variable_decode)
request.validation_errors = e.unpack_errors(**kwargs)
request.pecan['validation_errors'] = e.unpack_errors(**kwargs)
if error_handler is not None:
raise ValidationException()
if json:
@@ -347,21 +350,20 @@ class Pecan(object):
state.hooks = self.determine_hooks()
# store the routing path to allow hooks to modify it
request.routing_path = request.path
request.pecan['routing_path'] = request.path
# handle "on_route" hooks
self.handle_hooks('on_route', state)
# lookup the controller, respecting content-type as requested
# by the file extension on the URI
path = request.routing_path
path = request.pecan['routing_path']
if state.content_type is None and '.' in path.split('/')[-1]:
if not request.pecan['content_type'] and '.' in path.split('/')[-1]:
path, extension = splitext(path)
request.extension = extension
request.pecan['extension'] = extension
# preface with a letter to ensure compat for 2.5
state.content_type = guess_type('x' + extension)[0]
request.pecan['content_type'] = guess_type('x' + extension)[0]
controller, remainder = self.route(self.root, path)
cfg = _cfg(controller)
@@ -381,8 +383,11 @@ class Pecan(object):
state.controller = controller
# if unsure ask the controller for the default content type
if state.content_type is None:
state.content_type = cfg.get('content_type', 'text/html')
if not request.pecan['content_type']:
request.pecan['content_type'] = cfg.get('content_type', 'text/html')
elif cfg.get('content_type') is not None and \
request.pecan['content_type'] not in cfg.get('content_types', {}):
raise exc.HTTPNotFound
# get a sorted list of hooks, by priority
state.hooks = self.determine_hooks(controller)
@@ -402,7 +407,7 @@ class Pecan(object):
variable_decode=cfg.get('variable_decode')
)
elif 'pecan.validation_errors' in request.environ:
request.validation_errors = request.environ.pop('pecan.validation_errors')
request.pecan['validation_errors'] = request.environ.pop('pecan.validation_errors')
# fetch the arguments for the controller
args, kwargs = self.get_args(
@@ -423,17 +428,17 @@ class Pecan(object):
raw_namespace = result
# pull the template out based upon content type and handle overrides
template = cfg.get('content_types', {}).get(state.content_type)
template = cfg.get('content_types', {}).get(request.pecan['content_type'])
# check if for controller override of template
template = getattr(request, 'override_template', template)
state.content_type = getattr(request, 'override_content_type', state.content_type)
template = request.pecan.get('override_template', template)
request.pecan['content_type'] = request.pecan.get('override_content_type', request.pecan['content_type'])
# if there is a template, render it
if template:
if template == 'json':
state.content_type = 'application/json'
result = render(template, result)
request.pecan['content_type'] = 'application/json'
result = self.render(template, result)
# pass the response through htmlfill (items are popped out of the
# environment even if htmlfill won't run for proper cleanup)
@@ -442,8 +447,8 @@ class Pecan(object):
_htmlfill = request.environ.pop('pecan.htmlfill')
if 'pecan.params' in request.environ:
params = request.environ.pop('pecan.params')
if request.validation_errors and _htmlfill is not None and state.content_type == 'text/html':
errors = getattr(request, 'validation_errors', {})
if request.pecan['validation_errors'] and _htmlfill is not None and request.pecan['content_type'] == 'text/html':
errors = request.pecan['validation_errors']
result = htmlfill.render(result, defaults=params, errors=errors, **_htmlfill)
# If we are in a test request put the namespace where it can be
@@ -461,8 +466,8 @@ class Pecan(object):
response.body = result
# set the content type
if state.content_type:
response.content_type = state.content_type
if request.pecan['content_type']:
response.content_type = request.pecan['content_type']
def __call__(self, environ, start_response):
'''
@@ -471,15 +476,15 @@ class Pecan(object):
# create the request and response object
state.request = Request(environ)
state.content_type = None
state.response = Response()
state.hooks = []
state.app = self
# handle the request
try:
# add context to the request
# add context and environment to the request
state.request.context = {}
state.request.pecan = dict(content_type=None, validation_errors={})
self.handle_request()
except Exception, e:
@@ -502,7 +507,6 @@ class Pecan(object):
return state.response(environ, start_response)
finally:
# clean up state
del state.content_type
del state.hooks
del state.request
del state.response

View File

@@ -49,9 +49,12 @@ class GenericJSON(JSONEncoder):
props[key] = getattr(obj, key)
return props
elif isinstance(obj, ResultProxy):
return dict(rows=list(obj), count=obj.rowcount)
props = dict(rows=list(obj), count=obj.rowcount)
if props['count'] < 0:
props['count'] = len(props['rows'])
return props
elif isinstance(obj, RowProxy):
return dict(rows=dict(obj), count=1)
return dict(obj)
elif isinstance(obj, (MultiDict, UnicodeMultiDict)):
return obj.mixed()
else:

View File

@@ -57,7 +57,7 @@ class RestController(object):
# get the args to figure out how much to chop off
args = getargspec(getattr(self, method))
fixed_args = len(args[0][1:]) - len(getattr(request, 'routing_args', []))
fixed_args = len(args[0][1:]) - len(request.pecan.get('routing_args', []))
var_args = args[1]
# attempt to locate a sub-controller
@@ -166,7 +166,4 @@ class RestController(object):
_handle_put = _handle_post
def _set_routing_args(self, args):
if hasattr(request, 'routing_args'):
request.routing_args.extend(args)
else:
setattr(request, 'routing_args', args)
request.pecan.setdefault('routing_args', []).extend(args)

View File

@@ -11,9 +11,9 @@ class SampleForm(Schema):
class RootController(object):
@expose('index.html')
def index(self, name='', age=''):
return dict(errors=request.validation_errors, name=name, age=age)
return dict(errors=request.pecan['validation_errors'], name=name, age=age)
@expose('success.html', schema=SampleForm(), error_handler='index')
@expose('success.html', schema=SampleForm(), error_handler='/index')
def handle_form(self, name, age):
return dict(name=name, age=age)

View File

@@ -3,7 +3,7 @@ from paste.recursive import ForwardRequestException
from unittest import TestCase
from webtest import TestApp
from pecan import Pecan, expose, request, response, redirect, abort, make_app, override_template
from pecan import Pecan, expose, request, response, redirect, abort, make_app, override_template, render
from pecan.templating import _builtin_renderers as builtin_renderers, error_formatters
from pecan.decorators import accept_noncanonical
@@ -438,6 +438,10 @@ class TestBase(TestCase):
def internal(self):
redirect('/testing', internal=True)
@expose()
def bad_internal(self):
redirect('/testing', internal=True, code=301)
@expose()
def permanent(self):
redirect('/testing', code=301)
@@ -446,21 +450,25 @@ class TestBase(TestCase):
def testing(self):
return 'it worked!'
app = TestApp(Pecan(RootController()))
app = TestApp(make_app(RootController(), debug=True))
r = app.get('/')
assert r.status_int == 302
r = r.follow()
assert r.status_int == 200
assert r.body == 'it worked!'
self.assertRaises(ForwardRequestException, app.get, '/internal')
r = app.get('/internal')
assert r.status_int == 200
assert r.body == 'it worked!'
self.assertRaises(ValueError, app.get, '/bad_internal')
r = app.get('/permanent')
assert r.status_int == 301
r = r.follow()
assert r.status_int == 200
assert r.body == 'it worked!'
def test_streaming_response(self):
import StringIO
class RootController(object):
@@ -511,10 +519,10 @@ class TestBase(TestCase):
Test extension splits
"""
class RootController(object):
@expose()
@expose(content_type=None)
def _default(self, *args):
from pecan.core import request
return request.extension
return request.pecan['extension']
app = TestApp(Pecan(RootController()))
r = app.get('/index.html')
@@ -544,6 +552,117 @@ class TestBase(TestCase):
app = make_app(RootController(), wrap_app=wrap, debug=True)
assert len(wrapped_apps) == 1
def test_bad_content_type(self):
class RootController(object):
@expose()
def index(self):
return '/'
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert r.body == '/'
r = app.get('/index.html', expect_errors=True)
assert r.status_int == 200
assert r.body == '/'
r = app.get('/index.txt', expect_errors=True)
assert r.status_int == 404
def test_canonical_index(self):
class ArgSubController(object):
@expose()
def index(self, arg):
return arg
class AcceptController(object):
@accept_noncanonical
@expose()
def index(self):
return 'accept'
class SubController(object):
@expose()
def index(self):
return 'subindex'
class RootController(object):
@expose()
def index(self):
return 'index'
sub = SubController()
arg = ArgSubController()
accept = AcceptController()
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert 'index' in r.body
r = app.get('/index')
assert r.status_int == 200
assert 'index' in r.body
# for broken clients
r = app.get('', status=302)
assert r.status_int == 302
r = app.get('/sub/')
assert r.status_int == 200
assert 'subindex' in r.body
r = app.get('/sub', status=302)
assert r.status_int == 302
try:
r = app.post('/sub', dict(foo=1))
raise Exception, "Post should fail"
except Exception, e:
assert isinstance(e, RuntimeError)
r = app.get('/arg/index/foo')
assert r.status_int == 200
assert r.body == 'foo'
r = app.get('/accept/')
assert r.status_int == 200
assert 'accept' == r.body
r = app.get('/accept')
assert r.status_int == 200
assert 'accept' == r.body
app = TestApp(Pecan(RootController(), force_canonical=False))
r = app.get('/')
assert r.status_int == 200
assert 'index' in r.body
r = app.get('/sub')
assert r.status_int == 200
assert 'subindex' in r.body
r = app.post('/sub', dict(foo=1))
assert r.status_int == 200
assert 'subindex' in r.body
r = app.get('/sub/')
assert r.status_int == 200
assert 'subindex' in r.body
def test_proxy(self):
class RootController(object):
@expose()
def index(self):
request.testing = True
assert request.testing == True
del request.testing
assert hasattr(request, 'testing') == False
return '/'
app = TestApp(make_app(RootController(), debug=True))
r = app.get('/')
assert r.status_int == 200
class TestEngines(object):
@@ -652,88 +771,18 @@ class TestEngines(object):
assert 'Override' in r.body
assert r.content_type == 'text/plain'
def test_canonical_index(self):
class ArgSubController(object):
@expose()
def index(self, arg):
return arg
class AcceptController(object):
@accept_noncanonical
@expose()
def index(self):
return 'accept'
class SubController(object):
@expose()
def index(self):
return 'subindex'
def test_render(self):
#if 'mako' not in builtin_renderers:
# return
class RootController(object):
@expose()
def index(self):
return 'index'
sub = SubController()
arg = ArgSubController()
accept = AcceptController()
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert 'index' in r.body
r = app.get('/index')
assert r.status_int == 200
assert 'index' in r.body
def index(self, name='Jonathan'):
return render('mako.html', dict(name=name))
return dict(name=name)
# for broken clients
r = app.get('', status=302)
assert r.status_int == 302
r = app.get('/sub/')
assert r.status_int == 200
assert 'subindex' in r.body
r = app.get('/sub', status=302)
assert r.status_int == 302
try:
r = app.post('/sub', dict(foo=1))
raise Exception, "Post should fail"
except Exception, e:
assert isinstance(e, RuntimeError)
r = app.get('/arg/index/foo')
assert r.status_int == 200
assert r.body == 'foo'
r = app.get('/accept/')
assert r.status_int == 200
assert 'accept' == r.body
r = app.get('/accept')
assert r.status_int == 200
assert 'accept' == r.body
app = TestApp(Pecan(RootController(), force_canonical=False))
app = TestApp(Pecan(RootController(), template_path=self.template_path))
r = app.get('/')
assert r.status_int == 200
assert 'index' in r.body
r = app.get('/sub')
assert r.status_int == 200
assert 'subindex' in r.body
r = app.post('/sub', dict(foo=1))
assert r.status_int == 200
assert 'subindex' in r.body
r = app.get('/sub/')
assert r.status_int == 200
assert 'subindex' in r.body
assert "<h1>Hello, Jonathan!</h1>" in r.body

View File

@@ -125,3 +125,7 @@ class TestConf(TestCase):
conf = configuration.Config({'a':1})
self.assertEqual(['a'], dir(conf))
def test_config_bad_key(self):
conf = configuration.Config({'a': 1})
assert conf.a == 1
self.assertRaises(AttributeError, getattr, conf, 'b')

View File

@@ -696,7 +696,7 @@ class TestHooks(object):
password_confirm,
age):
run_hook.append('inside')
return str(len(request.validation_errors) > 0)
return str(len(request.pecan['validation_errors']) > 0)
@expose(schema=RegistrationSchema(), error_handler='/errors')
def with_handler(self, first_name,
@@ -707,7 +707,7 @@ class TestHooks(object):
password_confirm,
age):
run_hook.append('inside')
return str(len(request.validation_errors) > 0)
return str(len(request.pecan['validation_errors']) > 0)
# test that the hooks get properly run with no validation errors
app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))

View File

@@ -1,15 +1,20 @@
from datetime import datetime, date
from decimal import Decimal
from datetime import datetime, date
from decimal import Decimal
try:
from simplejson import loads
from simplejson import loads
except:
from json import loads
from unittest import TestCase
from json import loads
try:
from sqlalchemy import orm, schema, types
from sqlalchemy.engine import create_engine
except ImportError:
create_engine = None
from unittest import TestCase
from pecan.jsonify import jsonify, encode
from pecan import Pecan, expose, request
from webtest import TestApp
from webob.multidict import MultiDict, UnicodeMultiDict
from pecan.jsonify import jsonify, encode, ResultProxy, RowProxy
from pecan import Pecan, expose, request
from webtest import TestApp
from webob.multidict import MultiDict, UnicodeMultiDict
def make_person():
class Person(object):
@@ -106,3 +111,93 @@ class TestJsonifyGenericEncoder(TestCase):
class Foo(object): pass
self.assertRaises(TypeError, encode, Foo())
class TestJsonifySQLAlchemyGenericEncoder(TestCase):
def setUp(self):
if not create_engine:
self.create_fake_proxies()
else:
self.create_sa_proxies()
def create_fake_proxies(self):
# create a fake SA object
class FakeSAObject(object):
def __init__(self):
self._sa_class_manager = object()
self._sa_instance_state = 'awesome'
self.id = 1
self.first_name = 'Jonathan'
self.last_name = 'LaCour'
# create a fake result proxy
class FakeResultProxy(ResultProxy):
def __init__(self):
self.rowcount = -1
self.rows = []
def __iter__(self):
return iter(self.rows)
def append(self, row):
self.rows.append(row)
# create a fake row proxy
class FakeRowProxy(RowProxy):
def __init__(self, arg=None):
self.row = dict(arg)
def __getitem__(self, key):
return self.row.__getitem__(key)
def keys(self):
return self.row.keys()
# get the SA objects
self.sa_object = FakeSAObject()
self.result_proxy = FakeResultProxy()
self.result_proxy.append(FakeRowProxy([('id', 1), ('first_name', 'Jonathan'), ('last_name', 'LaCour')]))
self.result_proxy.append(FakeRowProxy([('id', 2), ('first_name', 'Yoann'), ('last_name', 'Roman')]))
self.row_proxy = FakeRowProxy([('id', 1), ('first_name', 'Jonathan'), ('last_name', 'LaCour')])
def create_sa_proxies(self):
# create the table and mapper
metadata = schema.MetaData()
user_table = schema.Table('user', metadata,
schema.Column('id', types.Integer, primary_key=True),
schema.Column('first_name', types.Unicode(25)),
schema.Column('last_name', types.Unicode(25)))
class User(object):
pass
orm.mapper(User, user_table)
# create the session
engine = create_engine('sqlite:///:memory:')
metadata.bind = engine
metadata.create_all()
session = orm.sessionmaker(bind=engine)()
# add some dummy data
user_table.insert().execute([
{'first_name': u'Jonathan', 'last_name': u'LaCour'},
{'first_name': u'Yoann', 'last_name': u'Roman'}
])
# get the SA objects
self.sa_object = session.query(User).first()
select = user_table.select()
self.result_proxy = select.execute()
self.row_proxy = select.execute().fetchone()
def test_sa_object(self):
result = encode(self.sa_object)
assert loads(result) == {'id': 1, 'first_name': 'Jonathan', 'last_name': 'LaCour'}
def test_result_proxy(self):
result = encode(self.result_proxy)
assert loads(result) == {'count': 2, 'rows': [
{'id': 1, 'first_name': 'Jonathan', 'last_name': 'LaCour'},
{'id': 2, 'first_name': 'Yoann', 'last_name': 'Roman'}
]}
def test_row_proxy(self):
result = encode(self.row_proxy)
assert loads(result) == {'id': 1, 'first_name': 'Jonathan', 'last_name': 'LaCour'}

View File

@@ -95,7 +95,7 @@ class TestValidation(object):
@expose()
def errors(self, *args, **kwargs):
assert len(request.validation_errors) > 0
assert len(request.pecan['validation_errors']) > 0
return 'There was an error!'
@expose(schema=RegistrationSchema())
@@ -106,7 +106,7 @@ class TestValidation(object):
password,
password_confirm,
age):
assert len(request.validation_errors) > 0
assert len(request.pecan['validation_errors']) > 0
return 'Success!'
@expose(schema=RegistrationSchema(), error_handler='/errors')
@@ -117,17 +117,17 @@ class TestValidation(object):
password,
password_confirm,
age):
assert len(request.validation_errors) > 0
assert len(request.pecan['validation_errors']) > 0
return 'Success!'
@expose(json_schema=RegistrationSchema())
def json(self, data):
assert len(request.validation_errors) > 0
assert len(request.pecan['validation_errors']) > 0
return 'Success!'
@expose(json_schema=RegistrationSchema(), error_handler='/errors')
def json_with_handler(self, data):
assert len(request.validation_errors) > 0
assert len(request.pecan['validation_errors']) > 0
return 'Success!'
@@ -193,13 +193,13 @@ class TestValidation(object):
@expose()
def errors(self, *args, **kwargs):
return 'Error with %s!' % ', '.join(request.validation_errors.keys())
return 'Error with %s!' % ', '.join(request.pecan['validation_errors'].keys())
@expose(schema=ColorSchema(),
variable_decode=True)
def index(self, **kwargs):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -207,16 +207,16 @@ class TestValidation(object):
error_handler='/errors',
variable_decode=True)
def with_handler(self, **kwargs):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@expose(json_schema=ColorSchema(),
variable_decode=True)
def json(self, data):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -224,16 +224,16 @@ class TestValidation(object):
error_handler='/errors',
variable_decode=True)
def json_with_handler(self, data):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@expose(schema=ColorSchema(),
variable_decode=dict())
def custom(self, **kwargs):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -241,16 +241,16 @@ class TestValidation(object):
error_handler='/errors',
variable_decode=dict())
def custom_with_handler(self, **kwargs):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@expose(json_schema=ColorSchema(),
variable_decode=dict())
def custom_json(self, data):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -258,16 +258,16 @@ class TestValidation(object):
error_handler='/errors',
variable_decode=dict())
def custom_json_with_handler(self, data):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@expose(schema=ColorSchema(),
variable_decode=dict(dict_char='-', list_char='.'))
def alternate(self, **kwargs):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -275,16 +275,16 @@ class TestValidation(object):
error_handler='/errors',
variable_decode=dict(dict_char='-', list_char='.'))
def alternate_with_handler(self, **kwargs):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@expose(json_schema=ColorSchema(),
variable_decode=dict(dict_char='-', list_char='.'))
def alternate_json(self, data):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -292,8 +292,8 @@ class TestValidation(object):
error_handler='/errors',
variable_decode=dict(dict_char='-', list_char='.'))
def alternate_json_with_handler(self, data):
if request.validation_errors:
return ', '.join(request.validation_errors.keys())
if request.pecan['validation_errors']:
return ', '.join(request.pecan['validation_errors'].keys())
else:
return 'Success!'
@@ -507,7 +507,7 @@ class TestValidation(object):
schema=ColorSchema(),
variable_decode=True)
def index(self, **kwargs):
if request.validation_errors:
if request.pecan['validation_errors']:
return dict()
else:
return dict(data=kwargs)
@@ -542,8 +542,8 @@ class TestValidation(object):
schema=NameSchema(),
htmlfill=dict(auto_insert_errors=True))
def json(self, **kwargs):
if request.validation_errors:
return dict(error_with=request.validation_errors.keys())
if request.pecan['validation_errors']:
return dict(error_with=request.pecan['validation_errors'].keys())
else:
return kwargs
@@ -639,7 +639,7 @@ class TestValidation(object):
@expose(template='mako:form_login.html',
schema=LoginSchema())
def index(self, **kwargs):
if request.validation_errors:
if request.pecan['validation_errors']:
return dict()
else:
return dict(data=kwargs)