Issue #7 new

wrapping const/pure/@safe/nothrow methods

lomereiter
created an issue

Hello,

The information about function attributes is not carried to the overload in a 'shim' class, that causes errors when I try to wrap such functions.

import pyd.pyd;

class MyFile {
    private string _fn;
    this(string filename) { _fn = filename; }
    string filename() @property const { return _fn; }
    //                     works without attributes
}

extern(C) void PydMain() {
    module_init();
    wrap_class!(MyFile,
           Property!(MyFile.filename, Mode!"r"),
           Init!(string))();
}

Comments (7)

  1. lomereiter reporter

    OK, now the issue is resolved for properties.

    But it remains for class methods with attributes. Example:

    ...
    string filename() @safe pure nothrow const { return _fn; }
    ...
    Def!(MyFile.filename),
    ...
    

    The error indicates that the overload doesn't take attributes into account:

    /usr/local/lib/python2.7/dist-packages/celerid/infrastructure/pyd/make_wrapper.d(134): Error: function pyd.make_wrapper.make_wrapper!(MyFile, Def!(filename), Init!(string)).wrapper.filename does not override any function, did you mean to override 'test.MyFile.filename'? ```

  2. ariovistus repo owner

    the tricky part is when you wrap a const function in Def and then try to override it in python. Hopefully the only modifications that can be made by python will be through pyd, so pyd will have to somehow propogate the const and stop attempts to modify this.

  3. lomereiter reporter

    OK, here's my attempt at getting string representation of const and attributes:

    template funcAttrsToStr(alias fn) {
        alias FunctionAttribute FA; 
        alias TypeTuple!(FA.pure_,    "pure ",     FA.nothrow_, "nothrow ",
                         FA.ref_,     "ref ",      FA.property, "@property ",
                         FA.trusted,  "@trusted ", FA.safe,     "@safe ") attrNames;
    
        template helper1(int attrs, CheckedAttrs...) {
            static if (CheckedAttrs.length == 0)
                enum helper1 = ""; 
            else static if (!(attrs & CheckedAttrs[0]))
                enum helper1 = helper1!(attrs, CheckedAttrs[2 .. $]);
            else 
                enum helper1 = CheckedAttrs[1] ~ helper1!(attrs, CheckedAttrs[2 .. $]);
        }   
    
        template helper2(alias fn) {
            static if (is(typeof(fn) == const))
                enum helper2 = "const ";
            else
                enum helper2 = ""; 
        }   
    
        enum funcAttrsToStr = helper1!(functionAttributes!fn, attrNames) ~ helper2!fn;
    }
    
  4. ariovistus repo owner

    For helper2 you also need to handle immutable, shared, and inout. But I already have code that does this, so you needn't bother. Propagating it through pyd is the annoying part.

  5. ariovistus repo owner

    nothrow at least is logically not possible to enable* because of plumbing that intercepts python overrides. Ditto for pure, trusted, and Safe Hammad. If we turned this off, then it would probably be doable, but that's the sort of thing I'd leave to the discretion of the user. So we need a flag in the api somewhere.

    for nonstatic member functions

  6. Log in to comment