Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent wrapping file locations containing white space #1120

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions babel/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import re
import textwrap
from collections.abc import Generator, Iterable
from itertools import chain
from typing import IO, Any, TypeVar

from babel import dates, localtime
Expand Down Expand Up @@ -205,6 +206,24 @@ class TextWrapper(textwrap.TextWrapper):
r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))', # em-dash
)

# e.g. '\u2068foo bar.py\u2069:42'
_enclosed_filename_re = re.compile(r'(\u2068[^\u2068]+?\u2069(?::-?\d+)?)')

def _split(self, text):
"""Splits the text into indivisible chunks while ensuring that file names
containing spaces are not broken up.
"""
enclosed_filename_start = '\u2068'
if enclosed_filename_start not in text:
# There are no file names which contain spaces, fallback to the default implementation
return super()._split(text)

super_ = super() # Python 3.9 fix, super() does not work in list comprehension
chunks = re.split(self._enclosed_filename_re, text)
chunks = [[c] if c.startswith(enclosed_filename_start) else super_._split(c) for c in chunks]
chunks = [c for c in chain.from_iterable(chunks) if c]
return chunks


def wraptext(text: str, width: int = 70, initial_indent: str = '', subsequent_indent: str = '') -> list[str]:
"""Simple wrapper around the ``textwrap.wrap`` function in the standard
Expand Down
13 changes: 13 additions & 0 deletions tests/messages/test_pofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,19 @@ def test_tab_in_location_already_enclosed(self):
msgstr ""'''


def test_wrap_with_enclosed_file_locations(self):
# Ensure that file names containing white space are not wrapped regardless of the --width parameter
catalog = Catalog()
catalog.add('foo', locations=[('\u2068test utils.py\u2069', 1)])
catalog.add('foo', locations=[('\u2068test utils.py\u2069', 3)])
buf = BytesIO()
pofile.write_po(buf, catalog, omit_header=True, include_lineno=True, width=1)
assert buf.getvalue().strip() == b'''#: \xe2\x81\xa8test utils.py\xe2\x81\xa9:1
#: \xe2\x81\xa8test utils.py\xe2\x81\xa9:3
msgid "foo"
msgstr ""'''


class RoundtripPoTestCase(unittest.TestCase):

def test_enclosed_filenames_in_location_comment(self):
Expand Down