Skip to content
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

Allow printing show_versions() to in-memory buffer to enable testing #2399

Merged
merged 3 commits into from
Mar 6, 2023

Conversation

weiji14
Copy link
Member

@weiji14 weiji14 commented Mar 5, 2023

Description of proposed changes

To increase code coverage of __init__.py, check the output of pygmt.show_versions() that is printed to an in-memory string buffer instead of stdout.

Adapted from https://github.com/xarray-contrib/xbatcher/blob/v0.2.0/xbatcher/tests/test_print_versions.py. Was looking through some code in xbatcher and noticed the neat print(..., file=io.StringIO) trick. Thanks @maxrjones!

Patches code coverage since #466

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If wrapping a new module, open a 'Wrap new GMT module' issue and submit reasonably-sized PRs.
  • If adding new functionality, add an example to docstrings or tutorials.
  • Use underscores (not hyphens) in names of Python files and directories.

Slash Commands

You can write slash commands (/command) in the first line of a comment to perform
specific operations. Supported slash commands are:

  • /format: automatically format and lint the code
  • /test-gmt-dev: run full tests on the latest GMT development version

To increase code coverage of `__init__.py`, check the output of `pygmt.show_versions()` that is printed to an in-memory string buffer instead of stdout. Adapted from https://github.com/xarray-contrib/xbatcher/blob/v0.2.0/xbatcher/tests/test_print_versions.py
@weiji14 weiji14 added the maintenance Boring but important stuff for the core devs label Mar 5, 2023
@weiji14 weiji14 added this to the 0.9.0 milestone Mar 5, 2023
@weiji14 weiji14 self-assigned this Mar 5, 2023
Also made the docstring for test_show_versions() a bit more descriptive.
@weiji14 weiji14 marked this pull request as ready for review March 5, 2023 22:49
@weiji14
Copy link
Member Author

weiji14 commented Mar 5, 2023

Code coverage report for this PR is at https://app.codecov.io/gh/GenericMappingTools/pygmt/pull/2399. The coverage for __init__.py has increased from 23.17% to 71.95% (+48.78%)

@seisman
Copy link
Member

seisman commented Mar 5, 2023

Looks great!

There is a unrelated CI failure, which is likely caused by recent upstream changes like GenericMappingTools/gmt#7295

____________________________ test_plot3d_projection ____________________________

args = ()
kwargs = {'data': array([[43.4847,  0.6227,  0.5309],
       [22.331 ,  3.7556,  0.3817],
       [40.8023,  5.5903,  0.7764],
 ...,  0.4305],
       [28.1125,  3.8456,  0.9338],
       [47.8333, -0.[722](https://github.com/GenericMappingTools/pygmt/actions/runs/4338387570/jobs/7575047135#step:17:723)5,  0.5969]]), 'region': [10, 70, -5, 10, 0, 1]}

    def wrapper(*args, **kwargs):
>       store.return_value[test_name] = obj(*args, **kwargs)

../../../../miniconda3/envs/pygmt/lib/python3.11/site-packages/pytest_mpl/plugin.py:107: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../pygmt/tests/test_plot3d.py:100: in test_plot3d_projection
    fig.plot3d(
../pygmt/helpers/decorators.py:818: in new_module
    return module_func(*args, **kwargs)
../pygmt/helpers/decorators.py:598: in new_module
    return module_func(*args, **kwargs)
../pygmt/helpers/decorators.py:738: in new_module
    return module_func(*args, **kwargs)
../pygmt/src/plot3d.py:242: in plot3d
    lib.call_module(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pygmt.clib.session.Session object at 0x14a06ae90>, module = 'plot3d'
args = '@GMTAPI@-S-I-D-V-T-N-000000 -Bag -Bzag -Ggreen -JR270/10c -Jz5 -R10/70/-5/10/0/1 -Ss1c -p225/30'

    def call_module(self, module, args):
        """
        Call a GMT module with the given arguments.
    
        Makes a call to ``GMT_Call_Module`` from the C API using mode
        ``GMT_MODULE_CMD`` (arguments passed as a single string).
    
        Most interactions with the C API are done through this function.
    
        Parameters
        ----------
        module : str
            Module name (``'coast'``, ``'basemap'``, etc).
        args : str
            String with the command line arguments that will be passed to the
            module (for example, ``'-R0/5/0/10 -JM'``).
    
        Raises
        ------
        GMTCLibError
            If the returned status code of the function is non-zero.
        """
        c_call_module = self.get_libgmt_func(
            "GMT_Call_Module",
            argtypes=[ctp.c_void_p, ctp.c_char_p, ctp.c_int, ctp.c_void_p],
            restype=ctp.c_int,
        )
    
        mode = self["GMT_MODULE_CMD"]
        status = c_call_module(
            self.session_pointer, module.encode(), mode, args.encode()
        )
        if status != 0:
>           raise GMTCLibError(
                f"Module '{module}' failed with status code {status}:\n{self._error_message}"
            )
E           pygmt.exceptions.GMTCLibError: Module 'plot3d' failed with status code 74:
Error:      plot3d [ERROR]: Western boundary is > 180 degrees from specified central meridian and thus your region is invalid
Error:      plot3d [ERROR]: General map projection error

../pygmt/clib/session.py:510: GMTCLibError
----------------------------- Captured stderr call -----------------------------
Error: [ERROR]: Western boundary is > 180 degrees from specified central meridian and thus your region is invalid
Error: [ERROR]: General map projection error

@seisman seisman added the final review call This PR requires final review and approval from a second reviewer label Mar 5, 2023
@seisman
Copy link
Member

seisman commented Mar 5, 2023

Looks great!

There is a unrelated CI failure, which is likely caused by recent upstream changes like GenericMappingTools/gmt#7295

____________________________ test_plot3d_projection ____________________________

args = ()
kwargs = {'data': array([[43.4847,  0.6227,  0.5309],
       [22.331 ,  3.7556,  0.3817],
       [40.8023,  5.5903,  0.7764],
 ...,  0.4305],
       [28.1125,  3.8456,  0.9338],
       [47.8333, -0.[722](https://github.com/GenericMappingTools/pygmt/actions/runs/4338387570/jobs/7575047135#step:17:723)5,  0.5969]]), 'region': [10, 70, -5, 10, 0, 1]}

    def wrapper(*args, **kwargs):
>       store.return_value[test_name] = obj(*args, **kwargs)

../../../../miniconda3/envs/pygmt/lib/python3.11/site-packages/pytest_mpl/plugin.py:107: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../pygmt/tests/test_plot3d.py:100: in test_plot3d_projection
    fig.plot3d(
../pygmt/helpers/decorators.py:818: in new_module
    return module_func(*args, **kwargs)
../pygmt/helpers/decorators.py:598: in new_module
    return module_func(*args, **kwargs)
../pygmt/helpers/decorators.py:738: in new_module
    return module_func(*args, **kwargs)
../pygmt/src/plot3d.py:242: in plot3d
    lib.call_module(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pygmt.clib.session.Session object at 0x14a06ae90>, module = 'plot3d'
args = '@GMTAPI@-S-I-D-V-T-N-000000 -Bag -Bzag -Ggreen -JR270/10c -Jz5 -R10/70/-5/10/0/1 -Ss1c -p225/30'

    def call_module(self, module, args):
        """
        Call a GMT module with the given arguments.
    
        Makes a call to ``GMT_Call_Module`` from the C API using mode
        ``GMT_MODULE_CMD`` (arguments passed as a single string).
    
        Most interactions with the C API are done through this function.
    
        Parameters
        ----------
        module : str
            Module name (``'coast'``, ``'basemap'``, etc).
        args : str
            String with the command line arguments that will be passed to the
            module (for example, ``'-R0/5/0/10 -JM'``).
    
        Raises
        ------
        GMTCLibError
            If the returned status code of the function is non-zero.
        """
        c_call_module = self.get_libgmt_func(
            "GMT_Call_Module",
            argtypes=[ctp.c_void_p, ctp.c_char_p, ctp.c_int, ctp.c_void_p],
            restype=ctp.c_int,
        )
    
        mode = self["GMT_MODULE_CMD"]
        status = c_call_module(
            self.session_pointer, module.encode(), mode, args.encode()
        )
        if status != 0:
>           raise GMTCLibError(
                f"Module '{module}' failed with status code {status}:\n{self._error_message}"
            )
E           pygmt.exceptions.GMTCLibError: Module 'plot3d' failed with status code 74:
Error:      plot3d [ERROR]: Western boundary is > 180 degrees from specified central meridian and thus your region is invalid
Error:      plot3d [ERROR]: General map projection error

../pygmt/clib/session.py:510: GMTCLibError
----------------------------- Captured stderr call -----------------------------
Error: [ERROR]: Western boundary is > 180 degrees from specified central meridian and thus your region is invalid
Error: [ERROR]: General map projection error

Reported in GenericMappingTools/gmt#7295 (comment)

@weiji14 weiji14 merged commit bc7779d into main Mar 6, 2023
@weiji14 weiji14 deleted the show-versions-stringio branch March 6, 2023 19:38
@weiji14 weiji14 removed the final review call This PR requires final review and approval from a second reviewer label Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Boring but important stuff for the core devs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants