Skip to content

Commit

Permalink
Merge pull request #6 from thomasw/python3
Browse files Browse the repository at this point in the history
Add python 3 support
  • Loading branch information
thomasw committed Sep 9, 2015
2 parents 1bab12e + 4441ba1 commit 6afd3ea
Show file tree
Hide file tree
Showing 25 changed files with 118 additions and 82 deletions.
12 changes: 9 additions & 3 deletions .travis.yml
@@ -1,9 +1,15 @@
language: python
sudo: false
python:
- "2.6"
- "2.7"
install: "pip install -r requirements.txt --use-mirrors"
- "3.3"
- "3.4"
- "pypy"
install:
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install -r requirements26.txt; fi
- if [[ $TRAVIS_PYTHON_VERSION != '2.6' ]]; then pip install -r requirements.txt; fi
script:
- nosetests --with-coverage --cover-package=querylist
- python setup.py nosetests
after_success:
coveralls
coveralls
4 changes: 4 additions & 0 deletions CONTRIBUTORS
@@ -0,0 +1,4 @@
The primary author and maintainer of querylist is Thomas Welfley. The following
people have also contributed to querylist:

William Stewart
7 changes: 7 additions & 0 deletions MANIFEST.in
@@ -0,0 +1,7 @@
include *.md
include requirements*.txt
include LICENSE
include CONTRIBUTORS
include setup.cfg

recursive-include docs *
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -26,7 +26,7 @@ Querylist can be installed like any other python package:

> pip install querylist

Querylist is tested against Python >2.5, <3.0.
Querylist is tested against Python 2.6, 2.7, 3.3, 3.4, and pypy.

## Usage

Expand Down Expand Up @@ -140,7 +140,8 @@ the following, which publishes all unpublished sites:
## Contributing

1. Fork the repo and then clone it locally.
2. Install the development requirements: `pip install -r requirements.txt`
2. Install the development requirements: `pip install -r requirements.txt` (
use `requirements26.txt` for python 2.6)
3. Use [testtube](https://github.com/thomasw/testtube/)'s `stir` command
(installed via #2) to monitor the project directory for changes and
automatically run the test suite.
Expand Down
4 changes: 4 additions & 0 deletions docs/source/changelog.rst
@@ -1,6 +1,10 @@
Changelog
=========

**0.3.0**

* Adds Python 3 support.

**0.2.0**

* Added a new field lookup called `call`. It uses the passed value as a callable
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Expand Up @@ -17,7 +17,7 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../../'))

from querylist import __version__, __author__
from querylist import __version__, __author__ # noqa
# -- General configuration --------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
Expand Down
3 changes: 1 addition & 2 deletions docs/source/installation.rst
Expand Up @@ -10,5 +10,4 @@ the querylist module.

>>> from querylist import BetterDict, QueryList

QueryList is currently only tested against Python 2.6 and 2.7, though it
should work in 2.5 as well.
Querylist is tested against Python 2.6, 2.7, 3.3, 3.4, and pypy.
9 changes: 4 additions & 5 deletions querylist/__init__.py
@@ -1,9 +1,8 @@
"""QueryList provides a simple way to filter lists of objects."""
from querylist.list import QueryList
from querylist.dict import BetterDict

from querylist import QueryList
from betterdict import BetterDict

__version__ = "0.2.0"
__author__ = "Thomas Welfley"
__version__ = '0.3.0'
__author__ = 'Thomas Welfley'

__all__ = ['QueryList', 'BetterDict']
File renamed without changes.
6 changes: 3 additions & 3 deletions querylist/querylist.py → querylist/list.py
@@ -1,5 +1,5 @@
from betterdict import BetterDict
from fieldlookup import field_lookup
from querylist.dict import BetterDict
from querylist.fieldlookup import field_lookup


class QueryList(list):
Expand Down Expand Up @@ -72,7 +72,7 @@ def _check_element(self, lookup_strings, instance):
object.
"""
for q, val in lookup_strings.iteritems():
for q, val in lookup_strings.items():
if not field_lookup(instance, q, val, True):
return False

Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Expand Up @@ -2,10 +2,9 @@
coveralls==0.4.1
flake8==2.3.0
frosted==1.4.1
nose==1.2.1
pinocchio==0.3.1
nose==1.3.6
pep257==0.4.1
unittest2==0.5.1
spec==1.2.2
testtube==1.0.0

# Documentation requirements.
Expand Down
4 changes: 4 additions & 0 deletions requirements26.txt
@@ -0,0 +1,4 @@
# These requirements are specifically needed for python 2.6
unittest2==1.1.0

-r requirements.txt
5 changes: 3 additions & 2 deletions setup.cfg
@@ -1,3 +1,4 @@
[nosetests]
with-spec=1
spec-color=1
with-specplugin=1
with-coverage=1
cover-package=querylist
31 changes: 20 additions & 11 deletions setup.py
Expand Up @@ -2,32 +2,41 @@

from setuptools import setup, find_packages

from querylist import __version__, __author__
import querylist

unittest2_module = 'unittest2==0.5.1'

# If we're using Python 3, unittest2 won't work. We need unittest2py3k
if sys.version_info > (3, 0):
unittest2_module = 'unittest2py3k==0.5.1'
unittest2_module = ''

if sys.version_info < (2, 7):
# spec causes python setup.py test to fail. This import fixes that for
# some reason.
import multiprocessing # noqa

# If we're still on python 2.6, we need unittest2
unittest2_module = 'unittest2<1.2'


setup(
name="querylist",
version=__version__,
name='querylist',
version=querylist.__version__,
url='https://github.com/thomasw/querylist',
download_url='https://github.com/thomasw/querylist/downloads',
author=__author__,
author=querylist.__author__,
author_email='thomas.welfley+querylist@gmail.com',
description='This package provides a QueryList class with django '
'ORM-esque filtering, excluding, and getting for lists. It '
'also provides BetterDict, a dot lookup/assignment capable '
'wrapper for dicts that is 100% backwards compatible.',
packages=find_packages(),
tests_require=["nose==1.2.1", "pinocchio==0.3.1", unittest2_module],
tests_require=[
'nose>=1.3.6,<1.4',
'spec>=1.2.2,<1.3',
unittest2_module
],
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Topic :: Software Development :: Libraries',
],
test_suite='nose.collector'
test_suite='nose.collector',
)
File renamed without changes.
4 changes: 4 additions & 0 deletions tests/base.py
@@ -0,0 +1,4 @@
try:
from unittest2 import TestCase # noqa
except ImportError:
from unittest import TestCase # noqa
@@ -1,9 +1,9 @@
import unittest2

from querylist import BetterDict

from tests.base import TestCase


class BetterDictActsAsDict(unittest2.TestCase):
class BetterDictActsAsDict(TestCase):
"""BetterDicts should act just like dictionaries"""
def setUp(self):
self.src_dict = {
Expand Down
@@ -1,8 +1,9 @@
from copy import deepcopy
import unittest2

from querylist import BetterDict

from tests.base import TestCase

SRC_DICT = {
'foo': 1,
'bar': {
Expand All @@ -24,7 +25,7 @@
}


class BetterDictTestCase(unittest2.TestCase):
class BetterDictTestCase(TestCase):
def setUp(self):
self.src_dict = deepcopy(SRC_DICT)
self.better_dict = BetterDict(self.src_dict)
Expand Down
@@ -1,9 +1,9 @@
import unittest2
from querylist.dict import BetterDictLookUp

from querylist.betterdict import BetterDictLookUp
from tests.base import TestCase


class BetterDictLookUpInstancesCan(unittest2.TestCase):
class BetterDictLookUpInstancesCan(TestCase):
def setUp(self):
self.src_dict = {
'foo': 1,
Expand Down
34 changes: 17 additions & 17 deletions querylist/tests/comparator_tests.py → tests/comparator_tests.py
@@ -1,11 +1,11 @@
import unittest2

from querylist.fieldlookup import FieldLookup

from tests.base import TestCase

fl = FieldLookup


class ExactTests(unittest2.TestCase):
class ExactTests(TestCase):
"""FieldLookup.exact()"""
def test_returns_true_if_passed_values_match_exactly(self):
self.assertTrue(fl.exact(1, 1))
Expand All @@ -14,7 +14,7 @@ def test_returns_false_if_passed_values_dont_match(self):
self.assertFalse(fl.exact(1, 2))


class IExactTests(unittest2.TestCase):
class IExactTests(TestCase):
"""FieldLookup.iexact()"""
def test_returns_true_if_case_insensitive_values_match(self):
self.assertTrue(fl.iexact('Yay', 'yay'))
Expand All @@ -23,7 +23,7 @@ def test_returns_false_if_values_dont_match(self):
self.assertFalse(fl.iexact('yay', 'foo'))


class ContainsTests(unittest2.TestCase):
class ContainsTests(TestCase):
"""FieldLookup.contains()"""
def test_returns_true_if_first_value_contains_second_value(self):
self.assertTrue(fl.contains('go team', 'team'))
Expand All @@ -35,7 +35,7 @@ def test_returns_false_if_first_value_does_not_contain_second(self):
self.assertFalse(fl.contains([1, 2], 3))


class IContainsTests(unittest2.TestCase):
class IContainsTests(TestCase):
"""FieldLookup.icontains()"""
def test_returns_true_if_first_value_contains_second_with_any_case(self):
self.assertTrue(fl.icontains('FLOrida', 'flo'))
Expand All @@ -44,7 +44,7 @@ def test_returns_False_if_first_value_doesnt_contain_second_value(self):
self.assertFalse(fl.icontains('Florida', 'Cal'))


class InTests(unittest2.TestCase):
class InTests(TestCase):
"""FieldLookup.in()"""
def test_returns_true_if_first_value_is_in_second_value(self):
self.assertTrue(fl.isin(1, [1, 2]))
Expand All @@ -53,7 +53,7 @@ def test_returns_false_if_second_value_does_not_contain_first_value(self):
self.assertFalse(fl.isin(4, [1, 2]))


class StartsWithTests(unittest2.TestCase):
class StartsWithTests(TestCase):
"""FieldLookup.startswith()"""
def test_returns_true_if_first_value_starts_with_second_value(self):
self.assertTrue(fl.startswith('kittens', 'kitten'))
Expand All @@ -62,7 +62,7 @@ def test_returns_false_if_first_value_doesnt_start_with_second(self):
self.assertFalse(fl.startswith('kittens', 'do'))


class IStartsWithTests(unittest2.TestCase):
class IStartsWithTests(TestCase):
"""FieldLookup.istartswith()"""
def test_lowercase_vals_and_return_true_if_first_starts_with_second(self):
self.assertTrue(fl.istartswith('Kittens', 'kitteN'))
Expand All @@ -71,7 +71,7 @@ def test_returns_false_if_first_value_doesnt_start_with_second(self):
self.assertFalse(fl.istartswith('Kittens', 'DOG'))


class EndsWithTests(unittest2.TestCase):
class EndsWithTests(TestCase):
"""FieldLookup.endswith()"""
def test_returns_true_if_first_value_ends_with_second_value(self):
self.assertTrue(fl.endswith('kittens', 'tens'))
Expand All @@ -80,7 +80,7 @@ def test_returns_false_if_first_value_doesnt_end_with_second(self):
self.assertFalse(fl.endswith('kittens', 'do'))


class IEndsWithTests(unittest2.TestCase):
class IEndsWithTests(TestCase):
"""FieldLookup.iendswith()"""
def test_lowercase_vals_and_return_true_if_first_ends_with_second(self):
self.assertTrue(fl.iendswith('Kittens', 'teNs'))
Expand All @@ -89,7 +89,7 @@ def test_returns_false_if_first_value_doesnt_end_with_second(self):
self.assertFalse(fl.iendswith('Kittens', 'DOG'))


class RegexTests(unittest2.TestCase):
class RegexTests(TestCase):
"""FieldLookup.regex()"""
def test_returns_true_if_first_value_matches_regex(self):
self.assertTrue(fl.regex('foo', r'\w*'))
Expand All @@ -98,7 +98,7 @@ def test_returns_false_if_first_value_doesnt_match_regex(self):
self.assertFalse(fl.regex('foo', r'\w*BOOP'))


class IRegexWithTests(unittest2.TestCase):
class IRegexWithTests(TestCase):
"""FieldLookup.iregex()"""
def test_returns_true_if_first_value_matches_iregex(self):
self.assertTrue(fl.iregex('foo', r'[A-Z]*'))
Expand All @@ -107,7 +107,7 @@ def test_returns_false_if_first_value_doesnt_match_iregex(self):
self.assertFalse(fl.iregex('foo', r'[A-Z]*BOOP'))


class GTTests(unittest2.TestCase):
class GTTests(TestCase):
"""FieldLookup.gt()"""
def test_returns_true_if_first_value_is_greater_than_second(self):
self.assertTrue(fl.gt(2, 1))
Expand All @@ -119,7 +119,7 @@ def test_returns_false_if_values_are_equal(self):
self.assertFalse(fl.gt(2, 2))


class GTETests(unittest2.TestCase):
class GTETests(TestCase):
"""FieldLookup.gte()"""
def test_returns_true_if_first_value_is_greater_than_second(self):
self.assertTrue(fl.gte(2, 1))
Expand All @@ -131,7 +131,7 @@ def test_returns_false_if_first_value_isnt_greater_than_second(self):
self.assertFalse(fl.gte(1, 2))


class LTTests(unittest2.TestCase):
class LTTests(TestCase):
"""FieldLookup.lt()"""
def test_returns_true_if_first_value_is_less_than_second(self):
self.assertTrue(fl.lt(1, 2))
Expand All @@ -143,7 +143,7 @@ def test_returns_false_if_values_are_equal(self):
self.assertFalse(fl.lt(2, 2))


class LTETests(unittest2.TestCase):
class LTETests(TestCase):
"""FieldLookup.lte()"""
def test_returns_true_if_first_value_is_less_than_second(self):
self.assertTrue(fl.lte(1, 2))
Expand Down

0 comments on commit 6afd3ea

Please sign in to comment.