-
Notifications
You must be signed in to change notification settings - Fork 8
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
Allow rules to be skipped #66
Allow rules to be skipped #66
Conversation
Rules can now return an empty value SkipRule(). When doing so, the rule is not computed at all by the Scorer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution! 🙏
Left a comment for discussion on the overall design of the feature.
I'm currently working on updating this with the Skip feature as well. Just externalizing here that having parametrized skips work well enough as long as they are used programatically and not through the configfile interface. I thought about having generic skips such as "skip_schema(schema)" and "keep_schema(schema)", but that would not work nicely with the configfile. On that note, Skip is not a great name because inverting it is also a valid use case. Any other name recommendation? RuleFilter? |
Great to hear @diorge! Yes I think it will be hard to configure these properly with the config files, let's keep it simple (for now)! Could you maybe elaborate on "inverting it"? That's not entirely clear to me. Anyway: |
Both "apply only on schema X" and "apply everywhere except schema X" are valid filters. One is skipping X, and the other is the invert operation. Anyway, yeah, |
Changes due to prettifier, ruff and mypy
- Filters no longer have their own config - Rules take instances of filters instead of types - Rule configuration now allows `model_filter_name`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing work 🚀 It works super well and code looks good. I have left a couple of suggestions and questions. Will take another look later this week!
Use a new field rule.model_filter_names instead of using rule.config["model_filter_names"]
My bad on not having installed the pre-commit hooks, the linter should be passing now |
Hey @diorge ! Thanks for this work, a really great feature 💪 I see now there are two mechanisms to disable evaluation for a model-rule pair. Is there any practical difference between them so we should keep both? For me, it feels like |
@druzhinin-kirill this has been brought up in a conversation marked as resolved. I'm not too strong for keeping it, but I do think it's a nice addition that does not bloat the lib too much. |
I see, got your points 👍
I would vote to keep filters only. They might have a little overhead compared to WDYT @jochemvandooren @matthieucan ? |
I'd compare the relationship of Anyway, if it is decided to remove the feature, I'd appreciate it if anyone else could pick this PR. I won't be able to work on it in the following weeks. |
I agree with that sentiment. Separating rules (pure logic) and configuration (to whom does that logic apply, with which parameters) will keep things simple, and avoid some edge-cases that do not warrant the extra complexity IMO. |
class SkipSchemaY(ModelFilter): | ||
description = "Applies a rule to every schema but Y." | ||
def evaluate(self, model: Model) -> bool: | ||
return model.schema.lower() != 'y' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know use-cases where the class version (as opposed to the decorator version) would be necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet, but no harm in having it as it does not really change implementation and it follows the same design of @rule
.
@diorge I made some changes to the PR! Mainly got rid of the |
@@ -57,11 +57,11 @@ def evaluate(self) -> None: | |||
self.results[model] = {} | |||
for rule in rules: | |||
try: | |||
result: RuleViolation | None = rule.evaluate(model, **rule.config) | |||
if rule.should_evaluate(model): # Consider model filter(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, if a filter skips the model, it's not now visible to the user. In the case of complex filters, it might be important to flag skipping so the filter behaves expectedly
It might be interesting to either:
- emit a warning if the model skipped (maybe too much noise)
- Keep track of skipped models in the skipped list attr. In the end,
Formatter
can use this to print at least the number of skipped models.
My proposal is to add self.skips
and track Model, Filter
I am fine to outline it as a new feature request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes let's keep it for another PR, then we can already release this one 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @diorge! Thanks a lot for bringing life 🚀
@diorge Thanks a lot for your contribution! 🙌 |
Solves #48 (partially?)
Introduce
ModelFilter
, which allowsRule
objects to be skipped, by filtering on aModel
. Adding filters is done in a similar way as rules, and can be configured using thepyproject.toml
configuration.