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

pygmt.which: Fix the bug when passing multiple files #2726

Merged
merged 3 commits into from
Oct 15, 2023
Merged

pygmt.which: Fix the bug when passing multiple files #2726

merged 3 commits into from
Oct 15, 2023

Conversation

seisman
Copy link
Member

@seisman seisman commented Oct 9, 2023

Description of proposed changes

Issue first reported in #2361 (comment). See that issue for context.

To reproduce the issue:

>>> from pygmt import which
>>> # doesn't work
>>> which(["@hotspots.txt", "@earth_relief_01d_g"])
gmtwhich [ERROR]: File ['@hotspots.txt', not found!
gmtwhich [ERROR]: File '@earth_relief_01d_g'] not found!
>>> # works
>>> which(fname=["@hotspots.txt", "@earth_relief_01d_g"])

Address #2361.

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

@seisman seisman added the bug Something isn't working label Oct 9, 2023
@seisman seisman added this to the 0.11.0 milestone Oct 9, 2023


def test_which_multiple():
"""
Make sure `which` returns file paths for multiple @files correctly.
"""
filenames = ["ridge.txt", "tut_ship.xyz"]
cached_files = which(fname=[f"@{fname}" for fname in filenames], download="c")
cached_files = which([f"@{fname}" for fname in filenames], download="c")
Copy link
Member Author

Choose a reason for hiding this comment

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

Now we can pass a list of files without having to use fname=

@seisman seisman added the needs review This PR has higher priority and needs review. label Oct 9, 2023
@seisman seisman requested a review from a team October 12, 2023 01:54
pygmt/tests/test_which.py Outdated Show resolved Hide resolved
use_alias,
)


@fmt_docstring
@use_alias(G="download", V="verbose")
@kwargs_to_strings(fname="sequence_space")
def which(fname, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

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

Reading up on https://peps.python.org/pep-0570/#positional-or-keyword-arguments and https://stackoverflow.com/questions/9450656/positional-argument-vs-keyword-argument (see also Max's previous comment at #731 (comment)), should we explicitly mark fname as positional_or_keyword like this (unsure if syntax is ok)?

Suggested change
def which(fname, **kwargs):
def which(/, fname, *, **kwargs):

Or just stick with the current one (which works also I think).

Copy link
Member Author

Choose a reason for hiding this comment

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

Better to open a separate issue so that we can have more discussions about the behavior and also have consistent function definitions in the whole project.

Copy link
Member

@weiji14 weiji14 Oct 15, 2023

Choose a reason for hiding this comment

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

On second thought, maybe we should enforce using keyword-only arguments like so:

Suggested change
def which(fname, **kwargs):
def which(*, fname, **kwargs):

Then the gmtwhich [ERROR] you mentioned at #2361 (comment) would turn into a slightly more useful error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 cached_files = which([f"@{fname}" for fname in filenames], download="c")

File ~/pygmt/pygmt/helpers/decorators.py:598, in use_alias.<locals>.alias_decorator.<locals>.new_module(*args, **kwargs)
    591     msg = (
    592         "Parameters 'Y' and 'yshift' are deprecated since v0.8.0. "
    593         "and will be removed in v0.12.0. "
    594         "Use Figure.shift_origin(yshift=...) instead."
    595     )
    596     warnings.warn(msg, category=SyntaxWarning, stacklevel=2)
--> 598 return module_func(*args, **kwargs)

TypeError: which() takes 0 positional arguments but 1 was given

Well, actually not that useful (it doesn't say that the fname keyword should be used. But something to consider - if we want to allow 1) positional_or_keyword (current), or 2) only keyword.

Copy link
Member Author

Choose a reason for hiding this comment

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

Instead, I prefer to def which(fname, *, **kwargs). It allows which("file.txt") which is much simpler than which(fname="file.txt").

Copy link
Member

Choose a reason for hiding this comment

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

Ok, let's go with that. I'll approve this PR, but you can apply the change afterwards.

Copy link
Member Author

Choose a reason for hiding this comment

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

def which(fname, *, **kwargs)

gives a syntax error:

'named arguments must follow bare *

See https://stackoverflow.com/questions/14301967/what-does-a-bare-asterisk-do-in-a-parameter-list-what-are-keyword-only-parame.

I'll leave the function definition as it is now.

use_alias,
)


@fmt_docstring
@use_alias(G="download", V="verbose")
@kwargs_to_strings(fname="sequence_space")
def which(fname, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

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

Ok, let's go with that. I'll approve this PR, but you can apply the change afterwards.

@seisman seisman merged commit 55c058a into main Oct 15, 2023
15 of 16 checks passed
@seisman seisman deleted the which branch October 15, 2023 10:08
@seisman seisman removed the needs review This PR has higher priority and needs review. label Oct 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants