Skip to content
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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ classifiers = [
]
dependencies = [
"azure-identity>=1.22.0",
"black>=25.12.0",
"colorama>=0.4.6",
"mcp[cli]>=1.12.1",
"numpy>=2.2.6",
Expand Down Expand Up @@ -81,6 +80,7 @@ known_local_folder = ["conftest"]
dev = [
"azure-mgmt-authorization>=4.0.0",
"azure-mgmt-keyvault>=12.1.1",
"black>=25.12.0",
"coverage[toml]>=7.9.1",
"google-api-python-client>=2.184.0",
"google-auth-httplib2>=0.2.0",
Expand Down
21 changes: 9 additions & 12 deletions src/typeagent/aitools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,24 @@ def timelog(label: str, verbose: bool = True):


def pretty_print(obj: object, prefix: str = "", suffix: str = "") -> None:
"""Pretty-print an object using black.
"""Pretty-print an object using pprint."""
import pprint

NOTE: Only works if its repr() is a valid Python expression.
"""
print(prefix + format_code(repr(obj)) + suffix)
line_width = min(200, shutil.get_terminal_size().columns)
print(pprint.pformat(obj, width=line_width))


def format_code(text: str, line_width=None) -> str:
"""Format a block of code using black, then reindent to 2 spaces.
"""Format a Python literal expression using pprint.

NOTE: The text must be a valid Python expression or code block.
NOTE: The text must be a valid Python literal expression (as produced by repr()).
"""
import black
import ast
import pprint

if line_width is None:
# Use the terminal width, but cap it to 200 characters.
line_width = min(200, shutil.get_terminal_size().columns)
formatted_text = black.format_str(
text, mode=black.Mode(line_length=line_width)
).rstrip()
return reindent(formatted_text)
return pprint.pformat(ast.literal_eval(text), width=line_width)


def reindent(text: str) -> str:
Expand Down
4 changes: 2 additions & 2 deletions src/typeagent/knowpro/answers.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ def create_question_prompt(question: str) -> str:

def create_context_prompt(context: AnswerContext) -> str:
# TODO: Use a more compact representation of the context than JSON.
import black
import pprint

prompt = [
"[ANSWER CONTEXT]",
"===",
black.format_str(str(dictify(context)), mode=black.Mode(line_length=200)),
pprint.pformat(dictify(context), width=200),
"===",
]
return "\n".join(prompt)
Expand Down
28 changes: 25 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,36 @@ def test_timelog():


def test_pretty_print():
# Use a simple object and check output is formatted by black
obj = {"a": 1}
buf = StringIO()
with redirect_stdout(buf):
utils.pretty_print(obj)
out = buf.getvalue()
# Should be valid Python and contain the dict
assert out == '{"a": 1}\n', out
assert out == "{'a': 1}\n", out


def test_pretty_print_nested():
obj = {"b": [1, 2], "a": {"nested": True}}
buf = StringIO()
with redirect_stdout(buf):
utils.pretty_print(obj)
out = buf.getvalue()
# pprint sorts keys and formats nested structures
assert "'a'" in out
assert "'nested'" in out


def test_format_code_simple():
text = repr({"a": 1})
result = utils.format_code(text)
assert result == "{'a': 1}"


def test_format_code_nested():
obj = {"b": [1, 2, 3], "a": {"nested": True}}
result = utils.format_code(repr(obj))
parsed = eval(result)
assert parsed == obj


def test_load_dotenv(really_needs_auth):
Expand Down
Loading