On Thu, Nov 21, 2019 at 04:49:00PM +0100, Tomáš Golembiovský wrote: > This may be confusing at first but is not that difficult once you wrap > your head around it. > > There are two types of arguments in Python: positional(*) and > keyword(**). There is a rule that all positional arguments are defined > before the keyword arguments. Also once an argument has a default value > it is considered keyword (not positional). There are some nuances for > which is best to reach to some documentation.
Thanks for the explanation. I think the api_version idea is the way to go, I have a patch for this coming up. Rich. > > > Another possibility is we could encourage existing Python plugins to > > add **kwargs to all functions where we might plausibly add extra > > parameters in future, ie. the above would become: > > > > def pwrite (h, buf, offset, **kwargs): > > > > This still requires all Python plugins to change, but at least they > > would remain backwards compatible with old and new nbdkit. However I > > couldn't actually work out how to make this work because: > > > > >>> def test(a, **kwargs): > > Here you defined single positional argument 'a'. > > > ... pass > > ... > > >>> test(1) > > >>> test(1,2) > > You are passing two positional arguments. A keyword argument has to have > a name. E.g. this will work: test(1, foo=2) > > > Traceback (most recent call last): > > File "<stdin>", line 1, in <module> > > TypeError: test() takes 1 positional argument but 2 were given > > > > Check the attached script for some examples. Hopefully that will help > you get a better grasp. > > Tomas > > -- > Tomáš Golembiovský <[email protected]> > #!/usr/bin/env python3 > > def abc(*args, **kwargs): > print(args) > print(kwargs) > > def with_positional(a, b, c, *args, **kwargs): > print(a, b, c) > print(args) > print(kwargs) > > # Wrong: cannot define keyword arguments before positional > #def with_keyword(a=None, b=None, c=None, *args, **kwargs): > # pass > > def with_keyword(*args, a=None, b=None, c=None, **kwargs): > print(a, b, c) > print(args) > print(kwargs) > > # This is also possible > def with_keyword2(*args, a, b, c, **kwargs): > pass > print(a, b, c) > print(args) > print(kwargs) > > # (1, 'abc') > # {'foo': 2, 'bar': 3} > abc(1, 'abc', foo=2, bar=3) > # Wrong: cannot pass positional arguments after keyword arguments > #abc(1, 'abc', foo=2, bar=3, 4, 5) > print('---') > > # 1 2 3 > # (4, 5) > # {'foo': 10, 'bar': 11} > with_positional(1, 2, 3, 4, 5, foo=10, bar=11) > # Wrong: a,b,c are alrady bound to 4,5,6 > #with_positional(4, 5, 6, foo=10, bar=11, a=1, b=2, c=3) > > # This works as one would expect > with_positional(a=1, b=2, c=3, foo=10, bar=11) > # These two are wrong > #with_positional(4, a=1, b=2, c=3, foo=10, bar=11) > #with_positional(a=1, b=2, c=3, 4, foo=10, bar=11) > > print('---') > with_keyword(4, 5, foo=10, bar=11) > with_keyword(4, 5, foo=10, bar=11, a=1, b=2, c=3) > > # These two are equivalent > with_keyword2(foo=10, bar=11, a=1, b=2, c=3) > with_keyword2(a=1, b=2, c=3, foo=10, bar=11) -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
