Refactor profiles filtering: add rank_profile, get_matching_profiles, get_highest_score_profiles#1705
Conversation
|
|
||
| def _profile_exclusion(matching_profiles, logger): | ||
| """Find out most matching profile byt host, task and family match. | ||
| def fullmatch(regex, string, flags=0): |
There was a problem hiding this comment.
this function is unchanged. the diff is incorrect
| ] | ||
|
|
||
|
|
||
| def get_matching_profiles( |
There was a problem hiding this comment.
What is the use-case for this function?
There was a problem hiding this comment.
a couple of use cases I currently can think of:
User selection from multiple valid profiles
eg.: a studio might have muliple playblast profiles defined (generic_maya_profile, anim_profile, low_quality_but_fast_profile, high_quality_but_slow_profile, ..)
Using this function plugins could present the users with a dropdown allowing them to select which profile to use
Profile composition
Some workflows could benefit from considering profiles as composable attributes rather than beeing mutually exclusive. Returning all matches could allow a plugin to dynamically merge them based on user input / context / other settings.
There was a problem hiding this comment.
Using this function plugins could present the users with a dropdown allowing them to select which profile to use
In that case you should not use profiles. Or rather do not call it profiles. Profiles are explicitly defined to match one or none for a set of filters. The use-case does not match the criteria.
What you are describing are presets, definitions, not profiles. In that cases you probably have all filtering values available and you're simply comparing left -> right, don't need to track score, just show preset which does match the filters. That is what this function does, but that should NOT be used for profiles.
| return regexes | ||
|
|
||
|
|
||
| def _profile_exclusion(matching_profiles, logger): |
There was a problem hiding this comment.
This functionality is not available anymore, I guess?
There was a problem hiding this comment.
The same functionally is now part of the ranking itself.
From how I understand the previous implemetiation:
filter_profileswould rank and filter profiles based on the number of matches (line ~199)_profile_exclusionthen selects the best match based on the position of the matched keys in order.
The new rank_profile function does both at the same time by generting a "order-aware-score"
There was a problem hiding this comment.
Not sure, this is not about score, it is about filters order in profiles. If there is profile with filters:
- product base type
- host names
- task types
When there are 2 profiles with score 1, one has matching task type and one has matching host name, this function would return the one which has matching host name because the filter has more "value" for the filtering.
There was a problem hiding this comment.
It still does that
here is an variation of the test_order_of_keys_matters test case to match the variable names
profiles = [
{"product_base_type": "model", "task": "modeling", "foo": "no"}, # 2 matches product_base_type + task
{"product_base_type": "model", "host": "maya", "foo": "yes"}, # 2 matches product_base_type + host
]
key_values = {
"product_base_type": "model",
"host": "maya", # host listed first => higher value
"task": "modeling",
}
matched = profiles_filtering.get_highest_score_profiles(profiles, key_values, log)
print(matched)
>>> [{'product_base_type': 'model', 'host': 'maya', 'foo': 'yes'}]
Changelog Description
Refactored profile filtering and added new methods so callers can match multiple profiles instead of only picking the single best one.
Additional info
Unchanged
filter_profilesexpected behaviour is unchanged and backwards compatible. (hopefully)New
rank_profile: ranks a single profile using a lexicographic binary score.1= exact match,0= wildcard); results form a bitmask so earlier keys matter more.0b110 = 6beats0b101 = 5(both have 2 value matches and 1 wildcard).1bits (e.g.score.bit_count()).rank_profiles: helper to rank multiple profilesget_matching_profiles: returns all profiles with a non‑negative score.get_highest_score_profiles: Returns all profiles with the highest score.Use case
Useful for addons that want to compose profiles dynamically (eg. merge multiple rules into one).
Example (eg. dynamic profiles for deadline):