aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-08-27 09:19:21 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-08-27 09:26:05 +0300
commitfef8a8d013c3cb51b6b3ed80e1ef5913d9ebe0ef (patch)
tree32c33d1bdfc4ddb3cdf82c0c9fba15708aacaeeb
parente5779e5f924155a97c86d80c14359136075d1da8 (diff)
downloadydb-fef8a8d013c3cb51b6b3ed80e1ef5913d9ebe0ef.tar.gz
Intermediate changes
-rw-r--r--contrib/python/prettytable/py3/.dist-info/METADATA12
-rw-r--r--contrib/python/prettytable/py3/README.md10
-rw-r--r--contrib/python/prettytable/py3/prettytable/prettytable.py97
-rw-r--r--contrib/python/prettytable/py3/tests/test_prettytable.py267
-rw-r--r--contrib/python/prettytable/py3/ya.make2
5 files changed, 368 insertions, 20 deletions
diff --git a/contrib/python/prettytable/py3/.dist-info/METADATA b/contrib/python/prettytable/py3/.dist-info/METADATA
index 47a7f8e093..6df980cfd8 100644
--- a/contrib/python/prettytable/py3/.dist-info/METADATA
+++ b/contrib/python/prettytable/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.3
Name: prettytable
-Version: 3.10.2
+Version: 3.11.0
Summary: A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
Project-URL: Changelog, https://github.com/jazzband/prettytable/releases
Project-URL: Homepage, https://github.com/jazzband/prettytable
@@ -707,6 +707,16 @@ will print:
</table>
```
+#### Setting HTML escaping
+
+By default, PrettyTable will escape the data contained in the header and data fields
+when sending output to HTML. This can be disabled by setting the `escape_header` and
+`escape_data` to false. For example:
+
+```python
+print(table.get_html_string(escape_header=False, escape_data=False))
+```
+
### Miscellaneous things
#### Copying a table
diff --git a/contrib/python/prettytable/py3/README.md b/contrib/python/prettytable/py3/README.md
index aa442709f4..bb365317da 100644
--- a/contrib/python/prettytable/py3/README.md
+++ b/contrib/python/prettytable/py3/README.md
@@ -675,6 +675,16 @@ will print:
</table>
```
+#### Setting HTML escaping
+
+By default, PrettyTable will escape the data contained in the header and data fields
+when sending output to HTML. This can be disabled by setting the `escape_header` and
+`escape_data` to false. For example:
+
+```python
+print(table.get_html_string(escape_header=False, escape_data=False))
+```
+
### Miscellaneous things
#### Copying a table
diff --git a/contrib/python/prettytable/py3/prettytable/prettytable.py b/contrib/python/prettytable/py3/prettytable/prettytable.py
index 62a1df1df2..7f5dacb58a 100644
--- a/contrib/python/prettytable/py3/prettytable/prettytable.py
+++ b/contrib/python/prettytable/py3/prettytable/prettytable.py
@@ -188,6 +188,8 @@ class PrettyTable:
"max_width",
"min_width",
"none_format",
+ "escape_header",
+ "escape_data",
]
for option in self._options:
if option in kwargs:
@@ -224,6 +226,14 @@ class PrettyTable:
self._reversesort = False
self._sort_key = kwargs["sort_key"] or (lambda x: x)
+ if kwargs["escape_data"] in (True, False):
+ self._escape_data = kwargs["escape_data"]
+ else:
+ self._escape_data = True
+ if kwargs["escape_header"] in (True, False):
+ self._escape_header = kwargs["escape_header"]
+ else:
+ self._escape_header = True
# Column specific arguments, use property.setters
self.align = kwargs["align"] or {}
self.valign = kwargs["valign"] or {}
@@ -380,6 +390,8 @@ class PrettyTable:
"xhtml",
"print_empty",
"oldsortslice",
+ "escape_header",
+ "escape_data",
):
self._validate_true_or_false(option, val)
elif option == "header_style":
@@ -1252,6 +1264,26 @@ class PrettyTable:
self._validate_option("oldsortslice", val)
self._oldsortslice = val
+ @property
+ def escape_header(self):
+ """Escapes the text within a header (True or False)"""
+ return self._escape_header
+
+ @escape_header.setter
+ def escape_header(self, val):
+ self._validate_option("escape_header", val)
+ self._escape_header = val
+
+ @property
+ def escape_data(self):
+ """Escapes the text within a data field (True or False)"""
+ return self._escape_data
+
+ @escape_data.setter
+ def escape_data(self, val):
+ self._validate_option("escape_data", val)
+ self._escape_data = val
+
##############################
# OPTION MIXER #
##############################
@@ -2087,8 +2119,20 @@ class PrettyTable:
csv_writer = csv.writer(csv_buffer, **csv_options)
if options.get("header"):
- csv_writer.writerow(self._field_names)
- for row in self._get_rows(options):
+ if options["fields"]:
+ csv_writer.writerow(
+ [f for f in self._field_names if f in options["fields"]]
+ )
+ else:
+ csv_writer.writerow(self._field_names)
+
+ rows = self._get_rows(options)
+ if options["fields"]:
+ rows = [
+ [d for f, d in zip(self._field_names, row) if f in options["fields"]]
+ for row in rows
+ ]
+ for row in rows:
csv_writer.writerow(row)
return csv_buffer.getvalue()
@@ -2112,12 +2156,26 @@ class PrettyTable:
json_options.update(
{key: value for key, value in kwargs.items() if key not in options}
)
- objects = []
+ objects: list[list[str] | dict[str, Any]] = []
if options.get("header"):
- objects.append(self.field_names)
- for row in self._get_rows(options):
- objects.append(dict(zip(self._field_names, row)))
+ if options["fields"]:
+ objects.append([f for f in self._field_names if f in options["fields"]])
+ else:
+ objects.append(self.field_names)
+ rows = self._get_rows(options)
+ if options["fields"]:
+ for row in rows:
+ objects.append(
+ {
+ f: d
+ for f, d in zip(self._field_names, row)
+ if f in options["fields"]
+ }
+ )
+ else:
+ for row in rows:
+ objects.append(dict(zip(self._field_names, row)))
return json.dumps(objects, **json_options)
@@ -2136,6 +2194,7 @@ class PrettyTable:
end - index of last data row to include in output PLUS ONE (list slice style)
fields - names of fields (columns) to include
header - print a header showing field names (True or False)
+ escape_header - escapes the text within a header (True or False)
border - print a border around the table (True or False)
preserve_internal_border - print a border inside the table even if
border is disabled (True or False)
@@ -2156,6 +2215,7 @@ class PrettyTable:
<table> tag
format - Controls whether or not HTML tables are formatted to match
styling options (True or False)
+ escape_data - escapes the text within a data field (True or False)
xhtml - print <br/> tags if True, <br> tags if False"""
options = self._get_options(kwargs)
@@ -2197,11 +2257,13 @@ class PrettyTable:
for field in self._field_names:
if options["fields"] and field not in options["fields"]:
continue
+ if options["escape_header"]:
+ field = escape(field)
+
lines.append(
- " <th>{}</th>".format(
- escape(field).replace("\n", linebreak)
- )
+ " <th>{}</th>".format(field.replace("\n", linebreak))
)
+
lines.append(" </tr>")
lines.append(" </thead>")
@@ -2214,10 +2276,11 @@ class PrettyTable:
for field, datum in zip(self._field_names, row):
if options["fields"] and field not in options["fields"]:
continue
+ if options["escape_data"]:
+ datum = escape(datum)
+
lines.append(
- " <td>{}</td>".format(
- escape(datum).replace("\n", linebreak)
- )
+ " <td>{}</td>".format(datum.replace("\n", linebreak))
)
lines.append(" </tr>")
lines.append(" </tbody>")
@@ -2273,9 +2336,12 @@ class PrettyTable:
for field in self._field_names:
if options["fields"] and field not in options["fields"]:
continue
+ if options["escape_header"]:
+ field = escape(field)
+
lines.append(
' <th style="padding-left: %dem; padding-right: %dem; text-align: center">%s</th>' # noqa: E501
- % (lpad, rpad, escape(field).replace("\n", linebreak))
+ % (lpad, rpad, field.replace("\n", linebreak))
)
lines.append(" </tr>")
lines.append(" </thead>")
@@ -2300,6 +2366,9 @@ class PrettyTable:
):
if options["fields"] and field not in options["fields"]:
continue
+ if options["escape_data"]:
+ datum = escape(datum)
+
lines.append(
' <td style="padding-left: %dem; padding-right: %dem; text-align: %s; vertical-align: %s">%s</td>' # noqa: E501
% (
@@ -2307,7 +2376,7 @@ class PrettyTable:
rpad,
align,
valign,
- escape(datum).replace("\n", linebreak),
+ datum.replace("\n", linebreak),
)
)
lines.append(" </tr>")
diff --git a/contrib/python/prettytable/py3/tests/test_prettytable.py b/contrib/python/prettytable/py3/tests/test_prettytable.py
index 9b51e4a2ce..5cebb89521 100644
--- a/contrib/python/prettytable/py3/tests/test_prettytable.py
+++ b/contrib/python/prettytable/py3/tests/test_prettytable.py
@@ -40,7 +40,7 @@ def test_version() -> None:
assert prettytable.__version__[-1].isdigit()
-def helper_table(rows: int = 3) -> PrettyTable:
+def helper_table(*, rows: int = 3) -> PrettyTable:
table = PrettyTable(["", "Field 1", "Field 2", "Field 3"])
v = 1
for row in range(rows):
@@ -1023,6 +1023,30 @@ class TestJSONOutput:
}
]""".strip()
)
+ options = {"fields": ["Field 1", "Field 3"]}
+ result = t.get_json_string(**options)
+ assert (
+ result.strip()
+ == """
+[
+ [
+ "Field 1",
+ "Field 3"
+ ],
+ {
+ "Field 1": "value 1",
+ "Field 3": "value3"
+ },
+ {
+ "Field 1": "value 4",
+ "Field 3": "value6"
+ },
+ {
+ "Field 1": "value 7",
+ "Field 3": "value9"
+ }
+]""".strip()
+ )
def test_json_output_options(self) -> None:
t = helper_table()
@@ -1198,6 +1222,234 @@ class TestHtmlOutput:
""".strip() # noqa: E501
)
+ def test_html_output_without_escaped_header(self) -> None:
+ t = helper_table(rows=0)
+ t.field_names = ["", "Field 1", "<em>Field 2</em>", "<a href='#'>Field 3</a>"]
+ result = t.get_html_string(escape_header=False)
+ assert (
+ result.strip()
+ == """
+<table>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Field 1</th>
+ <th><em>Field 2</em></th>
+ <th><a href='#'>Field 3</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+</table>
+""".strip()
+ )
+
+ def test_html_output_without_escaped_data(self) -> None:
+ t = helper_table(rows=0)
+ t.add_row(
+ [
+ 1,
+ "<b>value 1</b>",
+ "<span style='text-decoration: underline;'>value2</span>",
+ "<a href='#'>value3</a>",
+ ]
+ )
+ result = t.get_html_string(escape_data=False)
+ assert (
+ result.strip()
+ == """
+<table>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Field 1</th>
+ <th>Field 2</th>
+ <th>Field 3</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td><b>value 1</b></td>
+ <td><span style='text-decoration: underline;'>value2</span></td>
+ <td><a href='#'>value3</a></td>
+ </tr>
+ </tbody>
+</table>
+""".strip()
+ )
+
+ def test_html_output_with_escaped_header(self) -> None:
+ t = helper_table(rows=0)
+ t.field_names = ["", "Field 1", "<em>Field 2</em>", "<a href='#'>Field 3</a>"]
+ result = t.get_html_string(escape_header=True)
+ assert (
+ result.strip()
+ == """
+<table>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Field 1</th>
+ <th>&lt;em&gt;Field 2&lt;/em&gt;</th>
+ <th>&lt;a href=&#x27;#&#x27;&gt;Field 3&lt;/a&gt;</th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+</table>
+""".strip()
+ )
+
+ def test_html_output_with_escaped_data(self) -> None:
+ t = helper_table(rows=0)
+ t.add_row(
+ [
+ 1,
+ "<b>value 1</b>",
+ "<span style='text-decoration: underline;'>value2</span>",
+ "<a href='#'>value3</a>",
+ ]
+ )
+ result = t.get_html_string(escape_data=True)
+ assert (
+ result.strip()
+ == """
+<table>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Field 1</th>
+ <th>Field 2</th>
+ <th>Field 3</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td>&lt;b&gt;value 1&lt;/b&gt;</td>
+ <td>&lt;span style=&#x27;text-decoration: underline;&#x27;&gt;value2&lt;/span&gt;</td>
+ <td>&lt;a href=&#x27;#&#x27;&gt;value3&lt;/a&gt;</td>
+ </tr>
+ </tbody>
+</table>
+""".strip() # noqa: E501
+ )
+
+ def test_html_output_formatted_without_escaped_header(self) -> None:
+ t = helper_table(rows=0)
+ t.field_names = ["", "Field 1", "<em>Field 2</em>", "<a href='#'>Field 3</a>"]
+ result = t.get_html_string(escape_header=False, format=True)
+ assert (
+ result.strip()
+ == """
+<table frame="box" rules="cols">
+ <thead>
+ <tr>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center"></th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 1</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center"><em>Field 2</em></th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center"><a href='#'>Field 3</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+</table>
+""".strip() # noqa: E501
+ )
+
+ def test_html_output_formatted_without_escaped_data(self) -> None:
+ t = helper_table(rows=0)
+ t.add_row(
+ [
+ 1,
+ "<b>value 1</b>",
+ "<span style='text-decoration: underline;'>value2</span>",
+ "<a href='#'>value3</a>",
+ ]
+ )
+ result = t.get_html_string(escape_data=False, format=True)
+ assert (
+ result.strip()
+ == """
+<table frame="box" rules="cols">
+ <thead>
+ <tr>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center"></th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 1</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 2</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 3</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top">1</td>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top"><b>value 1</b></td>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top"><span style='text-decoration: underline;'>value2</span></td>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top"><a href='#'>value3</a></td>
+ </tr>
+ </tbody>
+</table>
+""".strip() # noqa: E501
+ )
+
+ def test_html_output_formatted_with_escaped_header(self) -> None:
+ t = helper_table(rows=0)
+ t.field_names = ["", "Field 1", "<em>Field 2</em>", "<a href='#'>Field 3</a>"]
+ result = t.get_html_string(escape_header=True, format=True)
+ assert (
+ result.strip()
+ == """
+<table frame="box" rules="cols">
+ <thead>
+ <tr>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center"></th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 1</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">&lt;em&gt;Field 2&lt;/em&gt;</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">&lt;a href=&#x27;#&#x27;&gt;Field 3&lt;/a&gt;</th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+</table>
+""".strip() # noqa: E501
+ )
+
+ def test_html_output_formatted_with_escaped_data(self) -> None:
+ t = helper_table(rows=0)
+ t.add_row(
+ [
+ 1,
+ "<b>value 1</b>",
+ "<span style='text-decoration: underline;'>value2</span>",
+ "<a href='#'>value3</a>",
+ ]
+ )
+ result = t.get_html_string(escape_data=True, format=True)
+ assert (
+ result.strip()
+ == """
+<table frame="box" rules="cols">
+ <thead>
+ <tr>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center"></th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 1</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 2</th>
+ <th style="padding-left: 1em; padding-right: 1em; text-align: center">Field 3</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top">1</td>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top">&lt;b&gt;value 1&lt;/b&gt;</td>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top">&lt;span style=&#x27;text-decoration: underline;&#x27;&gt;value2&lt;/span&gt;</td>
+ <td style="padding-left: 1em; padding-right: 1em; text-align: center; vertical-align: top">&lt;a href=&#x27;#&#x27;&gt;value3&lt;/a&gt;</td>
+ </tr>
+ </tbody>
+</table>
+""".strip() # noqa: E501
+ )
+
class TestPositionalJunctions:
"""Verify different cases for positional-junction characters"""
@@ -1522,6 +1774,13 @@ class TestCsvOutput:
"4,value 4,value5,value6\r\n"
"7,value 7,value8,value9\r\n"
)
+ options = {"fields": ["Field 1", "Field 3"]}
+ assert t.get_csv_string(**options) == (
+ "Field 1,Field 3\r\n"
+ "value 1,value3\r\n"
+ "value 4,value6\r\n"
+ "value 7,value9\r\n"
+ )
class TestLatexOutput:
@@ -2221,7 +2480,7 @@ class TestClearing:
class TestPreservingInternalBorders:
def test_internal_border_preserved(self) -> None:
- pt = helper_table(3)
+ pt = helper_table()
pt.border = False
pt.preserve_internal_border = True
@@ -2237,7 +2496,7 @@ class TestPreservingInternalBorders:
)
def test_internal_border_preserved_latex(self) -> None:
- pt = helper_table(3)
+ pt = helper_table()
pt.border = False
pt.format = True
pt.preserve_internal_border = True
@@ -2252,7 +2511,7 @@ class TestPreservingInternalBorders:
)
def test_internal_border_preserved_html(self) -> None:
- pt = helper_table(3)
+ pt = helper_table()
pt.format = True
pt.border = False
pt.preserve_internal_border = True
diff --git a/contrib/python/prettytable/py3/ya.make b/contrib/python/prettytable/py3/ya.make
index c44b0c331b..108de3e08a 100644
--- a/contrib/python/prettytable/py3/ya.make
+++ b/contrib/python/prettytable/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(3.10.2)
+VERSION(3.11.0)
LICENSE(BSD-3-Clause)