From 12253499782abd6f269632cbf5d20ed62f685c7f Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Wed, 29 Jul 2026 01:00:46 -0500 Subject: [PATCH] Add Dedent Common Whitespace From Multiline String as a Python TIL --- README.md | 3 +- ...common-whitespace-from-multiline-string.md | 46 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 python/dedent-common-whitespace-from-multiline-string.md diff --git a/README.md b/README.md index 629c5b7..bd706c0 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/). For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter). -_1843 TILs and counting..._ +_1844 TILs and counting..._ See some of the other learning resources I work on: @@ -1084,6 +1084,7 @@ If you've learned something here, support my efforts writing daily TILs by - [Control Passing Of Time In Tests](python/control-passing-of-time-in-tests.md) - [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md) - [Create A Range Of Descending Values](python/create-a-range-of-descending-values.md) +- [Dedent Common Whitespace From Multiline String](python/dedent-common-whitespace-from-multiline-string.md) - [Deduplicate A List Into A Tuple](python/deduplicate-a-list-into-a-tuple.md) - [Define Sequence Of Tests With Parametrize Decorator](python/define-sequence-of-tests-with-parametrize-decorator.md) - [Define Typed Class Interface With Protocol](python/define-typed-class-interface-with-protocol.md) diff --git a/python/dedent-common-whitespace-from-multiline-string.md b/python/dedent-common-whitespace-from-multiline-string.md new file mode 100644 index 0000000..9ca9d07 --- /dev/null +++ b/python/dedent-common-whitespace-from-multiline-string.md @@ -0,0 +1,46 @@ +# Dedent Common Whitespace From Multiline String + +I'm adding tests to cover some custom logic in the _usage_ messages that are +produced by Click [in a CLI I'm building](https://github.com/jbranchaud/py-vmt). +The usage output is a mutliline string formatted with some indentation. On top +of that, I'm putting it in a Python test file with some additional syntactical +indentation. + +If this was Ruby, I would reach for the `<<~` heredoc syntax. The closest +equivalent to that in Python is +[`textwrap.dedent`](https://docs.python.org/3/library/textwrap.html#textwrap.dedent). + +> Remove any common leading whitespace from every line in text. +> +> This can be used to make triple-quoted strings line up with the left edge of +> the display, while still presenting them in the source code in indented form. + +```python +import textwrap + +def test_base_help_message(): + runner = BetterCliRunner() + + help_result = runner.invoke(cli, ["--help"]) + output = textwrap.dedent("""\ + Usage: vmt [OPTIONS] COMMAND [ARGS]... + + Options: + -v, --verbose See extra output when running commands + --help Show this message and exit. + + Commands: + cancel + log + start + status + stop + """) + assert output in help_result.output +``` + +Before adding in `textwrap.dedent`, the test was failing because of bits of +extra whitespace that wasn't matching up with the actual CLI output. + +Note: the leading `\` after the opening `"""` is needed to remove the leading +newline that would otherwise be included.