diff --git a/.travis.yml b/.travis.yml index 44333a8..031ee34 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ language: python python: - "2.6" - "2.7" + - "3.2" + - "3.3" + - "3.4" install: - - pip install -r requirements/dev.txt --use-mirrors + - pip install -r requirements/dev.txt + - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then pip install unittest2; fi script: nosetests diff --git a/docs/conf.py b/docs/conf.py index c10f5c0..b71d592 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,6 +12,7 @@ # serve to show the default. import sys, os +import six # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -41,8 +42,8 @@ master_doc = 'index' # General information about the project. -project = u'pygithub3' -copyright = u'2012, David Medina' +project = six.u('pygithub3') +copyright = six.u('2012, David Medina') # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -189,8 +190,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'pygithub3.tex', u'pygithub3 Documentation', - u'David Medina', 'manual'), + ('index', 'pygithub3.tex', six.u('pygithub3 Documentation'), + six.u('David Medina'), 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -219,8 +220,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'pygithub3', u'pygithub3 Documentation', - [u'David Medina'], 1) + ('index', 'pygithub3', six.u('pygithub3 Documentation'), + [six.u('David Medina')], 1) ] # If true, show URL addresses after external links. @@ -233,8 +234,8 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'pygithub3', u'pygithub3 Documentation', - u'David Medina', 'pygithub3', 'One line description of project.', + ('index', 'pygithub3', six.u('pygithub3 Documentation'), + six.u('David Medina'), 'pygithub3', 'One line description of project.', 'Miscellaneous'), ] diff --git a/pygithub3/__init__.py b/pygithub3/__init__.py index 461dabe..1dffc6a 100644 --- a/pygithub3/__init__.py +++ b/pygithub3/__init__.py @@ -1,10 +1,10 @@ # -*- encoding: utf-8 -*- __title__ = 'pygithub3' -__version__ = '0.5' +__version__ = '0.6.2' __author__ = 'David Medina' __email__ = 'davidmedina9@gmail.com' __license__ = 'ISC' __copyright__ = 'Copyright 2012 David Medina' -from github import Github +from .github import Github diff --git a/pygithub3/core/client.py b/pygithub3/core/client.py index 139bee8..4d719e5 100644 --- a/pygithub3/core/client.py +++ b/pygithub3/core/client.py @@ -49,11 +49,10 @@ def set_credentials(self, login, password): def set_token(self, token): if token: - self.requester.params.append(('access_token', token)) + self.requester.params['access_token'] = token def __set_params(self, config): - per_page = ('per_page', config.get('per_page')) - self.requester.params.append(per_page) + self.requester.params['per_page'] = config.get('per_page') if config.get('verbose'): self.requester.config = {'verbose': config['verbose']} if config.get('timeout'): diff --git a/pygithub3/core/compat.py b/pygithub3/core/compat.py index c6dbf0a..d59a495 100644 --- a/pygithub3/core/compat.py +++ b/pygithub3/core/compat.py @@ -3,6 +3,8 @@ """ Utils to support python 2.6 compatibility """ from collections import MutableMapping +from six.moves import map +from six.moves import zip def _import_module(module_uri): diff --git a/pygithub3/core/json/__init__.py b/pygithub3/core/json/__init__.py index f0adb20..d9d19b1 100644 --- a/pygithub3/core/json/__init__.py +++ b/pygithub3/core/json/__init__.py @@ -9,6 +9,8 @@ except ImportError: import json +import six + GITHUB_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' @@ -21,7 +23,7 @@ def default(self, o): def gh_decoder_hook(dict_): - for k, v in dict_.iteritems(): + for k, v in six.iteritems(dict_): try: date = datetime.strptime(v, GITHUB_DATE_FORMAT) dict_[k] = date @@ -35,6 +37,13 @@ def dumps(obj, cls=GHJSONEncoder, **kwargs): def loads(s, object_hook=gh_decoder_hook, **kwargs): + if type(s) is six.binary_type: + # XXX(Kagami): json module from python3 can't load bytes while + # json from python2 can work with both str and unicode. Better + # to get only unicode in this function but let's go this hack + # for the time being. Seems like upstream bug: + # . + s = s.decode('utf-8') return json.loads(s, object_hook=object_hook, **kwargs) dump = json.dump diff --git a/pygithub3/core/result/base.py b/pygithub3/core/result/base.py index b33f97e..9e7cecb 100644 --- a/pygithub3/core/result/base.py +++ b/pygithub3/core/result/base.py @@ -2,6 +2,7 @@ # -*- encoding: utf-8 -*- import functools +import six class Method(object): @@ -72,7 +73,7 @@ def wrapper(self): @get_content def __next__(self): try: - return self.iterable.next() + return six.advance_iterator(self.iterable) except StopIteration: self.iterable = iter(self.getter(self.page)) raise StopIteration diff --git a/pygithub3/core/result/link.py b/pygithub3/core/result/link.py index dae8407..74a140b 100644 --- a/pygithub3/core/result/link.py +++ b/pygithub3/core/result/link.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -from urlparse import urlparse, parse_qs +from six.moves.urllib.parse import urlparse, parse_qs from pygithub3.core.third_libs.link_header import parse_link_value diff --git a/pygithub3/core/result/smart.py b/pygithub3/core/result/smart.py index 0343a9b..cd90460 100644 --- a/pygithub3/core/result/smart.py +++ b/pygithub3/core/result/smart.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- +import six + from . import base from .link import Link @@ -105,6 +107,6 @@ def get_page(self, page): :param int page: Page number """ - if page in xrange(1, self.pages + 1): + if page in six.moves.range(1, self.pages + 1): return base.Page(self.getter, page) return None diff --git a/pygithub3/core/third_libs/link_header.py b/pygithub3/core/third_libs/link_header.py index 3959604..67e70d1 100644 --- a/pygithub3/core/third_libs/link_header.py +++ b/pygithub3/core/third_libs/link_header.py @@ -5,6 +5,7 @@ Simple routines to parse and manipulate Link headers. """ +from __future__ import print_function __license__ = """ Copyright (c) 2009 Mark Nottingham @@ -86,4 +87,4 @@ def parse_link_value(instr): if __name__ == '__main__': import sys if len(sys.argv) > 1: - print parse_link_value(sys.argv[1]) \ No newline at end of file + print(parse_link_value(sys.argv[1])) diff --git a/pygithub3/requests/users/emails.py b/pygithub3/requests/users/emails.py index ff89b62..d2af8d9 100644 --- a/pygithub3/requests/users/emails.py +++ b/pygithub3/requests/users/emails.py @@ -3,6 +3,8 @@ import re +import six + from . import Request, ValidationError # Src: http://code.djangoproject.com/svn/django/trunk/django/core/validators.py @@ -30,7 +32,7 @@ def is_email(email): raise ValidationError("'%s' request needs emails" % (self.__class__.__name__)) - return filter(is_email, self.body) + return tuple(six.moves.filter(is_email, self.body)) class Delete(Request): diff --git a/pygithub3/services/gists/__init__.py b/pygithub3/services/gists/__init__.py index aadb136..579e291 100644 --- a/pygithub3/services/gists/__init__.py +++ b/pygithub3/services/gists/__init__.py @@ -2,7 +2,7 @@ # -*- encoding: utf-8 -*- from pygithub3.services.base import Service -from comments import Comments +from .comments import Comments class Gist(Service): diff --git a/pygithub3/services/issues/labels.py b/pygithub3/services/issues/labels.py index d1119d3..5bc0d81 100644 --- a/pygithub3/services/issues/labels.py +++ b/pygithub3/services/issues/labels.py @@ -2,6 +2,8 @@ # -*- encoding: utf-8 -*- from pygithub3.services.base import Service +from six.moves import map +from six.moves import zip class Labels(Service): diff --git a/pygithub3/tests/core/test_json.py b/pygithub3/tests/core/test_json.py index 7c0da86..da0fd3c 100644 --- a/pygithub3/tests/core/test_json.py +++ b/pygithub3/tests/core/test_json.py @@ -20,8 +20,8 @@ class TestJson(TestCase): json_ = '{"date_fake": "some_fake", "list": [1, 2, 3], "date_ok": "2008-01-14T04:33:35Z", "nested_dict": {"with_date": "2008-01-14T04:33:35Z"}}' def test_encoder(self): - to_json = json.dumps(self.dict_) - self.assertEquals(to_json, self.json_) + dict_ = json.loads(json.dumps(self.dict_)) + self.assertEquals(self.dict_, dict_) def test_decoder(self): to_dict = json.loads(self.json_) diff --git a/pygithub3/tests/core/test_result.py b/pygithub3/tests/core/test_result.py index 7f554ac..d535609 100644 --- a/pygithub3/tests/core/test_result.py +++ b/pygithub3/tests/core/test_result.py @@ -6,6 +6,7 @@ from pygithub3.core.result import smart, normal, base from pygithub3.tests.utils.core import (TestCase, mock_paginate_github_in_GET, request, mock_no_paginate_github_in_GET, MockPaginate) +import six class ResultInitMixin(object): @@ -36,7 +37,7 @@ def test_iteration_CALLS(self): def test_consumed_are_Pages(self): pages_that_are_Pages = len( - filter(lambda page: isinstance(page, base.Page), list(self.r))) + [page for page in self.r if isinstance(page, base.Page)]) self.assertEqual(pages_that_are_Pages, 3, 'There are not 3 Pages objs') def test_all_iteration_CALLS(self): @@ -64,7 +65,7 @@ def mock(self): return mock_no_paginate_github_in_GET def test_iteration_stop_at_1(self): - self.r.next() + six.advance_iterator(self.r) self.assertRaises(StopIteration, self.r.next) def test_get_only_1page(self): diff --git a/pygithub3/tests/resources/test_core.py b/pygithub3/tests/resources/test_core.py index 568edf4..e382999 100644 --- a/pygithub3/tests/resources/test_core.py +++ b/pygithub3/tests/resources/test_core.py @@ -39,8 +39,8 @@ def test_MAPS(self): self.assertEqual(self.r.simple.type, 'simple') def test_LIST_collection_map(self): - has_simple_objects = filter(lambda x: isinstance(x, HasSimple), - self.r.list_collection) + has_simple_objects = [obj for obj in self.r.list_collection + if isinstance(obj, HasSimple)] self.assertEqual(len(has_simple_objects), 2) self.assertEqual(self.r.list_collection[0].type, 'has_simple') self.assertEqual(self.r.list_collection[0].simple.type, 'simple') diff --git a/requirements/base.txt b/requirements/base.txt index 1ff0d4c..1af095c 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1 +1,2 @@ -requests==0.14.0 +requests>0.14.0 +six diff --git a/requirements/dev.txt b/requirements/dev.txt index 5b1f13b..3c80f96 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -2,5 +2,4 @@ nose mock -unittest2 sphinx diff --git a/setup.py b/setup.py index 37062b3..b26e6d2 100644 --- a/setup.py +++ b/setup.py @@ -14,11 +14,11 @@ pass setup( - name=pygithub3.__name__, + name='pygithub33', version=pygithub3.__version__, author=pygithub3.__author__, author_email=pygithub3.__email__, - url='https://github.com/copitux/python-github3', + url='https://github.com/Kagami/python-github3', description='Python wrapper for the github v3 api', long_description=open('README.rst').read(), license='ISC', @@ -28,12 +28,18 @@ 'nose', 'mock', ], - install_requires=map(str.strip, open(join('requirements', 'base.txt'))), + install_requires=[ + s.strip() for s in open(join('requirements', 'base.txt'))], include_package_data=True, classifiers=( 'Programming Language :: Python', + 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', 'License :: OSI Approved :: ISC License (ISCL)', 'Operating System :: OS Independent', 'Development Status :: 2 - Pre-Alpha',