diff --git a/.zuul.yaml b/.zuul.yaml index bd9ba2b..87263da 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -3,8 +3,9 @@ jobs: - tox-pep8 - tox-py27 + - tox-py36 gate: jobs: - tox-pep8 - tox-py27 - + - tox-py36 diff --git a/lodgeit/application.py b/lodgeit/application.py index 41a9ef8..c217a45 100644 --- a/lodgeit/application.py +++ b/lodgeit/application.py @@ -64,7 +64,7 @@ class LodgeIt(object): except NotFound: handler = get_controller('static/not_found') resp = handler() - except HTTPException, e: + except HTTPException as e: resp = e.get_response(environ) else: expires = datetime.utcnow() + timedelta(days=31) diff --git a/lodgeit/database.py b/lodgeit/database.py index f4d9e6f..b77d57c 100644 --- a/lodgeit/database.py +++ b/lodgeit/database.py @@ -8,6 +8,7 @@ :copyright: 2007-2010 by Armin Ronacher, Christopher Grebs. :license: BSD """ +import six import sys from types import ModuleType import sqlalchemy @@ -46,7 +47,7 @@ ModelBase.query = session.query_property() def _make_module(): db = ModuleType('db') for mod in sqlalchemy, orm: - for key, value in mod.__dict__.iteritems(): + for key, value in six.iteritems(mod.__dict__): if key in mod.__all__: setattr(db, key, value) diff --git a/lodgeit/i18n/__init__.py b/lodgeit/i18n/__init__.py index f4884ff..2c7cf7c 100644 --- a/lodgeit/i18n/__init__.py +++ b/lodgeit/i18n/__init__.py @@ -11,6 +11,7 @@ import os from babel import Locale, dates, UnknownLocaleError from babel.support import Translations +from six import text_type from lodgeit import local @@ -65,7 +66,7 @@ def list_languages(): continue try: locale = Locale.parse(filename) - except UnknownLocaleError: + except (UnknownLocaleError, ValueError): continue languages.append((str(locale), locale.display_name)) @@ -109,7 +110,7 @@ class _TranslationProxy(object): return bool(self.value) def __dir__(self): - return dir(unicode) + return dir(text_type) def __iter__(self): return iter(self.value) @@ -121,7 +122,7 @@ class _TranslationProxy(object): return str(self.value) def __unicode__(self): - return unicode(self.value) + return text_type(self.value) def __add__(self, other): return self.value + other @@ -169,7 +170,7 @@ class _TranslationProxy(object): def __repr__(self): try: - return 'i' + repr(unicode(self.value)) + return 'i' + repr(text_type(self.value)) except ValueError: return '<%s broken>' % self.__class__.__name__ diff --git a/lodgeit/lib/captcha.py b/lodgeit/lib/captcha.py index 9d33170..bf730f9 100644 --- a/lodgeit/lib/captcha.py +++ b/lodgeit/lib/captcha.py @@ -24,6 +24,11 @@ try: except ImportError: from sha import new as sha1 +try: + xrange +except NameError: + xrange = range + resource_path = abspath(join(dirname(__file__), pardir, 'res')) diff --git a/lodgeit/lib/filterable.py b/lodgeit/lib/filterable.py index 2ecbf11..abc801f 100644 --- a/lodgeit/lib/filterable.py +++ b/lodgeit/lib/filterable.py @@ -8,6 +8,8 @@ :copyright: 2008 by Christopher Grebs. :license: BSD. """ +import six + from lodgeit.i18n import _ from lodgeit.utils import render_template @@ -71,7 +73,7 @@ class Filterable(object): return ret def get_objects(self): - for field, filter in self.filters.iteritems(): + for field, filter in six.iteritems(self.filters): action, value = filter if value: func = ACTIONS_MAP[action] diff --git a/lodgeit/lib/highlighting.py b/lodgeit/lib/highlighting.py index ff088bc..4fac540 100644 --- a/lodgeit/lib/highlighting.py +++ b/lodgeit/lib/highlighting.py @@ -9,6 +9,7 @@ :license: BSD """ import re +import six import pygments import csv from operator import itemgetter @@ -195,7 +196,7 @@ def get_style(request=None, name_only=False): request = request or local.request if not request: style_name = DEFAULT_STYLE - elif isinstance(request, basestring): + elif isinstance(request, six.string_types): style_name = request else: style_name = request.cookies.get('style') @@ -251,6 +252,6 @@ def get_known_alias(lexer, default='text'): def list_languages(): """List all languages.""" - languages = LANGUAGES.items() + languages = list(LANGUAGES.items()) languages.sort(key=lambda x: x[1].lstrip(' _-.').lower()) return languages diff --git a/lodgeit/lib/json.py b/lodgeit/lib/json.py index bf110a3..70b7057 100644 --- a/lodgeit/lib/json.py +++ b/lodgeit/lib/json.py @@ -42,7 +42,7 @@ class JSONRequestHandler(object): 'data': self.funcs[method_name](*args, **kwargs), 'error': None } - except Exception, e: + except Exception as e: response = {'data': None, 'error': str(e).decode('utf-8')} body = dumps(response, indent=local.request.is_xhr and 2 or 0) return Response(body + '\n', mimetype='application/json') diff --git a/lodgeit/lib/webapi.py b/lodgeit/lib/webapi.py index 2bb5fb4..ffe7aa1 100644 --- a/lodgeit/lib/webapi.py +++ b/lodgeit/lib/webapi.py @@ -9,6 +9,7 @@ :license: BSD. """ import inspect +import six from lodgeit.models import Paste from lodgeit.database import db from lodgeit.lib.xmlrpc import XMLRPCRequestHandler @@ -39,7 +40,7 @@ def get_public_methods(): global _public_methods if _public_methods is None: result = [] - for name, f in json.funcs.iteritems(): + for name, f in six.iteritems(json.funcs): if name.startswith('system.') or f.hidden: continue args, varargs, varkw, defaults = inspect.getargspec(f) @@ -130,14 +131,14 @@ def pastes_get_last(): def pastes_get_languages(): """Get a list of supported languages.""" # this resolves lazy translations - return dict((key, unicode(value)) for - key, value in LANGUAGES.iteritems()) + return dict((key, six.text_type(value)) for + key, value in six.iteritems(LANGUAGES)) @exported('styles.getStyles') def styles_get_styles(): """Get a list of supported styles.""" - return STYLES.items() + return list(STYLES.items()) @exported('styles.getStylesheet') diff --git a/lodgeit/lib/xmlrpc.py b/lodgeit/lib/xmlrpc.py index 7792ddb..51d6f5f 100644 --- a/lodgeit/lib/xmlrpc.py +++ b/lodgeit/lib/xmlrpc.py @@ -10,7 +10,10 @@ """ import sys import re -from SimpleXMLRPCServer import SimpleXMLRPCDispatcher +try: + from SimpleXMLRPCServer import SimpleXMLRPCDispatcher +except ImportError: + from xmlrpc.server import SimpleXMLRPCDispatcher from werkzeug import Response from lodgeit import local diff --git a/lodgeit/models.py b/lodgeit/models.py index c9415d6..173a559 100644 --- a/lodgeit/models.py +++ b/lodgeit/models.py @@ -11,6 +11,7 @@ import time import difflib from datetime import datetime +from six import string_types from werkzeug import cached_property from lodgeit import local @@ -56,7 +57,7 @@ class Paste(db.Model): """Return the paste for an identifier. Private pastes must be loaded with their unique hash and public with the paste id. """ - if isinstance(identifier, basestring) and not identifier.isdigit(): + if isinstance(identifier, string_types) and not identifier.isdigit(): query = Paste.query.filter_by(private_id=identifier) else: query = Paste.query.filter_by(paste_id=int(identifier)) diff --git a/lodgeit/utils.py b/lodgeit/utils.py index 34235e0..b8be80c 100644 --- a/lodgeit/utils.py +++ b/lodgeit/utils.py @@ -8,6 +8,7 @@ :copyright: 2007-2008 by Christopher Grebs. :license: BSD """ +import base64 import re import time from os import path @@ -49,14 +50,16 @@ jinja_environment.globals['url_for'] = url_for def generate_user_hash(): """Generates an more or less unique SHA1 hash.""" - return sha1('%s|%s' % (random(), time.time())).hexdigest() + hash_base = '%s|%s' % (random(), time.time()) + return sha1(hash_base.encode()).hexdigest() def generate_paste_hash(): """Generates a more or less unique-truncated SHA1 hash.""" while 1: - digest = sha1('%s|%s' % (random(), time.time())).digest() - val = _word_only(digest.encode('base64').strip())[:20] + hash_base = '%s|%s' % (random(), time.time()) + digest = sha1(hash_base.encode()).digest() + val = _word_only(str(base64.b64encode(digest)).strip())[:20] # sanity check. number only not allowed (though unlikely) if not val.isdigit(): return val diff --git a/lodgeit/views/help/api.html b/lodgeit/views/help/api.html index f28e29c..a5caf01 100644 --- a/lodgeit/views/help/api.html +++ b/lodgeit/views/help/api.html @@ -18,13 +18,13 @@
{% filter escape %}
 >>> from xmlrpclib import ServerProxy
 >>> s = ServerProxy('{{ pastebin_url|escape }}xmlrpc/')
