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

Add attrs.validators.or_ validator #1303

Merged
merged 12 commits into from
Jul 17, 2024
Merged

Conversation

bibajz
Copy link
Contributor

@bibajz bibajz commented Jul 14, 2024

Closes #1214

Summary

Add attrs.validators.or_ validator, which is satisfied if at least one of the validators it is wrapping is satisfied, thus complementing the and_ and not_ "logical connectives" validators.

Pull Request Check List

  • Do not open pull requests from your main branch – use a separate branch!
    • There's a ton of footguns waiting if you don't heed this warning. You can still go back to your project, create a branch from your main branch, push it, and open the pull request from the new branch.
    • This is not a pre-requisite for your your pull request to be accepted, but you have been warned.
  • Added tests for changed code.
    Our CI fails if coverage is not 100%.
  • New features have been added to our Hypothesis testing strategy.
  • Changes or additions to public APIs are reflected in our type stubs (files ending in .pyi).
    • ...and used in the stub test file tests/typing_example.py.
    • If they've been added to attr/__init__.pyi, they've also been re-imported in attrs/__init__.pyi.
  • Updated documentation for changed code.
    • New functions/classes have to be added to docs/api.rst by hand.
    • Changes to the signature of @attr.s() have to be added by hand too.
    • Changed/added classes/methods/functions have appropriate versionadded, versionchanged, or deprecated directives.
      The next version is the second number in the current release + 1.
      The first number represents the current year.
      So if the current version on PyPI is 22.2.0, the next version is gonna be 22.3.0.
      If the next version is the first in the new year, it'll be 23.1.0.
  • Documentation in .rst and .md files is written using semantic newlines.
  • Changes (and possible deprecations) have news fragments in changelog.d.
  • Consider granting push permissions to the PR branch, so maintainers can fix minor issues themselves without pestering you.

TODO (done!)

  • Need to add entry into the changes dir, but that is dependent on the PR number of this PR, so needs to be post hoc - done in 6996627
  • Reflect the addition in docs/api.rst - done in 2ad53b3

Copy link

codspeed-hq bot commented Jul 14, 2024

CodSpeed Performance Report

Merging #1303 will not alter performance

Comparing bibajz:bibajz/or_validator (93c1f07) with main (37ac3ef)

Summary

✅ 12 untouched benchmarks

src/attr/validators.py Outdated Show resolved Hide resolved
Although good warning in general, in this particular code, they
do not fit here.

* BLE001 Do not catch blind exception: `Exception`
    `validators` usually raise `ValueError` upon their violation.
    However, it's not the only `Exception` they can raise - cf.
    `attrs.validators.not_` - therefore, it is desirable to catch
    them all!
* PERF203 `try`-`except` within a loop incurs performance overhead
    Fair point, but the loop is written in a way to short-circuit,
    ie. it will finish when a first validator is satisfied.
* S112 `try`-`except`-`continue` detected, consider logging the exception
    Not applicable here, we care only if **all** validators raise
    an exception, which is already accomodated for after the `for`
    loop.
@bibajz bibajz requested a review from hynek July 16, 2024 09:11
Copy link
Member

@hynek hynek left a comment

Choose a reason for hiding this comment

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

code's looking good; just a few smaller issues pls

tests/test_validators.py Show resolved Hide resolved
docs/api.rst Outdated
Comment on lines 469 to 472
>>> from typing import Union
>>> @define
... class C:
... val: Union[int, str] = field(validator=attrs.validators.or_(attrs.validators.instance_of(int), attrs.validators.instance_of(str)))
Copy link
Member

Choose a reason for hiding this comment

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

this is not a great validator because, and I may blow your mind here ;), is instance takes a tuple! So you could write this: attrs.validators.instance_of((int, str)) or even attrs.validators.instance_of(int | str) on modern Pythons.

Just make up something with numbers I guess?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, I was aware of the fact you can can isinstance with type argument being a tuple, but didn't put 2 and 2 together that it will be the case with attrs.validators.instance_of as well. 🤦🏻‍♂️

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in a0b6b24 .

I reworked the example to have one-or-many scenario, where the attribute can either a value of a type or a collection of values of the same type, encountered eg. in parsing the query parameters in HTTP URIs.

...?val=1&val=2&val=3

Is this OK?


As an aside, docs seem to be tested wth py312, so I don't have to do the typing ceremony and can write val: int | list[int], but since there are python versions in the test matrix that don't have this syntax on by default, should I keep it as it is now or rework to conform to newer versions?

Thanks!

Copy link
Member

Choose a reason for hiding this comment

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

Yes, please use the most-modern syntax. Let’s teach ppl modern features.

Example looks fine on a phone 😅

changelog.d/1303.change.md Outdated Show resolved Hide resolved
src/attr/validators.py Outdated Show resolved Hide resolved
@bibajz bibajz requested a review from hynek July 17, 2024 05:53
docs/api.rst Outdated Show resolved Hide resolved
Copy link
Member

@hynek hynek left a comment

Choose a reason for hiding this comment

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

Thanks!

@hynek hynek added this pull request to the merge queue Jul 17, 2024
Merged via the queue into python-attrs:main with commit 7c9b31e Jul 17, 2024
23 checks passed
@bibajz
Copy link
Contributor Author

bibajz commented Jul 17, 2024

Thanks!

No problem, pleasure on my side for being able to contribute to a library I consider one of the foundational for the whole Python ecosystem!

I thank you for timely responses and guidance.

Cheers,
Libor

@bibajz bibajz deleted the bibajz/or_validator branch July 17, 2024 14:45
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.

Multiple alternatives validator
2 participants