441139ea1cc7 — Gerald Klix (speedy) 3 years ago
SUM: Re-enabled parameters in method and variadic method.
5 files changed, 61 insertions(+), 38 deletions(-)

M docs/acknowledgements.rst
M gf/base.py
M setup.py
M tests/testgf.py
M tests/textest.py
M docs/acknowledgements.rst +1 -1
@@ 9,4 9,4 @@ Copyright
 =========
 
 © 2006-2013 Python Software Foundation.
-© 2013-2018 Gerald Klix.
+© 2013-2019 Gerald Klix.

          
M gf/base.py +13 -11
@@ 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
 

          
M setup.py +2 -1
@@ 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",

          
M tests/testgf.py +44 -19
@@ 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

          
M tests/textest.py +1 -6
@@ 6,12 6,7 @@ from doctest import (DocFileSuite, set_u
         REPORT_NDIFF, REPORT_ONLY_FIRST_FAILURE)
 from glob import glob
 
-import os, sys
-sys.path.insert(0,
-        os.path.abspath(
-            os.path.normpath(
-                os.path.join(
-                    os.path.basename(__file__), os.pardir))))
+import os
 
 from gf import IndentingWriter, push, pop
 from gf.go import get_text