# REPL crashes with custom pretty printing and Dictionaries

**URL:** https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622
**Category:** General Usage
**Tags:** pretty-printing
**Created:** [September 22, 2022, 8:23am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622 "2022-09-22T08:23:59Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [September 22, 2022, 8:23am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/1 "2022-09-22T08:23:59Z")

</div>

The REPL crashes when I run the following code twice, the first time giving the expected `StackOverflowError`:

```julia
using Dictionaries: dictionary

struct Bcode
    code::Int
end

Base.convert(::Type{String}, b::Bcode) = dictionary([Bcode(1) => "Z"])[b]
Base.show(io::IO, c::Bcode) = print(io, "$(convert(String, c))")

julia> Bcode(1)
Z

julia> Bcode(2)
Error showing value of type Bcode:
ERROR: StackOverflowError:
<snip>

julia> Bcode(2)
PS C:\Users\michele.zaffalon>

```

Additional information:

```julia
(test2) pkg> st
Status `C:\Users\michele.zaffalon\test2\Project.toml`
  [85a47980] Dictionaries v0.3.24

julia> versioninfo()
Julia Version 1.8.1
Commit afb6c60d69 (2022-09-06 15:09 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 6 × Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
  Threads: 1 on 6 virtual cores
Environment:
  JULIA_DEPOT_PATH = C:\Users\michele.zaffalon\.julia
  JULIA_PKG_USE_CLI_GIT = true

```

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [September 23, 2022, 10:48am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/2 "2022-09-23T10:48:34Z")

</div>

> [@mzaffalon](#):
>
> `Base.convert(::Type{String}, b::Bcode) = dictionary([Bcode(1) => "Z"])[b]`

This would be expected to throw an error for any `b` not equal to `Bcode(1)`. You are seeing a `StackOverflowError` in place of the true error, which should be something like

```julia
ERROR: IndexError("Dictionary does not contain index: Bcode(50)")
Stacktrace:
 [1] getindex(dict::Dictionary{Bcode, String}, i::Bcode)
   @ Dictionaries ~/.julia/packages/Dictionaries/8bcEH/src/AbstractDictionary.jl:46

```

---

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [September 23, 2022, 10:51am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/3 "2022-09-23T10:51:11Z")

</div>

I do expect a `StackOverflowError` every time I try to print anything except for `Bcode(1)`. What happens is that the REPL crashes the second time I try.

Should I report this?

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [September 23, 2022, 11:16am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/4 "2022-09-23T11:16:58Z")

</div>

It’s not clear to me what you are trying to achieve with what appears to be an unusual `convert` method. I think you would need to explain this reason, in addition to the odd behaviour.

---

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [September 23, 2022, 11:26am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/5 "2022-09-23T11:26:42Z")

</div>

> [@mzaffalon](#):
>
> Should I report this?

Perhaps worth reporting. I can’t reproduce the crash on Ubuntu, so this might be a Windows behavior.

---

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [September 23, 2022, 11:29am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/6 "2022-09-23T11:29:28Z")

</div>

I have a mapping between `Bcode`s and `String`s: for reasons of dispatch, I want to use `Bcode`s but for output to REPL I prefer the mnemonic names.

This is how I should have implemented it: the constructor prevents to create a `Bcode` for which there is no entry in the dictionary.

```julia
using Dictionaries: dictionary

const _bcode = dictionary([1 => "Z"])

struct Bcode
    code::Int
    Bcode(c) =
        c in keys(_bcode) ? new(c) : error("invalid code $c")
end

Base.convert(::Type{String}, b::Bcode) = _bcode[b.code]
Base.show(io::IO, c::Bcode) = print(io, "$(convert(String, c))")

```

The version I first posted was the first iteration of the code.

---

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [September 23, 2022, 11:38am UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/7 "2022-09-23T11:38:38Z")

</div>

> <https://github.com/JuliaLang/julia/issues/46870#issue-1383675194>
>
> \`\`\`
> using Dictionaries: dictionary
> 
> struct Bcode
> code::Int
> end
> 
> Base.…convert(::Type{String}, b::Bcode) = dictionary(\[Bcode(1) =\> "Z"\])\[b\]
> Base.show(io::IO, c::Bcode) = print(io, "$(convert(String, c))")
> 
> julia\> Bcode(1)
> Z
> 
> julia\> Bcode(2)
> Error showing value of type Bcode:
> ERROR: StackOverflowError:
> \<snip\>
> 
> julia\> Bcode(2)
> PS C:\\Users\\michele.zaffalon\>
> \`\`\`
> I do expect the \`StackOverflowError\` but when I try a second time, Julia quits. This seems to be a Windows only problem.
> 
> \`\`\`
> (test2) pkg\> st
> Status \`C:\\Users\\michele.zaffalon\\test2\\Project.toml\`
> \[85a47980\] Dictionaries v0.3.24
> 
> julia\> versioninfo()
> Julia Version 1.8.1
> Commit afb6c60d69 (2022-09-06 15:09 UTC)
> Platform Info:
> OS: Windows (x86\_64-w64-mingw32)
> CPU: 6 × Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz
> WORD\_SIZE: 64
> LIBM: libopenlibm
> LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
> Threads: 1 on 6 virtual cores
> Environment:
> JULIA\_DEPOT\_PATH = C:\\Users\\michele.zaffalon\\.julia
> JULIA\_PKG\_USE\_CLI\_GIT = true
> \`\`\`
> 
> Ref: https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [September 23, 2022, 12:47pm UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/8 "2022-09-23T12:47:24Z")

</div>

When `Dictionary` does not find `Bcode(2)` as a key in the dictionary, it wants to print an error message:

```julia
ERROR: Dictionaries.IndexError("Dictionary does not contain index: ***Bcode(2)***")

```

But the `***Bcode(2)***` in this hypothetical error message is the output of stringifying `Bcode(2)`, which prints this error. So an infinite recursion loop is called which isn’t infinite, because the call stack is exhausted, and `StackOverflowError` triggered.  
To avoid this, perhaps `getkey` should be used instead of indexing into dictionary. `getkey` has a default value. The following:

```julia
Base.convert(::Type{String}, b::Bcode) = getkey(Dict([Bcode(1) => "Z"]), b, "not found")

```

Doesn’t crash.

---

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [September 23, 2022, 1:02pm UTC](https://discourse.julialang.org/t/repl-crashes-with-custom-pretty-printing-and-dictionaries/87622/9 "2022-09-23T13:02:07Z")

</div>

@Dan I totally agree with your analysis and with that of @jd-foster. Enforcing the check in the constructor is another way to prevent the error.

I only wanted to report that Julia quits the second time I generate the error.
