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
    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):