[pytest-dev] marks - proposals for a new api and a path forward
Bruno Oliveira
nicoddemus at gmail.com
Tue Aug 29 18:56:22 EDT 2017
On Tue, Aug 29, 2017 at 4:53 PM Floris Bruynooghe <flub at devork.be> wrote:
> Hello,
>
> RonnyPfannschmidt <opensource at ronnypfannschmidt.de> writes:
> > Am 29.08.2017 um 15:18 schrieb Bruno Oliveira:
> >> On Sun, Aug 27, 2017 at 4:04 AM Ronny Pfannschmidt
> >> <opensource at ronnypfannschmidt.de
> >> <mailto:opensource at 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.
>
Not sure, I find the examples quite readable if we name the expressions:
```python
skip_marks = (m for m in node.marks() if m.name == 'skip')
for mark in skip_marks:
...
```
```python
blocker_marks = (m for m in node.marks() if isinstance(m.obj, Blocker))
for mark in blocker_marks:
mark.obj.maybe_trigger_outcome(origin=mark.origin, current=node)
```
So I think the idea is worthwhile. Also, it is simpler to add more ways to
filter the API later than remove something later, so there's that to
consider as well.
But I like that we seem to agree on the general direction of the API.
Cheers,
Bruno.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pytest-dev/attachments/20170829/b737e2f5/attachment-0001.html>
More information about the pytest-dev
mailing list