1. ariovistus
  2. pyd

Commits

ariovistus  committed 00de19e

fix issue 7

wrapped_member handles readonly/writeonly properties incorrectly
plus a typo in class_wrap

  • Participants
  • Parent commits 296ef00
  • Branches default

Comments (0)

Files changed (4)

File examples/pyd_unittests/class_wrap.d

View file
             ModuleName!"testing",
             Init!(int,double,string),
             Def!(Bizzy5.a),
+            Property!(Bizzy5.b, Mode!"r"),
+            Property!(Bizzy5.c, Mode!"rw"),
+            Property!(Bizzy5.e, Mode!"w"),
     )();
     }, PyInitOrdering.After);
 
         import std.string;
         return format("<%s, %s, '%s'>", i,d,s);
     }
+
+    @property string b() const { return "abc"; }
+
+    @property string c() { return "abc"; }
+    @property void c(string _val) { }
+
+    @property void e(string _val) { }
+
+
 }
 
 unittest {

File examples/pyd_unittests/struct_wrap.d

View file
             ModuleName!"testing",
             Init!(int,int,int),
             Member!("i"),
-            Member!("j"),
-            Member!("k"),
+            Member!("j", Mode!"r"),
+            Member!("k", Mode!"w"),
             Def!(Foo1.bar),
             )();
     }, PyInitOrdering.After);

File infrastructure/pyd/class_wrap.d

View file
     alias ID!(__traits(parent, p)) Parent;
     enum nom = __traits(identifier, p);
     alias TypeTuple!(__traits(getOverloads, Parent, nom)) Overloads;
-    static if(_mode == "" || countUntil(_mode, "r") != 1) {
+    static if(_mode == "" || countUntil(_mode, "r") != -1) {
         alias Filter!(IsGetter,Overloads) Getters;
         static if(_mode == "" && Getters.length == 0) {
             enum isgproperty = false;
             enum rmode = "";
-        }else{
+        }else {
+            import std.string;
             static assert(Getters.length != 0, 
-                    Format!("can't find property %s.%s getter", 
+                    format!("can't find property %s.%s getter", 
                         Parent.stringof, nom));
             static assert(Getters.length == 1, 
-                    Format!("can't handle property overloads of %s.%s getter (types %s)", 
+                    format!("can't handle property overloads of %s.%s getter (types %s)", 
                         Parent.stringof, nom, staticMap!(ReturnType,Getters).stringof));
             alias Getters[0] GetterFn;
             alias typeof(&GetterFn) getter_type;
         enum wmode = "";
     }
 
+    static if(rmode != "") {
+        alias ReturnType!(GetterFn) Type;
+    }else static if(wmode != "") {
+        alias ParameterTypeTuple!(SetterFn)[0] Type;
+    }
+
     enum mode = rmode ~ wmode;
     enum bool isproperty = isgproperty || issproperty;
 }
     alias property_parts!(fn, _mode) parts;
     pragma(msg, "property: ", parts.nom);
     static if(parts.isproperty) {
-        mixin _Member!(parts.nom, pyname, parts.mode, docstring);
+        mixin _Member!(parts.nom, pyname, parts.mode, docstring, parts);
 
         template shim(size_t i, T) {
             enum shim = "";

File infrastructure/pyd/struct_wrap.d

View file
 // It is intended that all of these templates accept a pointer-to-struct type
 // as a template parameter, rather than the struct type itself.
 
-template wrapped_member(T, string name, _M=void) {
+template wrapped_member(T, string name, string mode, PropertyParts...) {
     alias wrapped_class_type!(T) type;
     alias wrapped_class_object!(T) obj;
-    static if (is(_M == void)) {
+    static if(PropertyParts.length != 0) {
+        alias PropertyParts[0] ppart0;
+        alias ppart0.Type M;
+    }else {
         mixin("alias typeof(T."~name~") M;");
-    } else {
-        alias _M M;
-    }
-    extern(C)
-    PyObject* get(PyObject* self, void* closure) {
-        return exception_catcher(delegate PyObject*() {
-            T t = (cast(obj*)self).d_obj;
-            mixin("return d_to_python(t."~name~");");
-        });
+    } 
+    static if(countUntil(mode, "r") != -1) {
+        extern(C)
+            PyObject* get(PyObject* self, void* closure) {
+            return exception_catcher(delegate PyObject*() {
+                T t = (cast(obj*)self).d_obj;
+                mixin("return d_to_python(t."~name~");");
+            });
+        }
     }
 
-    extern(C)
-    int set(PyObject* self, PyObject* value, void* closure) {
-        return exception_catcher(delegate int() {
-            T t = (cast(obj*)self).d_obj;
-            mixin("t."~name~" = python_to_d!(M)(value);");
-            return 0;
-        });
+    static if(countUntil(mode, "w") != -1) {
+        extern(C)
+        int set(PyObject* self, PyObject* value, void* closure) {
+            return exception_catcher(delegate int() {
+                T t = (cast(obj*)self).d_obj;
+                mixin("t."~name~" = python_to_d!(M)(value);");
+                return 0;
+            });
+        }
     }
 }
 
     mixin _Member!(name, args.pyname, args.mode, args.docstring);
 }
 
-template _Member(string realname, string pyname, string mode, string docstring) {
+template _Member(string realname, string pyname, string mode, string docstring, parts...) {
     static const bool needs_shim = false;
     static void call(string classname, T) () {
         pragma(msg, "struct.member: " ~ pyname);
         alias wrapped_prop_list!(T) list;
         list[$-1].name = (pyname ~ "\0").dup.ptr;
         static if(countUntil(mode, "r") != -1) {
-            list[$-1].get = &wrapped_member!(T, realname).get;
+            list[$-1].get = &wrapped_member!(T, realname, mode, parts).get;
         }
         static if(countUntil(mode, "w") != -1) {
-            list[$-1].set = &wrapped_member!(T, realname).set;
+            list[$-1].set = &wrapped_member!(T, realname, mode, parts).set;
         }
         list[$-1].doc = (docstring~"\0").dup.ptr;
         list[$-1].closure = null;