Skip to content

Custom local variable display hook #96

@leifwalsh

Description

@leifwalsh

Is your feature request related to a problem? Please describe.

See #92 (comment), #75, and the discussion on #109.

Broadly, we'd like to give various actors more control over how local variable values get formatted in assertion failure messages.

There are several actors at play here:

  • Third-party container library authors who have built classes they want marbles to format in a custom way
  • Marbles developers who might want to customize the display of classes that are unaware of marbles (including containers in the standard library, numpy, and pandas)
  • Test authors, who might want to customize display of arbitrary classes (or instances), self-written or third-party
  • Test runners/consumers, who might want to customize (or most likely, disable display customization) with CLI parameters or configuration (critically, not editing test code)

Describe the solution you'd like
Some prior art can be seen in jupyter/ipython, which has a protocol where, if an object has a method _repr_ipython_, that method is used to display the object in output cells, and this falls back to __repr__ if it doesn't exist. Similarly, if a class implements _repr_marbles_, we could call that method instead of repr to create the string to display in failure messages.

We should consider how customization works in many directions:

  • A third-party container library author could implement a custom display hook for its classes (_repr_marbles_), which marbles could look for and use to render an instance of that class.
  • Marbles could customize the display of certain stdlib or third party objects in libraries that don't know about marbles (e.g. a numpy.array) by registering a display hook somewhere within marbles to use based on an isinstance check.
  • A test author could register within marbles a custom display mechanism for any type, whether that type is part of the test author's code, or a third party library the marbles developers don't know about.
  • Test consumers should have some control over how this customization works. At least, they should be able to disable it easily if it's getting in the way of understanding a test failure.

If you're interested in implementing this, let's discuss in this issue what you think about that approach, how you'd handle edge cases like "what if multiple registered custom display hooks are implemented?", how we should approach testing it, and what user controls we'll need (Should the --verbose flag affect this? Should we support a flag to disable these hooks?).

We should also consider what kinds of customization we want. Two easy ones that come to mind for me are line-wrapping lists on comma boundaries, and sorting sets so they're more visually comparable. A hard problem in this area that I haven't thought through is nested data structures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions