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

Fix abuse of return in a with test block #85

Open
Technologicat opened this issue Jan 31, 2022 · 0 comments
Open

Fix abuse of return in a with test block #85

Technologicat opened this issue Jan 31, 2022 · 0 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@Technologicat
Copy link
Owner

As of 0.15.1, the contents of the with test block are implicitly lifted into a function. This in itself is fine; it is documented behavior, and arguably the simplest way to achieve what the macro needs to do.

The problem is that to declare the expression whose value should be checked to decide the result of the test, the syntax to do so is currently return expr. This is arguably an abuse of a standard construct, in conflict with its established meaning, and thus it will likely confuse code analyzers and human readers alike.

So, let's add an expr macro to make the declaration instead, thus making the code read more like standard Python. The name of the macro needs some thought:

  • returns[] is the closest to the intention, but will confuse humans as to why there is a separate returns vs. the standard return.
  • result[], results_in[], or evaluates_into[]. Semantically slightly off; we want to declare a check, not a result.
  • check[]. Checkmate in t(h)ree? Still, probably the best so far.
  • Whatever the final name is, it should be compact (preferably one short-ish word), while making the intent blindingly obvious.

Also, with this change, we should make return inside a with test block into a syntax error, because it will not actually exit the parent function containing the with test block. This is a breaking change, so it has to wait until 1.0.0 (which is the next major release after 0.15.0). The best thing to do is to already introduce the alternative syntax in 0.15.x, and make the use of return in a with test block emit a DeprecationWarning until 1.0.0, where the old syntax will be removed.

Any local variables assigned to will still be local to the test. But an unexpected scope boundary shouldn't be as much of a problem as the abuse of a standard syntactic construct. For this there is precedent in Python itself, since comprehensions and generator expressions introduce a scope boundary. So do unpythonic's continuations.

The solution is the same; if you need to be able to replace a thing in the parent scope, keep it in a box. (You can also use nonlocal or global as appropriate, but that may make the coverage analyzer error out if a variable is seemingly assigned to before its nonlocal declaration.)

@Technologicat Technologicat added the enhancement New feature or request label Jan 31, 2022
@Technologicat Technologicat added this to the 0.15.x milestone Jan 31, 2022
@Technologicat Technologicat self-assigned this Jan 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant