Skip to content

Refactor the reference section of the docs #4311

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

Merged
merged 14 commits into from
Mar 22, 2025

Conversation

tybug
Copy link
Member

@tybug tybug commented Mar 18, 2025

Still a large pr but there's no sane way to split most of this without causing more work for me, thanks to all the inter-references. I could split the redirect extension off is probably the biggest thing

There's a minor amount of added or removed content here, but most of it is moving around existing stuff into their own page

@@ -1,19 +1,8 @@
====================
Reproducing failures
====================
Copy link
Member Author

Choose a reason for hiding this comment

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

My heading ordering is single =, single -, single ~ (and if you need to go beyond that you're probably doomed anyway). I try to avoid double headers for anything, but I think I might be the odd one out here, because e.g. the python rst guide recommends double headers for chapters. In defense of single headers, the python docs have way more structure than we do!

@tybug tybug mentioned this pull request Mar 18, 2025
36 tasks
ab_c = (a + b) + c
a_bc = a + (b + c)
difference = abs(ab_c - a_bc)
target(difference) # Without this, the test almost always passes
Copy link
Contributor

Choose a reason for hiding this comment

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

As fas as I can tell, target makes little difference here. Around 40% discover rate with or without it.

Copy link
Member Author

Choose a reason for hiding this comment

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

same..I'm not going to follow up on this right now, but I've added it as a TODO to #4309

Copy link
Contributor

@jobh jobh Mar 20, 2025

Choose a reason for hiding this comment

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

Thanks! A comment for that time (ignore for this PR) is that target likely doesn't work well here because difference is constant for large regions of the input space.

We might want to comment that the target should be fairly smooth, not discrete-valued, and not added willy-nilly as it may actually reduce bug-finding power with the default example budget (as indicated below).

For background, the optimiser seems to get more stuck than I'd expect in these flat regions. E.g.,

@given(st.floats())
@settings(database=None, phases=[Phase.generate, Phase.target])
def test_target(f):
    target(f > 1e5)
    print(f)

doesn't vary f very much inside the True region. Fair enough, but perhaps worth noting.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is great. I think target used to be better at this on the bytestring since a continuous in bytes could easily lead to discontinuous change in the output, which is less likely on the typed choice sequence. We might have to reintroduce a simulated annealing-style approach for each of the 5 primitive types.

@Zac-HD
Copy link
Member

Zac-HD commented Mar 19, 2025

Quick thoughts again:

  • Yeah, this is going to be about at our size limit, but I agree that chopping it up more wouldn't really be a net improvement.
  • IMO, searchability is really important for API reference docs. "land on page, cmd-f, done" is a key usecase that e.g. pytest serves well these days.
    • If that's way too large, one page for all of the strategies, and one for everything else?
    • Some of the stuff currently in reference docs will presumably move to explanations or how-tos later.
  • Makes sense to switch from .. automodule:: ..., but we should then add a test that we document every function in the strategies module (or perhaps everything listed in any __all__ attribute?
  • Haven't run through all the detail yet, since I'm expecting files to move around again.

@tybug
Copy link
Member Author

tybug commented Mar 19, 2025

yeah it's a fair point, I'm on board with one big page for the api reference. It'll be a bit awkward until we move the more tutorial-style things out from the api reference, but still an improvement on the status quo.

@tybug
Copy link
Member Author

tybug commented Mar 20, 2025

so I know we said just one or two reference pages, but I was working through this and I think there's a valid distinction between "api/coding reference" and "'meta' reference", like observability or the pytest plugin, which I've kept in separate pages for the moment. They don't feel right to me in an api reference page, because they don't have an in-library method exposed by Hypothesis.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we will eventually want to move this page somewhere better ("how to write type hints for your strategies"?), or remove it entirely, but top level is fine during the transition

Copy link
Member

Choose a reason for hiding this comment

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

Agree on both counts. We could start it out as e.g./how-to/type-annotate-strategies so that we can keep the URL longer term; I think it can still be top-level in the TOC regardless of location.

@tybug
Copy link
Member Author

tybug commented Mar 21, 2025

I've added a test to check that all exported names are documented, as recommended. This turned up a bug in the current docs where hypothesis.extra.numpy.boolean_dtypes is not documented. I couldn't figure out why, and since it's not a new issue I've added it as a todo item in the tracking list. NVM, immediately after sending this I realized it was because boolean_dtypes didn't have a docstring attached. I've fixed that too here.

Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

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

More scattered thoughts, and appreciation for the ongoing work 🙏

Copy link
Member

Choose a reason for hiding this comment

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

Agree on both counts. We could start it out as e.g./how-to/type-annotate-strategies so that we can keep the URL longer term; I think it can still be top-level in the TOC regardless of location.

Comment on lines +184 to +209
.. automodule:: xps
:members:
from_dtype,
Copy link
Member

Choose a reason for hiding this comment

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

Oooh... does your excellent new test check that this is complete? It's not an importable module, exactly...

Comment on lines 6 to 8
Strategy objects tell Hypothesis what types of inputs to generate. For instance, passing ``st.lists(st.integers(), min_size=1)`` to |@given| tells Hypothesis to generate lists of integers with at least one element.

Strategies can be combined using :ref:`combinator strategies <combinators>`, or modified using |strategy.filter|, |strategy.map|, or |strategy.flatmap|.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Strategy objects tell Hypothesis what types of inputs to generate. For instance, passing ``st.lists(st.integers(), min_size=1)`` to |@given| tells Hypothesis to generate lists of integers with at least one element.
Strategies can be combined using :ref:`combinator strategies <combinators>`, or modified using |strategy.filter|, |strategy.map|, or |strategy.flatmap|.
Strategies are the way we describe values for |@given| to generate. For instance, ``st.lists(st.integers(), min_size=1)`` tells Hypothesis to generate lists of integers with at least one element.
This reference page lists all of Hypothesis' first-party functions which return a strategy; there are also many provided by <third-party libraries>(xref), and you can define your own too. Note that people often say "strategy" when they mean "function returning a strategy"; it's usually clear from context which they meant.
Strategies can be passed to many strategy functions as arguments, combined using :ref:`combinator strategies <combinators>`, and modified using |strategy.filter|, |strategy.map|, or |strategy.flatmap|.

Copy link
Member Author

Choose a reason for hiding this comment

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

Strategies can be passed to many strategy functions as arguments

I get the distinction you're making, and I think it's worth making, but this is a confusing sentence to parse imo. Bite the technical incorrectness and say "strategies can be passed to other strategies as arguments"?

I've applied a variant of this, but happy to tweak further

Copy link
Member

Choose a reason for hiding this comment

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

I do think we need to call out both the distinction and the common sloppy usage in this explanatory header, but don't care exactly how we do that.

Copy link
Member

@Zac-HD Zac-HD left a comment

Choose a reason for hiding this comment

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

I think we're done with this part - obviously there are plenty of followups, but I feel good about shipping this as a single cohesive change for our users 😁

@Zac-HD Zac-HD enabled auto-merge March 22, 2025 08:16
@Zac-HD Zac-HD force-pushed the docs-reference branch 4 times, most recently from e6cfb7a to eb7aeb9 Compare March 22, 2025 09:38
@Zac-HD Zac-HD merged commit ccb8ec2 into HypothesisWorks:master Mar 22, 2025
50 of 51 checks passed
@tybug tybug deleted the docs-reference branch March 22, 2025 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants