Skip to content

Added __repr__ implementation on all locators and formators - #25767

Open
Daniil-Aleshechkin wants to merge 33 commits into
matplotlib:mainfrom
Daniil-Aleshechkin:added-repr-implementation-on-all-locators-and-formators
Open

Daniil-Aleshechkin wants to merge 33 commits into
matplotlib:mainfrom
Daniil-Aleshechkin:added-repr-implementation-on-all-locators-and-formators

Conversation

@Daniil-Aleshechkin

Copy link
Copy Markdown
  • PR Summary

Added an init_subclass implementation on the TickerHelper class that creates a wrapper over all the subclass' init methods. I'm assuming the following:

  1. All parameters will have repr implemented now and in the future. Basically they will be restricted to base types like ints, strs... etc
  2. The initialized paramters will not change. Essentially the repr function will be how the class was inited.

This closes #21898

PR Checklist

Linked Issue

  • Added "closes #0000" in the PR description to link it to the original issue.

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • [N/A] API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

For unit testing because of the nature of the feature, any parameters that get added/ changed in anyway will be coupled to the test, can someone recommend some safe classes that I can use?

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a while, please feel free to ping @matplotlib/developers or anyone who has commented on the PR. Most of our reviewers are volunteers and sometimes things fall through the cracks.

You can also join us on gitter for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide

We strive to be a welcoming and open project. Please follow our Code of Conduct.

@story645

Copy link
Copy Markdown
Member

I think an easy test is seeing if you can reproduce the locator and formatter examples (e.g. https://matplotlib.org/devdocs/gallery/ticks/tick-locators.html), but replace the titles with the reprs.

@ksunden

ksunden commented Apr 26, 2023

Copy link
Copy Markdown
Member

This is modifying the reported runtime signature of all Formatters to have Formatter.__init__(*args, **kwargs) as the only signature reported, rather than having a more informative runtime inspectable signature.

Comment thread lib/matplotlib/ticker.py Outdated
Comment on lines +2944 to +2946
tmin = ((vmin - t0) // minorstep + 1) * minorstep
tmax = ((vmax - t0) // minorstep + 1) * minorstep
locs = np.arange(tmin, tmax, minorstep) + t0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems unreleated, though I think it was included in a different recent PR

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must have been an artifact when I set the branch up. I'll remove it

@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

This is modifying the reported runtime signature of all Formatters to have Formatter.__init__(*args, **kwargs) as the only signature reported, rather than having a more informative runtime inspectable signature.

Yea I think I need to rebind the signature to my wrappers. Would doing something like.

wrapper = _init_repr_wrapper
wrapper.__signature__ = inspect.signature(originalInit)

work?

@ksunden

ksunden commented Apr 26, 2023

Copy link
Copy Markdown
Member

That may work, but the more standard/complete way of doing it is to use functools.wraps, as the code from the original issue does.

@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

That may work, but the more standard/complete way of doing it is to use functools.wraps, as the code from the original issue does.

Gotcha I'll give that a shot

@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

That may work, but the more standard/complete way of doing it is to use functools.wraps, as the code from the original issue does.

Seems like it fixed the wrapping issue, but now I have the problem where args is added to the signature when I think I'm creating an init method for classes that don't have one defined. Not sure exactly what's going on, because I still get the same issue when I don't add anything from this commit: d3aef45

@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

That may work, but the more standard/complete way of doing it is to use functools.wraps, as the code from the original issue does.

Seems like it fixed the wrapping issue, but now I have the problem where args is added to the signature when I think I'm creating an init method for classes that don't have one defined. Not sure exactly what's going on, because I still get the same issue when I don't add anything from this commit: d3aef45

I figured it out after my morning run today :)

Basically checking for null doesn't account for the case when we inherit an init method. My solution is I added a marker property and checked for it. I don't want to add it to the stubs though because it's only used for this. Is there a better / standard way of adding an arbitrary marker to the function?

@story645 story645 self-assigned this Apr 30, 2023
@QuLogic

QuLogic commented May 2, 2023

Copy link
Copy Markdown
Member

Basically checking for null doesn't account for the case when we inherit an init method. My solution is I added a marker property and checked for it. I don't want to add it to the stubs though because it's only used for this. Is there a better / standard way of adding an arbitrary marker to the function?

I think you'll want to be checking if '__init__' in cls.__dict__.

@tacaswell

Copy link
Copy Markdown
Member

This is very nice technical work, however the __repr__ should represent what the current state of the objects are not what what it was initialized with! A user that is looking at a (nice looking) repr of an object is going to have the expectation that that repr represents the current state of that object, not the state of the object at some point in the past!

Unfortunately I think the solution here is much less sophisticated and much more rote: write __repr__ methods for each class. If we also add __eq__ methods we can test that eval(repr(obj)) == obj and I agree with the suggestion that in the locator / formatter example being able to use the title of repr(obj) is a good manual visualization that it still looks good.

This does bring up the issue that there are attributes on these objects that influence how they render (and thus knowing the repr of two objects is the same is not enough to be sure that they are functionally the same), but I think that it is fair to say that is (well) out of scope.

@Daniil-Aleshechkin I'm sorry we led you down this path and asked you to do a bunch of work that is not going to land in its current state 😞

@Daniil-Aleshechkin
Daniil-Aleshechkin force-pushed the added-repr-implementation-on-all-locators-and-formators branch from e8f2a0a to 23d9ba9 Compare May 8, 2023 16:12
@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

Not sure exactly what's going on but is the test agent in a bad state? Only the python 3.10 agent is throwing an exception: "Traceback (most recent call last):\n File "", line 1, in \n File "/Users/runner/work/1/s/lib/matplo...ion (%s) doesn't match libtk.a version (%s)"\nRuntimeError: tk.h version (8.5) doesn't match libtk.a version (8.6)\n"

@QuLogic

QuLogic commented May 9, 2023

Copy link
Copy Markdown
Member

That's a known issue, but the other test failures are for the new tests here.

@Daniil-Aleshechkin

Copy link
Copy Markdown
Author

That's a known issue, but the other test failures are for the new tests here.

Managed to fix those. Do we know how to fix this issue?

@QuLogic

QuLogic commented May 15, 2023

Copy link
Copy Markdown
Member

That's up to Microsoft.

"""

def __repr__(self):
return f"{self.__class__.__name__}(base={self.base.__repr__()})"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These __repr__ should all be:

Suggested change
return f"{self.__class__.__name__}(base={self.base.__repr__()})"
return f"{self.__class__.__name__}(base={self.base!r})"

@story645

Copy link
Copy Markdown
Member

ping @Daniil-Aleshechkin any bandwidth for continuing with this?

@Daniil-Aleshechkin

Daniil-Aleshechkin commented Jun 27, 2023 •

Copy link
Copy Markdown
Author

ping @Daniil-Aleshechkin any bandwidth for continuing with this?

Ah completely forgot about this. I stopped working on it cause I was blocked on that issue with the python 3.10 test runner. Did that get resolved? If so, I can resume working :)

@github-actions

Copy link
Copy Markdown

Since this Pull Request has not been updated in 60 days, it has been marked "inactive." This does not mean that it will be closed, though it may be moved to a "Draft" state. This helps maintainers prioritize their reviewing efforts. You can pick the PR back up anytime - please ping us if you need a review or guidance to move the PR forward! If you do not plan on continuing the work, please let us know so that we can either find someone to take the PR over, or close it.

@github-actions github-actions Bot added the status: inactive Marked by the “Stale” Github Action label Sep 21, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Waiting for author

Development

Successfully merging this pull request may close these issues.

Reprs on formatters and locaters

6 participants