Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-79516: allow msgfmt.py to compile multiple input po files#10875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
s-ball wants to merge68 commits intopython:main
base:main
Choose a base branch
Loading
froms-ball:multi_inputs
Open
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
68 commits
Select commitHold shift + click to select a range
73b5ac8
Add test for current behaviour of msgfmt.py
s-ballDec 2, 2018
5fb1575
Final fix for bpo-9741, with tests proving it.
s-ballDec 2, 2018
b1968e9
Update docstrings for the script and make function
s-ballDec 2, 2018
0bc4ad3
Give make a simpler and more consistent interface.
s-ballDec 4, 2018
a9e67b4
Add a Misc/NEWS.d entry.
s-ballDec 5, 2018
6c59d6c
Merge branch 'multi_inputs' of https://github.com/s-ball/cpython into…
s-ballDec 5, 2018
1ce22c0
Merge branch 'main' into multi_inputs
s-ballJan 23, 2025
863bd97
Merge branch 'main' into multi_inputs
s-ballJan 23, 2025
4390ede
Fix an import error in test_i18n.py .
s-ballJan 23, 2025
008ea27
Fix another import error.
s-ballJan 23, 2025
8744743
Merge branch 'main' into multi_inputs
s-ballJan 23, 2025
93a6eb7
Merge branch 'main' into multi_inputs
s-ballFeb 23, 2025
ba26b80
Revert version number to 1.2
s-ballFeb 23, 2025
150cea1
Merge branch 'main' into multi_inputs
s-ballFeb 23, 2025
d9afabb
Merge branch 'main' into multi_inputs
s-ballFeb 24, 2025
9004387
Merge branch 'main' into multi_inputs
s-ballFeb 24, 2025
7556f79
Merge branch 'multi_inputs' of https://github.com/s-ball/cpython into…
s-ballFeb 27, 2025
80947d1
Merge branch 'main' into multi_inputs
s-ballFeb 27, 2025
12acb83
Merge branch 'main' into multi_inputs
s-ballFeb 27, 2025
1ecc1f3
Fix a merge error
s-ballFeb 27, 2025
e59ba68
Merge branch 'multi_inputs' of https://github.com/s-ball/cpython into…
s-ballFeb 27, 2025
4ffd20a
Merge branch 'main' into multi_inputs
s-ballFeb 27, 2025
7505f2b
Merge branch 'main' into multi_inputs
s-ballFeb 28, 2025
2c27120
Merge branch 'main' into multi_inputs
s-ballFeb 28, 2025
1f4e5ac
fix details
merwokFeb 28, 2025
4170796
Merge branch 'main' into multi_inputs
s-ballMar 1, 2025
46c08c5
Move tests for the gh-79516 issue to test_msgfmt.py
s-ballMar 1, 2025
24d89a6
Cosmetic improvements after review.
s-ballMar 1, 2025
17b4e05
Fix an import error
s-ballMar 1, 2025
bfc8a44
Merge branch 'main' into multi_inputs
s-ballMar 1, 2025
106dd40
Apply suggestions from code review
s-ballMar 2, 2025
9cb9395
Cosmetic improvements after review.
s-ballMar 2, 2025
08bc8d7
In test_msgfmt move data files to the data folder.
s-ballMar 2, 2025
9d992cd
Remove duplicate tests from test_msgfmt.
s-ballMar 2, 2025
31fd434
Merge branch 'main' into multi_inputs
s-ballMar 2, 2025
916aec7
Merge branch 'main' into multi_inputs
s-ballMar 2, 2025
51fcf09
Rename data files for test_msgfmt.Test_multi_input
s-ballMar 3, 2025
d51ad50
Apply suggestions from code review
s-ballMar 3, 2025
677f720
Cosmetic improvements after review.
s-ballMar 3, 2025
b4ea80a
compile_messages now accepts several input files
s-ballMar 4, 2025
3120add
whitespace nit
merwokMar 4, 2025
d642923
Merge branch 'main' into multi_inputs
s-ballMar 4, 2025
9d91f12
Make explicit how mo files can be re-generated.
s-ballMar 4, 2025
4d83cb7
Merge branch 'multi_inputs' of https://github.com/s-ball/cpython into…
s-ballMar 4, 2025
421272b
Apply suggestions from code review
s-ballMar 4, 2025
09b97d9
Update Lib/test/test_tools/test_msgfmt.py
s-ballMar 4, 2025
12cae51
Merge branch 'main' into multi_inputs
s-ballMar 5, 2025
3760851
Merge branch 'main' into multi_inputs
s-ballMar 15, 2025
d45039c
Generate json files for MultiInputTest data files.
s-ballMar 16, 2025
dde5ef1
Apply suggestions from code review
s-ballMar 16, 2025
bb6e0c5
Cosmetic improvements (long lines...)
s-ballMar 16, 2025
797990a
Merge branch 'multi_inputs' of https://github.com/s-ball/cpython into…
s-ballMar 16, 2025
c95af16
Merge branch 'main' into multi_inputs
s-ballMar 17, 2025
905ec70
Revert an unwanted change.
s-ballMar 17, 2025
b7a7c48
Simplifies the general logic of msgfmt.py
s-ballMar 18, 2025
1b3b73e
Update Tools/i18n/msgfmt.py
s-ballMar 18, 2025
1db2c66
Changes per review.
s-ballMar 18, 2025
3a6e1ef
Merge branch 'multi_inputs' of https://github.com/s-ball/cpython into…
s-ballMar 18, 2025
743bdc5
Removes the now unused get_names function.
s-ballMar 19, 2025
50e7145
Tests for extension corner cases for msgfmt.py
s-ballMar 19, 2025
caa8955
Merge branch 'main' into multi_inputs
s-ballApr 4, 2025
a4f1769
Fix a parameter inversion in test_msgfmt.py
s-ballApr 4, 2025
11f6e69
Merge branch 'main' into multi_inputs
s-ballApr 4, 2025
0ed3107
Merge branch 'main' into multi_inputs
s-ballApr 8, 2025
d1e0a26
Merge branch 'main' into multi_inputs
s-ballApr 8, 2025
213afcb
Merge branch 'main' into multi_inputs
s-ballMay 20, 2025
4d54e50
Merge main into multi_inputs
s-ballMay 22, 2025
ab97edd
Merge branch 'main' into multi_inputs
s-ballMay 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Final fix forbpo-9741, with tests proving it.
Also show that it is now possible to build multiple po files in onesingle script call.
  • Loading branch information
@s-ball
s-ball committedDec 2, 2018
commit5fb1575c1b812741a4c4f99787ec09bbd2f9893d
32 changes: 32 additions & 0 deletionsLib/test/test_tools/test_i18n.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -424,3 +424,35 @@ def test_both_with_outputfile(self):
'file1_fr.po', 'file2_fr.po')
with open('file1.mo', 'rb') as fin:
self.assertEqual(self.file12_fr_mo, fin.read())

def test_both_without_outputfile(self):
"""Test script without -o option and 2 input files"""
# msgfmt.py version 1.2 behaviour was that second mo file
# also merged previous po files
with temp_cwd(None):
with open("file1_fr.po", "wb") as out:
out.write(self.file1_fr_po)
with open("file2_fr.po", "wb") as out:
out.write(self.file2_fr_po)
assert_python_ok(self.script, 'file1_fr.po', 'file2_fr.po')
with open('file1_fr.mo', 'rb') as fin:
self.assertEqual(self.file1_fr_mo, fin.read())
with open('file2_fr.mo', 'rb') as fin:
self.assertEqual(self.file2_fr_mo, fin.read())

def test_consecutive_make_calls(self):
"""Directly calls make twice to prove bpo-9741 is fixed"""
sys.path.append(os.path.join(toolsdir,'i18n'))
from msgfmt import make
with temp_cwd(None):
with open("file1_fr.po", "wb") as out:
out.write(self.file1_fr_po)
with open("file2_fr.po", "wb") as out:
out.write(self.file2_fr_po)
make("file1_fr.po", "file1_fr.mo")
make("file2_fr.po", "file2_fr.mo")
with open('file1_fr.mo', 'rb') as fin:
self.assertEqual(self.file1_fr_mo, fin.read())
with open('file2_fr.mo', 'rb') as fin:
self.assertEqual(self.file2_fr_mo, fin.read())
sys.path.pop()
72 changes: 44 additions & 28 deletionsTools/i18n/msgfmt.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
#! /usr/bin/env python3
# Written by Martin v. Löwis <loewis@informatik.hu-berlin.de>

# Version 1.3 by s-ball <s-ball@laposte.net>
"""Generate binary message catalog from textual translation description.

This program converts a textual Uniforum-style message catalog (.po file) into
Expand DownExpand Up@@ -33,7 +33,7 @@
import array
from email.parser import HeaderParser

__version__ = "1.2"
__version__ = "1.3"

MESSAGES = {}

Expand All@@ -45,29 +45,27 @@ def usage(code, msg=''):
sys.exit(code)


def add(ctxt, id, str, fuzzy):
def add(ctxt, id, str, fuzzy, messages):
"Add a non-fuzzy translation to the dictionary."
global MESSAGES
if not fuzzy and str:
if ctxt is None:
MESSAGES[id] = str
messages[id] = str
else:
MESSAGES[b"%b\x04%b" % (ctxt, id)] = str
messages[b"%b\x04%b" % (ctxt, id)] = str


def generate():
def generate(messages):
"Return the generated output."
global MESSAGES
# the keys are sorted in the .mo file
keys = sorted(MESSAGES.keys())
keys = sorted(messages.keys())
offsets = []
ids = strs = b''
for id in keys:
# For each string, we need size and file offset. Each string is NUL
# terminated; the NUL does not count into the size.
offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id])))
offsets.append((len(ids), len(id), len(strs), len(messages[id])))
ids += id + b'\0'
strs +=MESSAGES[id] + b'\0'
strs +=messages[id] + b'\0'
output = ''
# The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables.
Expand DownExpand Up@@ -96,18 +94,40 @@ def generate():
return output


def make(filename, outfile):
ID = 1
STR = 2
CTXT = 3
def make(filenames, outfile):
messages = {}
if isinstance(filenames, str):
infile, outfile = get_names(filenames, outfile)
process(infile, messages)
elif outfile is None:
for filename in filenames:
infile, outfile = get_names(filename, None)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Now we can refactorget_names(). Split it on two parts -- for infile and for outfile. The first part can be inlined and moved inprocess(), and the second part can be left here, inmake().

messages.clear()
process(infile, messages)
output = generate(messages)
writefile(outfile, output)
return
else:
for filename in filenames:
infile, _ = get_names(filename, outfile)
process(infile, messages)
output = generate(messages)
writefile(outfile, output)

def get_names(filename, outfile):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It is no longer used.

# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
infile = filename
else:
infile = filename + '.po'
if outfile is None:
outfile = os.path.splitext(infile)[0] + '.mo'
return infile, outfile

def process(infile, messages):
ID = 1
STR = 2
CTXT = 3

try:
with open(infile, 'rb') as f:
Expand All@@ -130,7 +150,7 @@ def make(filename, outfile):
lno += 1
# If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == STR:
add(msgctxt, msgid, msgstr, fuzzy)
add(msgctxt, msgid, msgstr, fuzzy, messages)
section = msgctxt = None
fuzzy = 0
# Record a fuzzy mark
Expand All@@ -142,13 +162,13 @@ def make(filename, outfile):
# Now we are in a msgid or msgctxt section, output previous section
if l.startswith('msgctxt'):
if section == STR:
add(msgctxt, msgid, msgstr, fuzzy)
add(msgctxt, msgid, msgstr, fuzzy, messages)
section = CTXT
l = l[7:]
msgctxt = b''
elif l.startswith('msgid') and not l.startswith('msgid_plural'):
if section == STR:
add(msgctxt, msgid, msgstr, fuzzy)
add(msgctxt, msgid, msgstr, fuzzy, messages)
if not msgid:
# See whether there is an encoding declaration
p = HeaderParser()
Expand DownExpand Up@@ -203,21 +223,19 @@ def make(filename, outfile):
sys.exit(1)
# Add last entry
if section == STR:
add(msgctxt, msgid, msgstr, fuzzy)

# Compute output
output = generate()
add(msgctxt, msgid, msgstr, fuzzy, messages)

def writefile(outfile, output):
try:
with open(outfile,"wb") as f:
f.write(output)
except IOError as msg:
print(msg, file=sys.stderr)


def main():
def main(argv):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
defmain(argv):
defmain():

Why change this? sys.argv is more common in stdlib/tools from my experience.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I thought that passing argv that way allowed simpler tests for the decoding of the command line. But as you are more experimented in CPython than I am, I shall follow your advice :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That’s right but only for tests that import and call a main function, not when calling as a script 🙂

try:
opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
opts, args = getopt.getopt(argv, 'hVo:',
['help', 'version', 'output-file='])
except getopt.error as msg:
usage(1, msg)
Expand All@@ -237,10 +255,8 @@ def main():
print('No input file given', file=sys.stderr)
print("Try `msgfmt --help' for more information.", file=sys.stderr)
return

for filename in args:
make(filename, outfile)
make(args, outfile)


if __name__ == '__main__':
main()
main(sys.argv[1:])

[8]ページ先頭

©2009-2025 Movatter.jp