-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Improve ParameterSet with nested ParameterSet objects #9074
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
Comments
Do you have a concrete example where this helps, If it boils down to covariant and correlated values, it's not exactly a good representation |
@RonnyPfannschmidt Suppose we have a function that creates ParemeterSet, where value is the path to the file and id is the name of the file. def server_config(path_to_file, marks: list):
return pytest.param(path_to_file, id=path_to_file.split("/")[-1], marks=marks) Also, we have a function that creates ParameterSet, where value is the database connection config dictionary and id is alias: def conn_config(conn_config: dict, name: str, marks: list):
return pytest.param(conn_config, id=name, marks=marks) Now we need to check that certain server configurations work with certain connection configurations. @pytest.mark.parametrize(
"server, connection", [
pytest.param(
server_config("simple_server.yaml"),
conn_config({}, name="simple_connection"),
),
pytest.param(
server_config("extended_server.yaml", marks=[pytest.mark.full]),
conn_config({"foo": 1}, name="hard_connection"),
marks=[pytest.mark.long]
),
...
]
)
def test_example(server, connection):
assert check(server, connection) |
So we ought to talk about the idea of a single parameter, not Sets of those, I'll come back to the computer in about 3 hours and 400 km |
@RonnyPfannschmidt Yep. My idea is to recursively unpack nested ParameterSet objects and use their contents in one ParameterSet object |
i think its a good idea, we need to decide where exactly it should unpack, and whether or not a extra indication is needed |
I'm -1 on this. It uses the same thing to both mean "a set of paramters", but also "a single argument in that set", which seems like a lot of room for confusion. |
@RonnyPfannschmidt In my commit, I do unpack in ParameterSet
@pytest.mark.parametrize(
"a,b,c", [
pytest.param(
pytest.param(1, id="this_is_one"),
pytest.param(2, 3, id="this_is_two_and_three"),
)
]
)
<Function test_example[this_is_one-this_is_two_and_three]>
@pytest.mark.parametrize(
"a,b,c", [
pytest.param(
1,
pytest.param(2, id="this_is_two"),
3,
)
]
)
<Function test_example[1-this_is_two-3]> |
@The-Compiler I just want to improve current behavior and do it more friendly. I’m not sure that a common pytest user wants ParameterSet objects as parameter values, not the values itself |
That part we agree on: It probably doesn't make sense to use What I don't agree on is that your described behavior is an improvement or more user friendly. In my eyes in mixes two things together that don't really belong together, thus introducing more confusion that it solves. Take the combination of markers, for example: It doesn't make sense for a single argument value to have a marker. Viewed in isolation, the approach of taking each argument value's marker and combining them together to get the tests's markers might make sense, but I'm not convinced it's useful in general - it suddenly means that markers can be applied to a tests individual argument values, which just seems weird and confusing to me. Just my $0.02 though, let's see what others think. |
Actually, "combining marks" is one of thinking nice to have. The main aim is getting values from nested ParameterSet objects and merging their ids. In my case, I have many different functions, that build params for tests and I want to combine their values for different tests |
can you outline your use-case further, ti may be a good idea to have a completely own mechnaism instead, but without actually seeing what you need to do, all we can do is guesswork i agree with the sentient that params and parametersets are different "bags of things" in a sense |
In the term 'ParameterSet' I mean only the current pytest class. The main case is #9074 (comment) and I think this #9074 (comment) resolve it. This idea resolve many other cases, which I can only surmise, but the main point of they - use pre-created pytest.param as part of another pytest.param. It improves reuse codebase for preparing test data and test names readability in collect |
@vgorkavenko i think i need a expansion of that, a particular usage-side doesn't reveal the full use-case i'd like to avoid the X-Y-Problem for historic context, parameter-set got introduced to remove a really ugly hack that would transfer marks passed as parameterset into split sets of parameters and marks (which came about by organic growth in minimal steps) this additional feature you propose as i see it right now might be that type of minimal step one wants to avoid, |
I agree that infinite recursive unpacking in the future will make some ugly things. Maybe do limit nesting so that the user is not tempted to do something like this: @pytest.mark.parametrize(
"a,b,c", [
pytest.param(
pytest.param(
1,
pytest.param(2, 3, id="this_is_two_and_three"), id="this_is_one"
),
id="all",
)
]
) On the other hand, this equates pytest.param to actually a simple value, just with an alias and marks |
maybe it would help to introduce a explicit flattening helper, your specific use-case is still not clear to me i dont want to run a open ended experiment with this as time is sparse as is already |
As I said above, in the main case I want to use pre-created pytest param as part of the set in another pytest param (to use they values and ids and marks) and do this maximal intuitive. It seems to me that we do not understand each other, |
i do feel there is a missunderstanding, which is why i want to unroll the use-case, i'm currently under the impression that your specific use-case is served better by a specific helper as "generalized parameterset flattening" has to figure some holes in the spec for details like ids, marker transfer, composing the final parameterset |
I tend to agree with @RonnyPfannschmidt (though I feel like the example in #9074 (comment) is pretty concrete). If you have a custom It'd certainly be some less magic than the current proposal - then the remaining question is whether such a helper should live in the core. I think it shouldn't, unless there are other use cases it solves. On first sight, this seems like a quite exotic thing to me. |
@The-Compiler i agree that is "concrete in a sense" but as you mention, its a very specific case that can be handled much more simple than a more generalized unpacking that has to handle the edge-cases i can also envision a more restricted variant of combining them, (where we would allow that when a normal tuple/list is transformed into a parameter-set, we could consider first level parameterset instances that add marks/ids for single values (which could make useful constants for testcase parameter lists) |
@RonnyPfannschmidt I like ur idea. Indeed, recursive unpacking is too loud solution of this issue. It will be enough to consider only the first level |
Needs anything from me to "push" this issue? |
currently i dont have the bandwidth for feature work |
@RonnyPfannschmidt I created PR, please look at it when you find the time |
What's the problem this feature will solve?
I want the possibility to combinate ParameterSet objects to parametrize tests
Describe the solution you'd like
I want nested ParameterSet objects to be unpacked and combined their ids and marks
For example, I have this test:
This test won’t pass now, because nested ParameterSet objects throw in the test "as-is".
This is logical behavior, but useless.
I suggest unpack nested ParameterSet objects and merge their ids and marks. If parent ParameterSet has an id - it rewrites nested ids.
The example above will in collect:
<Function test_example[this_is_one-this_is_two-this_is_three]>
Here are a few more examples
1. ID rewriting
2. Use simple values with ParameterSet
3. Merge marks
In this case, marks merged in one list - [one, two, three, full]
I have a solution that works, but I wrote it "on a napkin" - vgorkavenko@99c0712
The text was updated successfully, but these errors were encountered: