# HG changeset patch # User Gerald Klix (speedy) # Date 1565371016 -7200 # Fri Aug 09 19:16:56 2019 +0200 # Node ID 441139ea1cc76fa859a9dae00ff2f1bf7acd2134 # Parent 9af9659145c8bc697c262fcf06dd67b6af0efba6 SUM: Re-enabled parameters in method and variadic method. diff --git a/docs/acknowledgements.rst b/docs/acknowledgements.rst --- a/docs/acknowledgements.rst +++ b/docs/acknowledgements.rst @@ -9,4 +9,4 @@ ========= © 2006-2013 Python Software Foundation. -© 2013-2018 Gerald Klix. +© 2013-2019 Gerald Klix. diff --git a/gf/base.py b/gf/base.py --- a/gf/base.py +++ b/gf/base.py @@ -91,12 +91,12 @@ 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 @@ 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 @@ 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 @@ 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 diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ #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 @@ "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", diff --git a/tests/testgf.py b/tests/testgf.py --- a/tests/testgf.py +++ b/tests/testgf.py @@ -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 @@ class VariadicTestCase(TestCase): """Test variadic methods.""" - + def test_variadic(self): """Test variadic methods.""" @@ -26,19 +27,19 @@ @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 @@ self.assertEqual(varfun2("a", "b"), "a|b") self.assertEqual(varfun2("c") , "c: ()") - + def test_override(self): """Test variadic overrides.""" @@ -181,7 +182,7 @@ 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 @@ """A subclass.""" self.SubTC = SubTC - + @self.tg.method() def tg(to: self.TC): return "TC" @@ -209,7 +210,7 @@ @self.tg.method() def tg(to: self.SubTC): return tg(super(self.TC, to)) + " and SubTC" - + class SuperCallTest(AbstractTwoClassTest): @@ -226,7 +227,7 @@ 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 @@ @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 @@ "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 @@ "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 @@ 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 @@ 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 diff --git a/tests/textest.py b/tests/textest.py --- a/tests/textest.py +++ b/tests/textest.py @@ -6,12 +6,7 @@ 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