Skip to content

Commit eead974

Browse files
maxrjoneswillschlitzerseismanweiji14yvonnefroehlich
authored
Add contributing guides for wrapping a GMT module (#1687)
Co-authored-by: Will Schlitzer <schlitzer90@gmail.com> Co-authored-by: Dongdong Tian <seisman.info@gmail.com> Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> Co-authored-by: Yvonne Fröhlich <94163266+yvonnefroehlich@users.noreply.github.com>
1 parent 7926a95 commit eead974

1 file changed

Lines changed: 83 additions & 9 deletions

File tree

doc/contributing.md

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,11 @@ To increase the chances of getting your pull request accepted quickly, try to:
163163
- Write tests for the code you wrote/modified if needed.
164164
Please refer to [Testing your code](contributing.md#testing-your-code) or
165165
[Testing plots](contributing.md#testing-plots).
166-
- Include an example of new features in the gallery or tutorials.
167-
Please refer to [Gallery plots](contributing.md#contributing-gallery-plots)
168-
or [Tutorials](contributing.md#contributing-tutorials).
166+
- Include an example of new features in the gallery or tutorials. Please refer to
167+
[Gallery plots](contributing.md#contributing-gallery-plots) or
168+
[Tutorials](contributing.md#contributing-tutorials). If adding a new
169+
method/function/class, the gallery example or tutorial should be submitted in a
170+
separate pull request.
169171
* Have a good coding style
170172
- Use readable code, as it is better than clever code (even with comments).
171173
- Follow the [PEP8](https://pep8.org) style guide for code and the
@@ -466,14 +468,15 @@ function/class/module/method.
466468

467469
### PyGMT Code Overview
468470

469-
The source code for PyGMT is located in the `pygmt/` directory. When contributing
470-
code, be sure to follow the general guidelines in the
471-
[pull request workflow](contributing.md#pull-request-workflow) section.
471+
The source code for PyGMT is located in the `pygmt/` directory. When contributing code,
472+
please open an issue first to discuss the feature and its implementation and be sure to
473+
follow the general guidelines in the [pull request workflow](#pull-request-workflow)
474+
section.
472475

473476
### Code Style
474477

475478
We use the [ruff](https://docs.astral.sh/ruff) tool to format the code, so we
476-
don't have to think about it. It loosely follow the [PEP8](https://pep8.org) guide
479+
don't have to think about it. It loosely follows the [PEP8](https://pep8.org) guide
477480
but with a few differences. Regardless, you won't have to worry about formatting
478481
the code yourself. Before committing, run it to automatically format your code:
479482

@@ -511,6 +514,77 @@ contains rules for running the linter checks:
511514
make check # Runs ruff in check mode
512515
```
513516

517+
### Wrapping a GMT Module
518+
519+
Wrapping a GMT module in PyGMT is usually a big task, but it can progress more smoothly
520+
and efficiently when divided into **small, manageable chunks**. This section gives an
521+
overview of the main tasks involved.
522+
523+
1. Open "wrapper request" issue - create a feature request for wrapping a module and
524+
discuss what features should be available in the wrapper [optional, usually done by
525+
users].
526+
2. Open a "wrapper tracking" issue - use the "Wrapper for a GMT module" issue template,
527+
to track the progress of wrapping the module. Link it to the
528+
[Project board](https://github.com/orgs/GenericMappingTools/projects/3), and close
529+
the "wrapper request issue" with a comment such as [usually done by maintainers]:
530+
> Thank you for opening the feature request. The progress of wrapping the module will
531+
> be tracked in issue #XXX and
532+
> the [Project board](https://github.com/orgs/GenericMappingTools/projects/3).
533+
3. Open one PR for the initial implementation, focusing on required and essential
534+
parameters [done by maintainers or contributors].
535+
4. Close the "wrapper tracking issue" once the initial implementation is merged. Leave a
536+
comment such as [done by maintainers]:
537+
> The initial implementation of wrapping the XXX module was completed in PR #XXX.
538+
> Not all functionalities are implemented yet. Further progress will be tracked in
539+
> the Project board.
540+
This is necessary to avoid having too many long-term open issues.
541+
5. Open one or more PRs to implement the remaining features and missing aliases.
542+
6. Open one PR to add a gallery example or a tutorial.
543+
544+
These PRs can be split among multiple contributors. There is no obligation for a single
545+
contributor to complete all steps. Please comment on the "wrapper tracking issue" if you
546+
would like to open a PR for any of these tasks to avoid redundant efforts.
547+
548+
#### Initial Feature Implementation
549+
550+
First, comment on the "Wrapper tracking issue" that you will be working on the initial
551+
implementation. This first pull request should be as minimal as possible - only adding
552+
the required functionality (i.e., wrapping the required GMT parameters and supporting
553+
the primary input/output types).
554+
555+
The following steps are common to all initial implementation pull requests that wrap a
556+
GMT module:
557+
558+
* Create a new module `<module-name>.py` in `pygmt/src`. The module docstring should
559+
include the module name and a short description of the functionality (e.g.,
560+
`grdfill - Fill blank areas from a grid.`).
561+
* Add a function `<module-name>` to the module. When writing the new function, it is
562+
generally easiest to reference the source code for other functions that input/output
563+
similar object types.
564+
* Write a detailed docstring following the
565+
[numpy style guide](https://numpydoc.readthedocs.io/en/latest/format.html).
566+
* Add the function to the import statements in `pygmt/src/__init__.py` and
567+
`pygmt/__init__.py`.
568+
* Add the function to appropriate section of the API documentation in `doc/api/index.rst`.
569+
* Add a testing module `test_<module-name>.py` in `pygmt/tests`, following
570+
the guidelines in the [testing your code](#testing-your-code) section.
571+
572+
#### Add Missing Aliases
573+
574+
After the initial implementation, missing aliases can be added in separate PRs:
575+
576+
* Select a suitable alias for each GMT option, following the guidelines in the
577+
[code style](#code-style) section. Before creating a new alias, check:
578+
579+
- whether the parameter is listed in the `COMMON_DOCSTRINGS` dictionary in
580+
`pygmt/helpers/decorators.py`
581+
- whether other wrapped GMT modules have a similar parameter
582+
- whether [GMT.jl](https://www.generic-mapping-tools.org/GMT.jl/dev/) has defined an alias
583+
* Add the alias to the `AliasSystem` class and the function signature.
584+
* Add the alias and description to the parameters section of the docstring, using the
585+
`fmt_docstring` decorator to add descriptions for parameters included in the
586+
`COMMON_DOCSTRINGS` dictionary.
587+
514588
### Testing your Code
515589

516590
Automated testing helps ensure that our code is as free of bugs as it can be.
@@ -524,10 +598,10 @@ existing functionality.
524598
Tests also help us be confident that we won't break your code in the future.
525599

526600
When writing tests, don't test everything that the GMT function already tests, such as
527-
the every unique combination arguments. An exception to this would be the most popular
601+
every unique combination of arguments. An exception to this would be the most popular
528602
methods, such as <code>pygmt.Figure.plot</code> and <code>pygmt.Figure.basemap</code>.
529603
The highest priority for tests should be the Python-specific code, such as numpy,
530-
pandas, and xarray objects and the virtualfile mechanism.
604+
pandas, and Xarray objects and the virtualfile mechanism.
531605

532606
If you're **new to testing**, see existing test files for examples of things to do.
533607
**Don't let the tests keep you from submitting your contribution!**

0 commit comments

Comments
 (0)