@@ 91,12 91,12 @@ class GenericFunction(object):
else:
return (some_object,) + type(some_object).__mro__
- def method(self):
+ def method(self, *args):
"""Decorator to register a method for a specific set of types.
"""
def helper(function):
- types = self._get_functions_types(function)
+ types = self._get_functions_types(function, args)
self.register_func(types, function, False)
return self.substitute
@@ 115,14 115,14 @@ class GenericFunction(object):
for t in types):
self.compute_mro = self.compute_mro_non_type_case
- def variadic_method(self):
+ def variadic_method(self, *args):
"""Decorator to register a method for a specific set of types.
The method has a variable argument count.
"""
def helper(function):
- types = self._get_functions_types(function)
+ types = self._get_functions_types(function, args)
self.register_func(types, function, True)
return self.substitute
@@ 161,12 161,14 @@ class GenericFunction(object):
self.cache = {} # Clear the cache (later we can optimize this).
- def _get_functions_types(self, function):
+ def _get_functions_types(self, function, types):
"""Answer the types of the functions parameters."""
- return [object if parameter.annotation == Parameter.empty
- else parameter.annotation
- for parameter in get_signature(function).parameters.values()
- if parameter.kind == Parameter.POSITIONAL_OR_KEYWORD]
+ return (types if types else
+ [object if parameter.annotation == Parameter.empty
+ else parameter.annotation
+ for parameter in
+ get_signature(function).parameters.values()
+ if parameter.kind == Parameter.POSITIONAL_OR_KEYWORD])
def __call__(self, *args):
"""Call the overloaded function."""
@@ 394,14 396,14 @@ def _generic(
genericFunction.substitute = substitute
return substitute
-def method():
+def method(*args):
"""Automatically call the `method´ method of a generic function.
This function is intended to be used as a decorator.
"""
def helper(function):
- return find_generic(function).method()(function)
+ return find_generic(function).method(*args)(function)
return helper
@@ 28,7 28,7 @@ for lineno, line in enumerate(long_descr
#D: sys.path.insert(0, "tests")
setup(name="gf3",
- version='0.2.4',
+ version='0.2.5a',
description="A package with lisp-like generic functions for python 3.",
long_description=long_description,
long_description_content_type='text/x-rst',
@@ 38,6 38,7 @@ setup(name="gf3",
"Intended Audience :: Developers",
"License :: OSI Approved :: Python Software Foundation License",
"Operating System :: OS Independent",
+ "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.5",
@@ 1,9 1,10 @@
# -*- coding: utf-8 -*-
"""Tests for the generic object (`go`) module."""
-
+import gf
+print(gf)
from gf import (Object, FinalizingMixin, Writer,
- generic, method, variadic_method,
+ generic, method, variadic_method,
Dispatch, isgeneric, merge,
__init__, __call__, __del__,
__spy__, __add__, __out__, as_string, spy,
@@ 16,7 17,7 @@ from unittest import TestCase as Builtin
class VariadicTestCase(TestCase):
"""Test variadic methods."""
-
+
def test_variadic(self):
"""Test variadic methods."""
@@ 26,19 27,19 @@ class VariadicTestCase(TestCase):
@varfun0.variadic_method()
def varfun0(*arguments):
return tuple(reversed(arguments))
-
+
@varfun1.variadic_method()
def varfun1(tc: self.TC, *arguments):
return (tc,) + tuple(reversed(arguments))
-
+
@method()
def __eq__(tc0: self.TC, tc1: self.TC): # Make `assertEqual`work!
return tc0.a0 == tc1.a0 and tc0.a1 == tc1.a1
-
+
@method()
def __eq__(tc0: self.TC, t: tuple): # Make `assertEqual`work!
return False
-
+
@method()
def __ne__(tc0: self.TC, tc1: self.TC): # Make `assertEqual`work!
return tc0.a0 != tc1.a0 or tc0.a1 != tc1.a1
@@ 73,7 74,7 @@ class VariadicTestCase(TestCase):
self.assertEqual(varfun2("a", "b"), "a|b")
self.assertEqual(varfun2("c") , "c: ()")
-
+
def test_override(self):
"""Test variadic overrides."""
@@ 181,7 182,7 @@ class DispatchOnClassOnlyTest(TestCase):
def test_add_dispatch_on_object(self):
"""Specifying an object to dispatch on should raise a ``TypeError``"""
with self.assertRaises(TypeError):
-
+
@self.tg.method()
def tg(to: self.TC, fortyTwo: 42):
return "Gotcha"
@@ 201,7 202,7 @@ class AbstractTwoClassTest(TestCase):
"""A subclass."""
self.SubTC = SubTC
-
+
@self.tg.method()
def tg(to: self.TC):
return "TC"
@@ 209,7 210,7 @@ class AbstractTwoClassTest(TestCase):
@self.tg.method()
def tg(to: self.SubTC):
return tg(super(self.TC, to)) + " and SubTC"
-
+
class SuperCallTest(AbstractTwoClassTest):
@@ 226,7 227,7 @@ class MergeGenericsTest(AbstractTwoClass
super().setUp()
self.other_tg = generic("other_tg", "Test generic")
-
+
@self.other_tg.method()
def other_tg(to: self.TC):
return "TC (other)"
@@ 238,7 239,7 @@ class MergeGenericsTest(AbstractTwoClass
@self.other_tg.method()
def other_tg(an_integer: int):
return "int: [%d] (other)" % an_integer
-
+
@self.tg.method()
def other_tg(a_string: str):
return "str: [%s]" % a_string
@@ 258,9 259,9 @@ class MergeGenericsTest(AbstractTwoClass
"TC (other) and SubTC (other)")
self.assertEqual(self.other_tg(42), "int: [42] (other)")
self.assertEqual(self.tg("Sepp"), "str: [Sepp]")
- self.assertEqual(self.other_tg("Sepp", 12),
+ self.assertEqual(self.other_tg("Sepp", 12),
"int: [12] (other)|str: [Sepp]")
- self.assertEqual(self.tg("Sepp", 12),
+ self.assertEqual(self.tg("Sepp", 12),
"str: [Sepp]|int: [12] (other)")
merged_tg = merge(self.tg, self.other_tg)
self.assertEqual(merged_tg(self.TC()), "TC (other)")
@@ 268,9 269,9 @@ class MergeGenericsTest(AbstractTwoClass
"TC (other) and SubTC (other)")
self.assertEqual(merged_tg(42), "int: [42] (other)")
self.assertEqual(merged_tg("Sepp"), "str: [Sepp]")
- self.assertEqual(merged_tg("Sepp", 12),
+ self.assertEqual(merged_tg("Sepp", 12),
"int: [12] (other)|str: [Sepp]")
- self.assertEqual(merged_tg("Sepp", 12),
+ self.assertEqual(merged_tg("Sepp", 12),
"int: [12] (other)|str: [Sepp]")
def test_merge_variadics(self):
@@ 281,9 282,9 @@ class MergeGenericsTest(AbstractTwoClass
self.assertEqual(self.other_tg([], 1, 2), "List (other): (1, 2)")
merged_tg = merge(self.tg, self.other_tg)
self.assertEqual(merged_tg([], 1, 2), "List (other): (1, 2)")
- self.assertEqual(merged_tg([], 1, 2, 3),
+ self.assertEqual(merged_tg([], 1, 2, 3),
"List (other): (1, 2, 3)")
-
+
class TestIsGeneric(BuiltinTestCase):
"""Test the is generic function."""
@@ 299,6 300,30 @@ class TestIsGeneric(BuiltinTestCase):
self.assertTrue(isgeneric(isgeneric))
+class TestMethodDecoratorWithArguments(TestCase):
+ """Test method decorators with arguments."""
+
+ def setUp(self):
+ """Test a methods decorator with arguments."""
+ super().setUp()
+ test_generic = self.test_generic = generic()
+
+ @test_generic.method(int, int)
+ def test_generic(a0, a1):
+ return [a0, a1]
+
+ @test_generic.variadic_method(type)
+ def test_generic(constructor, *args):
+ return constructor(args)
+
+ def test_method_call(self):
+ """Test a method defined with method decorator arguments."""
+ self.assertEqual([4711, 42], self.test_generic(4711, 42))
+
+ def test_variadic_method_call(self):
+ """Test a variadic method defined with method decorator arguments."""
+ self.assertEqual([1, 2, 3], self.test_generic(list, 1, 2, 3))
+
if __name__ == "__main__":
from unittest import main