Skip to content

Commit

Permalink
Add python 2.6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
Toilal committed Nov 14, 2015
1 parent 5faa117 commit a40cff6
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
language: python
python:
- 2.6
- 2.7
- 3.3
- 3.4
Expand All @@ -11,7 +12,7 @@ install:
- pip install pylint
- pip install coveralls
script:
- pylint rebulk
- if [[ $TRAVIS_PYTHON_VERSION != 2.6 ]]; then pylint rebulk; fi
- coverage run --source=rebulk setup.py test
- python setup.py build
after_success:
Expand Down
2 changes: 1 addition & 1 deletion rebulk/loose.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def argspec_args(argspec, constructor, *args, **kwargs):
if argspec.keywords:
call_kwarg = kwargs
else:
call_kwarg = {k: kwargs[k] for k in kwargs if k in argspec.args}
call_kwarg = dict((k, kwargs[k]) for k in kwargs if k in argspec.args) # Python 2.6 dict comprehension
if argspec.varargs:
call_args = args
else:
Expand Down
6 changes: 5 additions & 1 deletion rebulk/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
"""
Classes and functions related to matches
"""
from collections import defaultdict, MutableSequence, OrderedDict
from collections import defaultdict, MutableSequence
try:
from collections import OrderedDict
except ImportError: # pragma: no-cover
from ordereddict import OrderedDict # pylint:disable=import-error
import copy
import six

Expand Down
2 changes: 1 addition & 1 deletion rebulk/pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def match_options(self):
return self._match_kwargs

def _match(self, pattern, input_string, context=None):
names = {v: k for k, v in pattern.groupindex.items()}
names = dict((v, k) for k, v in pattern.groupindex.items())
for match_object in pattern.finditer(input_string):
start = match_object.start()
end = match_object.end()
Expand Down
58 changes: 29 additions & 29 deletions rebulk/test/test_toposort.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,28 @@

class TestCase(object):
def test_simple(self):
results = list(toposort({2: {11}, 9: {11, 8}, 10: {11, 3}, 11: {7, 5}, 8: {7, 3}}))
expected = [{3, 5, 7}, {8, 11}, {2, 9, 10}]
results = list(toposort({2: set([11]), 9: set([11, 8]), 10: set([11, 3]), 11: set([7, 5]), 8: set([7, 3])}))
expected = [set([3, 5, 7]), set([8, 11]), set([2, 9, 10])]
assert results == expected

# make sure self dependencies are ignored
results = list(toposort({2: {2, 11}, 9: {11, 8}, 10: {10, 11, 3}, 11: {7, 5}, 8: {7, 3}}))
expected = [{3, 5, 7}, {8, 11}, {2, 9, 10}]
results = list(toposort({2: set([2, 11]), 9: set([11, 8]), 10: set([10, 11, 3]), 11: set([7, 5]), 8: set([7, 3])}))
expected = [set([3, 5, 7]), set([8, 11]), set([2, 9, 10])]
assert results == expected

assert list(toposort({1: set()})) == [{1}]
assert list(toposort({1: {1}})) == [{1}]
assert list(toposort({1: set()})) == [set([1])]
assert list(toposort({1: set([1])})) == [set([1])]

def test_no_dependencies(self):
assert list(toposort({1: {2}, 3: {4}, 5: {6}})) == [{2, 4, 6}, {1, 3, 5}]
assert list(toposort({1: set(), 3: set(), 5: set()})) == [{1, 3, 5}]
assert list(toposort({1: set([2]), 3: set([4]), 5: set([6])})) == [set([2, 4, 6]), set([1, 3, 5])]
assert list(toposort({1: set(), 3: set(), 5: set()})) == [set([1, 3, 5])]

def test_empty(self):
assert list(toposort({})) == []

def test_strings(self):
results = list(toposort({'2': {'11'}, '9': {'11', '8'}, '10': {'11', '3'}, '11': {'7', '5'}, '8': {'7', '3'}}))
expected = [{'3', '5', '7'}, {'8', '11'}, {'2', '9', '10'}]
results = list(toposort({'2': set(['11']), '9': set(['11', '8']), '10': set(['11', '3']), '11': set(['7', '5']), '8': set(['7', '3'])}))
expected = [set(['3', '5', '7']), set(['8', '11']), set(['2', '9', '10'])]
assert results == expected

