Public hypothesis strategies for generating xarray data
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.2k
- Forks
- 1.4k
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 14
Description
Proposal
We should expose a public set of hypothesis strategies for use in testing xarray code. It could be useful for downstream users, but also for our own internal test suite. It should live in xarray.testing.strategies. Specifically perhaps
xarray.testing.strategies.variablesxarray.testing.strategies.dataarraysxarray.testing.strategies.datasets- (
xarray.testing.strategies.datatrees?) xarray.testing.strategies.indexesxarray.testing.strategies.chunksizesfollowingdask.array.testing.strategies.chunks
This issue is different from #1846 because that issue describes how we could use such strategies in our own testing code, whereas this issue is for how we create general strategies that we could use in many places (including exposing publicly).
I've become interested in this as part of wanting to see #6894 happen. #6908 would effectively close this issue, but itself is just a pulled out section of all the work @keewis did in #4972.
(Also xref https://github.com/pydata/xarray/issues/2686. Also also @max-sixty didn't you have an issue somewhere about creating better and public test fixtures?)
Previous work
I was pretty surprised to see this comment by @Zac-HD in #1846
@rdturnermtl wrote a Hypothesis extension for Xarray, which is at least a nice demo of what's possible.
given that we might have just used that instead of writing new ones in #4972! (@keewis had you already seen that extension?)
We could literally just include that extension in xarray and call this issue solved...
Shrinking performance of strategies
However I was also reading about strategies that shrink yesterday and think that we should try to make some effort to come up with strategies for producing xarray objects that shrink in a performant and well-motivated manner. In particular by pooling the knowledge of the @xarray-dev core team we could try to create strategies that search for many of the edge cases that we are collectively aware of.
My understanding of that guide is that our strategies ideally should:
-
Quickly include or exclude complexity
For instance
if draw(booleans()): # then add coordinates to generated dataset.It might also be nice to have strategy constructors which allow passing other strategies in, so the user can choose how much complexity they want their strategy to generate. e.g. I think a signature like this should be possible
from hypothesis import strategies as st @st.composite def dataarrays( data: xr.Variable | st.SearchStrategy[xr.Variable] | duckarray | st.SearchStrategy[duckarray] | None ..., coords: ..., dims: ..., attrs: ..., name: ..., ) -> st.SearchStrategy[xr.DataArray]: """ Hypothesis strategy for generating arbitrary DataArray objects. Parameters ---------- data Can pass an absolute value of an appropriate type (i.e. `Variable`, `np.ndarray` etc.), or pass a strategy which generates such types. Default is that the generated DataArray could contain any possible data. ... (similar flexibility for other constructor arguments) """ ... -
Deliberately generate known edge cases
For instance deliberately create:
- dimension coordinates,
- names which are Hashable but not strings,
- multi-indexes,
- weird dtypes,
- NaNs,
- duckarrays instead of
np.ndarray, - inconsistent chunking between different variables,
- (any other ideas?)
-
Be very modular internally, to help with "keeping things local"
Each sub-strategy should be in its own function, so that hypothesis' decision tree can cut branches off as soon as possible.
-
Avoid obvious inefficiencies
e.g. not
.filter(...)orassume(...)if we can help it, and if we do need them then keep them in the same function that generates that data. Plus just keep all sizes small by default.
Perhaps the solutions implemented in #6894 or this hypothesis xarray extension already meet these criteria - I'm not sure. I just wanted a dedicated place to discuss building the strategies specifically, without it getting mixed in with complicated discussions about whatever we're trying to use the strategies for!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed xarray.testing.strategies namespace, the existing hypothesis-gufunc extension, and the work referenced in #6894 and #6908. Compare possible variables, dataarrays, datasets, datatrees, indexes, and chunksizes strategies against the shrinking and edge-case goals. Done means an agreed, reusable public strategy set with appropriate tests and documentation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100