diff --git a/.gitignore b/.gitignore index 90c2bfe..b1b5b23 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ __pycache__/ # Distribution / packaging .Python env/ +.venv/ build/ develop-eggs/ dist/ diff --git a/.travis.yml b/.travis.yml index a0f717d..d731b3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,10 @@ language: python python: - - 2.7 + - 3.5 - 3.6 - - pypy + - 3.7 + - 3.8 + - pypy3 install: - pip install tox-travis - pip install pytest-cov coveralls diff --git a/README.rst b/README.rst index 68650ea..93a0c75 100644 --- a/README.rst +++ b/README.rst @@ -9,8 +9,7 @@ implemented Google Translate API. This uses the `Google Translate Ajax API `__ to make calls to such methods as detect and translate. -Compatible with Python 2.7+ and 3.4+. (Note: Python 2 support will be dropped in the -next major release.) +Compatible with Python 3.5+. For details refer to the `API Documentation `__. diff --git a/example/translate_word_doc.py b/example/translate_word_doc.py index 64b893b..d5c74f8 100644 --- a/example/translate_word_doc.py +++ b/example/translate_word_doc.py @@ -4,9 +4,9 @@ from googletrans import Translator def translate_doc(filename, destination='zh-CN', mix=True): """ - translate a word document type of file and save the result as document and keep the exactly same file format. - :param filename: word doc file - :param destination='zh-CN': + translate a word document type of file and save the result as document and keep the exactly same file format. + :param filename: word doc file + :param destination='zh-CN': :param mix=True: if True, will have original language and target language into the same doc. paragraphs by paragraphs. """ def tx(t): return Translator().translate(t, dest=destination).text diff --git a/googletrans/__init__.py b/googletrans/__init__.py index b8f1ac9..0371da3 100644 --- a/googletrans/__init__.py +++ b/googletrans/__init__.py @@ -4,4 +4,4 @@ __version__ = '2.4.1' from googletrans.client import Translator -from googletrans.constants import LANGCODES, LANGUAGES +from googletrans.constants import LANGCODES, LANGUAGES # noqa diff --git a/googletrans/client.py b/googletrans/client.py index e965d27..af4ceb8 100644 --- a/googletrans/client.py +++ b/googletrans/client.py @@ -9,7 +9,6 @@ import random from googletrans import urls, utils from googletrans.adapters import TimeoutAdapter -from googletrans.compat import PY3 from googletrans.gtoken import TokenAcquirer from googletrans.constants import DEFAULT_USER_AGENT, LANGCODES, LANGUAGES, SPECIAL_CASES from googletrans.models import Translated, Detected @@ -18,7 +17,7 @@ from googletrans.models import Translated, Detected EXCLUDES = ('en', 'ca', 'fr') -class Translator(object): +class Translator: """Google Translate ajax API implementation class You have to create an instance of Translator to use this API @@ -30,8 +29,8 @@ class Translator(object): :param user_agent: the User-Agent header to send when making requests. :type user_agent: :class:`str` - :param proxies: proxies configuration. - Dictionary mapping protocol or protocol and host to the URL of the proxy + :param proxies: proxies configuration. + Dictionary mapping protocol or protocol and host to the URL of the proxy For example ``{'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}`` :type proxies: dictionary @@ -69,9 +68,6 @@ class Translator(object): return random.choice(self.service_urls) def _translate(self, text, dest, src, override): - if not PY3 and isinstance(text, str): # pragma: nocover - text = text.decode('utf-8') - token = self.token_acquirer.do(text) params = utils.build_params(query=text, src=src, dest=dest, token=token, override=override) @@ -189,20 +185,10 @@ class Translator(object): pron = data[0][1][-2] except Exception: # pragma: nocover pass - if not PY3 and isinstance(pron, unicode) and isinstance(origin, str): # pragma: nocover - origin = origin.decode('utf-8') + if dest in EXCLUDES and pron == origin: pron = translated - # for python 2.x compatbillity - if not PY3: # pragma: nocover - if isinstance(src, str): - src = src.decode('utf-8') - if isinstance(dest, str): - dest = dest.decode('utf-8') - if isinstance(translated, str): - translated = translated.decode('utf-8') - # put final values into a new Translated object result = Translated(src=src, dest=dest, origin=origin, text=translated, pronunciation=pron, extra_data=extra_data) diff --git a/googletrans/compat.py b/googletrans/compat.py deleted file mode 100644 index c11e55f..0000000 --- a/googletrans/compat.py +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- -import sys -try: # pragma: nocover - from urllib.parse import quote -except: # pragma: nocover - from urllib import quote - - -PY3 = sys.version_info > (3, ) - -unicode = str if PY3 else unicode diff --git a/googletrans/constants.py b/googletrans/constants.py index 15ac728..e3e3788 100644 --- a/googletrans/constants.py +++ b/googletrans/constants.py @@ -42,6 +42,7 @@ LANGUAGES = { 'ha': 'hausa', 'haw': 'hawaiian', 'iw': 'hebrew', + 'he': 'hebrew', 'hi': 'hindi', 'hmn': 'hmong', 'hu': 'hungarian', @@ -109,8 +110,6 @@ LANGUAGES = { 'yi': 'yiddish', 'yo': 'yoruba', 'zu': 'zulu', - 'fil': 'Filipino', - 'he': 'Hebrew' } LANGCODES = dict(map(reversed, LANGUAGES.items())) diff --git a/googletrans/gtoken.py b/googletrans/gtoken.py index 1f23081..a9558fe 100644 --- a/googletrans/gtoken.py +++ b/googletrans/gtoken.py @@ -6,13 +6,10 @@ import time import requests - -from googletrans.compat import PY3 -from googletrans.compat import unicode from googletrans.utils import rshift -class TokenAcquirer(object): +class TokenAcquirer: """Google Translate API token generator translate.google.com uses a token to authorize the requests. If you are @@ -62,12 +59,9 @@ class TokenAcquirer(object): return # this will be the same as python code after stripping out a reserved word 'var' - code = unicode(self.RE_TKK.search(r.text).group(1)).replace('var ', '') + code = self.RE_TKK.search(r.text).group(1).replace('var ', '') # unescape special ascii characters such like a \x3d(=) - if PY3: # pragma: no cover - code = code.encode().decode('unicode-escape') - else: # pragma: no cover - code = code.decode('string_escape') + code = code.encode().decode('unicode-escape') if code: tree = ast.parse(code) @@ -150,9 +144,9 @@ class TokenAcquirer(object): else: # Python doesn't natively use Unicode surrogates, so account for those a += [ - math.floor((val - 0x10000)/0x400 + 0xD800), - math.floor((val - 0x10000)%0x400 + 0xDC00) - ] + math.floor((val - 0x10000) / 0x400 + 0xD800), + math.floor((val - 0x10000) % 0x400 + 0xDC00) + ] b = self.tkk if self.tkk != '0' else '' d = b.split('.') @@ -176,13 +170,13 @@ class TokenAcquirer(object): if (l & 64512) == 55296 and g + 1 < size and \ a[g + 1] & 64512 == 56320: g += 1 - l = 65536 + ((l & 1023) << 10) + (a[g] & 1023) # This bracket is important + l = 65536 + ((l & 1023) << 10) + (a[g] & 1023) # This bracket is important e.append(l >> 18 | 240) e.append(l >> 12 & 63 | 128) else: e.append(l >> 12 | 224) e.append(l >> 6 & 63 | 128) - e.append(l & 63 | 128) + e.append(l & 63 | 128) g += 1 a = b for i, value in enumerate(e): diff --git a/googletrans/models.py b/googletrans/models.py index 7aa9ed2..34bf7e3 100644 --- a/googletrans/models.py +++ b/googletrans/models.py @@ -1,4 +1,4 @@ -class Translated(object): +class Translated: """Translate result object :param src: source langauge (default: auto) @@ -19,13 +19,17 @@ class Translated(object): return self.__unicode__() def __unicode__(self): # pragma: nocover - return u'Translated(src={src}, dest={dest}, text={text}, pronunciation={pronunciation}, ' \ - u'extra_data={extra_data})'.format( - src=self.src, dest=self.dest, text=self.text, pronunciation=self.pronunciation, - extra_data='"' + repr(self.extra_data)[:10] + '..."') + return ( + u'Translated(src={src}, dest={dest}, text={text}, pronunciation={pronunciation}, ' + u'extra_data={extra_data})'.format( + src=self.src, dest=self.dest, text=self.text, + pronunciation=self.pronunciation, + extra_data='"' + repr(self.extra_data)[:10] + '..."' + ) + ) -class Detected(object): +class Detected: """Language detection result object :param lang: detected language @@ -40,4 +44,4 @@ class Detected(object): def __unicode__(self): # pragma: nocover return u'Detected(lang={lang}, confidence={confidence})'.format( - lang=self.lang, confidence=self.confidence) \ No newline at end of file + lang=self.lang, confidence=self.confidence) diff --git a/googletrans/utils.py b/googletrans/utils.py index 0f4d624..0c91727 100644 --- a/googletrans/utils.py +++ b/googletrans/utils.py @@ -1,5 +1,4 @@ """A conversion module for googletrans""" -from __future__ import print_function import re import json @@ -31,7 +30,7 @@ def legacy_format_json(original): # save state states = [] text = original - + # save position for double-quoted texts for i, pos in enumerate(re.finditer('"', text)): # pos.start() is a double-quote diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 6f5275b..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/setup.py b/setup.py index ab89b75..2c16385 100644 --- a/setup.py +++ b/setup.py @@ -52,11 +52,10 @@ def install(): 'Operating System :: MacOS :: MacOS X', 'Topic :: Education', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7'], + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8'], packages=find_packages(exclude=['docs', 'tests']), keywords='google translate translator', install_requires=[ diff --git a/tox.ini b/tox.ini index c4364b9..2a84f20 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,9 @@ [tox] -envlist = py27,py36,pypy +envlist = py35,py36,py37,py38,pypy3 [testenv] deps= - -r{toxinidir}/requirements.txt pytest - pytest-capturelog pytest-cov commands= py.test --cov-report= --cov={envsitepackagesdir}/googletrans {posargs:}