On Fri, Nov 22, 2019 at 11:55 PM Eric Blake <eblake(a)redhat.com> wrote:
On 11/22/19 3:46 PM, Nir Soffer wrote:
>>>> and for zero (once fast zero is supported later in the series), it
could
>>>> look like:
>>>>
>>>> def zero(h, count, offset, may_trim=False, fua=False, fast=False):
>>>
>>> This is nicer - but not extensible.
>>
>> Why not? Any future flag additions would still appear as new key=value
>> kwargs.
>
> Because there is no **kwargs argument, you will get TypeError when adding new
> argument. We will need new api version whenever we add new argument.
Not if you use PyObject_Call(fn, args, kwargs) or similar to pass
'may_trim=False' as a kwarg instead of a positional.
As long as new flags are always passed via keyword instead of position, and we don't
pass any keywords that the plugin has not opted into,
then we can add
new keywords and call plugins with fewer flags than what our current
nbdkit supports.
> This is extensible:
>
> def zero(h, count, offset, may_trim=False, fua=False, fast=False, **kwargs):
But that is also called via PyObject_Call(fn, args, kwargs) - as long as
we pass kwargs correctly, the C code doesn't care whether the Python
definition has a ** catchall or not, because the rules for translating
the C code's two lists (one of positional, the other of kwargs) into the
Python signature work for multiple different python signatures.
I see, this will work and is extensible, but it may be harder to write
correct plugin
code. You may forget to define can_foo() and then define foo=None or define
can_foo() and forget to define the foo argument.
Nir