This is definitely a bug. Here's a slightly simpler workaround than those suggested in the comments:
Uncompress[str, HoldComplete] // InputForm
Generally speaking, InputForm
and OutputForm
are safer than StandardForm
. This is for a couple of reasons. Much more of those textual formats happens inside the raw kernel, where evaluation leaks are easier to control. (I know of a couple, but really only because I can read the source code.) The second reason is that there is a class of evaluation which is allowed to happen during formatting, namely Dynamic
evaluation--this allows the FE to ask the kernel to evaluate pieces of the expression in order to display them or respond to user actions. Since the frontend will only do this for box-type (e.g, StandardForm
) cells, using InputForm
or OutputForm
will prevent these evaluations.
Edit and expansion in response to @Kuba's comment:
We do try hard to avoid evaluation leaks during formatting, but it can be quite challenging while also make things look "right" in the way most people want them to. And in, fact, this case (as well as Kuba's) shows one of the design issues that hasn't been quite solved.
DefaultElement
is an option to GridBox
. Options to boxes generally want expressions, not other boxes, as values. So we don't run MakeBoxes
on the input. But if the particular box is not HoldAll
, the expression isn't protected from further evaluation once MakeBoxes
is done. On the other hand, if the value isn't valid (whatever that means) there basically two possibilities: either disable formatting completely, or format with the value protected somehow (say replacing the Rule
by RuleDelayed
). But that will result in pink boxing in the FE. You'll notice that completely invalid inputs to typeset generators (say, Grid[{a}]
) don't format at all. In other cases, you get pinking (e.g., Hold[Graphics[{Red, Disk[]}]]
) (because GraphicsBox
is HoldAll
). Getting it completely right in all cases? Hard.
ToString@Uncompress[str, HoldComplete]
works. But I do not understand why the evaluation leaks otherwise. It must leak in the display code (MakeBoxes, etc.) $\endgroup$ToString[Uncompress[str, HoldComplete], InputForm]
$\endgroup$HoldComplete[Grid[{{}}, DefaultElement -> (Print[1]; "x")]]
$\endgroup$