def test_objects(self):
Expand All @@ -53,34 +53,34 @@ def test_objects(self):
o9 = object()
o10 = object()
o11 = object()
results = list(toposort({o2: {o11}, o9: {o11, o8}, o10: {o11, o3}, o11: {o7, o5}, o8: {o7, o3, o8}}))
expected = [{o3, o5, o7}, {o8, o11}, {o2, o9, o10}]
results = list(toposort({o2: set([o11]), o9: set([o11, o8]), o10: set([o11, o3]), o11: set([o7, o5]), o8: set([o7, o3, o8])}))
expected = [set([o3, o5, o7]), set([o8, o11]), set([o2, o9, o10])]
assert results == expected

def test_cycle(self):
# a simple, 2 element cycle
with pytest.raises(CyclicDependency):
list(toposort({1: {2}, 2: {1}}))
list(toposort({1: set([2]), 2: set([1])}))

# an indirect cycle
with pytest.raises(CyclicDependency):
list(toposort({1: {2}, 2: {3}, 3: {1}}))
list(toposort({1: set([2]), 2: set([3]), 3: set([1])}))

def test_input_not_modified(self):
data = {2: {11},
9: {11, 8},
10: {11, 3},
11: {7, 5},
8: {7, 3, 8}, # includes something self-referential
data = {2: set([11]),
9: set([11, 8]),
10: set([11, 3]),
11: set([7, 5]),
8: set([7, 3, 8]), # includes something self-referential
}
orig = data.copy()
results = list(toposort(data))
assert data == orig

def test_input_not_modified_when_cycle_error(self):
data = {1: {2},
2: {1},
3: {4},
data = {1: set([2]),
2: set([1]),
3: set([4]),
}
orig = data.copy()
with pytest.raises(CyclicDependency):
Expand All @@ -90,13 +90,13 @@ def test_input_not_modified_when_cycle_error(self):

class TestCaseAll(object):
def test_sort_flatten(self):
data = {2: {11},
9: {11, 8},
10: {11, 3},
11: {7, 5},
8: {7, 3, 8}, # includes something self-referential
data = {2: set([11]),
9: set([11, 8]),
10: set([11, 3]),
11: set([7, 5]),
8: set([7, 3, 8]), # includes something self-referential
}
expected = [{3, 5, 7}, {8, 11}, {2, 9, 10}]
expected = [set([3, 5, 7]), set([8, 11]), set([2, 9, 10])]
assert list(toposort(data)) == expected

# now check the sorted results
Expand All @@ -107,5 +107,5 @@ def test_sort_flatten(self):

# and the unsorted results. break the results up into groups to compare them
actual = toposort_flatten(data, False)
results = [{i for i in actual[0:3]}, {i for i in actual[3:5]}, {i for i in actual[5:8]}]
results = [set([i for i in actual[0:3]]), set([i for i in actual[3:5]]), set([i for i in actual[5:8]])]
assert results == expected
9 changes: 5 additions & 4 deletions rebulk/toposort.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
# Modifications:
# - merged Pull request #2 for CyclicDependency error
# - import reduce as original name
# - support python 2.6 dict comprehension

# pylint: skip-file
from functools import reduce


class CyclicDependency(ValueError):
def __init__(self, cyclic):
s = 'Cyclic dependencies exist among these items: {}'.format(', '.join(repr(x) for x in cyclic.items()))
s = 'Cyclic dependencies exist among these items: {0}'.format(', '.join(repr(x) for x in cyclic.items()))
super(CyclicDependency, self).__init__(s)
self.cyclic = cyclic

Expand Down Expand Up @@ -51,15 +52,15 @@ def toposort(data):
# Find all items that don't depend on anything.
extra_items_in_deps = reduce(set.union, data.values()) - set(data.keys())
# Add empty dependences where needed.
data.update({item: set() for item in extra_items_in_deps})
data.update(dict((item, set()) for item in extra_items_in_deps))
while True:
ordered = set(item for item, dep in data.items() if len(dep) == 0)
if not ordered:
break
yield ordered
data = {item: (dep - ordered)
data = dict((item, (dep - ordered))
for item, dep in data.items()
if item not in ordered}
if item not in ordered)
if len(data) != 0:
raise CyclicDependency(data)

Expand Down
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@
# -*- coding: utf-8 -*-

from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand

from platform import python_implementation

import sys
import os


here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, 'README.rst')).read()

install_requires = ['six', 'regex']
if sys.version_info < (2, 7):
install_requires.extend(['ordereddict'])

if python_implementation() == 'PyPy':
install_requires.remove('regex') # PyPy doesn't support regex module

Expand All @@ -32,6 +34,7 @@
'Operating System :: OS Independent',
'Intended Audience :: Developers',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
Expand Down

0 comments on commit a40cff6

Please sign in to comment.