Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ExeBy/smexe_ro.../opt/alt/python31.../bin
File: pygettext3.py
#! /opt/alt/python310/bin/python3.10
[0] Fix | Delete
# -*- coding: iso-8859-1 -*-
[1] Fix | Delete
# Originally written by Barry Warsaw <barry@python.org>
[2] Fix | Delete
#
[3] Fix | Delete
# Minimally patched to make it even more xgettext compatible
[4] Fix | Delete
# by Peter Funk <pf@artcom-gmbh.de>
[5] Fix | Delete
#
[6] Fix | Delete
[7] Fix | Delete
# Added checks that _() only contains string literals, and
[8] Fix | Delete
# command line args are resolved to module lists, i.e. you
[9] Fix | Delete
# can now pass a filename, a module or package name, or a
[10] Fix | Delete
# directory (including globbing chars, important for Win32).
[11] Fix | Delete
# Made docstring fit in 80 chars wide displays using pydoc.
[12] Fix | Delete
#
[13] Fix | Delete
[14] Fix | Delete
# for selftesting
[15] Fix | Delete
try:
[16] Fix | Delete
import fintl
[17] Fix | Delete
_ = fintl.gettext
[18] Fix | Delete
except ImportError:
[19] Fix | Delete
_ = lambda s: s
[20] Fix | Delete
[21] Fix | Delete
__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
[22] Fix | Delete
[23] Fix | Delete
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
[24] Fix | Delete
internationalization of C programs. Most of these tools are independent of
[25] Fix | Delete
the programming language and can be used from within Python programs.
[26] Fix | Delete
Martin von Loewis' work[1] helps considerably in this regard.
[27] Fix | Delete
[28] Fix | Delete
There's one problem though; xgettext is the program that scans source code
[29] Fix | Delete
looking for message strings, but it groks only C (or C++). Python
[30] Fix | Delete
introduces a few wrinkles, such as dual quoting characters, triple quoted
[31] Fix | Delete
strings, and raw strings. xgettext understands none of this.
[32] Fix | Delete
[33] Fix | Delete
Enter pygettext, which uses Python's standard tokenize module to scan
[34] Fix | Delete
Python source code, generating .pot files identical to what GNU xgettext[2]
[35] Fix | Delete
generates for C and C++ code. From there, the standard GNU tools can be
[36] Fix | Delete
used.
[37] Fix | Delete
[38] Fix | Delete
A word about marking Python strings as candidates for translation. GNU
[39] Fix | Delete
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
[40] Fix | Delete
and gettext_noop. But those can be a lot of text to include all over your
[41] Fix | Delete
code. C and C++ have a trick: they use the C preprocessor. Most
[42] Fix | Delete
internationalized C source includes a #define for gettext() to _() so that
[43] Fix | Delete
what has to be written in the source is much less. Thus these are both
[44] Fix | Delete
translatable strings:
[45] Fix | Delete
[46] Fix | Delete
gettext("Translatable String")
[47] Fix | Delete
_("Translatable String")
[48] Fix | Delete
[49] Fix | Delete
Python of course has no preprocessor so this doesn't work so well. Thus,
[50] Fix | Delete
pygettext searches only for _() by default, but see the -k/--keyword flag
[51] Fix | Delete
below for how to augment this.
[52] Fix | Delete
[53] Fix | Delete
[1] https://www.python.org/workshops/1997-10/proceedings/loewis.html
[54] Fix | Delete
[2] https://www.gnu.org/software/gettext/gettext.html
[55] Fix | Delete
[56] Fix | Delete
NOTE: pygettext attempts to be option and feature compatible with GNU
[57] Fix | Delete
xgettext where ever possible. However some options are still missing or are
[58] Fix | Delete
not fully implemented. Also, xgettext's use of command line switches with
[59] Fix | Delete
option arguments is broken, and in these cases, pygettext just defines
[60] Fix | Delete
additional switches.
[61] Fix | Delete
[62] Fix | Delete
Usage: pygettext [options] inputfile ...
[63] Fix | Delete
[64] Fix | Delete
Options:
[65] Fix | Delete
[66] Fix | Delete
-a
[67] Fix | Delete
--extract-all
[68] Fix | Delete
Extract all strings.
[69] Fix | Delete
[70] Fix | Delete
-d name
[71] Fix | Delete
--default-domain=name
[72] Fix | Delete
Rename the default output file from messages.pot to name.pot.
[73] Fix | Delete
[74] Fix | Delete
-E
[75] Fix | Delete
--escape
[76] Fix | Delete
Replace non-ASCII characters with octal escape sequences.
[77] Fix | Delete
[78] Fix | Delete
-D
[79] Fix | Delete
--docstrings
[80] Fix | Delete
Extract module, class, method, and function docstrings. These do
[81] Fix | Delete
not need to be wrapped in _() markers, and in fact cannot be for
[82] Fix | Delete
Python to consider them docstrings. (See also the -X option).
[83] Fix | Delete
[84] Fix | Delete
-h
[85] Fix | Delete
--help
[86] Fix | Delete
Print this help message and exit.
[87] Fix | Delete
[88] Fix | Delete
-k word
[89] Fix | Delete
--keyword=word
[90] Fix | Delete
Keywords to look for in addition to the default set, which are:
[91] Fix | Delete
%(DEFAULTKEYWORDS)s
[92] Fix | Delete
[93] Fix | Delete
You can have multiple -k flags on the command line.
[94] Fix | Delete
[95] Fix | Delete
-K
[96] Fix | Delete
--no-default-keywords
[97] Fix | Delete
Disable the default set of keywords (see above). Any keywords
[98] Fix | Delete
explicitly added with the -k/--keyword option are still recognized.
[99] Fix | Delete
[100] Fix | Delete
--no-location
[101] Fix | Delete
Do not write filename/lineno location comments.
[102] Fix | Delete
[103] Fix | Delete
-n
[104] Fix | Delete
--add-location
[105] Fix | Delete
Write filename/lineno location comments indicating where each
[106] Fix | Delete
extracted string is found in the source. These lines appear before
[107] Fix | Delete
each msgid. The style of comments is controlled by the -S/--style
[108] Fix | Delete
option. This is the default.
[109] Fix | Delete
[110] Fix | Delete
-o filename
[111] Fix | Delete
--output=filename
[112] Fix | Delete
Rename the default output file from messages.pot to filename. If
[113] Fix | Delete
filename is `-' then the output is sent to standard out.
[114] Fix | Delete
[115] Fix | Delete
-p dir
[116] Fix | Delete
--output-dir=dir
[117] Fix | Delete
Output files will be placed in directory dir.
[118] Fix | Delete
[119] Fix | Delete
-S stylename
[120] Fix | Delete
--style stylename
[121] Fix | Delete
Specify which style to use for location comments. Two styles are
[122] Fix | Delete
supported:
[123] Fix | Delete
[124] Fix | Delete
Solaris # File: filename, line: line-number
[125] Fix | Delete
GNU #: filename:line
[126] Fix | Delete
[127] Fix | Delete
The style name is case insensitive. GNU style is the default.
[128] Fix | Delete
[129] Fix | Delete
-v
[130] Fix | Delete
--verbose
[131] Fix | Delete
Print the names of the files being processed.
[132] Fix | Delete
[133] Fix | Delete
-V
[134] Fix | Delete
--version
[135] Fix | Delete
Print the version of pygettext and exit.
[136] Fix | Delete
[137] Fix | Delete
-w columns
[138] Fix | Delete
--width=columns
[139] Fix | Delete
Set width of output to columns.
[140] Fix | Delete
[141] Fix | Delete
-x filename
[142] Fix | Delete
--exclude-file=filename
[143] Fix | Delete
Specify a file that contains a list of strings that are not be
[144] Fix | Delete
extracted from the input files. Each string to be excluded must
[145] Fix | Delete
appear on a line by itself in the file.
[146] Fix | Delete
[147] Fix | Delete
-X filename
[148] Fix | Delete
--no-docstrings=filename
[149] Fix | Delete
Specify a file that contains a list of files (one per line) that
[150] Fix | Delete
should not have their docstrings extracted. This is only useful in
[151] Fix | Delete
conjunction with the -D option above.
[152] Fix | Delete
[153] Fix | Delete
If `inputfile' is -, standard input is read.
[154] Fix | Delete
""")
[155] Fix | Delete
[156] Fix | Delete
import os
[157] Fix | Delete
import importlib.machinery
[158] Fix | Delete
import importlib.util
[159] Fix | Delete
import sys
[160] Fix | Delete
import glob
[161] Fix | Delete
import time
[162] Fix | Delete
import getopt
[163] Fix | Delete
import ast
[164] Fix | Delete
import token
[165] Fix | Delete
import tokenize
[166] Fix | Delete
[167] Fix | Delete
__version__ = '1.5'
[168] Fix | Delete
[169] Fix | Delete
default_keywords = ['_']
[170] Fix | Delete
DEFAULTKEYWORDS = ', '.join(default_keywords)
[171] Fix | Delete
[172] Fix | Delete
EMPTYSTRING = ''
[173] Fix | Delete
[174] Fix | Delete
[175] Fix | Delete
[176] Fix | Delete
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
[177] Fix | Delete
# there.
[178] Fix | Delete
pot_header = _('''\
[179] Fix | Delete
# SOME DESCRIPTIVE TITLE.
[180] Fix | Delete
# Copyright (C) YEAR ORGANIZATION
[181] Fix | Delete
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
[182] Fix | Delete
#
[183] Fix | Delete
msgid ""
[184] Fix | Delete
msgstr ""
[185] Fix | Delete
"Project-Id-Version: PACKAGE VERSION\\n"
[186] Fix | Delete
"POT-Creation-Date: %(time)s\\n"
[187] Fix | Delete
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
[188] Fix | Delete
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
[189] Fix | Delete
"Language-Team: LANGUAGE <LL@li.org>\\n"
[190] Fix | Delete
"MIME-Version: 1.0\\n"
[191] Fix | Delete
"Content-Type: text/plain; charset=%(charset)s\\n"
[192] Fix | Delete
"Content-Transfer-Encoding: %(encoding)s\\n"
[193] Fix | Delete
"Generated-By: pygettext.py %(version)s\\n"
[194] Fix | Delete
[195] Fix | Delete
''')
[196] Fix | Delete
[197] Fix | Delete
[198] Fix | Delete
def usage(code, msg=''):
[199] Fix | Delete
print(__doc__ % globals(), file=sys.stderr)
[200] Fix | Delete
if msg:
[201] Fix | Delete
print(msg, file=sys.stderr)
[202] Fix | Delete
sys.exit(code)
[203] Fix | Delete
[204] Fix | Delete
[205] Fix | Delete
[206] Fix | Delete
def make_escapes(pass_nonascii):
[207] Fix | Delete
global escapes, escape
[208] Fix | Delete
if pass_nonascii:
[209] Fix | Delete
# Allow non-ascii characters to pass through so that e.g. 'msgid
[210] Fix | Delete
[211] Fix | Delete
# escape any character outside the 32..126 range.
[212] Fix | Delete
mod = 128
[213] Fix | Delete
escape = escape_ascii
[214] Fix | Delete
else:
[215] Fix | Delete
mod = 256
[216] Fix | Delete
escape = escape_nonascii
[217] Fix | Delete
escapes = [r"\%03o" % i for i in range(mod)]
[218] Fix | Delete
for i in range(32, 127):
[219] Fix | Delete
escapes[i] = chr(i)
[220] Fix | Delete
escapes[ord('\\')] = r'\\'
[221] Fix | Delete
escapes[ord('\t')] = r'\t'
[222] Fix | Delete
escapes[ord('\r')] = r'\r'
[223] Fix | Delete
escapes[ord('\n')] = r'\n'
[224] Fix | Delete
escapes[ord('\"')] = r'\"'
[225] Fix | Delete
[226] Fix | Delete
[227] Fix | Delete
def escape_ascii(s, encoding):
[228] Fix | Delete
return ''.join(escapes[ord(c)] if ord(c) < 128 else c for c in s)
[229] Fix | Delete
[230] Fix | Delete
def escape_nonascii(s, encoding):
[231] Fix | Delete
return ''.join(escapes[b] for b in s.encode(encoding))
[232] Fix | Delete
[233] Fix | Delete
[234] Fix | Delete
def is_literal_string(s):
[235] Fix | Delete
return s[0] in '\'"' or (s[0] in 'rRuU' and s[1] in '\'"')
[236] Fix | Delete
[237] Fix | Delete
[238] Fix | Delete
def safe_eval(s):
[239] Fix | Delete
# unwrap quotes, safely
[240] Fix | Delete
return eval(s, {'__builtins__':{}}, {})
[241] Fix | Delete
[242] Fix | Delete
[243] Fix | Delete
def normalize(s, encoding):
[244] Fix | Delete
# This converts the various Python string types into a format that is
[245] Fix | Delete
# appropriate for .po files, namely much closer to C style.
[246] Fix | Delete
lines = s.split('\n')
[247] Fix | Delete
if len(lines) == 1:
[248] Fix | Delete
s = '"' + escape(s, encoding) + '"'
[249] Fix | Delete
else:
[250] Fix | Delete
if not lines[-1]:
[251] Fix | Delete
del lines[-1]
[252] Fix | Delete
lines[-1] = lines[-1] + '\n'
[253] Fix | Delete
for i in range(len(lines)):
[254] Fix | Delete
lines[i] = escape(lines[i], encoding)
[255] Fix | Delete
lineterm = '\\n"\n"'
[256] Fix | Delete
s = '""\n"' + lineterm.join(lines) + '"'
[257] Fix | Delete
return s
[258] Fix | Delete
[259] Fix | Delete
[260] Fix | Delete
def containsAny(str, set):
[261] Fix | Delete
"""Check whether 'str' contains ANY of the chars in 'set'"""
[262] Fix | Delete
return 1 in [c in str for c in set]
[263] Fix | Delete
[264] Fix | Delete
[265] Fix | Delete
def getFilesForName(name):
[266] Fix | Delete
"""Get a list of module files for a filename, a module or package name,
[267] Fix | Delete
or a directory.
[268] Fix | Delete
"""
[269] Fix | Delete
if not os.path.exists(name):
[270] Fix | Delete
# check for glob chars
[271] Fix | Delete
if containsAny(name, "*?[]"):
[272] Fix | Delete
files = glob.glob(name)
[273] Fix | Delete
list = []
[274] Fix | Delete
for file in files:
[275] Fix | Delete
list.extend(getFilesForName(file))
[276] Fix | Delete
return list
[277] Fix | Delete
[278] Fix | Delete
# try to find module or package
[279] Fix | Delete
try:
[280] Fix | Delete
spec = importlib.util.find_spec(name)
[281] Fix | Delete
name = spec.origin
[282] Fix | Delete
except ImportError:
[283] Fix | Delete
name = None
[284] Fix | Delete
if not name:
[285] Fix | Delete
return []
[286] Fix | Delete
[287] Fix | Delete
if os.path.isdir(name):
[288] Fix | Delete
# find all python files in directory
[289] Fix | Delete
list = []
[290] Fix | Delete
# get extension for python source files
[291] Fix | Delete
_py_ext = importlib.machinery.SOURCE_SUFFIXES[0]
[292] Fix | Delete
for root, dirs, files in os.walk(name):
[293] Fix | Delete
# don't recurse into CVS directories
[294] Fix | Delete
if 'CVS' in dirs:
[295] Fix | Delete
dirs.remove('CVS')
[296] Fix | Delete
# add all *.py files to list
[297] Fix | Delete
list.extend(
[298] Fix | Delete
[os.path.join(root, file) for file in files
[299] Fix | Delete
if os.path.splitext(file)[1] == _py_ext]
[300] Fix | Delete
)
[301] Fix | Delete
return list
[302] Fix | Delete
elif os.path.exists(name):
[303] Fix | Delete
# a single file
[304] Fix | Delete
return [name]
[305] Fix | Delete
[306] Fix | Delete
return []
[307] Fix | Delete
[308] Fix | Delete
[309] Fix | Delete
class TokenEater:
[310] Fix | Delete
def __init__(self, options):
[311] Fix | Delete
self.__options = options
[312] Fix | Delete
self.__messages = {}
[313] Fix | Delete
self.__state = self.__waiting
[314] Fix | Delete
self.__data = []
[315] Fix | Delete
self.__lineno = -1
[316] Fix | Delete
self.__freshmodule = 1
[317] Fix | Delete
self.__curfile = None
[318] Fix | Delete
self.__enclosurecount = 0
[319] Fix | Delete
[320] Fix | Delete
def __call__(self, ttype, tstring, stup, etup, line):
[321] Fix | Delete
# dispatch
[322] Fix | Delete
## import token
[323] Fix | Delete
## print('ttype:', token.tok_name[ttype], 'tstring:', tstring,
[324] Fix | Delete
## file=sys.stderr)
[325] Fix | Delete
self.__state(ttype, tstring, stup[0])
[326] Fix | Delete
[327] Fix | Delete
def __waiting(self, ttype, tstring, lineno):
[328] Fix | Delete
opts = self.__options
[329] Fix | Delete
# Do docstring extractions, if enabled
[330] Fix | Delete
if opts.docstrings and not opts.nodocstrings.get(self.__curfile):
[331] Fix | Delete
# module docstring?
[332] Fix | Delete
if self.__freshmodule:
[333] Fix | Delete
if ttype == tokenize.STRING and is_literal_string(tstring):
[334] Fix | Delete
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
[335] Fix | Delete
self.__freshmodule = 0
[336] Fix | Delete
return
[337] Fix | Delete
if ttype in (tokenize.COMMENT, tokenize.NL, tokenize.ENCODING):
[338] Fix | Delete
return
[339] Fix | Delete
self.__freshmodule = 0
[340] Fix | Delete
# class or func/method docstring?
[341] Fix | Delete
if ttype == tokenize.NAME and tstring in ('class', 'def'):
[342] Fix | Delete
self.__state = self.__suiteseen
[343] Fix | Delete
return
[344] Fix | Delete
if ttype == tokenize.NAME and tstring in opts.keywords:
[345] Fix | Delete
self.__state = self.__keywordseen
[346] Fix | Delete
return
[347] Fix | Delete
if ttype == tokenize.STRING:
[348] Fix | Delete
maybe_fstring = ast.parse(tstring, mode='eval').body
[349] Fix | Delete
if not isinstance(maybe_fstring, ast.JoinedStr):
[350] Fix | Delete
return
[351] Fix | Delete
for value in filter(lambda node: isinstance(node, ast.FormattedValue),
[352] Fix | Delete
maybe_fstring.values):
[353] Fix | Delete
for call in filter(lambda node: isinstance(node, ast.Call),
[354] Fix | Delete
ast.walk(value)):
[355] Fix | Delete
func = call.func
[356] Fix | Delete
if isinstance(func, ast.Name):
[357] Fix | Delete
func_name = func.id
[358] Fix | Delete
elif isinstance(func, ast.Attribute):
[359] Fix | Delete
func_name = func.attr
[360] Fix | Delete
else:
[361] Fix | Delete
continue
[362] Fix | Delete
[363] Fix | Delete
if func_name not in opts.keywords:
[364] Fix | Delete
continue
[365] Fix | Delete
if len(call.args) != 1:
[366] Fix | Delete
print(_(
[367] Fix | Delete
'*** %(file)s:%(lineno)s: Seen unexpected amount of'
[368] Fix | Delete
' positional arguments in gettext call: %(source_segment)s'
[369] Fix | Delete
) % {
[370] Fix | Delete
'source_segment': ast.get_source_segment(tstring, call) or tstring,
[371] Fix | Delete
'file': self.__curfile,
[372] Fix | Delete
'lineno': lineno
[373] Fix | Delete
}, file=sys.stderr)
[374] Fix | Delete
continue
[375] Fix | Delete
if call.keywords:
[376] Fix | Delete
print(_(
[377] Fix | Delete
'*** %(file)s:%(lineno)s: Seen unexpected keyword arguments'
[378] Fix | Delete
' in gettext call: %(source_segment)s'
[379] Fix | Delete
) % {
[380] Fix | Delete
'source_segment': ast.get_source_segment(tstring, call) or tstring,
[381] Fix | Delete
'file': self.__curfile,
[382] Fix | Delete
'lineno': lineno
[383] Fix | Delete
}, file=sys.stderr)
[384] Fix | Delete
continue
[385] Fix | Delete
arg = call.args[0]
[386] Fix | Delete
if not isinstance(arg, ast.Constant):
[387] Fix | Delete
print(_(
[388] Fix | Delete
'*** %(file)s:%(lineno)s: Seen unexpected argument type'
[389] Fix | Delete
' in gettext call: %(source_segment)s'
[390] Fix | Delete
) % {
[391] Fix | Delete
'source_segment': ast.get_source_segment(tstring, call) or tstring,
[392] Fix | Delete
'file': self.__curfile,
[393] Fix | Delete
'lineno': lineno
[394] Fix | Delete
}, file=sys.stderr)
[395] Fix | Delete
continue
[396] Fix | Delete
if isinstance(arg.value, str):
[397] Fix | Delete
self.__addentry(arg.value, lineno)
[398] Fix | Delete
[399] Fix | Delete
def __suiteseen(self, ttype, tstring, lineno):
[400] Fix | Delete
# skip over any enclosure pairs until we see the colon
[401] Fix | Delete
if ttype == tokenize.OP:
[402] Fix | Delete
if tstring == ':' and self.__enclosurecount == 0:
[403] Fix | Delete
# we see a colon and we're not in an enclosure: end of def
[404] Fix | Delete
self.__state = self.__suitedocstring
[405] Fix | Delete
elif tstring in '([{':
[406] Fix | Delete
self.__enclosurecount += 1
[407] Fix | Delete
elif tstring in ')]}':
[408] Fix | Delete
self.__enclosurecount -= 1
[409] Fix | Delete
[410] Fix | Delete
def __suitedocstring(self, ttype, tstring, lineno):
[411] Fix | Delete
# ignore any intervening noise
[412] Fix | Delete
if ttype == tokenize.STRING and is_literal_string(tstring):
[413] Fix | Delete
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
[414] Fix | Delete
self.__state = self.__waiting
[415] Fix | Delete
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
[416] Fix | Delete
tokenize.COMMENT):
[417] Fix | Delete
# there was no class docstring
[418] Fix | Delete
self.__state = self.__waiting
[419] Fix | Delete
[420] Fix | Delete
def __keywordseen(self, ttype, tstring, lineno):
[421] Fix | Delete
if ttype == tokenize.OP and tstring == '(':
[422] Fix | Delete
self.__data = []
[423] Fix | Delete
self.__lineno = lineno
[424] Fix | Delete
self.__state = self.__openseen
[425] Fix | Delete
else:
[426] Fix | Delete
self.__state = self.__waiting
[427] Fix | Delete
[428] Fix | Delete
def __openseen(self, ttype, tstring, lineno):
[429] Fix | Delete
if ttype == tokenize.OP and tstring == ')':
[430] Fix | Delete
# We've seen the last of the translatable strings. Record the
[431] Fix | Delete
# line number of the first line of the strings and update the list
[432] Fix | Delete
# of messages seen. Reset state for the next batch. If there
[433] Fix | Delete
# were no strings inside _(), then just ignore this entry.
[434] Fix | Delete
if self.__data:
[435] Fix | Delete
self.__addentry(EMPTYSTRING.join(self.__data))
[436] Fix | Delete
self.__state = self.__waiting
[437] Fix | Delete
elif ttype == tokenize.STRING and is_literal_string(tstring):
[438] Fix | Delete
self.__data.append(safe_eval(tstring))
[439] Fix | Delete
elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
[440] Fix | Delete
token.NEWLINE, tokenize.NL]:
[441] Fix | Delete
# warn if we see anything else than STRING or whitespace
[442] Fix | Delete
print(_(
[443] Fix | Delete
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
[444] Fix | Delete
) % {
[445] Fix | Delete
'token': tstring,
[446] Fix | Delete
'file': self.__curfile,
[447] Fix | Delete
'lineno': self.__lineno
[448] Fix | Delete
}, file=sys.stderr)
[449] Fix | Delete
self.__state = self.__waiting
[450] Fix | Delete
[451] Fix | Delete
def __addentry(self, msg, lineno=None, isdocstring=0):
[452] Fix | Delete
if lineno is None:
[453] Fix | Delete
lineno = self.__lineno
[454] Fix | Delete
if not msg in self.__options.toexclude:
[455] Fix | Delete
entry = (self.__curfile, lineno)
[456] Fix | Delete
self.__messages.setdefault(msg, {})[entry] = isdocstring
[457] Fix | Delete
[458] Fix | Delete
def set_filename(self, filename):
[459] Fix | Delete
self.__curfile = filename
[460] Fix | Delete
self.__freshmodule = 1
[461] Fix | Delete
[462] Fix | Delete
def write(self, fp):
[463] Fix | Delete
options = self.__options
[464] Fix | Delete
timestamp = time.strftime('%Y-%m-%d %H:%M%z')
[465] Fix | Delete
encoding = fp.encoding if fp.encoding else 'UTF-8'
[466] Fix | Delete
print(pot_header % {'time': timestamp, 'version': __version__,
[467] Fix | Delete
'charset': encoding,
[468] Fix | Delete
'encoding': '8bit'}, file=fp)
[469] Fix | Delete
# Sort the entries. First sort each particular entry's keys, then
[470] Fix | Delete
# sort all the entries by their first item.
[471] Fix | Delete
reverse = {}
[472] Fix | Delete
for k, v in self.__messages.items():
[473] Fix | Delete
keys = sorted(v.keys())
[474] Fix | Delete
reverse.setdefault(tuple(keys), []).append((k, v))
[475] Fix | Delete
rkeys = sorted(reverse.keys())
[476] Fix | Delete
for rkey in rkeys:
[477] Fix | Delete
rentries = reverse[rkey]
[478] Fix | Delete
rentries.sort()
[479] Fix | Delete
for k, v in rentries:
[480] Fix | Delete
# If the entry was gleaned out of a docstring, then add a
[481] Fix | Delete
# comment stating so. This is to aid translators who may wish
[482] Fix | Delete
# to skip translating some unimportant docstrings.
[483] Fix | Delete
isdocstring = any(v.values())
[484] Fix | Delete
# k is the message string, v is a dictionary-set of (filename,
[485] Fix | Delete
# lineno) tuples. We want to sort the entries in v first by
[486] Fix | Delete
# file name and then by line number.
[487] Fix | Delete
v = sorted(v.keys())
[488] Fix | Delete
if not options.writelocations:
[489] Fix | Delete
pass
[490] Fix | Delete
# location comments are different b/w Solaris and GNU:
[491] Fix | Delete
elif options.locationstyle == options.SOLARIS:
[492] Fix | Delete
for filename, lineno in v:
[493] Fix | Delete
d = {'filename': filename, 'lineno': lineno}
[494] Fix | Delete
print(_(
[495] Fix | Delete
'# File: %(filename)s, line: %(lineno)d') % d, file=fp)
[496] Fix | Delete
elif options.locationstyle == options.GNU:
[497] Fix | Delete
# fit as many locations on one line, as long as the
[498] Fix | Delete
# resulting line length doesn't exceed 'options.width'
[499] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function