Skip to content

Commit 71503e0

Browse files
Update typespecs and enforce with and limit in Inspect.Algebra (#10205)
1 parent 983ee5c commit 71503e0

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

lib/elixir/lib/inspect/algebra.ex

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,32 @@ defmodule Inspect.Opts do
3131
options. Useful when implementing the `Inspect` protocol for nested structs
3232
to pass the custom options through.
3333
34-
* `:inspect_fun` (since v1.9.0) - a function to build algebra documents,
35-
defaults to `Inspect.inspect/2`.
34+
* `:inspect_fun` (since v1.9.0) - a function to build algebra documents.
35+
Defaults to `Inspect.inspect/2`.
3636
3737
* `:limit` - limits the number of items that are inspected for tuples,
38-
bitstrings, maps, lists and any other collection of items. It does not
39-
apply to printable strings nor printable charlists and defaults to 50.
38+
bitstrings, maps, lists and any other collection of items, with the exception of
39+
printable strings and printable charlists which use the `:printable_limit` option.
4040
If you don't want to limit the number of items to a particular number,
41-
use `:infinity`.
41+
use `:infinity`. It accepts a positive integer or `:infinity`.
42+
Defaults to `50`.
4243
43-
* `:pretty` - if set to `true` enables pretty printing, defaults to `false`.
44+
* `:pretty` - if set to `true` enables pretty printing. Defaults to `false`.
4445
4546
* `:printable_limit` - limits the number of characters that are inspected
4647
on printable strings and printable charlists. You can use `String.printable?/1`
4748
and `List.ascii_printable?/1` to check if a given string or charlist is
48-
printable. Defaults to 4096. If you don't want to limit the number of
49-
characters to a particular number, use `:infinity`.
49+
printable. If you don't want to limit the number of characters to a particular
50+
number, use `:infinity`. It accepts a positive integer or `:infinity`.
51+
Defaults to `4096`.
5052
5153
* `:safe` - when `false`, failures while inspecting structs will be raised
5254
as errors instead of being wrapped in the `Inspect.Error` exception. This
5355
is useful when debugging failures and crashes for custom inspect
5456
implementations.
5557
5658
* `:structs` - when `false`, structs are not formatted by the inspect
57-
protocol, they are instead printed as maps, defaults to `true`.
59+
protocol, they are instead printed as maps. Defaults to `true`.
5860
5961
* `:syntax_colors` - when set to a keyword list of colors the output is
6062
colorized. The keys are types and the values are the colors to use for
@@ -63,10 +65,10 @@ defmodule Inspect.Opts do
6365
`:string`, and `:tuple`. Custom data types may provide their own options.
6466
Colors can be any `t:IO.ANSI.ansidata/0` as accepted by `IO.ANSI.format/1`.
6567
66-
* `:width` - defaults to 80 characters, used when pretty is `true` or when
67-
printing to IO devices. Set to 0 to force each item to be printed on its
68+
* `:width` - number of characters per line used when pretty is `true` or when
69+
printing to IO devices. Set to `0` to force each item to be printed on its
6870
own line. If you don't want to limit the number of items to a particular
69-
number, use `:infinity`.
71+
number, use `:infinity`. Defaults to `80`.
7072
7173
"""
7274

@@ -95,13 +97,13 @@ defmodule Inspect.Opts do
9597
charlists: :infer | :as_lists | :as_charlists,
9698
custom_options: keyword,
9799
inspect_fun: (any, t -> Inspect.Algebra.t()),
98-
limit: pos_integer | :infinity,
100+
limit: non_neg_integer | :infinity,
99101
pretty: boolean,
100-
printable_limit: pos_integer | :infinity,
102+
printable_limit: non_neg_integer | :infinity,
101103
safe: boolean,
102104
structs: boolean,
103105
syntax_colors: [{color_key, IO.ANSI.ansidata()}],
104-
width: pos_integer | :infinity
106+
width: non_neg_integer | :infinity
105107
}
106108
end
107109

@@ -266,6 +268,9 @@ defmodule Inspect.Algebra do
266268
when is_binary(doc) or doc in [:doc_nil, :doc_line] or
267269
(is_tuple(doc) and elem(doc, 0) in @docs)
268270

271+
defguardp is_limit(limit) when limit == :infinity or (is_integer(limit) and limit >= 0)
272+
defguardp is_width(limit) when limit == :infinity or (is_integer(limit) and limit >= 0)
273+
269274
# Elixir + Inspect.Opts conveniences
270275

271276
@doc """
@@ -397,13 +402,14 @@ defmodule Inspect.Algebra do
397402
{:lists.reverse(["..." | acc]), simple?}
398403
end
399404

400-
defp container_each([term | terms], limit, opts, fun, acc, simple?) when is_list(terms) do
405+
defp container_each([term | terms], limit, opts, fun, acc, simple?)
406+
when is_list(terms) and is_limit(limit) do
401407
limit = decrement(limit)
402408
doc = fun.(term, %{opts | limit: limit})
403409
container_each(terms, limit, opts, fun, [doc | acc], simple? and simple?(doc))
404410
end
405411

406-
defp container_each([left | right], limit, opts, fun, acc, simple?) do
412+
defp container_each([left | right], limit, opts, fun, acc, simple?) when is_limit(limit) do
407413
limit = decrement(limit)
408414
left = fun.(left, %{opts | limit: limit})
409415
right = fun.(right, %{opts | limit: limit})
@@ -884,7 +890,7 @@ defmodule Inspect.Algebra do
884890
885891
"""
886892
@spec format(t, non_neg_integer | :infinity) :: iodata
887-
def format(doc, width) when is_doc(doc) and (width == :infinity or width >= 0) do
893+
def format(doc, width) when is_doc(doc) and is_width(width) do
888894
format(width, 0, [{0, :flat, doc}])
889895
end
890896

@@ -900,7 +906,12 @@ defmodule Inspect.Algebra do
900906
#
901907
@typep mode :: :flat | :flat_no_break | :break | :break_no_flat
902908

903-
@spec fits?(width :: integer(), column :: integer(), break? :: boolean(), entries) :: boolean()
909+
@spec fits?(
910+
width :: non_neg_integer(),
911+
column :: non_neg_integer(),
912+
break? :: boolean(),
913+
entries
914+
) :: boolean()
904915
when entries:
905916
maybe_improper_list({integer(), mode(), t()}, {:tail, boolean(), entries} | [])
906917

@@ -961,7 +972,9 @@ defmodule Inspect.Algebra do
961972
defp fits?(w, k, b?, [{i, m, doc_group(x, _)} | t]),
962973
do: fits?(w, k, b?, [{i, m, x} | {:tail, b?, t}])
963974

964-
@spec format(integer | :infinity, integer, [{integer, mode, t}]) :: [binary]
975+
@spec format(width :: non_neg_integer() | :infinity, column :: non_neg_integer(), [
976+
{integer, mode, t}
977+
]) :: [binary]
965978
defp format(_, _, []), do: []
966979
defp format(w, k, [{_, _, :doc_nil} | t]), do: format(w, k, t)
967980
defp format(w, _, [{i, _, :doc_line} | t]), do: [indent(i) | format(w, i, t)]

lib/logger/lib/logger/utils.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,11 @@ defmodule Logger.Utils do
162162
defp inspect_width(_, width), do: width
163163

164164
defp inspect_data([data | _], opts) do
165+
width = if opts.width == :none, do: 80, else: opts.width
166+
165167
data
166168
|> Inspect.Algebra.to_doc(opts)
167-
|> Inspect.Algebra.format(opts.width)
169+
|> Inspect.Algebra.format(width)
168170
end
169171

170172
@doc """

0 commit comments

Comments
 (0)