chore: Remove python 2.7 support and various cleanup (#179)

Co-authored-by: Bastien Vallet <b.vallet@criteo.com>
This commit is contained in:
Bastien Vallet 2020-06-08 12:09:24 +02:00 committed by GitHub
parent afb17c76bf
commit 778b00758e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 38 additions and 69 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ __pycache__/
# Distribution / packaging # Distribution / packaging
.Python .Python
env/ env/
.venv/
build/ build/
develop-eggs/ develop-eggs/
dist/ dist/

View File

@ -1,8 +1,10 @@
language: python language: python
python: python:
- 2.7 - 3.5
- 3.6 - 3.6
- pypy - 3.7
- 3.8
- pypy3
install: install:
- pip install tox-travis - pip install tox-travis
- pip install pytest-cov coveralls - pip install pytest-cov coveralls

View File

@ -9,8 +9,7 @@ implemented Google Translate API. This uses the `Google Translate Ajax
API <https://translate.google.com>`__ to make calls to such methods as API <https://translate.google.com>`__ to make calls to such methods as
detect and translate. detect and translate.
Compatible with Python 2.7+ and 3.4+. (Note: Python 2 support will be dropped in the Compatible with Python 3.5+.
next major release.)
For details refer to the `API For details refer to the `API
Documentation <https://py-googletrans.readthedocs.io/en/latest>`__. Documentation <https://py-googletrans.readthedocs.io/en/latest>`__.

View File

@ -4,9 +4,9 @@ from googletrans import Translator
def translate_doc(filename, destination='zh-CN', mix=True): 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. 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 filename: word doc file
:param destination='zh-CN': :param destination='zh-CN':
:param mix=True: if True, will have original language and target language into the same doc. paragraphs by paragraphs. :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 def tx(t): return Translator().translate(t, dest=destination).text

View File

@ -4,4 +4,4 @@ __version__ = '2.4.1'
from googletrans.client import Translator from googletrans.client import Translator
from googletrans.constants import LANGCODES, LANGUAGES from googletrans.constants import LANGCODES, LANGUAGES # noqa

View File

@ -9,7 +9,6 @@ import random
from googletrans import urls, utils from googletrans import urls, utils
from googletrans.adapters import TimeoutAdapter from googletrans.adapters import TimeoutAdapter
from googletrans.compat import PY3
from googletrans.gtoken import TokenAcquirer from googletrans.gtoken import TokenAcquirer
from googletrans.constants import DEFAULT_USER_AGENT, LANGCODES, LANGUAGES, SPECIAL_CASES from googletrans.constants import DEFAULT_USER_AGENT, LANGCODES, LANGUAGES, SPECIAL_CASES
from googletrans.models import Translated, Detected from googletrans.models import Translated, Detected
@ -18,7 +17,7 @@ from googletrans.models import Translated, Detected
EXCLUDES = ('en', 'ca', 'fr') EXCLUDES = ('en', 'ca', 'fr')
class Translator(object): class Translator:
"""Google Translate ajax API implementation class """Google Translate ajax API implementation class
You have to create an instance of Translator to use this API 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. :param user_agent: the User-Agent header to send when making requests.
:type user_agent: :class:`str` :type user_agent: :class:`str`
:param proxies: proxies configuration. :param proxies: proxies configuration.
Dictionary mapping protocol or protocol and host to the URL of the proxy 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'}`` For example ``{'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}``
:type proxies: dictionary :type proxies: dictionary
@ -69,9 +68,6 @@ class Translator(object):
return random.choice(self.service_urls) return random.choice(self.service_urls)
def _translate(self, text, dest, src, override): 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) token = self.token_acquirer.do(text)
params = utils.build_params(query=text, src=src, dest=dest, params = utils.build_params(query=text, src=src, dest=dest,
token=token, override=override) token=token, override=override)
@ -189,20 +185,10 @@ class Translator(object):
pron = data[0][1][-2] pron = data[0][1][-2]
except Exception: # pragma: nocover except Exception: # pragma: nocover
pass 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: if dest in EXCLUDES and pron == origin:
pron = translated 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 # put final values into a new Translated object
result = Translated(src=src, dest=dest, origin=origin, result = Translated(src=src, dest=dest, origin=origin,
text=translated, pronunciation=pron, extra_data=extra_data) text=translated, pronunciation=pron, extra_data=extra_data)

View File

@ -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

View File

@ -42,6 +42,7 @@ LANGUAGES = {
'ha': 'hausa', 'ha': 'hausa',
'haw': 'hawaiian', 'haw': 'hawaiian',
'iw': 'hebrew', 'iw': 'hebrew',
'he': 'hebrew',
'hi': 'hindi', 'hi': 'hindi',
'hmn': 'hmong', 'hmn': 'hmong',
'hu': 'hungarian', 'hu': 'hungarian',
@ -109,8 +110,6 @@ LANGUAGES = {
'yi': 'yiddish', 'yi': 'yiddish',
'yo': 'yoruba', 'yo': 'yoruba',
'zu': 'zulu', 'zu': 'zulu',
'fil': 'Filipino',
'he': 'Hebrew'
} }
LANGCODES = dict(map(reversed, LANGUAGES.items())) LANGCODES = dict(map(reversed, LANGUAGES.items()))

