@@ -71,7 +71,43 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
7171return IntPtr . Zero ;
7272}
7373
74- return CLRObject . GetInstHandle ( obj , self . pyHandle ) ;
74+ return self . WrapObject ( obj ) ;
75+ }
76+
77+ /// <summary>
78+ /// Wrap the given object in an interface object, so that only methods
79+ /// of the interface are available.
80+ /// </summary>
81+ public IntPtr WrapObject ( object impl )
82+ {
83+ var objPtr = CLRObject . GetInstHandle ( impl , pyHandle ) ;
84+ return objPtr ;
85+ }
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 ) ;
75111}
76112}
77113}