Hello, RonnyPfannschmidt <opensou...@ronnypfannschmidt.de> writes: > Am 29.08.2017 um 15:18 schrieb Bruno Oliveira: >> On Sun, Aug 27, 2017 at 4:04 AM Ronny Pfannschmidt >> <opensou...@ronnypfannschmidt.de >> <mailto:opensou...@ronnypfannschmidt.de>> wrote: >> what i imagine is an api like this: >> >> node.find_marks() -> iterates over all marks of all nodes >> node.find_marks('name') -> iterates over all marks that have a name >> node.find_marks(SomeType) -> iterates over all marks that are instaces >> of the type >> >> >> This seems reasonable. Minor suggestion, perhaps name the methods >> "iter_marks" instead? Seems better based on the descriptions of each one >> ("iterates over all marks...") > > i'd like to bikeshed on the names a bit in order to give them exactly > the meaning they should have - perhaps i should split iteration and > filtering even
In general I'd agree that splitting the iteration and filtering might be more pythonic, also python has generally moved away from calling things "iter_*" I think. Lastly I find the Node.find_marks_with_nodes() variation rather clumsy as well. After thinking about this a bit the best I can come up with is the simple Node.marks() method. As is common in Python it takes no arguments and does not filter, it just returns an iterator. To make that work you'd also need to change what object the iterator returns, I imagine something like this: class MarkHolder: name = 'old_mark_name' or None obj = SomeType or whatever obj the old ones are origin = Node (As an aside I'm guessing this class would be a prime candidate to be marked @attr.s thing) While you get an extra layer it's both rather Pythonic in the API with respect to the behaviour of the iterator method as well as py.testy with the use of holder.obj. (I'm not sure if "py.testy" is generally perceived as a desirable property or not ;-)) >> node.push_mark(markobj) -> pushes a mark to a node, always requires a >> mark object wither taken from pytest.mark or a new style one This method I do like, it should probably come with a symmetric Node.pop_mark() as well which would mirror dict.pop() behaviour. >> following up the evaluation of skip marksfor example would look like >> this: >> >> for mark in node.find_marks('skip'): >> if eval_mark(node, mark): >> pytest.skip(mark.args) for mark in (m for m in node.marks() if m.name == 'skip'): ... >> a more complex marker could be wored the following >> >> for orgin, blocker in node.find_marks_with_node(Blocker): >> blocker.maybe_trigger_outcome(orgin=orgin, current=node) for mark in (m for m in node.marks() if isinstance(m.obj, Blocker)): mark.obj.maybe_trigger_outcome(origin=mark.origin, current=node) Having written these examples without any filtering API I do admit I'm doubting my earlier evaluation about this being a more Pythonic API. It certainly is a lot more writing and probably even harder to read as well. But I thought I'd still send the mail as it's still useful food for thought. >> as for putting those marks on nodes, >> i would just use pytest.mark(Foo(a=1. b=2) as the deorator >> >> >> I definitely like this idea, this will handle *args and **kwargs much >> more naturally and less error prone, plus it makes it easier to document >> marks as well. Agreed that this seems nice. Cheers, Floris _______________________________________________ pytest-dev mailing list pytest-dev@python.org https://mail.python.org/mailman/listinfo/pytest-dev