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

feature: Adding Python type hints for input specifications #2298

Open
dannbuckley opened this issue Sep 2, 2024 · 5 comments
Open

feature: Adding Python type hints for input specifications #2298

dannbuckley opened this issue Sep 2, 2024 · 5 comments
Labels
enhancement in progress enhancement in progress
Milestone

Comments

@dannbuckley
Copy link

Is your feature request related to a problem? Please describe.
The documentation for the "type recarray" entries in the dfn specifications is sometimes hard to understand. These parameters might be a little easier to understand if there were type annotations in the __init__ definitions. This is sort of already done in the package docstring, but the docstring is written in MODFLOW descriptive types.

Describe the solution you'd like
Add an annotation line to the dfn specification to store Python type information, and modify the createpackages.py utility to add Python type annotations to the package __init__ definition.

Example dfn change (sim-tdis.dfn):

block perioddata
name perioddata
type recarray perlen nstp tsmult
+ annotation = tuple[tuple[float, int, float], ...]
reader urword
optional false
longname stress period time information
description
default_value ((1.0, 1, 1.0),)

Example __init__ change after updating packages: (mftdis.py):

def __init__(
    self,
    simulation,
    ...,
-   perioddata=((1.0, 1, 1.0),),
+   perioddata: tuple[tuple[float, int, float], ...] = ((1.0, 1, 1.0),),
    ...,
):
    ...

Additional context
Some examples:

@wpbonelli wpbonelli added this to the 4.0 milestone Sep 3, 2024
@wpbonelli wpbonelli added the in progress enhancement in progress label Sep 3, 2024
@wpbonelli
Copy link
Member

@dannbuckley

Thanks for this. Agreed that the mapping between the MF6 input spec and the Python/FloPy equivalent is not always clear. Your timing is excellent, we have just begun to think on this for the next major version.

Embedding Python type annotations in the DFN would be one approach, but I think we want to avoid coupling MF6 or any other program's input specification to Python. It's not MF6's concern how flopy represents input parameters, nor is it flopy's concern how MF6 does so — notwithstanding the fact that users must currently concern themselves with such, since flopy reproduces a lot of MF6 implementation details. But IMO we want to get away from that.

We could aim instead for a pythonic specification with a sound type-theoretic basis, which is translated under the hood into a form suitable for MF6 or whatever program FloPy is driving. I think there are a few parts to this, which could form the foundation of a generic plugin framework anyone could implement to bind flopy to a model code:

  • rigorous type-hinting in the classes forming a program's interface
  • named/structured tuples — e.g., List[Period] where Period is either an alias for tuple[float, int, float] or an explicit record class
  • a serialization layer to map Python input context to the format expected by the underlying program — conversion logic lives here, and only the plugin developer has to care about the details of the mapping

This would also allow consistent APIs for MF6 and older MODFLOW programs, which is a major friction point as it stands.

@dannbuckley
Copy link
Author

@wpbonelli

I'll throw a couple of other options out here too. The dataclasses module was added to the standard library in 3.7. I think it was meant as a replacement for named tuples, but is still somewhat limited. There's also attrs, which I think has better support for inheritance/subclassing.

@wpbonelli
Copy link
Member

@dannbuckley we are working on an attrs-based prototype right this moment, in fact!

@wpbonelli
Copy link
Member

do you mind editing the issue title? maybe "type hints for input specifications" or something reflecting the more general utility of typing annotations

@dannbuckley dannbuckley changed the title feature: Adding Python type annotations in the MODFLOW 6 dfn specifications feature: Adding Python type hints for input specifications Sep 5, 2024
@wpbonelli
Copy link
Member

@dannbuckley I had an initial look at how we might generate named tuples alongside the components they appear in and substitute them into docstrings and typehints, I think your suggestion to add type hints is achievable in the near term (pre v4). More to come soon

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

No branches or pull requests

2 participants