Skip to content

Commit

Permalink
#1 support multiple args reduction into one
Browse files Browse the repository at this point in the history
  • Loading branch information
petr-s committed Mar 21, 2016
1 parent 7eb64dd commit 5307b04
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
23 changes: 17 additions & 6 deletions clearest/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from abc import ABCMeta, abstractmethod
from collections import defaultdict
from copy import deepcopy
from types import LambdaType
from xml.dom.minidom import Document
from xml.etree.ElementTree import tostring, Element

Expand Down Expand Up @@ -94,17 +95,27 @@ def is_matching(signature, args, path, query):


def parse_args(args, path, query):
def one_or_many(dict_, key):
return dict_[key][0] if len(dict_[key]) == 1 else dict_[key]
def one_or_many(fn_, dict_, key):
result = [fn_(value) for value in dict_[key]]
return result[0] if len(result) == 1 else result

kwargs = {}
for arg, parse_fn in six.iteritems(args):
if parse_fn is None:
kwargs[arg] = one_or_many(query, arg)
kwargs[arg] = one_or_many(lambda x: x, query, arg)
elif isinstance(parse_fn, tuple):
kwargs[arg] = parse_fn[DEFAULT] if arg not in query else parse_fn[CALLABLE](one_or_many(query, arg))
kwargs[arg] = parse_fn[DEFAULT] if arg not in query else one_or_many(parse_fn[CALLABLE], query, arg)
elif isinstance(parse_fn, LambdaType):
_code = six.get_function_code(parse_fn)
closures = six.get_function_closure(parse_fn)
if closures:
assert len(closures) <= 1
fn = closures[0].cell_contents
else:
fn = eval(".".join(_code.co_names), six.get_function_globals(parse_fn))
kwargs[arg] = fn(**parse_args(get_function_args(parse_fn), path, query))
else:
kwargs[arg] = parse_fn(one_or_many(query, arg))
kwargs[arg] = one_or_many(parse_fn, query, arg)
return kwargs


Expand All @@ -126,7 +137,7 @@ def parse_form_data(input_file, n, rest):
elif state == 2 and not len(line):
state = 3
elif state == 3:
kwargs[name] = line
kwargs[name] = [line]
state = 0
return kwargs

Expand Down
37 changes: 37 additions & 0 deletions tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
from tests.wsgi import WSGITestCase


def g_login(user, password):
return 1


class Test(WSGITestCase):
def setUp(self):
unregister_all()
Expand Down Expand Up @@ -119,6 +123,16 @@ def asd(a=int):
self.assertEqual(HTTP_OK, self.status)
self.assertEqual(((42,), {}), asd.called_with)

def test_application_simple_var_parse_many(self):
@GET("/asd")
@called_with
def asd(a=int):
return {}

self.get("/asd?a=42&a=84")
self.assertEqual(HTTP_OK, self.status)
self.assertEqual((([42, 84],), {}), asd.called_with)

def test_application_simple_var_default(self):
@GET("/asd")
@called_with
Expand Down Expand Up @@ -246,3 +260,26 @@ def asd():
self.assertTrue(CONTENT_TYPE in self.headers)
self.assertEqual(MIME_XML, self.headers[CONTENT_TYPE])
self.assertEqual(tostring(fromstring("<root/>")), tostring(fromstring(result)))

def test_application_simple_lambda_closure(self):
def login(user, password):
return 1

@GET("/asd")
@called_with
def asd(user_id=lambda user, password: login):
return {}

self.get("/asd?user=guest&password=secret")
self.assertEqual(HTTP_OK, self.status)
self.assertEqual(((1,), {}), asd.called_with)

def test_application_simple_lambda(self):
@GET("/asd")
@called_with
def asd(user_id=lambda user, password: g_login):
return {}

self.get("/asd?user=guest&password=secret")
self.assertEqual(HTTP_OK, self.status)
self.assertEqual(((1,), {}), asd.called_with)

0 comments on commit 5307b04

Please sign in to comment.