Skip to content

Speed up wcsaxes import by avoiding unnecessary pytest import - #10302

Closed
lpsinger wants to merge 1 commit into
astropy:mainfrom
lpsinger:pytest-speed-up-import
Closed

lpsinger wants to merge 1 commit into
astropy:mainfrom
lpsinger:pytest-speed-up-import

Conversation

@lpsinger

@lpsinger lpsinger commented May 4, 2020 •

Copy link
Copy Markdown
Contributor

In astropy.visualization.wcsaxes, do not import pytest unless we are actually running the tests. Pytest is a fairly heavyweight import, so it should not be imported unless it's actually needed.

mhvk
mhvk previously approved these changes May 4, 2020

@mhvk mhvk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, this simply seems wrong. I'm confident enough to approve, but it would be good for @astrofrog to review, since he added it here.

@mhvk

mhvk commented May 4, 2020

Copy link
Copy Markdown
Contributor

@lpsinger - if you did notice other cases, and have time, definitely tell where or open other PRs.

@lpsinger

lpsinger commented May 4, 2020

Copy link
Copy Markdown
Contributor Author

Unfortunately, the conftest.py doesn't work. I'm trying a few different strategies here.

@mhvk

mhvk commented May 4, 2020

Copy link
Copy Markdown
Contributor

Might it work in tests/__init__.py?

@mhvk
mhvk dismissed their stale review May 4, 2020 20:21

Approval was premature

@mhvk

mhvk commented May 4, 2020

Copy link
Copy Markdown
Contributor

Hmm, I think I'm starting to see the problem (never think @astrofrog did strange looking things for no reason..). pytest probably traverses the tree and tries to import things, just to look for tests.

But perhaps one can avoid loading pytest by trying to import matplotlib in __init__.py and if that fails do the pytest.importorskip step? By that time, the user is most likely trying to import something from wcsaxes anyway, so if matplotlib is not present, they are getting a failure regardless and the time doesn't matter so much.

Aside: pytest used to be just a single file which we shipped, hardly a heavy dependence!

@mhvk

mhvk commented May 4, 2020

Copy link
Copy Markdown
Contributor

p.s. I cancelled travis to save some cycles, since you wrote things didn't work.

@lpsinger
lpsinger force-pushed the pytest-speed-up-import branch from d0df5e6 to 4868eda Compare May 4, 2020 20:39
@pep8speaks

pep8speaks commented May 4, 2020 •

Copy link
Copy Markdown

Hello @lpsinger 👋! It looks like you've made some changes in your pull request, so I've checked the code again for style.

There are no PEP8 style issues with this pull request - thanks! 🎉

Comment last updated at 2020-05-04 21:18:18 UTC

@lpsinger

lpsinger commented May 4, 2020

Copy link
Copy Markdown
Contributor Author

@mhvk, @bsipocz, I force-pushed a new implementation. Please take a look and send feedback. If you like it, I'll clean it up, make the same change for all other impacted modules, and add a changelog entry.

In `astropy.visualization.wcsaxes`, do not import pytest unless
we are actually running the tests. Pytest is a fairly heavyweight
import, so it should not be imported unless it's actually needed.
@lpsinger
lpsinger force-pushed the pytest-speed-up-import branch from 4868eda to 43fea65 Compare May 4, 2020 21:18
@lpsinger lpsinger changed the title WIP: Speed up astropy imports by moving pytest skips to conftest.py Speed up wcsaxes import by avoiding unnecessary pytest import May 4, 2020

if tests.RUNNING:
import pytest
pytest.importorskip("matplotlib")

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.

Wait a minute. Why is this even here? It should have been in the individual test modules under tests. Looks like we inherited this from the package we absorbed in #5496. @astrofrog , do you remember why this is at subpackage init level and not the tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I suspect that this is because wcsaxes is unique in Astropy in that it subclasses many different Matplotlib subclasses, and so the conditional imports of the kind in astropy.visualization.mpl_normalize were not appropriate:

try:
    import matplotlib  # pylint: disable=W0611
    from matplotlib.colors import Normalize
    from matplotlib import pyplot as plt
except ImportError:
    class Normalize:
        def __init__(self, *args, **kwargs):
            raise ImportError('matplotlib is required in order to use this '
                              'class.')

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.

I suppose it was a convenient way to make sure mpl is needed for the whole module and skip it at collection time at the earliest and quickest way possible. Fully agreed that it should not be used like this.

@pllim pllim left a comment

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.

I have a feeling that this is not the correct solution. See my comment above. Thanks for bringing this to our attention!

@mhvk

mhvk commented May 4, 2020

Copy link
Copy Markdown
Contributor

@lpsinger - that feels too hacky, modifying some almost global state. I also worry that things like pytest astropy/visualization will not be covered. My suggestion above might be better, but I agree with @pllim that at this point it would be good to get @astrofrog's opinion, since he almost certainly struggled with this when moving wcsaxes over here.

Also, which other modules have things like this? Maybe some of those can more easily be changed? Because you are definitely right that we should not be importing pytest anywhere but in tests directories!

@lpsinger

lpsinger commented May 4, 2020

Copy link
Copy Markdown
Contributor Author

Also, which other modules have things like this? Maybe some of those can more easily be changed? Because you are definitely right that we should not be importing pytest anywhere but in tests directories!

Happily, this is the only such module in Astropy itself.

