It's pretty standard behaviour for Python. Right now, `eval(repr(...))` works unless you have shadowed the name
Ellipsis.
>>> err = ValueError('something went wrong')
>>> ValueError = list
>>> eval(repr(err))
['s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', ' ', 'w', 'e', 'n',
't', ' ', 'w', 'r', 'o', 'n', 'g']
Yeah, my surprise was kind of a "thinko." I think I was thinking of the eval() separately from the repr(). But nonetheless, the idempotency question still arises, and I believe is reasonable.
Unless we make the ellipsis object `...` callable. But that doesn't help
us if the name Ellipsis has been rebound. Then it will call the rebound
object.
> Let's change the behavior of the Ellipsis object slightly to have either a
> .__call__() or .__getitem__() method that returns itself
That was exactly what I suggested. The three dots themselves, which CANNOT be bound to any other object, could be callable or indexable. If you define a class Ellipsis to use that name, it makes no difference to `repr(...) == "...[Ellipsis]"` Note that I am NOT proposing `Ellipsis(...)` as the repr for EXACTLY that reason.
Not every builtin needs a mollyguard to protect against misuse.
I'm not likely to rebind `Ellipsis` so that's not really my concern. Rather, I'm interested in the point André Roberge started the thread with. The repr of '...' should be more self-explanatory to beginners. It's basically co-opting the square brackets or parenthesis to mean something that doesn't really have anything to do with calling or indexing in order to have a repr—in tracebacks specifically, but elsewhere also—that reminds users of the connection between `...` and `Ellipsis`.
-- The dead increasingly dominate and strangle both the living and the
not-yet born. Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.