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

Teach the Ghostwriter about @staticmethod and @classmethod methods #3354

Merged
merged 55 commits into from
Jun 7, 2022

Conversation

Cheukting
Copy link
Contributor

@Cheukting Cheukting commented May 19, 2022

In this PR:

  • makes the CLI understands module_a.ClassA.function
  • make sure roundtrip works and not get confused with functions in other classes
  • improve on 'magic discovery' and make it works with classes
    • Discover class/static methods when input just module
    • Accept class as input

closes #3318

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.

Off to a good start 🙂

hypothesis-python/src/hypothesis/extra/cli.py Outdated Show resolved Hide resolved
hypothesis-python/src/hypothesis/extra/cli.py Outdated Show resolved Hide resolved
hypothesis-python/src/hypothesis/extra/cli.py Outdated Show resolved Hide resolved
@Cheukting Cheukting force-pushed the ghostwriter_imrpovement branch from 6abd9c3 to c08d3c5 Compare May 21, 2022 17:59
@Cheukting
Copy link
Contributor Author

@Zac-HD I have a question since a class is also callable, I think in the previous logic, if you put a class as input it will write a test as if it is a function but if you put the module as input it will not be discovered. Do you mind clarifying what is the desired behaviour for the class itself?

@Zac-HD
Copy link
Member

Zac-HD commented May 23, 2022

I think the previous behavior is fine here; but I'm pretty happy going with whatever is easiest to implement - the Ghostwriter is really aimed at making it easy to get started, so I care a lot about handling functions and very little about classes (because just creating an instance is rarely a useful test).

@Cheukting
Copy link
Contributor Author

Cheukting commented May 23, 2022 via email

@Cheukting Cheukting force-pushed the ghostwriter_imrpovement branch from 6b91652 to bb1b526 Compare May 23, 2022 06:46
@Cheukting
Copy link
Contributor Author

Cheukting commented May 23, 2022

  • write an expected-output test so that we can see that the results are qualitatively good
  • confirm that we can write {fuzz,roundtrip,equivalence} tests as well as magic

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.

Code comments below; I also took a couple of attempts and eventually (after looking at the Sphinx source code!) managed to get the classmethod and staticmethod cross-references to link properly 😅

Comment on lines 193 to 203
pytest.param(
("xml_etree_ElementTree_py38", ghostwriter.magic(xml.etree.ElementTree)),
marks=[
pytest.mark.skipif(
sys.version_info[:2] != (3, 8),
reason="output generated with Python 3.8",
)
],
),
pytest.param(
("xml_etree_ElementTree_py310", ghostwriter.magic(xml.etree.ElementTree)),
Copy link
Member

Choose a reason for hiding this comment

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

I'd try defining a class in this module, and use that - it works for the with_docstring function, for example.

hypothesis-python/src/hypothesis/extra/ghostwriter.py Outdated Show resolved Hide resolved
@Zac-HD
Copy link
Member

Zac-HD commented May 31, 2022

Looking good! I think the 3.11 failure is a genuine problem somewhere in either Pytest or maybe Hypothesis (pre-dating thia PR), so I'll aim to investigate and fix that in the next few days.

And thanks again for sticking with this long process 🤩

@Zac-HD
Copy link
Member

Zac-HD commented Jun 1, 2022

Yep, the 3.11 crash was an upstream CPython-nightly issue affecting Pytest, which has since been fixed: pytest-dev/pytest#10008.

@Zac-HD
Copy link
Member

Zac-HD commented Jun 2, 2022

Will closing and reopening unstick CI? Let's find out!

@Zac-HD Zac-HD closed this Jun 2, 2022
@Zac-HD Zac-HD reopened this Jun 2, 2022
@Zac-HD
Copy link
Member

Zac-HD commented Jun 2, 2022

Welp, looks like GitHub Actions is pretty seriously degraded at the moment... I'll restart again when it recovers 🙃

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.

We're very close now - just some minor comments and a request for, well, more comments on the tests 🙂

hypothesis-python/src/hypothesis/extra/ghostwriter.py Outdated Show resolved Hide resolved
Comment on lines 47 to 51
("hypothesis.strategies.builds", lambda: fuzz(hypothesis.strategies.builds)),
# Discover methods in class
("hypothesis.errors.StopTest", lambda: magic(StopTest)),
# Imports submodule (importlib.import_module passes; __import__ fails)
("hypothesis.errors.StopTest", lambda: fuzz(StopTest)),
("hypothesis.strategies", lambda: magic(hypothesis.strategies)),
Copy link
Member

Choose a reason for hiding this comment

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

What are each of these new tests checking for? Is that comment about import semantics still correct, even though we've changed what we're testing?

I'd prefer to just swap magic(StopTest) for fuzz(StopTest), but if we're adding more we also need to add corresponding comments.

Copy link
Contributor Author

@Cheukting Cheukting Jun 2, 2022

Choose a reason for hiding this comment

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

Because there's no classmethod and staticmethod in StopTest so it didn't work for fuzz before (the CLI will show "nothing to test" and fuzz will have an error) this is due to the class itself was not tested in the previous generation of this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What are each of these new tests checking for?

I think the comment above kinda indicates something? for the magic(hypothesis.strategies) it is a submodule and for magic(StopTest) it discovers the methods in class (though I think it's a bad example as there's nothing in StopTest I believe)

Comment on lines 170 to 174
(
"my_func",
"XX",
"Found the 'mycode' module and 'my_func' attribute, but it doesn't have a 'XX' attribute.",
),
Copy link
Member

Choose a reason for hiding this comment

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

You could compress this parametrize down to just ("my_func", " and 'my_func' attribute", "attribute") - with a bit more string formatting. That would make it much more compact, which I think would be easier to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean the error message? Can't quite get what you mean here 🙃

@Cheukting
Copy link
Contributor Author

@Cheukting Cheukting force-pushed the ghostwriter_imrpovement branch from c0687b2 to d6a999a Compare June 5, 2022 09:14
@Cheukting Cheukting force-pushed the ghostwriter_imrpovement branch from d6a999a to dfee405 Compare June 5, 2022 12:39
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'm back from a busy weekend, and we're completely done and ready to merge! Congrats Cheuk; it turned out to be a long and twisty one but a great contribution in the end 😁:tada:

@Zac-HD Zac-HD merged commit 208b862 into HypothesisWorks:master Jun 7, 2022
@Cheukting
Copy link
Contributor Author

I'm back from a busy weekend, and we're completely done and ready to merge! Congrats Cheuk; it turned out to be a long and twisty one but a great contribution in the end 😁🎉

Thank you for your patient guidance @Zac-HD

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.

Teach the Ghostwriter about @staticmethod and @classmethod methods
2 participants