@@ -76,16 +76,38 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
7676
7777 /// <summary>
7878 /// Wrap the given object in an interface object, so that only methods
79- /// of the interface are available. The wrapped object is available
80- /// through properties in both converted/encoded (__implementation__)
81- /// and raw form (__raw_implementation__).
79+ /// of the interface are available.
8280 /// </summary>
8381 public IntPtr WrapObject ( object impl )
8482 {
8583 var objPtr = CLRObject . GetInstHandle ( impl , pyHandle ) ;
86- Runtime . PyObject_SetAttrString ( objPtr , "__implementation__" , Converter . ToPython ( impl ) ) ;
87- Runtime . PyObject_SetAttrString ( objPtr , "__raw_implementation__" , CLRObject . GetInstHandle ( impl ) ) ;
8884 return objPtr ;
8985 }
86+
87+ /// <summary>
88+ /// Expose the wrapped implementation through attributes in both
89+ /// converted/encoded (__implementation__) and raw (__raw_implementation__) form.
90+ /// </summary>
91+ public static IntPtr tp_getattro ( IntPtr ob , IntPtr key )
92+ {
93+ var clrObj = ( CLRObject ) GetManagedObject ( ob ) ;
94+
95+ if ( ! Runtime . PyString_Check ( key ) )
96+ {
97+ return Exceptions . RaiseTypeError ( "string expected" ) ;
98+ }
99+
100+ string name = Runtime . GetManagedString ( key ) ;
101+ if ( name == "__implementation__" )
102+ {
103+ return Converter . ToPython ( clrObj . inst ) ;
104+ }
105+ else if ( name == "__raw_implementation__" )
106+ {
107+ return CLRObject . GetInstHandle ( clrObj . inst ) ;
108+ }
109+
110+ return Runtime . PyObject_GenericGetAttr ( ob , key ) ;
111+ }
90112 }
91113}
0 commit comments