diff --git a/nanohttp.py b/nanohttp.py index b90a7c1..6a53b97 100644 --- a/nanohttp.py +++ b/nanohttp.py @@ -17,7 +17,7 @@ import ujson -__version__ = '0.1.10' +__version__ = '0.1.11' DEFAULT_CONFIG_FILE = 'nanohttp.yml' DEFAULT_ADDRESS = '8080' @@ -354,13 +354,14 @@ def __delattr__(self, key): def action(*verbs, encoding='utf-8', content_type=None, inner_decorator=None): def _decorator(func): + argcount = func.__code__.co_argcount if inner_decorator is not None: func = inner_decorator(func) func.__http_methods__ = verbs if verbs else 'any' - func.__response_encoding__ = encoding + func.__argcount__ = argcount if content_type: func.__content_type__ = content_type @@ -500,10 +501,7 @@ def _serve_handler(self, handler, *remaining_paths): if hasattr(handler, '__content_type__'): context.response_content_type = handler.__content_type__ - try: - return handler(*remaining_paths) - except TypeError as ex: - raise HttpNotFound(str(ex)) + return handler(*remaining_paths) def _dispatch(self, *remaining_paths): if not len(remaining_paths): @@ -519,8 +517,10 @@ def _dispatch(self, *remaining_paths): if handler is not None: remaining_paths = (path, ) + remaining_paths - if handler is None or not hasattr(handler, '__http_methods__') \ - or (hasattr(handler, '__annotations__') and len(handler.__annotations__) < len(remaining_paths)): + args_count = len(remaining_paths) + if (handler is None or not hasattr(handler, '__http_methods__')) \ + or (hasattr(handler, '__argcount__') and handler.__argcount__ < args_count) \ + or (hasattr(handler, '__annotations__') and len(handler.__annotations__) < args_count): raise HttpNotFound() if 'any' != handler.__http_methods__ and context.method not in handler.__http_methods__: diff --git a/practice/type_annotation.py b/practice/type_annotation.py new file mode 100644 index 0000000..b9fd757 --- /dev/null +++ b/practice/type_annotation.py @@ -0,0 +1,29 @@ + +import functools + + +def a(arg1, arg2, kw1=None, kw2=None, *args, kw3=None, **kw): + ttttttt = 66 + + +@functools.wraps(a, ) +def w(*args, **kwargs): + return a(*args, **kwargs) + + +def describe(f): + print(f.__name__) + code = f.__code__ + for k in dir(code): + if k.startswith('co_'): + v = getattr(code, k) + print(k, v) + + +def main(): + describe(a) + describe(w) + + +if __name__ == '__main__': + main() diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py index ab850e0..b048f59 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -53,7 +53,7 @@ def contact(self, contact_id: int=None): yield "Contact: %s" % contact_id @html - def users(self, user_id: int, attr: str=None): + def users(self, user_id: int=None, attr: str=None): yield 'User: %s\n' % user_id yield 'Attr: %s\n' % attr @@ -72,7 +72,7 @@ def test_root(self): def test_arguments(self): self.assert_get('/contact/1', expected_response='Contact: 1') self.assert_post('/contact', expected_response='Contact: None') - self.assert_get('/users', status=404) + self.assert_get('/users', expected_response='User: None\nAttr: None\n') self.assert_get('/users/10/') self.assert_get('/users/10/jobs', expected_response='User: 10\nAttr: jobs\n') self.assert_get('/users/10/11/11', status=404)