Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: AvivC/genericfuncs
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: GlobalRadio/genericfuncs
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 1 commit
  • 4 files changed
  • 1 contributor

Commits on Sep 29, 2016

  1. Added python 3 support and dropped python 2

    Iago Veloso committed Sep 29, 2016

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    29c0676 View commit details
Showing with 18 additions and 30 deletions.
  1. +1 −1 README.rst
  2. +6 −10 genericfuncs.py
  3. +3 −3 setup.py
  4. +8 −16 test/test_basic.py
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ Installation

.. code-block:: bash
pip install genericfuncs
pip3 install genericfuncs
Advanced
16 changes: 6 additions & 10 deletions genericfuncs.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
from __future__ import unicode_literals, division, print_function, absolute_import

import collections
import inspect
from collections import namedtuple
import functools
from itertools import imap


class generic(object):
@@ -142,7 +138,7 @@ def _make_predicate_from_callable(self, predicate_source):

def _make_predicate_from_dict(self, predicate_dict):
def predicate(*args, **kwargs):
for arg_name, arg_predicate_source in predicate_dict.iteritems():
for arg_name, arg_predicate_source in predicate_dict.items():
arg_value = self._base_func.get_arg_value(arg_name, args, kwargs)

gen = generic(_FunctionInfo(args=[arg_name]))
@@ -158,15 +154,15 @@ def _make_type_predicate(self, predicate):
if isinstance(predicate, type):
def type_predicate(*args, **kwargs):
return all(isinstance(obj, predicate) for obj in args) \
and all(isinstance(obj, predicate) for key, obj in kwargs.iteritems())
and all(isinstance(obj, predicate) for key, obj in kwargs.items())

elif isinstance(predicate, dict):
if any((not isinstance(value, (type, collections.Iterable))) for value in predicate.values()):
if any((not isinstance(value, (type, collections.Iterable))) for value in list(predicate.values())):
raise TypeError('In a dict that maps arguments to expected types, '
'the values must be either types or iterables of types.')

def type_predicate(*args, **kwargs):
for arg_name, expected_arg_type in predicate.iteritems():
for arg_name, expected_arg_type in predicate.items():
arg_value = self._base_func.get_arg_value(arg_name, args, kwargs)

if isinstance(expected_arg_type, collections.Iterable):
@@ -182,7 +178,7 @@ def type_predicate(*args, **kwargs):
return _PartialFunction(type_predicate, self._base_func, args=self._base_func.args)

def _make_predicate_from_iterable(self, predicates, aggregator=all):
partial_func_predicates = map(self.make_predicate, predicates)
partial_func_predicates = list(map(self.make_predicate, predicates))

def composed_predicates(*args, **kwargs):
return aggregator(predicate(*args, **kwargs) for predicate in partial_func_predicates)
@@ -251,7 +247,7 @@ def __init__(self, function, base_function, args=None):

def __call__(self, *args, **kwargs):
partial_args = self._find_arg_values(args)
partial_kwargs = {k: v for k, v in kwargs.iteritems() if k in self.args}
partial_kwargs = {k: v for k, v in kwargs.items() if k in self.args}
return self._function(*partial_args, **partial_kwargs)

def _find_arg_values(self, input_arg_values):
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
name='genericfuncs',
description='Dynamic dispatch over arbitrary predicates',
long_description=_readme,
version='0.2.0',
version='0.2.1pr1',
url='https://github.com/AvivC/genericfuncs',
author='Aviv Cohn',
author_email='avivcohn123@yahoo.com',
@@ -18,8 +18,8 @@
classifiers=[
'Development Status :: 3 - Alpha',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Topic :: Software Development :: Libraries',
24 changes: 8 additions & 16 deletions test/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from __future__ import unicode_literals
from __future__ import division

import pytest
import genericfuncs

@@ -22,10 +19,6 @@ def genfunc(a, b, c):
def when_a_largerthan_b_largerthan_c(a, b, c):
return 'a > b > c'

@genfunc.when(long)
def when_all_params_long(a, b, c):
return 'all are long'

@genfunc.when(lambda a, b, c: a < b < c)
def when_a_lessthan_b_lessthan_c(a, b, c):
return 'a < b < c'
@@ -48,7 +41,6 @@ def when_all_equal_eight(a, b, c):

assert genfunc(4, 4, 4) == 'default impl'
assert genfunc(5, 3, 2) == 'a > b > c'
assert genfunc(10L, 20L, 1L) == 'all are long'
assert genfunc(1, 10, 30) == 'a < b < c'
assert genfunc(2, 10, 0) == 'one or more is 0'
assert genfunc(8, 8, 8) == 'a == b == c == 8'
@@ -122,7 +114,7 @@ def _(a, b, c):
def _(c):
return locals()

@genfunc.when([lambda b: b == 'paramb', lambda a, c: a == 'parama' and c == 'paramc', basestring])
@genfunc.when([lambda b: b == 'paramb', lambda a, c: a == 'parama' and c == 'paramc', str])
def _(c):
return locals()

@@ -152,17 +144,17 @@ def _(a, b, c):
assert genfunc(1, b=1, c=1) == 'default'
with pytest.raises(TypeError) as exc_info:
genfunc(1, 1, 1, c=1)
assert 'got multiple values for keyword argument' in str(exc_info)
assert 'got multiple values' in str(exc_info)
with pytest.raises(TypeError) as exc_info:
genfunc(1, 1, 1, b=1, c=1)
assert 'got multiple values for keyword argument' in str(exc_info)
assert 'got multiple values' in str(exc_info)

assert genfunc(3, 2, 1) == [3, 2, 1]
assert genfunc(a=3, b=2, c=1) == [3, 2, 1]
assert genfunc(3, 2, c=1) == [3, 2, 1]
with pytest.raises(TypeError) as exc_info:
genfunc(3, 2, 1, b=2, c=1)
assert 'got multiple values for keyword argument' in str(exc_info)
assert 'got multiple values' in str(exc_info)


def test_invalid_genfunc_calls_raise_error():
@@ -221,7 +213,7 @@ def _(a):
def _(a):
return 'a.startswith(\'bar\')'

@genfunc.when(lambda a: a.endswith('foo'), type=basestring)
@genfunc.when(lambda a: a.endswith('foo'), type=str)
def _(a):
return 'a.endswith(\'foo\')'

@@ -250,7 +242,7 @@ def genfunc(a, b):
def _(a):
return 'a > b'

@genfunc.when(lambda b: b.endswith('bar'), type={'b': basestring})
@genfunc.when(lambda b: b.endswith('bar'), type={'b': str})
def _(a):
return 'b.endswith(\'bar\')'

@@ -311,14 +303,14 @@ def _(a, b):

@genfunc.when({
'a': lambda a: a.startswith('foo')
}, type=basestring)
}, type=str)
def _(a, b):
return 'a starts with foo and all args are strings'

@genfunc.when({
'a': lambda a: a.startswith('foo')
}, type={
'a': basestring,
'a': str,
'b': float
})
def _(a, b):