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

Fix off-by-one issue in pretty-formatter #1665

Merged
merged 3 commits into from
Feb 7, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def _handle_sequence_obj(
# Convert each item to a pretty string.
items_as_str = tuple(
self._handle_any_obj(
list_item, remaining_line_width=max(0, remaining_line_width - len(self._indent_prefix))
list_item, remaining_line_width=max(1, remaining_line_width - len(self._indent_prefix))
)
for list_item in list_like_obj
)
Expand Down Expand Up @@ -216,7 +216,7 @@ def _handle_indented_key_value_item( # type: ignore[misc]
# ]

# See if the value fits in the previous line.
remaining_width_for_value = max(0, remaining_line_width - len(result_lines[-1]))
remaining_width_for_value = max(1, remaining_line_width - len(result_lines[-1]))
value_str = self._handle_any_obj(value, remaining_line_width=remaining_width_for_value)
value_lines = value_str.splitlines()

Expand Down Expand Up @@ -456,7 +456,7 @@ def mf_pformat_dict( # type: ignore
else:
value_str = mf_pformat(
obj=value,
max_line_length=max(0, max_line_length - len(indent_prefix)),
max_line_length=max(1, max_line_length - len(indent_prefix)),
indent_prefix=indent_prefix,
include_object_field_names=include_object_field_names,
include_none_object_fields=include_none_object_fields,
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

from metricflow_semantics.formatting.formatting_helpers import mf_dedent
from metricflow_semantics.mf_logging.lazy_formattable import LazyFormat
from tests_metricflow_semantics.mf_logging.recorded_logging_context import RecordingLogHandler, recorded_logging_context
from typing_extensions import override

from tests_metricflow_semantics.mf_logging.recorded_logging_context import RecordingLogHandler, recorded_logging_context

logger = logging.getLogger(__name__)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from __future__ import annotations

import logging
import textwrap

from metricflow_semantics.formatting.formatting_helpers import mf_dedent
from metricflow_semantics.mf_logging.pretty_print import mf_pformat_dict

logger = logging.getLogger(__name__)


def test_pformat_many() -> None: # noqa: D103
result = mf_pformat_dict("Example description:", obj_dict={"object_0": (1, 2, 3), "object_1": {4: 5}})

assert (
textwrap.dedent(
"""\
Example description:
object_0: (1, 2, 3)
object_1: {4: 5}
"""
).rstrip()
== result
)


def test_pformat_many_with_raw_strings() -> None: # noqa: D103
result = mf_pformat_dict("Example description:", obj_dict={"object_0": "foo\nbar"}, preserve_raw_strings=True)

assert (
textwrap.dedent(
"""\
Example description:
object_0:
foo
bar
"""
).rstrip()
== result
)


def test_pformat_dict_with_empty_message() -> None:
"""Test `mf_pformat_dict` without a description."""
result = mf_pformat_dict(obj_dict={"object_0": (1, 2, 3), "object_1": {4: 5}})

assert (
mf_dedent(
"""
object_0: (1, 2, 3)
object_1: {4: 5}
"""
)
== result
)


def test_pformat_dict_with_pad_sections_with_newline() -> None:
"""Test `mf_pformat_dict` with new lines between sections."""
result = mf_pformat_dict(obj_dict={"object_0": (1, 2, 3), "object_1": {4: 5}}, pad_items_with_newlines=True)

assert (
mf_dedent(
"""
object_0: (1, 2, 3)

object_1: {4: 5}
"""
)
== result
)


def test_pformat_many_with_strings() -> None: # noqa: D103
result = mf_pformat_dict("Example description:", obj_dict={"object_0": "foo\nbar"})
assert (
textwrap.dedent(
"""\
Example description:
object_0: 'foo\\nbar'
"""
).rstrip()
== result
)


def test_minimal_length() -> None:
"""Test where the max_line_length is the minimal length."""
assert mf_pformat_dict("Example output", {"foo": "bar"}, max_line_length=1) == mf_dedent(
"""
Example output
foo: 'bar'
"""
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

from dbt_semantic_interfaces.implementations.elements.dimension import PydanticDimension
from dbt_semantic_interfaces.type_enums import DimensionType
from metricflow_semantics.formatting.formatting_helpers import mf_dedent
from metricflow_semantics.mf_logging.formatting import indent
from metricflow_semantics.mf_logging.pretty_formattable import MetricFlowPrettyFormattable
from metricflow_semantics.mf_logging.pretty_print import mf_pformat, mf_pformat_dict
from metricflow_semantics.mf_logging.pretty_print import mf_pformat
from metricflow_semantics.test_helpers.metric_time_dimension import MTD_SPEC_DAY
from typing_extensions import override

Expand Down Expand Up @@ -146,50 +145,6 @@ def test_pydantic_model() -> None: # noqa: D103
)


def test_pformat_many() -> None: # noqa: D103
result = mf_pformat_dict("Example description:", obj_dict={"object_0": (1, 2, 3), "object_1": {4: 5}})

assert (
textwrap.dedent(
"""\
Example description:
object_0: (1, 2, 3)
object_1: {4: 5}
"""
).rstrip()
== result
)


def test_pformat_many_with_raw_strings() -> None: # noqa: D103
result = mf_pformat_dict("Example description:", obj_dict={"object_0": "foo\nbar"}, preserve_raw_strings=True)

assert (
textwrap.dedent(
"""\
Example description:
object_0:
foo
bar
"""
).rstrip()
== result
)


def test_pformat_many_with_strings() -> None: # noqa: D103
result = mf_pformat_dict("Example description:", obj_dict={"object_0": "foo\nbar"})
assert (
textwrap.dedent(
"""\
Example description:
object_0: 'foo\\nbar'
"""
).rstrip()
== result
)


def test_custom_pretty_print() -> None:
"""Check that `MetricFlowPrettyFormattable` can be used to override the result when using MF's pretty-printer."""

Expand All @@ -204,34 +159,3 @@ def pretty_format(self) -> Optional[str]:
return f"{self.__class__.__name__}({self.field_0:.2f})"

assert mf_pformat(_ExampleDataclass(1.2345)) == f"{_ExampleDataclass.__name__}(1.23)"


def test_pformat_dict_with_empty_message() -> None:
"""Test `mf_pformat_dict` without a description."""
result = mf_pformat_dict(obj_dict={"object_0": (1, 2, 3), "object_1": {4: 5}})

assert (
mf_dedent(
"""
object_0: (1, 2, 3)
object_1: {4: 5}
"""
)
== result
)


def test_pformat_dict_with_pad_sections_with_newline() -> None:
"""Test `mf_pformat_dict` with new lines between sections."""
result = mf_pformat_dict(obj_dict={"object_0": (1, 2, 3), "object_1": {4: 5}}, pad_items_with_newlines=True)

assert (
mf_dedent(
"""
object_0: (1, 2, 3)

object_1: {4: 5}
"""
)
== result
)