Changeset 100
- Timestamp:
- 02/17/07 02:32:39 (5 years ago)
- Files:
-
- trunk/examples/inherit/inherit.d (modified) (2 diffs)
- trunk/examples/inherit/test.py (modified) (1 diff)
- trunk/examples/testdll/test.py (modified) (1 diff)
- trunk/examples/testdll/testdll.d (modified) (1 diff)
- trunk/infrastructure/pyd/LICENSE (modified) (1 diff)
- trunk/infrastructure/pyd/class_wrap.d (modified) (17 diffs)
- trunk/infrastructure/pyd/ctor_wrap.d (modified) (1 diff)
- trunk/infrastructure/pyd/def.d (modified) (1 diff)
- trunk/infrastructure/pyd/dg_convert.d (modified) (1 diff)
- trunk/infrastructure/pyd/exception.d (modified) (1 diff)
- trunk/infrastructure/pyd/func_wrap.d (modified) (1 diff)
- trunk/infrastructure/pyd/iteration.d (modified) (1 diff)
- trunk/infrastructure/pyd/lib_abstract.d (modified) (2 diffs)
- trunk/infrastructure/pyd/make_object.d (modified) (2 diffs)
- trunk/infrastructure/pyd/make_wrapper.d (added)
- trunk/infrastructure/pyd/op_wrap.d (modified) (1 diff)
- trunk/infrastructure/pyd/pyd.d (modified) (1 diff)
- trunk/infrastructure/pyd/pydobject.d (modified) (1 diff)
- trunk/infrastructure/pyd/struct_wrap.d (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/examples/inherit/inherit.d
r91 r100 21 21 } 22 22 23 class BaseWrap : Base {24 mixin OverloadShim;25 this(int i) { super(i); }26 void foo() {27 get_overload(&super.foo, "foo");28 }29 void bar() {30 get_overload(&super.bar, "bar");31 }32 }33 34 class DeriveWrap : Derived {35 mixin OverloadShim;36 this(int i) { super(i); }37 void foo() {38 get_overload(&super.foo, "foo");39 }40 }41 42 23 void call_poly(Base b) { 43 24 writefln("call_poly:"); … … 57 38 } 58 39 59 Base return_poly_wrap() {60 if (b3 is null) b3 = new DeriveWrap(3);61 return b3;62 }63 64 40 extern(C) void PydMain() { 65 41 def!(call_poly); 66 42 def!(return_poly_base); 67 43 def!(return_poly_derived); 68 def!(return_poly_wrap);69 44 70 45 module_init(); 71 46 72 wrapped_class!(Base) b; 73 b.hide(); 74 b.def!(Base.foo); 75 b.def!(Base.bar); 76 finalize_class(b); 47 wrap_class!( 48 Base, 49 Init!(void function(int)), 50 Def!(Base.foo), 51 Def!(Base.bar) 52 ); 77 53 78 wrapped_class!(Derived) d; 79 d.hide(); 80 d.def!(Derived.foo); 81 finalize_class(d); 82 83 wrapped_class!(BaseWrap, "Base") bw; 84 bw.init!(void function(int)); 85 bw.def!(BaseWrap.foo); 86 bw.def!(BaseWrap.bar); 87 finalize_class(bw); 88 89 wrapped_class!(DeriveWrap, "Derived") dw; 90 dw.init!(void function(int)); 91 dw.parent!(BaseWrap); 92 dw.def!(DeriveWrap.foo); 93 finalize_class(dw); 54 wrap_class!( 55 Derived, 56 Init!(void function(int)), 57 Def!(Derived.foo) 58 ); 94 59 } 95 60 trunk/examples/inherit/test.py
r91 r100 50 50 print "inherit.return_poly_derived returned the same object twice" 51 51 assert b2 is b2a 52 b3 = inherit.return_poly_wrap()53 print "inherit.return_poly_wrap returned instance of DeriveWrap"54 assert type(b3) == inherit.Derived55 52 56 53 print trunk/examples/testdll/test.py
r67 r100 38 38 print 39 39 40 print "Testing class wrapping" 40 41 a = testdll.Foo(10) 42 print "Class instantiated!" 43 print "Testing method wrapping:" 41 44 a.foo() 45 print "Testing property wrapping:" 46 print a.i 47 a.i = 50 48 print a.i 42 49 43 50 print "Testing opApply wrapping:" trunk/examples/testdll/testdll.d
r67 r100 118 118 module_init(); 119 119 120 wrapped_class!(Foo) f; 121 // Constructor wrapping 122 f.init!(void function(int), void function(int, int)); 123 // Member function wrapping 124 f.def!(Foo.foo); 125 // Property wrapping 126 f.prop!(Foo.i); 127 finalize_class(f); 120 wrap_class!( 121 Foo, 122 Init!(void delegate(int), void delegate(int, int)), 123 Property!(Foo.i), 124 Def!(Foo.foo) 125 ); 128 126 129 wrapped_struct!(S) s; 130 s.def!(S.write_s); 131 const size_t i = S.i.offsetof; 132 const size_t t = S.s.offsetof; 133 s.member!(int, i, "i"); 134 s.member!(char[], t, "s"); 135 finalize_struct(s); 127 wrap_struct!( 128 S, 129 Def!(S.write_s), 130 Member!("i"), 131 Member!("s") 132 ); 136 133 } 137 134 trunk/infrastructure/pyd/LICENSE
r24 r100 1 Copyright (c) 2006Kirk McDonald1 Copyright 2006, 2007 Kirk McDonald 2 2 3 3 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/class_wrap.d
r91 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of … … 32 32 } 33 33 import pyd.make_object; 34 import pyd.make_wrapper; 34 35 import pyd.op_wrap; 36 import pyd.make_wrapper; 35 37 import pyd.lib_abstract : 36 38 symbolnameof, … … 40 42 ReturnType, 41 43 minArgs, 42 objToStr 44 objToStr, 45 ToString 43 46 ; 44 47 … … 46 49 47 50 PyTypeObject*[ClassInfo] wrapped_classes; 51 template shim_class(T) { 52 PyTypeObject* shim_class; 53 } 48 54 49 55 // This is split out in case I ever want to make a subtype of a wrapped class. … … 243 249 ////////////////////////////// 244 250 251 /+ 245 252 /** 246 253 * This struct wraps a D class. Its member functions are the primary way of … … 252 259 static bool _private = false; 253 260 alias T wrapped_type; 254 /** 255 * Wraps a member function of the class. 256 * 257 * Params: 258 * fn = The member function to wrap. 259 * name = The name of the function as it will appear in Python. 260 * fn_t = The type of the function. It is only useful to specify this 261 * if more than one function has the same name as this one. 262 */ 263 static void def(alias fn, char[] name = symbolnameof!(fn), fn_t=typeof(&fn)) (char[] docstring="") { 261 +/ 262 263 //enum ParamType { Def, StaticDef, Property, Init, Parent, Hide, Iter, AltIter } 264 struct DoNothing { 265 static void call(T) () {} 266 } 267 /** 268 Wraps a member function of the class. 269 270 Params: 271 fn = The member function to wrap. 272 name = The name of the function as it will appear in Python. 273 fn_t = The type of the function. It is only useful to specify this 274 if more than one function has the same name as this one. 275 */ 276 template Def(alias fn, char[] name = symbolnameof!(fn), fn_t=typeof(&fn), uint MIN_ARGS=minArgs!(fn)) { 277 alias Def!(fn, symbolnameof!(fn), name, fn_t, MIN_ARGS) Def; 278 } 279 struct Def(alias fn, char[] _realname, char[] name, fn_t, uint MIN_ARGS) { 280 //static const type = ParamType.Def; 281 alias fn func; 282 alias fn_t func_t; 283 static const char[] realname = _realname; 284 static const char[] funcname = name; 285 static const uint min_args = MIN_ARGS; 286 287 static void call(T) () { 264 288 pragma(msg, "class.def: " ~ name); 265 289 static PyMethodDef empty = { null, null, 0, null }; … … 268 292 list[length-1].ml_meth = &method_wrap!(T, fn, fn_t).func; 269 293 list[length-1].ml_flags = METH_VARARGS; 270 list[length-1].ml_doc = (docstring ~ \0).ptr;294 list[length-1].ml_doc = ""; 271 295 list ~= empty; 272 296 // It's possible that appending the empty item invalidated the … … 274 298 wrapped_class_type!(T).tp_methods = list.ptr; 275 299 } 276 277 /** 278 * Wraps a static member function of the class. Identical to pyd.def.def 279 */ 280 static void static_def(alias fn, char[] name = symbolnameof!(fn), fn_t=typeof(&fn), uint MIN_ARGS=minArgs!(fn)) (char[] docstring="") { 300 template shim(uint i) { 301 const char[] shim = 302 " alias Params["~ToString!(i)~"] __pyd_p"~ToString!(i)~";\n" 303 " ReturnType!(__pyd_p"~ToString!(i)~".func_t) "~_realname~"(ParameterTypeTuple!(__pyd_p"~ToString!(i)~".func_t) t) {\n" 304 " return __pyd_get_overload!(\""~_realname~"\", __pyd_p"~ToString!(i)~".func_t).func(\""~name~"\", t);\n" 305 " }\n"; 306 } 307 template shim_call(char[] varname, uint i) { 308 const char[] shim_call = "Def!("~varname~"."~_realname~", p"~ToString!(i)~".realname, p"~ToString!(i)~".funcname, p"~ToString!(i)~".func_t, p"~ToString!(i)~".min_args)"; 309 } 310 } 311 312 /** 313 Wraps a static member function of the class. Identical to pyd.def.def 314 */ 315 struct StaticDef(alias fn, char[] name = symbolnameof!(fn), fn_t=typeof(&fn), uint MIN_ARGS=minArgs!(fn)) { 316 //static const type = ParamType.StaticDef; 317 alias fn func; 318 alias fn_t func_t; 319 static const char[] funcname = name; 320 static const uint min_args = MIN_ARGS; 321 static void call(T) () { 281 322 pragma(msg, "class.static_def: " ~ name); 282 323 static PyMethodDef empty = { null, null, 0, null }; … … 285 326 list[length-1].ml_meth = &function_wrap!(fn, MIN_ARGS, fn_t).func; 286 327 list[length-1].ml_flags = METH_VARARGS | METH_STATIC; 287 list[length-1].ml_doc = (docstring ~ \0).ptr;328 list[length-1].ml_doc = ""; 288 329 list ~= empty; 289 330 wrapped_class_type!(T).tp_methods = list; 290 331 } 291 292 /** 293 * Wraps a property of the class. 294 * 295 * Params: 296 * fn = The property to wrap. 297 * name = The name of the property as it will appear in Python. 298 * RO = Whether this is a read-only property. 299 */ 300 static void prop(alias fn, char[] name = symbolnameof!(fn), bool RO=false) (char[] docstring="") { 332 template shim(uint i) { 333 const char[] shim = ""; 334 } 335 template shim_call(char[] varname, uint i) { 336 const char[] shim_call = "DoNothing"; 337 } 338 } 339 340 /** 341 Wraps a property of the class. 342 343 Params: 344 fn = The property to wrap. 345 name = The name of the property as it will appear in Python. 346 RO = Whether this is a read-only property. 347 */ 348 template Property(alias fn, char[] name = symbolnameof!(fn), bool RO=false) { 349 alias Property!(fn, symbolnameof!(fn), name, RO) Property; 350 } 351 struct Property(alias fn, char[] _realname, char[] name, bool RO) { 352 alias property_parts!(fn).getter_type get_t; 353 alias property_parts!(fn).setter_type set_t; 354 static const char[] realname = _realname; 355 static const char[] funcname = name; 356 static const bool readonly = RO; 357 static void call(T) () { 301 358 pragma(msg, "class.prop: " ~ name); 302 359 static PyGetSetDef empty = { null, null, null, null, null }; … … 308 365 &wrapped_set!(T, fn).func; 309 366 } 310 wrapped_prop_list!(T)[length-1].doc = (docstring ~ \0).ptr;367 wrapped_prop_list!(T)[length-1].doc = ""; 311 368 wrapped_prop_list!(T)[length-1].closure = null; 312 369 wrapped_prop_list!(T) ~= empty; … … 316 373 wrapped_prop_list!(T).ptr; 317 374 } 318 319 /** 320 * Wraps the constructors of the class. 321 * 322 * This template takes a series of specializations of the ctor template 323 * (see ctor_wrap.d), each of which describes a different constructor 324 * that the class supports. The default constructor need not be 325 * specified, and will always be available if the class supports it. 326 * 327 * Bugs: 328 * This currently does not support having multiple constructors with 329 * the same number of arguments. 330 */ 331 static void init(C ...) () { 375 template shim_setter(uint i) { 376 static if (RO) { 377 const char[] shim_setter = ""; 378 } else { 379 const char[] shim_setter = 380 " ReturnType!(__pyd_p"~ToString!(i)~".set_t) "~_realname~"(ParameterTypeTuple!(__pyd_p"~ToString!(i)~".set_t) t) {\n" 381 " return __pyd_get_overload!(\""~_realname~"\", __pyd_p"~ToString!(i)~".set_t).func(\""~name~"\", t);\n" 382 " }\n"; 383 } 384 } 385 template shim(uint i) { 386 const char[] shim = 387 " alias Params["~ToString!(i)~"] __pyd_p"~ToString!(i)~";\n" 388 " ReturnType!(__pyd_p"~ToString!(i)~".get_t) "~_realname~"() {\n" 389 " return __pyd_get_overload!(\""~_realname~"\", __pyd_p"~ToString!(i)~".get_t).func(\""~name~"\");\n" 390 " }\n" ~ 391 shim_setter!(i); 392 } 393 template shim_call(char[] varname, uint i) { 394 const char[] shim_call = "Property!("~varname~"."~_realname~", p"~ToString!(i)~".realname, p"~ToString!(i)~".funcname, p"~ToString!(i)~".readonly)"; 395 } 396 } 397 398 /** 399 Wraps the constructors of the class. 400 401 This template takes a series of specializations of the ctor template 402 (see ctor_wrap.d), each of which describes a different constructor 403 that the class supports. The default constructor need not be 404 specified, and will always be available if the class supports it. 405 406 Bugs: 407 This currently does not support having multiple constructors with 408 the same number of arguments. 409 */ 410 struct Init(C ...) { 411 alias C ctors; 412 static void call(T) () { 332 413 wrapped_class_type!(T).tp_init = 333 414 &wrapped_ctors!(T, C).init_func; 334 415 } 335 336 static void parent(Parent) () { 337 wrapped_class_type!(T).tp_base = &wrapped_class_type!(Parent); 338 } 339 340 static void hide() { 341 _private = true; 342 } 343 344 // Iteration wrapping support requires StackThreads 345 version(Pyd_with_StackThreads) { 346 347 /** 348 * Allows selection of alternate opApply overloads. iter_t should be 349 * the type of the delegate in the opApply function that the user wants 350 * to be the default. 351 */ 352 static void iter(iter_t) () { 416 template shim_impl(uint i, uint c=0) { 417 static if (c < ctors.length) { 418 const char[] shim_impl = 419 " this(ParameterTypeTuple!(__pyd_c"~ToString!(i)~"["~ToString!(c)~"]) t) {\n" 420 " super(t);\n" 421 " }\n" ~ shim_impl!(i, c+1); 422 } else { 423 const char[] shim_impl = ""; 424 } 425 } 426 template shim(uint i) { 427 const char[] shim = 428 " alias Params["~ToString!(i)~"] __pyd_p"~ToString!(i)~";\n" 429 " alias __pyd_p"~ToString!(i)~".ctors __pyd_c"~ToString!(i)~";\n"~ 430 shim_impl!(i); 431 } 432 template shim_call(char[] varname, uint i) { 433 const char[] shim_call = "Init!(p"~ToString!(i)~".ctors)"; 434 } 435 } 436 437 // Iteration wrapping support requires StackThreads 438 version(Pyd_with_StackThreads) { 439 440 /** 441 Allows selection of alternate opApply overloads. iter_t should be 442 the type of the delegate in the opApply function that the user wants 443 to be the default. 444 */ 445 struct Iter(iter_t) { 446 static void call(T) () { 353 447 PydStackContext_Ready(); 354 wrapped_class_type!(T).tp_iter = &wrapped_iter!(T, T.opApply, int function(iter_t)).iter; 355 } 356 357 /** 358 * Exposes alternate iteration methods, originally intended for use with 359 * D's delegate-as-iterator features, as methods returning a Python 360 * iterator. 361 */ 362 static void alt_iter(alias fn, char[] name = symbolnameof!(fn), iter_t = funcDelegInfoT!(typeof(&fn)).Meta.ArgType!(0)) (char[] docstring="") { 448 // This strange bit of hackery is needed since we operate on pointer- 449 // to-struct types, rather than just struct types. 450 static if (is(T S : S*) && is(S == struct)) { 451 wrapped_class_type!(T).tp_iter = &wrapped_iter!(T, S.opApply, int function(iter_t)).iter; 452 } else { 453 wrapped_class_type!(T).tp_iter = &wrapped_iter!(T, T.opApply, int function(iter_t)).iter; 454 } 455 } 456 } 457 458 /** 459 Exposes alternate iteration methods, originally intended for use with 460 D's delegate-as-iterator features, as methods returning a Python 461 iterator. 462 */ 463 struct AltIter(alias fn, char[] name = symbolnameof!(fn), iter_t = funcDelegInfoT!(typeof(&fn)).Meta.ArgType!(0)) { 464 static void call(T) () { 363 465 static PyMethodDef empty = { null, null, 0, null }; 364 466 alias wrapped_method_list!(T) list; … … 373 475 wrapped_class_type!(T).tp_methods = list; 374 476 } 375 376 } /*Pyd_with_StackThreads*/ 377 } 378 379 /** 380 * Finalize the wrapping of the class. It is neccessary to call this after all 381 * calls to the wrapped_class member functions. 382 */ 383 void finalize_class(CLS) (CLS cls, char[] docstring="", char[] modulename="") { 384 alias CLS.wrapped_type T; 477 } 478 479 } /*Pyd_with_StackThreads*/ 480 481 private 482 template comma(uint i, uint length) { 483 static if (i < length-1) { 484 const char[] comma = ","; 485 } else { 486 const char[] comma = ""; 487 } 488 } 489 490 private 491 template recursive_call(char[] name, int i, Params...) { 492 static if (i < Params.length) { 493 const char[] recursive_call = Params[i].shim_call!(name, i) ~ comma!(i, Params.length) ~ recursive_call!(name, i+1, Params); 494 } else { 495 const char[] recursive_call = ""; 496 } 497 } 498 499 private 500 template aliases(uint i, Params...) { 501 static if (i < Params.length) { 502 const char[] aliases = "alias Params["~ToString!(i)~"] p"~ToString!(i)~";\n" ~ aliases!(i+1, Params); 503 } else { 504 const char[] aliases = ""; 505 } 506 } 507 508 void wrap_class(T, Params...) (char[] docstring="", char[] modulename="") { 509 wrap_class!(void, T, symbolnameof!(T), Params)(docstring, modulename); 510 } 511 void wrap_class(T, char[] name, Params...) (char[] docstring="", char[] modulename="") { 512 wrap_class!(void, T, name, Params)(docstring, modulename); 513 } 514 515 void wrap_class(wrapping, _T, char[] name, Params...) (char[] docstring="", char[] modulename="") { 516 //alias CLS.wrapped_type T; 517 //const char[] name = CLS._name; 518 static if (is(_T == class)) { 519 pragma(msg, "wrap_class: " ~ name); 520 alias _T T; 521 } else { 522 pragma(msg, "wrap_struct: " ~ name); 523 alias _T* T; 524 } 385 525 alias wrapped_class_type!(T) type; 386 const char[] name = CLS._name; 387 static if (is(T == class)) { 388 pragma(msg, "finalize_class: " ~ name); 389 } else { 390 pragma(msg, "finalize_struct: " ~ name); 391 } 392 pragma(msg, "finalize_class, T is " ~ prettytypeof!(T)); 393 526 //pragma(msg, "wrap_class, T is " ~ prettytypeof!(T)); 527 528 //Params params; 529 foreach (param; Params) { 530 param.call!(T)(); 531 } 532 394 533 assert(Pyd_Module_p(modulename) !is null, "Must initialize module before wrapping classes."); 395 534 char[] module_name = toString(PyModule_GetName(Pyd_Module_p(modulename))); 396 // Fill in missing values 535 536 ////////////////// 537 // Basic values // 538 ////////////////// 397 539 type.ob_type = PyType_Type_p(); 398 540 type.tp_basicsize = (wrapped_class_object!(T)).sizeof; … … 403 545 type.tp_name = (module_name ~ "." ~ name ~ \0).ptr; 404 546 405 // Check for wrapped parent classes, if one was not explicitly supplied. 406 if (type.tp_base is null) { 547 ///////////////// 548 // Inheritance // 549 ///////////////// 550 static if (is(wrapping == void)) { 551 // Inherit directly-wrapped classes from their wrapped superclass. 407 552 static if (is(T B == super)) { 408 553 foreach (C; B) { … … 414 559 } 415 560 } 416 } 417 561 } else { 562 // Inherit shims from their grandparent's shim. 563 static if (is(wrapping B == super)) { 564 foreach (C; B) { 565 static if (is(C == class) && !is(C == Object)) { 566 type.tp_base = shim_class!(C); 567 } 568 } 569 } 570 } 571 572 //////////////////////// 573 // Operator overloads // 574 //////////////////////// 418 575 // Numerical operator overloads 419 576 if (wrapped_class_as_number!(T) != PyNumberMethods.init) { … … 448 605 } 449 606 450 if (CLS._private) { 607 ////////////////////////// 608 // Constructor wrapping // 609 ////////////////////////// 610 static if (is(wrapping == void) && is(T == class)) { 611 // Non-shim classes cannot be instantiated from Python. 451 612 type.tp_init = null; 452 613 } else { 453 614 // If a ctor wasn't supplied, try the default. 615 // If the default ctor isn't available, and no ctors were supplied, 616 // then this class cannot be instantiated from Python. 617 // (Structs always use the default ctor.) 454 618 static if (is(typeof(new T))) { 455 619 if (type.tp_init is null) { … … 462 626 } 463 627 } 628 629 ////////////////// 630 // Finalization // 631 ////////////////// 464 632 if (PyType_Ready(&type) < 0) { 465 633 throw new Exception("Couldn't ready wrapped type!"); 466 634 } 467 635 Py_INCREF(cast(PyObject*)&type); 468 if (!CLS._private) { 636 // Only directly expose a class to Python if it is a shim. 637 static if (!is(wrapping == void) || is(T U : U*) && is(U == struct)) { 469 638 PyModule_AddObject(Pyd_Module_p(modulename), name.ptr, cast(PyObject*)&type); 470 639 } 640 471 641 is_wrapped!(T) = true; 472 642 static if (is(T == class)) { 473 643 wrapped_classes[T.classinfo] = &type; 474 } 475 } 476 477 template OverloadShim() { 478 std.traits.ReturnType!(dg_t) get_overload(dg_t, T ...) (dg_t dg, char[] name, T t) { 479 python.PyObject** _pyobj = cast(void*)this in wrapped_gc_objects; 480 python.PyTypeObject** _pytype = this.classinfo in wrapped_classes; 481 if (_pyobj is null || _pytype is null || (*_pyobj).ob_type != *_pytype) { 482 // If this object's type is not the wrapped class's type (that is, 483 // if this object is actually a Python subclass of the wrapped 484 // class), then call the Python object. 485 python.PyObject* method = python.PyObject_GetAttrString(*_pyobj, (name ~ \0).ptr); 486 if (method is null) handle_exception(); 487 dg_t pydg = PydCallable_AsDelegate!(dg_t)(method); 488 python.Py_DECREF(method); 489 return pydg(t); 490 } else { 491 return dg(t); 644 // If this is a class passed in by the user, create and wrap the shim. 645 // (By recursively calling this function.) 646 static if (is(wrapping == void)) { 647 alias make_wrapper!(T, Params).wrapper wrapper_class; 648 // Construct the recursive call. Since /this/ call to wrap_class 649 // was passed aliases to the members of the /base/ class, we need 650 // to pass the recursive call aliases to the members of the /shim/. 651 // The recursive_call template goes through each member of Params 652 // and constructs this. 653 654 // This is a workaround for some tuple shortcomings... 655 const char[] a = aliases!(0, Params); 656 pragma(msg, a); 657 mixin(a); 658 659 const char[] call = "wrap_class!(T, wrapper_class, name, "~recursive_call!("wrapper_class", 0, Params)~")();"; 660 pragma(msg, call); 661 mixin(call); 662 shim_class!(T) = &wrapped_class_type!(wrapper_class); 492 663 } 493 664 } … … 565 736 alias wrapped_class_type!(T) type; 566 737 wrapped_object* self = cast(wrapped_object*)_self; 567 if (!is_wrapped!(T) || self is null || !PyObject_TypeCheck(_self, &type)) {738 if (!is_wrapped!(T) || self is null || (is(T : Object) && cast(T)cast(Object)self.d_obj is null)) { 568 739 throw new Exception("Error extracting D object from Python object..."); 569 740 } trunk/infrastructure/pyd/ctor_wrap.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/def.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/dg_convert.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/exception.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/func_wrap.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/iteration.d
r68 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/lib_abstract.d
r69 r100 25 25 module pyd.lib_abstract; 26 26 27 version ( Pyd_with_Tango) {27 version (Tango) { 28 28 import tango.stdc.string : strlen; 29 29 import tango.text.convert.Integer : qadut; … … 50 50 public import std.traits : ParameterTypeTuple, ReturnType; 51 51 public import std.bind : minArgs = minNumArgs; 52 public import std.metastrings : ToString; 52 53 } trunk/infrastructure/pyd/make_object.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of … … 248 248 // We can only convert to a class if it has been wrapped, and of course 249 249 // we can only convert the object if it is the wrapped type. 250 if (is_wrapped!(T) && PyObject_TypeCheck(o, &wrapped_class_type!(T))) {250 if (is_wrapped!(T) && cast(T)((cast(wrapped_class_object!(Object)*)o).d_obj) !is null) { 251 251 return WrapPyObject_AsObject!(T)(o); 252 252 } trunk/infrastructure/pyd/op_wrap.d
r69 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/pyd.d
r60 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of trunk/infrastructure/pyd/pydobject.d
r69 r100 170 170 return new PydObject(PyObject_Str(m_ptr)); 171 171 } 172 /// Allows use of PydObject in writef via %s173 version (Pyd_with_Tango) {172 version (Tango) { 173 /// Allows PydObject to be formatted. 174 174 char[] toUtf8() { 175 175 return d_type!(char[])(m_ptr); 176 176 } 177 177 } else { 178 /// Allows use of PydObject in writef via %s 178 179 char[] toString() { 179 180 return d_type!(char[])(m_ptr); trunk/infrastructure/pyd/struct_wrap.d
r92 r100 1 1 /* 2 Copyright (c) 2006Kirk McDonald2 Copyright 2006, 2007 Kirk McDonald 3 3 4 4 Permission is hereby granted, free of charge, to any person obtaining a copy of … … 34 34 ; 35 35 36 //import std.stdio; 37 //import std.string; 38 //import meta.Nameof; 36 // It is intended that all of these templates accept a pointer-to-struct type 37 // as a template parameter, rather than the struct type itself. 39 38 40 // With the exception of the T passed to wrapped_struct, it is intended that 41 // all of these templates accept a pointer-to-struct type as a template 42 // parameter, rather than the struct type itself. 43 44 template wrapped_member(T, M, size_t offset) { 39 template wrapped_member(T, char[] name, _M=void) { 45 40 alias wrapped_class_type!(T) type; 46 41 alias wrapped_class_object!(T) obj; 47 //alias typeof(member) M; 42 static if (is(_M == void)) { 43 mixin("alias typeof(T."~name~") M;"); 44 } else { 45 alias _M M; 46 } 48 47 extern(C) 49 48 PyObject* get(PyObject* self, void* closure) { 50 49 return exception_catcher(delegate PyObject*() { 51 50 T t = (cast(obj*)self).d_obj; 52 M* m = cast(M*)(cast(void*)t + offset); 53 return _py(*m); 51 mixin("return _py(t."~name~");"); 54 52 }); 55 53 } … … 59 57 return exception_catcher(delegate int() { 60 58 T t = (cast(obj*)self).d_obj; 61 M* m = cast(M*)(cast(void*)(t) + offset); 62 *m = d_type!(M)(value); 59 mixin("t."~name~" = d_type!(M)(value);"); 63 60 return 0; 64 61 }); … … 66 63 } 67 64 68 struct wrapped_struct(T, char[] structname = symbolnameof!(T)) { 69 pragma(msg, "wrapped_struct: " ~ structname); 70 static const char[] _name = structname; 71 static bool _private = false; 72 alias T* wrapped_type; 73 74 static void member(M, size_t offset, char[] name) (char[] docstring="") { 65 struct Member(char[] realname, char[] name=realname) { 66 static void call(T) () { 75 67 pragma(msg, "struct.member: " ~ name); 76 68 static PyGetSetDef empty = {null, null, null, null, null}; 77 alias wrapped_prop_list!(T *) list;69 alias wrapped_prop_list!(T) list; 78 70 list[length-1].name = (name ~ \0).ptr; 79 list[length-1].get = &wrapped_member!(T *, M, offset).get;80 list[length-1].set = &wrapped_member!(T *, M, offset).set;81 list[length-1].doc = (docstring ~ \0).ptr;71 list[length-1].get = &wrapped_member!(T, realname).get; 72 list[length-1].set = &wrapped_member!(T, realname).set; 73 list[length-1].doc = ""; 82 74 list[length-1].closure = null; 83 75 list ~= empty; 84 wrapped_class_type!(T *).tp_getset = list.ptr;76 wrapped_class_type!(T).tp_getset = list.ptr; 85 77 } 86 87 alias wrapped_class!(T*, structname).def def;88 alias wrapped_class!(T*, structname).static_def static_def;89 alias wrapped_class!(T*, structname).prop prop;90 91 version(Pyd_with_StackThreads) {92 93 static void iter(iter_t) () {94 PydStackContext_Ready();95 wrapped_class_type!(T*).tp_iter = &wrapped_iter!(T*, T.opApply, int function(iter_t)).iter;96 }97 98 alias wrapped_class!(T*, structname).alt_iter alt_iter;99 100 } /*Pyd_with_StackThreads*/101 78 } 102 79 103 alias pyd.class_wrap.finalize_class finalize_struct;80 alias wrap_class wrap_struct; 104 81 105 /+106 void finalize_struct(SCT) (SCT sct, char[] modulename="") {107 alias SCT.wrapped_type T;108 alias wrapped_class_type!(T) type;109 const char[] name = SCT._name;110 pragma(msg, "finalize_struct: " ~ name);111 112 assert(Pyd_Module_p(modulename) !is null, "Must initialize module before wrapping structs.");113 char[] module_name = toString(PyModule_GetName(Pyd_Module_p(modulename)));114 // Fill in missing values115 type.ob_type = PyType_Type_p();116 type.tp_basicsize = (wrapped_class_object!(T)).sizeof;117 type.tp_doc = name ~ " objects" ~ \0;118 type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;119 //type.tp_repr = &wrapped_repr!(T).repr;120 type.tp_methods = wrapped_method_list!(T);121 type.tp_name = module_name ~ "." ~ name ~ \0;122 123 }124 +/
