diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-08-27 09:19:21 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-08-27 09:26:05 +0300 |
commit | fef8a8d013c3cb51b6b3ed80e1ef5913d9ebe0ef (patch) | |
tree | 32c33d1bdfc4ddb3cdf82c0c9fba15708aacaeeb | |
parent | e5779e5f924155a97c86d80c14359136075d1da8 (diff) | |
download | ydb-fef8a8d013c3cb51b6b3ed80e1ef5913d9ebe0ef.tar.gz |
Intermediate changes
-rw-r--r-- | contrib/python/prettytable/py3/.dist-info/METADATA | 12 | ||||
-rw-r--r-- | contrib/python/prettytable/py3/README.md | 10 | ||||
-rw-r--r-- | contrib/python/prettytable/py3/prettytable/prettytable.py | 97 | ||||
-rw-r--r-- | contrib/python/prettytable/py3/tests/test_prettytable.py | 267 | ||||
-rw-r--r-- | contrib/python/prettytable/py3/ya.make | 2 |
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><em>Field 2</em></th> + <th><a href='#'>Field 3</a></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><b>value 1</b></td> + <td><span style='text-decoration: underline;'>value2</span></td> + <td><a href='#'>value3</a></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"><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_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"><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 + ) + 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) |