Menu

Pythonic argument handling

Help
2017-03-06
2017-03-08
  • Joerg Kreuzberger

    Hi!
    Whats the best way for registered and wrapped CPP Classes to wrap optional arguments? I would like to implement someting like the **kword argument handler, who could map the optional arguments to a QVariantMap. Is this already supported in any way? Where would be the location to implement it if required? Is there a better way to to handle optional arguments with the current implementation?
    Any help appreciated...

     
  • Florian Link

    Florian Link - 2017-03-06

    This is not yet supported. You can have N QVariant arguments in your slot and each variable can have QVariant() as its default, but there is no way to get access to the keywords of a Python call atm.
    I could think of a conversion of kw args to a QVariantMap that is passed as special argument, but the question would be the syntax to detect that this is the kw argument... maybe with a special name or special PythonQt class?

     
  • Joerg Kreuzberger

    Not sure if i understand your answer right. I agree that we have the same opinion to handle kwargs with a QVariant Map. The problem is how to detect it where? I assume in the slot definition of the wrapped C++ class?
    Or did you mean on the python side?

    If the issue is on the c++ slot side, no issue to handle this with a special argument name , e.g. QVariantMap kwargs.

     
  • Joerg Kreuzberger

    We are migrating to Qt 5 this year, but i am not sure if the qt5 slot mechanism could handle variadic functions? this could be also a way? Depends on moc.

     
  • Florian Link

    Florian Link - 2017-03-08

    Yes, I meant the C++ side and a special name would indeed be a solution.
    The only difference with real kwargs in Python would be that those optional parameters could ONLY be given as a keyword (while they can be given as normal parameters in Python), not as optional parameters and that the user can't see which optional keywords are available (while in Python they are visible on the signature of the function/method).

    I think I don't have resources right now to implement this, but you can give it a try...
    It would be around the PythonQtSlot.cpp code.

     
  • Joerg Kreuzberger

    not sure what you mean again.
    The function call would e.g. be in python

    def summarize(a, **kwargs):
      if kwargs is not None:
        for key,value in kwargs.items():
          print("%s=%s" % (key, value))
    
    
    summarize(1)
    summarize(1,x=3,b=5)
    

    Outputs
    x=3
    b=5

    If i implement a slot in c++

    int sumMap( MyObject* obj, int a, QVariantMap kwargs) { obj->sum(a); return kwargs.count(); }
    

    and call it on an object in python like this:

    x.sumMap(1,a=2,b=3)

    I get the error

    ValueError: Called sumMap(int a, QVariantMap kwargs) -> int with wrong number of arguments: (1,)

    This is from PythQtSlot.cpp (PythonQtSlotFunction_CallImpl)
    Here i would start to implement to handle the "special kwargs" arguments

     
  • Florian Link

    Florian Link - 2017-03-08

    Yes, exactly that is the place where you would have to implement it.

    What I was referring to is that in Python you can have:

    def summarize(a, b = 4, c = 5):
    ...

    and then you can call it via:

    summarize(1, b=1,c=2)

    or

    summarize(1, 2, 3)

    The last syntax would not work in the C++ case with the kwargs at the end.

     
  • Joerg Kreuzberger

    ok, thats clear due to the "unnamed" parameters.

    Whats the best way to contribute to the project? I have seen a commontk/PythonQt in Github. Or just send changed files?

     
  • Florian Link

    Florian Link - 2017-03-08

    You can send me a patch/diff against the svn trunk.

     
  • Joerg Kreuzberger

    Hi!
    Attached is a patch of PyhtonQtSlot.cpp. This works now for me. Its a diff against my current version of PythonQt, not the SVN Trunk head. Could you review it for suggestions? Especially for the PyTuple handling, i am not very familier with it.

    The Slot in the Wrapper class is
    void foo( MyObject* obj, int a, QVariantMap kwargs = QVariantMap())

    The code looks for "kwargs" and a not null kw parameter given to the function.

    Attached is also a second patch, Regarding evalScriptTrace in PythonQt. The trace function is not set back.

    In August i plan to migrate to qt5, then i will switch to the current trunk head. Then i could supply a patch again.

     
  • Joerg Kreuzberger

    ok, found out that theres an issue with overloaded slots.
    in the case for kwargs if have to find the right slot with kwargs parameter name and call it directly

     
  • Joerg Kreuzberger

    Attached version handles correct slot now on overloads with kw arguments.
    It has some duplicated code, but optimization is done later :-)
    From my version to the trunk version there seems to be only minor changes
    Patch against trunk will be delivered when my migration to qt5 is done.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.