mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-22 14:41:39 +00:00
Format files with black
- Format all files with black - Update tox.ini flake8 arguments to be compatible - Add black to requirements-extra.txt - Reduce ignored flake8 rules and fix a few violations
This commit is contained in:
@@ -18,20 +18,17 @@ import os
|
||||
import imp
|
||||
import sys
|
||||
import glob
|
||||
import time
|
||||
import token
|
||||
import tokenize
|
||||
import operator
|
||||
|
||||
__version__ = '1.5'
|
||||
__version__ = "1.5"
|
||||
|
||||
default_keywords = ['_']
|
||||
DEFAULTKEYWORDS = ', '.join(default_keywords)
|
||||
default_keywords = ["_"]
|
||||
DEFAULTKEYWORDS = ", ".join(default_keywords)
|
||||
|
||||
EMPTYSTRING = ''
|
||||
EMPTYSTRING = ""
|
||||
|
||||
|
||||
|
||||
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
|
||||
# there.
|
||||
pot_header = """
|
||||
@@ -41,17 +38,17 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: utf-8\\n"
|
||||
"""
|
||||
|
||||
|
||||
def usage(code, msg=''):
|
||||
|
||||
def usage(code, msg=""):
|
||||
print(__doc__ % globals(), file=sys.stderr)
|
||||
if msg:
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(code)
|
||||
|
||||
|
||||
|
||||
escapes = []
|
||||
|
||||
|
||||
def make_escapes(pass_iso8859):
|
||||
global escapes
|
||||
if pass_iso8859:
|
||||
@@ -66,11 +63,11 @@ def make_escapes(pass_iso8859):
|
||||
escapes.append(chr(i))
|
||||
else:
|
||||
escapes.append("\\%03o" % i)
|
||||
escapes[ord('\\')] = '\\\\'
|
||||
escapes[ord('\t')] = '\\t'
|
||||
escapes[ord('\r')] = '\\r'
|
||||
escapes[ord('\n')] = '\\n'
|
||||
escapes[ord('\"')] = '\\"'
|
||||
escapes[ord("\\")] = "\\\\"
|
||||
escapes[ord("\t")] = "\\t"
|
||||
escapes[ord("\r")] = "\\r"
|
||||
escapes[ord("\n")] = "\\n"
|
||||
escapes[ord('"')] = '\\"'
|
||||
|
||||
|
||||
def escape(s):
|
||||
@@ -83,26 +80,26 @@ def escape(s):
|
||||
|
||||
def safe_eval(s):
|
||||
# unwrap quotes, safely
|
||||
return eval(s, {'__builtins__':{}}, {})
|
||||
return eval(s, {"__builtins__": {}}, {})
|
||||
|
||||
|
||||
def normalize(s):
|
||||
# This converts the various Python string types into a format that is
|
||||
# appropriate for .po files, namely much closer to C style.
|
||||
lines = s.split('\n')
|
||||
lines = s.split("\n")
|
||||
if len(lines) == 1:
|
||||
s = '"' + escape(s) + '"'
|
||||
else:
|
||||
if not lines[-1]:
|
||||
del lines[-1]
|
||||
lines[-1] = lines[-1] + '\n'
|
||||
lines[-1] = lines[-1] + "\n"
|
||||
for i in range(len(lines)):
|
||||
lines[i] = escape(lines[i])
|
||||
lineterm = '\\n"\n"'
|
||||
s = '""\n"' + lineterm.join(lines) + '"'
|
||||
return s
|
||||
|
||||
|
||||
|
||||
def containsAny(str, set):
|
||||
"""Check whether 'str' contains ANY of the chars in 'set'"""
|
||||
return 1 in [c in str for c in set]
|
||||
@@ -111,20 +108,24 @@ def containsAny(str, set):
|
||||
def _visit_pyfiles(list, dirname, names):
|
||||
"""Helper for getFilesForName()."""
|
||||
# get extension for python source files
|
||||
if '_py_ext' not in globals():
|
||||
if "_py_ext" not in globals():
|
||||
global _py_ext
|
||||
_py_ext = [triple[0] for triple in imp.get_suffixes()
|
||||
if triple[2] == imp.PY_SOURCE][0]
|
||||
_py_ext = [
|
||||
triple[0] for triple in imp.get_suffixes() if triple[2] == imp.PY_SOURCE
|
||||
][0]
|
||||
|
||||
# don't recurse into CVS directories
|
||||
if 'CVS' in names:
|
||||
names.remove('CVS')
|
||||
if "CVS" in names:
|
||||
names.remove("CVS")
|
||||
|
||||
# add all *.py files to list
|
||||
list.extend(
|
||||
[os.path.join(dirname, file) for file in names
|
||||
if os.path.splitext(file)[1] == _py_ext]
|
||||
)
|
||||
[
|
||||
os.path.join(dirname, file)
|
||||
for file in names
|
||||
if os.path.splitext(file)[1] == _py_ext
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def _get_modpkg_path(dotted_name, pathlist=None):
|
||||
@@ -135,13 +136,14 @@ def _get_modpkg_path(dotted_name, pathlist=None):
|
||||
extension module.
|
||||
"""
|
||||
# split off top-most name
|
||||
parts = dotted_name.split('.', 1)
|
||||
parts = dotted_name.split(".", 1)
|
||||
|
||||
if len(parts) > 1:
|
||||
# we have a dotted path, import top-level package
|
||||
try:
|
||||
file, pathname, description = imp.find_module(parts[0], pathlist)
|
||||
if file: file.close()
|
||||
if file:
|
||||
file.close()
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
@@ -154,8 +156,7 @@ def _get_modpkg_path(dotted_name, pathlist=None):
|
||||
else:
|
||||
# plain name
|
||||
try:
|
||||
file, pathname, description = imp.find_module(
|
||||
dotted_name, pathlist)
|
||||
file, pathname, description = imp.find_module(dotted_name, pathlist)
|
||||
if file:
|
||||
file.close()
|
||||
if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]:
|
||||
@@ -195,7 +196,7 @@ def getFilesForName(name):
|
||||
|
||||
return []
|
||||
|
||||
|
||||
|
||||
class TokenEater:
|
||||
def __init__(self, options):
|
||||
self.__options = options
|
||||
@@ -208,9 +209,9 @@ class TokenEater:
|
||||
|
||||
def __call__(self, ttype, tstring, stup, etup, line):
|
||||
# dispatch
|
||||
## import token
|
||||
## print >> sys.stderr, 'ttype:', token.tok_name[ttype], \
|
||||
## 'tstring:', tstring
|
||||
# import token
|
||||
# print >> sys.stderr, 'ttype:', token.tok_name[ttype], \
|
||||
# 'tstring:', tstring
|
||||
self.__state(ttype, tstring, stup[0])
|
||||
|
||||
def __waiting(self, ttype, tstring, lineno):
|
||||
@@ -226,7 +227,7 @@ class TokenEater:
|
||||
self.__freshmodule = 0
|
||||
return
|
||||
# class docstring?
|
||||
if ttype == tokenize.NAME and tstring in ('class', 'def'):
|
||||
if ttype == tokenize.NAME and tstring in ("class", "def"):
|
||||
self.__state = self.__suiteseen
|
||||
return
|
||||
if ttype == tokenize.NAME and tstring in opts.keywords:
|
||||
@@ -234,7 +235,7 @@ class TokenEater:
|
||||
|
||||
def __suiteseen(self, ttype, tstring, lineno):
|
||||
# ignore anything until we see the colon
|
||||
if ttype == tokenize.OP and tstring == ':':
|
||||
if ttype == tokenize.OP and tstring == ":":
|
||||
self.__state = self.__suitedocstring
|
||||
|
||||
def __suitedocstring(self, ttype, tstring, lineno):
|
||||
@@ -242,13 +243,12 @@ class TokenEater:
|
||||
if ttype == tokenize.STRING:
|
||||
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
||||
self.__state = self.__waiting
|
||||
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
|
||||
tokenize.COMMENT):
|
||||
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT, tokenize.COMMENT):
|
||||
# there was no class docstring
|
||||
self.__state = self.__waiting
|
||||
|
||||
def __keywordseen(self, ttype, tstring, lineno):
|
||||
if ttype == tokenize.OP and tstring == '(':
|
||||
if ttype == tokenize.OP and tstring == "(":
|
||||
self.__data = []
|
||||
self.__lineno = lineno
|
||||
self.__state = self.__openseen
|
||||
@@ -256,7 +256,7 @@ class TokenEater:
|
||||
self.__state = self.__waiting
|
||||
|
||||
def __openseen(self, ttype, tstring, lineno):
|
||||
if ttype == tokenize.OP and tstring == ')':
|
||||
if ttype == tokenize.OP and tstring == ")":
|
||||
# We've seen the last of the translatable strings. Record the
|
||||
# line number of the first line of the strings and update the list
|
||||
# of messages seen. Reset state for the next batch. If there
|
||||
@@ -266,20 +266,25 @@ class TokenEater:
|
||||
self.__state = self.__waiting
|
||||
elif ttype == tokenize.STRING:
|
||||
self.__data.append(safe_eval(tstring))
|
||||
elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
|
||||
token.NEWLINE, tokenize.NL]:
|
||||
elif ttype not in [
|
||||
tokenize.COMMENT,
|
||||
token.INDENT,
|
||||
token.DEDENT,
|
||||
token.NEWLINE,
|
||||
tokenize.NL,
|
||||
]:
|
||||
# warn if we see anything else than STRING or whitespace
|
||||
print('*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"' % {
|
||||
'token': tstring,
|
||||
'file': self.__curfile,
|
||||
'lineno': self.__lineno
|
||||
}, file=sys.stderr)
|
||||
print(
|
||||
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
|
||||
% {"token": tstring, "file": self.__curfile, "lineno": self.__lineno},
|
||||
file=sys.stderr,
|
||||
)
|
||||
self.__state = self.__waiting
|
||||
|
||||
def __addentry(self, msg, lineno=None, isdocstring=0):
|
||||
if lineno is None:
|
||||
lineno = self.__lineno
|
||||
if not msg in self.__options.toexclude:
|
||||
if msg not in self.__options.toexclude:
|
||||
entry = (self.__curfile, lineno)
|
||||
self.__messages.setdefault(msg, {})[entry] = isdocstring
|
||||
|
||||
@@ -289,7 +294,6 @@ class TokenEater:
|
||||
|
||||
def write(self, fp):
|
||||
options = self.__options
|
||||
timestamp = time.strftime('%Y-%m-%d %H:%M+%Z')
|
||||
# The time stamp in the header doesn't have the same format as that
|
||||
# generated by xgettext...
|
||||
print(pot_header, file=fp)
|
||||
@@ -317,15 +321,15 @@ class TokenEater:
|
||||
# location comments are different b/w Solaris and GNU:
|
||||
elif options.locationstyle == options.SOLARIS:
|
||||
for filename, lineno in v:
|
||||
d = {'filename': filename, 'lineno': lineno}
|
||||
print('# File: %(filename)s, line: %(lineno)d' % d, file=fp)
|
||||
d = {"filename": filename, "lineno": lineno}
|
||||
print("# File: %(filename)s, line: %(lineno)d" % d, file=fp)
|
||||
elif options.locationstyle == options.GNU:
|
||||
# fit as many locations on one line, as long as the
|
||||
# resulting line length doesn't exceeds 'options.width'
|
||||
locline = '#:'
|
||||
locline = "#:"
|
||||
for filename, lineno in v:
|
||||
d = {'filename': filename, 'lineno': lineno}
|
||||
s = ' %(filename)s:%(lineno)d' % d
|
||||
d = {"filename": filename, "lineno": lineno}
|
||||
s = " %(filename)s:%(lineno)d" % d
|
||||
if len(locline) + len(s) <= options.width:
|
||||
locline = locline + s
|
||||
else:
|
||||
@@ -334,37 +338,34 @@ class TokenEater:
|
||||
if len(locline) > 2:
|
||||
print(locline, file=fp)
|
||||
if isdocstring:
|
||||
print('#, docstring', file=fp)
|
||||
print('msgid', normalize(k), file=fp)
|
||||
print("#, docstring", file=fp)
|
||||
print("msgid", normalize(k), file=fp)
|
||||
print('msgstr ""\n', file=fp)
|
||||
|
||||
|
||||
|
||||
def main(source_files, outpath, keywords=None):
|
||||
global default_keywords
|
||||
|
||||
# for holding option values
|
||||
class Options:
|
||||
# constants
|
||||
GNU = 1
|
||||
SOLARIS = 2
|
||||
# defaults
|
||||
extractall = 0 # FIXME: currently this option has no effect at all.
|
||||
extractall = 0 # FIXME: currently this option has no effect at all.
|
||||
escape = 0
|
||||
keywords = []
|
||||
outfile = 'messages.pot'
|
||||
outfile = "messages.pot"
|
||||
writelocations = 1
|
||||
locationstyle = GNU
|
||||
verbose = 0
|
||||
width = 78
|
||||
excludefilename = ''
|
||||
excludefilename = ""
|
||||
docstrings = 0
|
||||
nodocstrings = {}
|
||||
|
||||
options = Options()
|
||||
locations = {'gnu' : options.GNU,
|
||||
'solaris' : options.SOLARIS,
|
||||
}
|
||||
|
||||
|
||||
options.outfile = outpath
|
||||
if keywords:
|
||||
options.keywords = keywords
|
||||
@@ -378,11 +379,14 @@ def main(source_files, outpath, keywords=None):
|
||||
# initialize list of strings to exclude
|
||||
if options.excludefilename:
|
||||
try:
|
||||
fp = open(options.excludefilename, encoding='utf-8')
|
||||
fp = open(options.excludefilename, encoding="utf-8")
|
||||
options.toexclude = fp.readlines()
|
||||
fp.close()
|
||||
except IOError:
|
||||
print("Can't read --exclude-file: %s" % options.excludefilename, file=sys.stderr)
|
||||
print(
|
||||
"Can't read --exclude-file: %s" % options.excludefilename,
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
else:
|
||||
options.toexclude = []
|
||||
@@ -391,8 +395,8 @@ def main(source_files, outpath, keywords=None):
|
||||
eater = TokenEater(options)
|
||||
for filename in source_files:
|
||||
if options.verbose:
|
||||
print('Working on %s' % filename)
|
||||
fp = open(filename, encoding='utf-8')
|
||||
print("Working on %s" % filename)
|
||||
fp = open(filename, encoding="utf-8")
|
||||
closep = 1
|
||||
try:
|
||||
eater.set_filename(filename)
|
||||
@@ -401,14 +405,16 @@ def main(source_files, outpath, keywords=None):
|
||||
for _token in tokens:
|
||||
eater(*_token)
|
||||
except tokenize.TokenError as e:
|
||||
print('%s: %s, line %d, column %d' % (
|
||||
e.args[0], filename, e.args[1][0], e.args[1][1]),
|
||||
file=sys.stderr)
|
||||
print(
|
||||
"%s: %s, line %d, column %d"
|
||||
% (e.args[0], filename, e.args[1][0], e.args[1][1]),
|
||||
file=sys.stderr,
|
||||
)
|
||||
finally:
|
||||
if closep:
|
||||
fp.close()
|
||||
|
||||
fp = open(options.outfile, 'w', encoding='utf-8')
|
||||
fp = open(options.outfile, "w", encoding="utf-8")
|
||||
closep = 1
|
||||
try:
|
||||
eater.write(fp)
|
||||
|
||||
Reference in New Issue
Block a user