Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix problem with (deep)copy of TextPath#20921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed

Conversation

deep-jkl
Copy link
Contributor

@deep-jkldeep-jkl commentedAug 27, 2021
edited
Loading

PR Summary

The problem is that deepcopy of TextPath calls deepcopy of Path. In turnPath utilizessuper().__init__ for creating a new
instance. However,Path.__init__ andTextPath.__init__ are completely different.

Related to Issue#20943

PR Checklist

  • Has pytest style unit tests (andpytest passes).
  • IsFlake 8 compliant (runflake8 on changed files to check).
  • [N/A] New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs shouldbuild without error).
  • Conforms to Matplotlib style conventions (installflake8-docstrings and runflake8 --docstring-convention=all).
  • [N/A] New features have an entry indoc/users/next_whats_new/ (follow instructions in README.rst there).
  • [N/A] API changes documented indoc/api/next_api_changes/ (follow instructions in README.rst there).

Copy link
Member

@tacaswelltacaswell left a comment

Choose a reason for hiding this comment

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

Thank you for working on this, however I think this is the wrong fix.

__deepcopy__ should return the same type as the object being copied (I pushed a commit updating the test to check this)!. I think a better fix is to override the__deepcopy__ onTextPath.

It may also be worth looking into usingPath._fast_from_codes_and_verts inPath.__deepcopy__ + patching on some other state + extending it inTextPath to add any additional state if needed.

Anyone can dismiss this review.

@tacaswelltacaswell added this to thev3.5.1 milestoneAug 28, 2021
@deep-jkl
Copy link
ContributorAuthor

Thank you for working on this, however I think this is the wrong fix.

__deepcopy__ should return the same type as the object being copied (I pushed a commit updating the test to check this)!. I think a better fix is to override the__deepcopy__ onTextPath.

It may also be worth looking into usingPath._fast_from_codes_and_verts inPath.__deepcopy__ + patching on some other state + extending it inTextPath to add any additional state if needed.

Anyone can dismiss this review.

Mea culpa! It was mine bad design. With the help of stack overflow I have come to another implementation.

Regarding thePath._fast_from_codes_and_verts, can I have a look at it in another PR?
However, I have noticed that some methods ofPath returnPath object, so for exampleTextPath((0,0), ".").cleaned() will convertTextPath into plainPath, shouldn't we address this?

@deep-jkl
Copy link
ContributorAuthor

I have filled an issue tracker for case that I will fail in this PR :-)
Issue#20943

from matplotlib.textpath import TextPath


def test_set_size():
Copy link
Member

Choose a reason for hiding this comment

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

Can this get a docstring, even if very cursory? I can't really tell what it is supposed to be testing...

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

I have added a simple docstring. I have revisited the test and I think that it tests the required functionality.

@deep-jkldeep-jklforce-pushed thetextpath-deepcopy-problem branch fromfeaa882 toebebec0CompareSeptember 21, 2021 19:50
deep-jkland others added6 commitsSeptember 21, 2021 23:45
The problem is that deepcopy of TextPath calls deepcopy of Path.In turn `Path` utilizes `super().__init__` for creating a newinstance. However, `Path.__init__ and TextPath.__init__ arecompletely different. Moreover, `TextPath.__init__` convertssome arguments directly to list of vertices, hence it is notpossible to create a new instance of `TextPath` from its members.Additionally, there is a problem with caching. When copying, thevertices can be copied uncached, which causes discrepanciesbetween members of copy and original members (recaching creates newmembers). Therefore validation of cache was removed and new verticesare generated at every size set.
This time, revalidation is enabled. Added test for member deepcopy().
@deep-jkl
Copy link
ContributorAuthor

@jklymak@tacaswell can you review this again, please?

@deep-jkldeep-jkl mentioned this pull requestSep 28, 2021
9 tasks
@jklymak
Copy link
Member

Maybe this is fine, however, I don't understand why you want to deep copy this class in the first place to know if it is correct, and what use it will be put to.

setattr(new_instance, k, deepcopy(v, memo))
return new_instance

deepcopy = __deepcopy__
Copy link
Contributor

@anntzeranntzerOct 5, 2021
edited
Loading

Choose a reason for hiding this comment

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

Do you need this as a public method? I'd saycopy.deepcopy(textpath) is good enough (and in fact, perhttps://github.com/matplotlib/matplotlib/pull/20921/files#r721988323, it does a bit more)?

self._revalidate_path()
cls = self.__class__
new_instance = cls.__new__(cls)
memo[id(self)] = new_instance
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need to fill in the memo yourself,copy.deepcopy already does that for you:https://github.com/python/cpython/blob/7c2a040a10654d67ff543a55858ba2d7a9f7eea8/Lib/copy.py#L175-L176

@anntzer
Copy link
Contributor

Actually, having reviewed this, I think#21280 is a better solution?

@deep-jkl
Copy link
ContributorAuthor

Maybe this is fine, however, I don't understand why you want to deep copy this class in the first place to know if it is correct, and what use it will be put to.

I might done it the other way around, sorry. This requirement comes from another PR, where I have changed MarkerStyle instantiation from MarkerStyle to utilizedeepcopy instead ofupdate, because I felt that update does not assure immutability.

see
https://github.com/matplotlib/matplotlib/pull/20914/files#diff-0463a29ec8272d330266fc7f9314e6d1ee12dd8099a8b7184dd510823326991bL345

I got into the whole copy/deepcopy mess when I unexpectedly discovered some bug see#20731 .
I am sorry that this is so complex, I hope that we can figure it out :-D

@deep-jkl
Copy link
ContributorAuthor

Actually, having reviewed this, I think#21280 is a better solution?

This looks much better, I didn't knew that you can usesuper() this way. Thanks, feel free to close this PR :-)

@anntzer
Copy link
Contributor

Thanks for pointing out the original issue :)

@anntzeranntzer closed thisOct 5, 2021
@QuLogicQuLogic modified the milestones:v3.5.1,v3.5.0,v3.6.0Oct 28, 2021
@deep-jkldeep-jkl deleted the textpath-deepcopy-problem branchApril 13, 2022 18:31
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@anntzeranntzeranntzer left review comments

@jklymakjklymakjklymak left review comments

@tacaswelltacaswellAwaiting requested review from tacaswell

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
v3.6.0
Development

Successfully merging this pull request may close these issues.

5 participants
@deep-jkl@jklymak@anntzer@tacaswell@QuLogic

[8]ページ先頭

©2009-2025 Movatter.jp