Custom local variable display hook
- Dominant language
- Python
- Stars
- 155
- Forks
- 22
- PR merge metrics
- No merged PRs in 30d
Description
**Is your feature request related to a problem? Please describe.**
See https://github.com/twosigma/marbles/issues/92#issuecomment-423780916, #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.
Contributor guide
Research direction
Start by reading the linked discussion in issue #92, along with issues #75 and #109, then inspect the existing assertion failure formatting. Define the hook precedence, registration model, nested-value behavior, testing approach, and user controls before implementation; done means the design is agreed and the resulting failure messages behave consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100