Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Replaced noqa-comments by using Axes3D.name instead of '3d' for proje… #12249

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

folkol
Copy link

@folkol folkol commented Sep 24, 2018

…ction parameters.

PR Summary

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@tacaswell tacaswell added this to the v3.1 milestone Sep 24, 2018
@tacaswell
Copy link
Member

Thanks for the contributio @folkol !

I am 50/50 on this change. On one hand, removing the #noqa is a good thing, however passing the string to projection kwarg seems like a very useful thing to show in the examples. @folkol any thoughts on the trade-offs?

@QuLogic
Copy link
Member

QuLogic commented Sep 24, 2018

There was a mention of this before, but it was never decided upon: #11651 (comment)

@timhoffm
Copy link
Member

@folkol Thanks for bringing up the topic. Improving the style of the examples is really valuable. I support getting rid of # noqa in the examples because it might confuse people.

However, whether to use projection='3d' or projection=Axes3D.name should only be determined by what we want the users to actually use in their code. And I'm -1 on projection=Axes3D.name. It's less readable and less clear.

Let's just exclude F401 in all examples from the mplot3d section of the gallery via .flake8.

Note: For our internal code, I propose to leave the # noqa in place because this narrows the scope to exactly that import.

@WeatherGod
Copy link
Member

WeatherGod commented Sep 25, 2018 via email

@folkol
Copy link
Author

folkol commented Sep 25, 2018

Yeah, the change is 100% a workaround for tooling issues — which sucks. I think that it is for the better, though (as long as the examples must pass a linter). I also agree with @tacaswell on the 50/50 part.

Maybe running the linter with global ignores for the example files would be even better? (With the risk of missing actual errors in the process.)

@anntzer
Copy link
Contributor

anntzer commented Sep 25, 2018

does from ... import Axes3D as _ placate flake8? (if it doesn't I'd suggest opening an issue with them...)
edit: done, PyCQA/pyflakes#366

@timhoffm
Copy link
Member

From a code style point of view from ... import Axes3D as _ is not better than an unused from ... import Axes3D. It's just another workaround to placate flake8.

In the end, a plugin approach for the 3d Axes would be best. Importing Axes3D to make 3D Axes work is the original workaround, which drags all the other workarounds along. However, I'm afraid that's a bit more work (haven't looked into the details).

@anntzer
Copy link
Contributor

anntzer commented Sep 25, 2018

It's a longstanding python convention that assigning to _ means "I syntactically need to assign this to something, but I don't care". Doing the same for imports doesn't seem too big of a stretch.

OTOH we could also just always register Axes3D by default, it's not clear to me why we don't (beyond the hypothetical case of allowing installs of matplotlib that don't include mpl_toolkits, but 1) I don't think we should actually bother to allow that, and 2) even if we really do we can just wrap the registration in a try... except ImportError).

@timhoffm
Copy link
Member

timhoffm commented Sep 25, 2018

The general notion for _ is well known. However I've never seen it used for imports. And indeed google has three results for searching

python "import as _"

One of which is pylint, which ignores this since pylint 1.7

I'm fine with default-registering Axes3D.

@eric-wieser
Copy link
Contributor

Would it make sense to allow projection=Axes3D, ie drop the .name?

@folkol
Copy link
Author

folkol commented Sep 26, 2018

I don't think so, @eric-wieser, the parameter expects a name: str for which projection to use — letting the plot code know about "name" seems like a hacky solution to a non-problem. I think that the most pragmatic suggestion so far is to just register Axes3D by default — since this is the only example that is using the ugly noqa-pragma as far as I can tell.

@eric-wieser
Copy link
Contributor

eric-wieser commented Sep 26, 2018

letting the plot code know about "name" seems like a hacky solution to a non-problem

I'd say the inverse - why convert a name to a class via projection_class = get_projection_class(Axes3D.name) inside process_projection_requirements when you could use projection_class = Axes3D directly?

My proposed patch would be:

-   if isinstance(projection, str) or projection is None:
+   if isinstance(projection, type):  # maybe: check subclass of `matplotlib.axes.Axes`
+       projection_class = projection
+   elif isinstance(projection, str) or projection is None:
        projection_class = get_projection_class(projection)
    elif hasattr(projection, '_as_mpl_axes'):
        projection_class, extra_kwargs = projection._as_mpl_axes()
        kwargs.update(**extra_kwargs)
    else:
        raise TypeError('projection must be a string, None or implement a '
                        '_as_mpl_axes method. Got %r' % projection)
`

@folkol
Copy link
Author

folkol commented Sep 27, 2018

@eric-wieser That isn't too bad, but it is still a workaround to satisfy linters. (In my opinion, projection='3d' reads better as an API than projection=Axes3D). Register Axes3D by default, and everyone will be happy!

@anntzer
Copy link
Contributor

anntzer commented Sep 27, 2018

I honestly believe we should be perfectly happy to skip style checks in the examples if that leads to more convoluted code, see #11621 (comment) (which quite a few other core devs agree with). Let's not overthink this.

@eric-wieser
Copy link
Contributor

eric-wieser commented Sep 27, 2018

This isn't just about the example though - it's about downstream code using style checks having to work around this too. I'd argue that requiring users to import something but then not use it directly is confusing, and violates "Explicit is better than implicit".

If you view the style checkers as opinionated interpretations of what is considered "pythonic", then you could argue that if your API design requires you to make a style exception at all call sites, it might be unpythonic.

I'm not saying projection='3d' is a bad idea - but for users of matlab coming to python for the first time, being told they have to import something only not to use it is not going to help them build a mental model of how imports work.

@anntzer anntzer mentioned this pull request Sep 28, 2018
6 tasks
@jklymak jklymak modified the milestones: v3.1.0, v3.2.0 Feb 26, 2019
@jklymak
Copy link
Member

jklymak commented Feb 26, 2019

I think this has enough core devs against this change, and whether our unused import is bad style or not, thats how its currently done. Closing but fee free to re-open if this PR wants to morph into setting the exception in .flake8.

@jklymak jklymak closed this Feb 26, 2019
@anntzer anntzer mentioned this pull request Feb 26, 2019
6 tasks
@timhoffm
Copy link
Member

The issue is resolved by #13520.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants