diff --git a/helpers/merge_names.py b/helpers/merge_names.py index b4628a9..a282df3 100644 --- a/helpers/merge_names.py +++ b/helpers/merge_names.py @@ -3,6 +3,8 @@ import os import json +import six + FIXTURES = ['mongolian/fixtures/mongolian_names_list.json', 'russian/fixtures/pagan_names_list.json', @@ -27,8 +29,8 @@ def names_equal(name, original_name): if language not in original_languages: continue - text = languages[language] if isinstance(languages[language], basestring) else languages[language][0] - original_text = original_languages[language] if isinstance(original_languages[language], basestring) else original_languages[language][0] + text = languages[language] if isinstance(languages[language], six.string_types) else languages[language][0] + original_text = original_languages[language] if isinstance(original_languages[language], six.string_types) else original_languages[language][0] if text == original_text: return True @@ -37,8 +39,8 @@ def names_equal(name, original_name): def merge_names(name, original_name): - for gender, languages in name['genders'].iteritems(): - for language, data in languages.iteritems(): + for gender, languages in six.iteritems(name['genders']): + for language, data in six.iteritems(languages): original_name['genders'][gender][language] = data @@ -54,7 +56,7 @@ def pretty_dump(data): content = [] content.append(u'{') - for key, value in data.iteritems(): + for key, value in six.iteritems(data): if key != 'names': content.append(u' "%s": %s,' % (key, json.dumps(value, ensure_ascii=False))) diff --git a/pynames/exceptions.py b/pynames/exceptions.py index 48d5de7..16bbfb2 100644 --- a/pynames/exceptions.py +++ b/pynames/exceptions.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + class PynamesError(Exception): MSG = None @@ -9,7 +11,7 @@ class PynamesError(Exception): class NoDefaultNameValue(PynamesError): - MSG = u'Name: can not get default value for name with data: %(raw_data)r' + MSG = 'Name: can not get default value for name with data: %(raw_data)r' class FromListGeneratorError(PynamesError): @@ -17,7 +19,7 @@ class FromListGeneratorError(PynamesError): class NoNamesLoadedFromListError(FromListGeneratorError): - MSG = u'no names loaded from "%(source)s"' + MSG = 'no names loaded from "%(source)s"' class FromTablesGeneratorError(PynamesError): @@ -25,11 +27,11 @@ class FromTablesGeneratorError(PynamesError): class WrongTemplateStructureError(FromTablesGeneratorError): - MSG = u'wrong template structure - cannot choose template for genders %(genders)r with template source: "%(source)s"' + MSG = 'wrong template structure - cannot choose template for genders %(genders)r with template source: "%(source)s"' class NotEqualFormsLengths(FromTablesGeneratorError): - MSG = u'not equal forms lengths: [%(left)r] and [%(right)r]' + MSG = 'not equal forms lengths: [%(left)r] and [%(right)r]' class WrongCSVData(FromTablesGeneratorError): diff --git a/pynames/from_list_generator.py b/pynames/from_list_generator.py index 9875e38..996e214 100644 --- a/pynames/from_list_generator.py +++ b/pynames/from_list_generator.py @@ -1,4 +1,7 @@ # coding: utf-8 + +from __future__ import unicode_literals + import json import random diff --git a/pynames/from_tables_generator.py b/pynames/from_tables_generator.py index 7b68475..8688ec8 100644 --- a/pynames/from_tables_generator.py +++ b/pynames/from_tables_generator.py @@ -1,11 +1,14 @@ # coding: utf-8 +from __future__ import unicode_literals + # python lib: import json import random from collections import Iterable # thirdparties: +import six import unicodecsv # pynames: @@ -39,28 +42,28 @@ class Template(object): @classmethod def merge_forms(cls, left, right): - if not isinstance(left, basestring): - if not isinstance(right, basestring): + if not isinstance(left, six.string_types): + if not isinstance(right, six.string_types): if len(left) != len(right): raise exceptions.NotEqualFormsLengths(left=left, right=right) return [l+r for l, r in zip(left, right)] else: return [l+right for l in left] else: - if not isinstance(right, basestring): + if not isinstance(right, six.string_types): return [left+r for r in right] else: return left + right def get_name(self, tables): languages = dict( - (lang, u'') for lang in self.languages + (lang, '') for lang in self.languages ) for slug in self.template: record = random.choice(tables[slug]) languages = { lang: self.merge_forms(forms, record['languages'][lang]) - for lang, forms in languages.iteritems() + for lang, forms in six.iteritems(languages) } genders = dict( @@ -103,7 +106,7 @@ class FromTablesGenerator(BaseGenerator): raise NotImplementedError(error_msg) with file_adapter(source) as f: - data = json.load(f) + data = json.loads(f.read().decode('utf-8')) self.native_language = data['native_language'] self.languages = set(data['languages']) self.full_forms_for_languages = set(data.get('full_forms_for_languages', set())) @@ -153,7 +156,7 @@ class FromTablesGenerator(BaseGenerator): return name.get_for(gender, language) def test_names_consistency(self, test): - for table_name, table in self.tables.iteritems(): + for table_name, table in six.iteritems(self.tables): for record in table: test.assertEqual(set(record['languages'].keys()) & self.languages, self.languages) diff --git a/pynames/names.py b/pynames/names.py index 1fcf27d..d69a297 100644 --- a/pynames/names.py +++ b/pynames/names.py @@ -1,5 +1,9 @@ # coding: utf-8 +from __future__ import unicode_literals + +import six + from pynames.relations import GENDER, LANGUAGE from pynames import exceptions @@ -20,7 +24,7 @@ class Name(object): forms = self.translations[gender][language] - if not isinstance(forms, basestring): + if not isinstance(forms, six.string_types): return forms[0] return forms @@ -31,7 +35,7 @@ class Name(object): forms = self.translations[gender][language] - if not isinstance(forms, basestring): + if not isinstance(forms, six.string_types): return list(forms) return None diff --git a/pynames/relations.py b/pynames/relations.py index 3b2b5f3..f065488 100644 --- a/pynames/relations.py +++ b/pynames/relations.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + class GENDER: MALE = 'm' FEMALE = 'f' diff --git a/pynames/tests/__init__.py b/pynames/tests/__init__.py index 91bd147..e69de29 100644 --- a/pynames/tests/__init__.py +++ b/pynames/tests/__init__.py @@ -1,7 +0,0 @@ -# coding: utf-8 - -from pynames.tests.test_name import * -from pynames.tests.test_from_list_generator import * -from pynames.tests.test_from_tables_generator import * -from pynames.tests.test_generators import * -from pynames.tests.test_utils import * diff --git a/pynames/tests/test_from_list_generator.py b/pynames/tests/test_from_list_generator.py index 35b7e10..3ffc28a 100644 --- a/pynames/tests/test_from_list_generator.py +++ b/pynames/tests/test_from_list_generator.py @@ -1,8 +1,12 @@ # coding: utf-8 +from __future__ import unicode_literals + import os import unittest +from six.moves import xrange + from pynames.relations import GENDER, LANGUAGE from pynames.from_list_generator import FromListGenerator diff --git a/pynames/tests/test_from_tables_generator.py b/pynames/tests/test_from_tables_generator.py index 52b07e7..b1aef3f 100644 --- a/pynames/tests/test_from_tables_generator.py +++ b/pynames/tests/test_from_tables_generator.py @@ -1,8 +1,13 @@ # coding: utf-8 +from __future__ import unicode_literals + import os import unittest +import six +from six.moves import xrange + from pynames.relations import GENDER, LANGUAGE from pynames.from_tables_generator import FromTablesGenerator, FromCSVTablesGenerator @@ -116,13 +121,9 @@ class TestFromCSVTablesGenerator(unittest.TestCase): csv_generator = self.TestCSVGenerator() for attr_name in ['native_language', 'languages', 'templates', 'tables']: - try: - json_attr = getattr(json_generator, attr_name) - csv_attr = getattr(csv_generator, attr_name) - if isinstance(json_attr, list): - self.assertItemsEqual(csv_attr, json_attr) - else: - self.assertEqual(csv_attr, json_attr) - except Exception: - from nose.tools import set_trace; set_trace() - raise + json_attr = getattr(json_generator, attr_name) + csv_attr = getattr(csv_generator, attr_name) + if isinstance(json_attr, list): + six.assertCountEqual(self, csv_attr, json_attr) + else: + self.assertEqual(csv_attr, json_attr) diff --git a/pynames/tests/test_name.py b/pynames/tests/test_name.py index 19182c0..0403736 100644 --- a/pynames/tests/test_name.py +++ b/pynames/tests/test_name.py @@ -1,5 +1,8 @@ # coding: utf-8 +from __future__ import unicode_literals + +import six import unittest from pynames.relations import GENDER, LANGUAGE @@ -10,7 +13,7 @@ class TestName(unittest.TestCase): def test_base(self): name = Name('ru', {'genders': {'m': {'ru': 'ru_name'}}}) - self.assertEqual(unicode(name), 'ru_name') + self.assertEqual(six.text_type(name), 'ru_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_name') self.assertEqual(name.get_for(GENDER.MALE), 'ru_name') self.assertEqual(name.get_forms_for(GENDER.MALE), None) @@ -18,7 +21,7 @@ class TestName(unittest.TestCase): def test_genders(self): name = Name('ru', {'genders': {'m': {'ru': 'ru_m_name'}, 'f': {'ru': 'ru_f_name'}}}) - self.assertEqual(unicode(name), 'ru_m_name') + self.assertEqual(six.text_type(name), 'ru_m_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_m_name') self.assertEqual(name.get_for(GENDER.FEMALE, LANGUAGE.RU), 'ru_f_name') @@ -27,7 +30,7 @@ class TestName(unittest.TestCase): 'en': 'en_m_name'}, 'f': {'ru': 'ru_f_name', 'en': 'en_f_name'}}}) - self.assertEqual(unicode(name), 'ru_m_name') + self.assertEqual(six.text_type(name), 'ru_m_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_m_name') self.assertEqual(name.get_for(GENDER.FEMALE, LANGUAGE.RU), 'ru_f_name') self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.EN), 'en_m_name') diff --git a/pynames/tests/test_utils.py b/pynames/tests/test_utils.py index acab40a..a62aa06 100644 --- a/pynames/tests/test_utils.py +++ b/pynames/tests/test_utils.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + import os import tempfile import unittest diff --git a/pynames/utils.py b/pynames/utils.py index b7865e8..0430487 100644 --- a/pynames/utils.py +++ b/pynames/utils.py @@ -1,5 +1,7 @@ # coding: utf-8 +from __future__ import unicode_literals + import contextlib import importlib import pkgutil @@ -54,6 +56,6 @@ def file_adapter(file_or_path): if is_file(file_or_path): file_obj = file_or_path else: - file_obj = open(file_or_path) + file_obj = open(file_or_path, 'rb') yield file_obj file_obj.close() diff --git a/setup.py b/setup.py index a5e70ad..eb2a544 100644 --- a/setup.py +++ b/setup.py @@ -22,12 +22,14 @@ setuptools.setup( 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', 'Natural Language :: English', 'Natural Language :: Russian'], keywords=['gamedev', 'game', 'game development', 'names', 'names generation'], packages=setuptools.find_packages(), - install_requires=['unicodecsv'], + install_requires=['six', 'unicodecsv'], include_package_data=True, test_suite = 'tests', )