@pllim

pllim commented May 5, 2020

Copy link
Copy Markdown
Member

I feel like the more correct solution would be something like #10260 but it is a lot more work and is borderline controversial to some people.

I mean, if we make yaml, asdf, etc go through strict import checks in io.misc, why not here as well? matplotlib is just as optional as those packages.

@mhvk

mhvk commented May 5, 2020

Copy link
Copy Markdown
Contributor

Agree with the sentiment, though there are lots of modules here which use it, and having the whole module indented becomes a bit much! But perhaps there are cleverer solutions?

@pllim

pllim commented May 5, 2020

Copy link
Copy Markdown
Member

Well, in the PR for asdf linked above, the dependency namespace is replaced with generic junk, which would make the import work fine without dependency installed, but you get exception when you actually try to use the stuff for real. So the tradeoff is no error on import but you don't get told you are missing a dependency until later. 🤷 This game is hard to win.

@astropy-bot

astropy-bot Bot commented Oct 7, 2020

Copy link
Copy Markdown

Hi humans 👋 - this pull request hasn't had any new commits for approximately 5 months. I plan to close this in a month if the pull request doesn't have any new commits by then.

In lieu of a stalled pull request, please consider closing this and open an issue instead if a reminder is needed to revisit in the future. Maintainers may also choose to add keep-open label to keep this PR open but it is discouraged unless absolutely necessary.

If this PR still needs to be reviewed, as an author, you can rebase it to reset the clock.

If you believe I commented on this pull request incorrectly, please report this here.

@astrofrog astrofrog modified the milestones: v4.0.2, v4.0.3, v4.0.4 Oct 10, 2020
@bsipocz bsipocz modified the milestones: v4.0.4, v4.0.5 Nov 25, 2020
@eteq eteq modified the milestones: v4.0.5, v4.0.6 Mar 18, 2021
@lpsinger

lpsinger commented Apr 7, 2021

Copy link
Copy Markdown
Contributor Author

I see that this has been re-milestoned several times. Would you like me to rebase it?

@pllim

pllim commented Apr 7, 2021

Copy link
Copy Markdown
Member

@lpsinger , thanks for pinging us. Personally, I am not convinced that this is the correct solution.

It is weird that the pytest.importorskip("matplotlib") is in __init__.py of a non-test code, so that definitely needs to be fixed, but not like this. Perhaps @astrofrog or @Cadair can provide some insight.

@astrofrog

astrofrog commented Apr 7, 2021 •

Copy link
Copy Markdown
Member

I wonder if we could use

doctest_subpackage_requires =
to prevent issues with pytest when matplotlib is not installed? (Not at computer so can't check right now)

@lpsinger

lpsinger commented Apr 7, 2021

Copy link
Copy Markdown
Contributor Author

FWIW, I tried putting the pytest.importorskip in a conftest.py module, and it didn't work.

@lpsinger

lpsinger commented Apr 7, 2021

Copy link
Copy Markdown
Contributor Author

I wonder if we could use

doctest_subpackage_requires =

to prevent issues with pytest when matplotlib is not installed? (Not at computer so can't check right now)

Just tried that. Didn't work.

@pllim

pllim commented Apr 7, 2021

Copy link
Copy Markdown
Member

What about moving pytest.importorskip("matplotlib") to each of the affected test modules, and deleting it from __init__.py? Sure, it is more duplication but it is more correct, no?

@lpsinger

lpsinger commented Apr 7, 2021

Copy link
Copy Markdown
Contributor Author

What about moving pytest.importorskip("matplotlib") to each of the affected test modules, and deleting it from __init__.py? Sure, it is more duplication but it is more correct, no?

That would not work. The import errors occur during collection, not while running the tests.

@pllim

pllim commented Apr 7, 2021

Copy link
Copy Markdown
Member

The import errors occur during collection

Ah, right, that rings a faraway bell now.

Sigh... How does io.misc do it? I mean, they use optional dependencies too and I don't see pytest imported in astropy/io/misc/asdf/__init__.py

@astrofrog astrofrog modified the milestones: v4.0.6, v4.0.7 Aug 24, 2021
@github-actions github-actions Bot added the Close? Tell stale bot that this issue/PR is stale label Sep 3, 2021
@github-actions

github-actions Bot commented Sep 4, 2021

Copy link
Copy Markdown
Contributor

Hi humans 👋 - this pull request hasn't had any new commits for approximately 1 year, 4 months. I plan to close this in 30 days if the pull request doesn't have any new commits by then.

In lieu of a stalled pull request, please consider closing this and open an issue instead if a reminder is needed to revisit in the future. Maintainers may also choose to add keep-open label to keep this PR open but it is discouraged unless absolutely necessary.

If this PR still needs to be reviewed, as an author, you can rebase it to reset the clock.

If you believe I commented on this pull request incorrectly, please report this here.

@github-actions github-actions Bot added the closed-by-bot Closed by stale bot label Oct 5, 2021
@github-actions

github-actions Bot commented Oct 5, 2021

Copy link
Copy Markdown
Contributor

I'm going to close this pull request as per my previous message. If you think what is being added/fixed here is still important, please remember to open an issue to keep track of it. Thanks!

If this is the first time I am commenting on this issue, or if you believe I closed this issue incorrectly, please report this here.

@github-actions github-actions Bot closed this Oct 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants