diff --git a/.travis.yml b/.travis.yml index 35748bf..d05374e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ env: - TOX_ENV=py27-1.4 - TOX_ENV=py27-1.5 - TOX_ENV=py27-1.6 + - TOX_ENV=py27-1.7 install: - pip install tox script: diff --git a/requirements.txt b/requirements.txt index 41dabba..29af7a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,14 @@ # Requirements for using tower -Django==1.4.5 +Django>=1.4.5,<1.8 babel==1.3 jinja2 +six>=1.9.0 translate-toolkit -e git://github.com/jbalogh/jingo.git#egg=jingo # Requirements for running the tests -django-nose==1.1 -mock==1.0.1 +django-nose>=1.1 +mock>=1.0.1 # Requirements to build the docs Sphinx diff --git a/run_tests.py b/run_tests.py index 74b0fae..f2e70e1 100755 --- a/run_tests.py +++ b/run_tests.py @@ -3,19 +3,16 @@ import os import sys +if __name__ == "__main__": + # Set up the environment for our test project. + ROOT = os.path.abspath(os.path.dirname(__file__)) -# Set up the environment for our test project. -ROOT = os.path.abspath(os.path.dirname(__file__)) + os.environ['DJANGO_SETTINGS_MODULE'] = 'tower-project.settings' + sys.path.insert(0, os.path.join(ROOT, 'examples')) -os.environ['DJANGO_SETTINGS_MODULE'] = 'tower-project.settings' -sys.path.insert(0, os.path.join(ROOT, 'examples')) + from django.core.management import execute_from_command_line -# This can't be imported until after we've fiddled with the -# environment. -from django.test.utils import setup_test_environment -setup_test_environment() + # Run the equivalent of "django-admin.py test" + sys.argv.insert(1, 'test') -from django.core.management import call_command - -# Run the equivalent of "django-admin.py test" -call_command('test') + execute_from_command_line(sys.argv) diff --git a/tower/__init__.py b/tower/__init__.py index 95245b6..721860c 100644 --- a/tower/__init__.py +++ b/tower/__init__.py @@ -5,10 +5,18 @@ import django from django.conf import settings from django.utils.functional import lazy -from django.utils.importlib import import_module from django.utils.translation import (trans_real as django_trans, ugettext as django_ugettext, ungettext as django_nugettext) +try: + from importlib import import_module +except ImportError: + from django.utils.importlib import import_module + +try: + from django.utils import six +except ImportError: + import six from babel.messages.extract import extract_python from jinja2 import ext @@ -52,8 +60,8 @@ def ungettext(singular, plural, number, context=None): return plural_stripped return ret -ugettext_lazy = lazy(ugettext, unicode) -ungettext_lazy = lazy(ungettext, unicode) +ugettext_lazy = lazy(ugettext, six.text_type) +ungettext_lazy = lazy(ungettext, six.text_type) def add_context(context, message): diff --git a/tower/management/commands/amalgamate.py b/tower/management/commands/amalgamate.py index c430bb5..6dbdfc2 100644 --- a/tower/management/commands/amalgamate.py +++ b/tower/management/commands/amalgamate.py @@ -58,10 +58,10 @@ def handle(self, *args, **options): 'messages.po') if not os.path.isfile(r_messages): - print " Can't find (%s). Skipping..." % (r_messages) + print(" Can't find (%s). Skipping..." % (r_messages)) continue - print "Mushing python strings into messages.po for %s" % (locale) + print("Mushing python strings into messages.po for %s" % (locale)) # Step 3: Merge our new combined .pot with the .po file if locale == "en_US": @@ -90,7 +90,7 @@ def handle(self, *args, **options): # commands in the middle of Step 3. for domain in standalone_domains: - print "Merging %s strings to each locale..." % domain + print("Merging %s strings to each locale..." % domain) z_domain_keys = os.path.join(locale_dir, 'z-%s.pot' % domain) if not os.path.isfile(z_domain_keys): sys.exit("Can't find z-%s.pot" % domain) @@ -104,11 +104,11 @@ def handle(self, *args, **options): 'z-%s.po' % domain) if not os.path.isfile(z_domain_messages): - print " Can't find (%s). Creating..." % (z_domain_messages) + print(" Can't find (%s). Creating..." % (z_domain_messages)) t = open(z_domain_messages, 'w') t.close() - print "Merging z-%s.po for %s" % (domain, locale) + print("Merging z-%s.po for %s" % (domain, locale)) z_domain_keys_file = open(z_domain_keys) @@ -133,6 +133,6 @@ def handle(self, *args, **options): p4.communicate() mergeme.close() - print "Domain %s finished" % domain + print("Domain %s finished" % domain) - print "All finished" + print("All finished") diff --git a/tower/management/commands/extract.py b/tower/management/commands/extract.py index be2f586..8f0e42c 100644 --- a/tower/management/commands/extract.py +++ b/tower/management/commands/extract.py @@ -1,6 +1,5 @@ import os import tempfile -from optparse import make_option from subprocess import Popen from django.core.management.base import BaseCommand @@ -90,22 +89,25 @@ def create_pofile_from_babel(extracted): class Command(BaseCommand): - option_list = BaseCommand.option_list + ( - make_option('--domain', '-d', default=DEFAULT_DOMAIN, dest='domain', - help='The domain of the message files. If "all" ' - 'everything will be extracted and combined into ' - '%s.pot. (default: %%default).' % TEXT_DOMAIN), - make_option('--output-dir', '-o', - default=os.path.join(settings.ROOT, 'locale', 'templates', - 'LC_MESSAGES'), - dest='outputdir', - help='The directory where extracted files will be placed. ' - '(Default: %default)'), - make_option('-c', '--create', - action='store_true', dest='create', default=False, - help='Create output-dir if missing'), - - ) + + def add_arguments(self, parser): + parser.add_argument('--domain', '-d', + default=DEFAULT_DOMAIN, + dest='domain', + help='The domain of the message files. If "all" ' + 'everything will be extracted and combined into ' + '%s.pot. (default: %%default).' % TEXT_DOMAIN) + parser.add_argument('--output-dir', '-o', + default=os.path.join(settings.ROOT, 'locale', 'templates', + 'LC_MESSAGES'), + dest='outputdir', + help='The directory where extracted files will be placed. ' + '(Default: %default)') + parser.add_argument('-c', '--create', + action='store_true', + dest='create', + default=False, + help='Create output-dir if missing') def handle(self, *args, **options): domains = options.get('domain') @@ -113,9 +115,9 @@ def handle(self, *args, **options): if not os.path.isdir(outputdir): if not options.get('create'): - print ("Output directory must exist (%s) unless -c option is " - "given. " - "Specify one with --output-dir" % outputdir) + print("Output directory must exist (%s) unless -c option is " + "given. " + "Specify one with --output-dir" % outputdir) return "FAILURE\n" else: os.makedirs(outputdir) @@ -129,11 +131,11 @@ def handle(self, *args, **options): def callback(filename, method, options): if method != 'ignore': - print " %s" % filename + print(" %s" % filename) for domain in domains: - print "Extracting all strings in domain %s..." % (domain) + print("Extracting all strings in domain %s..." % (domain)) methods = settings.DOMAIN_METHODS[domain] extracted = extract_from_dir(root, @@ -154,8 +156,8 @@ def callback(filename, method, options): pot_files.append(os.path.join(outputdir, '%s.pot' % i)) if len(pot_files) > 1: - print ("Concatenating the non-standalone domains into %s.pot" % - TEXT_DOMAIN) + print("Concatenating the non-standalone domains into %s.pot" % + TEXT_DOMAIN) final_out = os.path.join(outputdir, '%s.pot' % TEXT_DOMAIN) @@ -179,4 +181,4 @@ def callback(filename, method, options): for i in [x for x in domains if x not in standalone_domains]: os.remove(os.path.join(outputdir, '%s.pot' % i)) - print 'done' + print('done') diff --git a/tower/management/commands/merge.py b/tower/management/commands/merge.py index 6d6a52b..cbc14e4 100644 --- a/tower/management/commands/merge.py +++ b/tower/management/commands/merge.py @@ -50,7 +50,7 @@ def handle(self, *args, **options): for domain in domains: - print "Merging %s strings to each locale..." % domain + print("Merging %s strings to each locale..." % domain) domain_pot = os.path.join(locale_dir, 'templates', 'LC_MESSAGES', '%s.pot' % domain) if not os.path.isfile(domain_pot): @@ -69,7 +69,7 @@ def handle(self, *args, **options): '%s.po' % domain) if not os.path.isfile(domain_po): - print " Can't find (%s). Creating..." % (domain_po) + print(" Can't find (%s). Creating..." % (domain_po)) if not call(["which", "msginit"], stdout=PIPE) == 0: raise Exception("You do not have gettext installed.") p1 = Popen(["msginit", @@ -80,7 +80,7 @@ def handle(self, *args, **options): "--width=200",]) p1.communicate() - print "Merging %s.po for %s" % (domain, locale) + print("Merging %s.po for %s" % (domain, locale)) domain_pot_file = open(domain_pot) @@ -100,13 +100,13 @@ def handle(self, *args, **options): domain_po, "-"] if os.path.isfile(compendium): - print "(using a compendium)" + print("(using a compendium)") command.insert(1, '--compendium=%s' % compendium) p3 = Popen(command, stdin=mergeme) p3.communicate() mergeme.close() - print "Domain %s finished" % domain + print("Domain %s finished" % domain) - print "All finished" + print("All finished") Command.help = Command.__doc__ diff --git a/tower/tests/helpers.py b/tower/tests/helpers.py index ae6325f..6b08fc2 100644 --- a/tower/tests/helpers.py +++ b/tower/tests/helpers.py @@ -16,7 +16,7 @@ def fake_extract_from_dir(filename, fileobj, method, options=OPTIONS_MAP, keywords=TOWER_KEYWORDS, comment_tags=COMMENT_TAGS): """ We use Babel's exctract_from_dir() to pull out our gettext - strings. In the tests, I don't have a directory of files, I have StringIO + strings. In the tests, I don't have a directory of files, I have BytesIO objects. So, we fake the original function with this one.""" for lineno, message, comments, context in extract(method, fileobj, keywords, comment_tags, options): diff --git a/tower/tests/test_l10n.py b/tower/tests/test_l10n.py index 9d2c9b0..db58556 100644 --- a/tower/tests/test_l10n.py +++ b/tower/tests/test_l10n.py @@ -1,4 +1,4 @@ -from cStringIO import StringIO +from io import BytesIO import django from django.utils import translation @@ -262,7 +262,7 @@ def test_template_gettext_functions(): def test_extract_tower_python(): - fileobj = StringIO(TEST_PO_INPUT) + fileobj = BytesIO(TEST_PO_INPUT) method = 'tower.extract_tower_python' output = fake_extract_from_dir(filename="filename", fileobj=fileobj, method=method) @@ -272,7 +272,7 @@ def test_extract_tower_python(): def test_extract_tower_template(): - fileobj = StringIO(TEST_TEMPLATE_INPUT) + fileobj = BytesIO(TEST_TEMPLATE_INPUT) method = 'tower.extract_tower_template' output = fake_extract_from_dir(filename="filename", fileobj=fileobj, method=method) @@ -282,7 +282,7 @@ def test_extract_tower_template(): def test_extract_tower_python_backwards_compatible(): - fileobj = StringIO(TEST_PO_INPUT) + fileobj = BytesIO(TEST_PO_INPUT) method = 'tower.management.commands.extract.extract_tower_python' output = fake_extract_from_dir(filename="filename", fileobj=fileobj, method=method) @@ -292,7 +292,7 @@ def test_extract_tower_python_backwards_compatible(): def test_extract_tower_template_backwards_compatible(): - fileobj = StringIO(TEST_TEMPLATE_INPUT) + fileobj = BytesIO(TEST_TEMPLATE_INPUT) method = 'tower.management.commands.extract.extract_tower_template' output = fake_extract_from_dir(filename="filename", fileobj=fileobj, method=method) diff --git a/tox.ini b/tox.ini index 342cc93..7a00f84 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26-1.4, py26-1.5, py26-1.6, py27-1.4, py27-1.5, py27-1.6 +envlist = py26-1.4, py26-1.5, py26-1.6, py27-1.4, py27-1.5, py27-1.6, py27-1.7 toxworkdir = {homedir}/.tox-tower [testenv] @@ -15,36 +15,41 @@ deps = -egit+https://github.com/jbalogh/jingo.git#egg=jingo [testenv:py26-1.4] basepython = python2.6 deps = - Django==1.4.10 + Django==1.4.20 {[testenv]deps} [testenv:py26-1.5] basepython = python2.6 deps = - Django==1.5.5 + Django==1.5.12 {[testenv]deps} [testenv:py26-1.6] basepython = python2.6 deps = - Django==1.6 + Django==1.6.11 {[testenv]deps} [testenv:py27-1.4] basepython = python2.7 deps = - Django==1.4.10 + Django==1.4.20 {[testenv]deps} - [testenv:py27-1.5] basepython = python2.7 deps = - Django==1.5.5 + Django==1.5.12 {[testenv]deps} [testenv:py27-1.6] basepython = python2.7 deps = - Django==1.6 + Django==1.6.11 + {[testenv]deps} + +[testenv:py27-1.7] +basepython = python2.7 +deps = + Django==1.7.7 {[testenv]deps}