-{% endfilter %}
+{% endfilter %}

{% trans %}For example if you want to fetch one paste from the server you can do this:{% endtrans %}

{% filter escape %}
 >>> paste = s.pastes.getPaste(23)
->>> print paste['code']
+>>> print(paste['code'])
 '{{ "{% if users %}" }}\n...'
 {% endfilter %}

{% trans %}JSON Quickstart{% endtrans %}

diff --git a/requirements.txt b/requirements.txt index e748eb4..b0cf666 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +six Jinja2 Werkzeug<0.16 Pygments diff --git a/scripts/lodgeit.py b/scripts/lodgeit.py index b0f9cc0..7ebf7f2 100755 --- a/scripts/lodgeit.py +++ b/scripts/lodgeit.py @@ -22,8 +22,10 @@ 2006 Matt Good , 2005 Raphael Slinckx """ +from __future__ import print_function import os import sys +from six import text_type from optparse import OptionParser @@ -39,7 +41,7 @@ _server_name = None def fail(msg, code): """Bail out with an error message.""" - print >> sys.stderr, 'ERROR: %s' % msg + print('ERROR: %s' % msg, file=sys.stderr) sys.exit(code) @@ -83,14 +85,14 @@ def load_default_settings(): def make_utf8(text, encoding): """Convert a text to UTF-8, brute-force.""" try: - u = unicode(text, 'utf-8') + u = text_type(text, 'utf-8') uenc = 'utf-8' except UnicodeError: try: - u = unicode(text, encoding) + u = text_type(text, encoding) uenc = 'utf-8' except UnicodeError: - u = unicode(text, 'iso-8859-15', 'ignore') + u = text_type(text, 'iso-8859-15', 'ignore') uenc = 'iso-8859-15' try: import chardet @@ -99,7 +101,7 @@ def make_utf8(text, encoding): d = chardet.detect(text) if d['encoding'] == uenc: return u.encode('utf-8') - return unicode(text, d['encoding'], 'ignore').encode('utf-8') + return text_type(text, d['encoding'], 'ignore').encode('utf-8') def get_xmlrpc_service(): @@ -110,7 +112,7 @@ def get_xmlrpc_service(): try: _xmlrpc_service = xmlrpclib.ServerProxy(_server_name + 'xmlrpc/', allow_none=True) - except Exception, err: + except Exception as err: fail('Could not connect to Pastebin: %s' % err, -1) return _xmlrpc_service @@ -184,10 +186,12 @@ def print_languages(): """Print a list of all supported languages, with description.""" xmlrpc = get_xmlrpc_service() languages = xmlrpc.pastes.getLanguages().items() - languages.sort(lambda a, b: cmp(a[1].lower(), b[1].lower())) - print 'Supported Languages:' + languages.sort( + lambda a, b: (a[1].lower() > b[1].lower())-(a[1].lower() < b[1].lower()) + ) + print('Supported Languages:') for alias, name in languages: - print ' %-30s%s' % (alias, name) + print(' %-30s%s' % (alias, name)) def download_paste(uid): @@ -196,7 +200,7 @@ def download_paste(uid): paste = xmlrpc.pastes.getPaste(uid) if not paste: fail('Paste "%s" does not exist.' % uid, 5) - print paste['code'].encode('utf-8') + print(paste['code'].encode('utf-8')) def create_paste(code, language, filename, mimetype, private): @@ -221,7 +225,7 @@ def compile_paste(filenames, langopt): lang = langopt or '' if not filenames: data = read_file(sys.stdin) - print 'Pasting...' + print('Pasting...') if not langopt: mime = get_mimetype(data, '') or '' fname = '' @@ -292,7 +296,7 @@ def main(): # special modes of operation: # - paste script version if opts.version: - print '%s: version %s' % (SCRIPT_NAME, VERSION) + print('%s: version %s' % (SCRIPT_NAME, VERSION)) sys.exit() # - print list of languages elif opts.languages: @@ -310,7 +314,7 @@ def main(): # load file(s) try: data, language, filename, mimetype = compile_paste(args, opts.language) - except Exception, err: + except Exception as err: fail('Error while reading the file(s): %s' % err, 2) if not data: fail('Aborted, no content to paste.', 4) @@ -319,7 +323,7 @@ def main(): code = make_utf8(data, opts.encoding) pid = create_paste(code, language, filename, mimetype, opts.private) url = '%sshow/%s/' % (_server_name, pid) - print url + print(url) if opts.open_browser: open_webbrowser(url) if opts.clipboard: diff --git a/scripts/make-bootstrap.py b/scripts/make-bootstrap.py index 2025a68..8e0335d 100755 --- a/scripts/make-bootstrap.py +++ b/scripts/make-bootstrap.py @@ -6,6 +6,7 @@ Creates a bootstrap script for LodgeIt """ +from __future__ import print_function from virtualenv import create_bootstrap_script @@ -33,4 +34,4 @@ def easy_install(package, home_dir, optional_args=None): """ if __name__ == '__main__': - print create_bootstrap_script(EXTRA_TEXT) + print(create_bootstrap_script(EXTRA_TEXT)) diff --git a/tests/unittest/test_api.py b/tests/unittest/test_api.py index 8e12396..d58fdf1 100644 --- a/tests/unittest/test_api.py +++ b/tests/unittest/test_api.py @@ -59,7 +59,7 @@ def test_json_get_recent(): return resp paste_ids = [] - for x in xrange(10): + for x in range(10): resp = run(x) paste_ids.append(int(json(resp)['data'])) diff --git a/tox.ini b/tox.ini index 79fc2dc..fa8f58c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 1.6 -envlist = pep8, py27 +envlist = pep8, py27, py36 skipsdist = True [testenv] @@ -10,7 +10,6 @@ deps = -r{toxinidir}/requirements.txt commands = nosetests [testenv:pep8] -basepython = python2 commands = flake8 [flake8]