View File

@ -6,13 +6,10 @@ import time
import requests import requests
from googletrans.compat import PY3
from googletrans.compat import unicode
from googletrans.utils import rshift from googletrans.utils import rshift
class TokenAcquirer(object): class TokenAcquirer:
"""Google Translate API token generator """Google Translate API token generator
translate.google.com uses a token to authorize the requests. If you are translate.google.com uses a token to authorize the requests. If you are
@ -62,12 +59,9 @@ class TokenAcquirer(object):
return return
# this will be the same as python code after stripping out a reserved word 'var' # 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(=) # unescape special ascii characters such like a \x3d(=)
if PY3: # pragma: no cover code = code.encode().decode('unicode-escape')
code = code.encode().decode('unicode-escape')
else: # pragma: no cover
code = code.decode('string_escape')
if code: if code:
tree = ast.parse(code) tree = ast.parse(code)
@ -150,9 +144,9 @@ class TokenAcquirer(object):
else: else:
# Python doesn't natively use Unicode surrogates, so account for those # Python doesn't natively use Unicode surrogates, so account for those
a += [ a += [
math.floor((val - 0x10000)/0x400 + 0xD800), math.floor((val - 0x10000) / 0x400 + 0xD800),
math.floor((val - 0x10000)%0x400 + 0xDC00) math.floor((val - 0x10000) % 0x400 + 0xDC00)
] ]
b = self.tkk if self.tkk != '0' else '' b = self.tkk if self.tkk != '0' else ''
d = b.split('.') d = b.split('.')
@ -176,13 +170,13 @@ class TokenAcquirer(object):
if (l & 64512) == 55296 and g + 1 < size and \ if (l & 64512) == 55296 and g + 1 < size and \
a[g + 1] & 64512 == 56320: a[g + 1] & 64512 == 56320:
g += 1 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 >> 18 | 240)
e.append(l >> 12 & 63 | 128) e.append(l >> 12 & 63 | 128)
else: else:
e.append(l >> 12 | 224) e.append(l >> 12 | 224)
e.append(l >> 6 & 63 | 128) e.append(l >> 6 & 63 | 128)
e.append(l & 63 | 128) e.append(l & 63 | 128)
g += 1 g += 1
a = b a = b
for i, value in enumerate(e): for i, value in enumerate(e):

View File

@ -1,4 +1,4 @@
class Translated(object): class Translated:
"""Translate result object """Translate result object
:param src: source langauge (default: auto) :param src: source langauge (default: auto)
@ -19,13 +19,17 @@ class Translated(object):
return self.__unicode__() return self.__unicode__()
def __unicode__(self): # pragma: nocover def __unicode__(self): # pragma: nocover
return u'Translated(src={src}, dest={dest}, text={text}, pronunciation={pronunciation}, ' \ return (
u'extra_data={extra_data})'.format( u'Translated(src={src}, dest={dest}, text={text}, pronunciation={pronunciation}, '
src=self.src, dest=self.dest, text=self.text, pronunciation=self.pronunciation, u'extra_data={extra_data})'.format(
extra_data='"' + repr(self.extra_data)[:10] + '..."') 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 """Language detection result object
:param lang: detected language :param lang: detected language
@ -40,4 +44,4 @@ class Detected(object):
def __unicode__(self): # pragma: nocover def __unicode__(self): # pragma: nocover
return u'Detected(lang={lang}, confidence={confidence})'.format( return u'Detected(lang={lang}, confidence={confidence})'.format(
lang=self.lang, confidence=self.confidence) lang=self.lang, confidence=self.confidence)

View File

@ -1,5 +1,4 @@
"""A conversion module for googletrans""" """A conversion module for googletrans"""
from __future__ import print_function
import re import re
import json import json
@ -31,7 +30,7 @@ def legacy_format_json(original):
# save state # save state
states = [] states = []
text = original text = original
# save position for double-quoted texts # save position for double-quoted texts
for i, pos in enumerate(re.finditer('"', text)): for i, pos in enumerate(re.finditer('"', text)):
# pos.start() is a double-quote # pos.start() is a double-quote

View File

@ -1 +0,0 @@
requests==2.13.0

View File

@ -52,11 +52,10 @@ def install():
'Operating System :: MacOS :: MacOS X', 'Operating System :: MacOS :: MacOS X',
'Topic :: Education', 'Topic :: Education',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6', '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']), packages=find_packages(exclude=['docs', 'tests']),
keywords='google translate translator', keywords='google translate translator',
install_requires=[ install_requires=[

View File

@ -1,11 +1,9 @@
[tox] [tox]
envlist = py27,py36,pypy envlist = py35,py36,py37,py38,pypy3
[testenv] [testenv]
deps= deps=
-r{toxinidir}/requirements.txt
pytest pytest
pytest-capturelog
pytest-cov pytest-cov
commands= commands=
py.test --cov-report= --cov={envsitepackagesdir}/googletrans {posargs:} py.test --cov-report= --cov={envsitepackagesdir}/googletrans {posargs:}