@@ -164,18 +164,20 @@ internal static Type CreateDerivedType(string name,
164164 if ( py_dict != IntPtr . Zero && Runtime . PyDict_Check ( py_dict ) )
165165 {
166166 Runtime . Incref ( py_dict ) ;
167- PyDict dict = new PyDict ( py_dict ) ;
168-
169- foreach ( PyObject pyKey in dict . Keys ( ) )
167+ using ( PyDict dict = new PyDict ( py_dict ) )
168+ using ( PyObject keys = dict . Keys ( ) )
170169 {
171- PyObject value = dict [ pyKey ] ;
172- if ( value . HasAttr ( "_clr_property_type_" ) )
170+ foreach ( PyObject pyKey in keys )
173171 {
174- string propertyName = pyKey . ToString ( ) ;
175- pyProperties . Add ( propertyName ) ;
172+ using ( PyObject value = dict [ pyKey ] )
173+ if ( value . HasAttr ( "_clr_property_type_" ) )
174+ {
175+ string propertyName = pyKey . ToString ( ) ;
176+ pyProperties . Add ( propertyName ) ;
176177
177- // Add the property to the type
178- AddPythonProperty ( propertyName , value , typeBuilder ) ;
178+ // Add the property to the type
179+ AddPythonProperty ( propertyName , value , typeBuilder ) ;
180+ }
179181 }
180182 }
181183 }
@@ -204,21 +206,23 @@ internal static Type CreateDerivedType(string name,
204206 if ( py_dict != IntPtr . Zero && Runtime . PyDict_Check ( py_dict ) )
205207 {
206208 Runtime . Incref ( py_dict ) ;
207- PyDict dict = new PyDict ( py_dict ) ;
208-
209- foreach ( PyObject pyKey in dict . Keys ( ) )
209+ using ( PyDict dict = new PyDict ( py_dict ) )
210+ using ( PyObject keys = dict . Keys ( ) )
210211 {
211- PyObject value = dict [ pyKey ] ;
212- if ( value . HasAttr ( "_clr_return_type_" ) && value . HasAttr ( "_clr_arg_types_" ) )
212+ foreach ( PyObject pyKey in keys )
213213 {
214- string methodName = pyKey . ToString ( ) ;
214+ using ( PyObject value = dict [ pyKey ] )
215+ if ( value . HasAttr ( "_clr_return_type_" ) && value . HasAttr ( "_clr_arg_types_" ) )
216+ {
217+ string methodName = pyKey . ToString ( ) ;
215218
216- // if this method has already been redirected to the python method skip it
217- if ( virtualMethods . Contains ( methodName ) )
218- continue ;
219+ // if this method has already been redirected to the python method skip it
220+ if ( virtualMethods . Contains ( methodName ) )
221+ continue ;
219222
220- // Add the method to the type
221- AddPythonMethod ( methodName , value , typeBuilder ) ;
223+ // Add the method to the type
224+ AddPythonMethod ( methodName , value , typeBuilder ) ;
225+ }
222226 }
223227 }
224228 }
@@ -386,62 +390,64 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
386390 if ( func . HasAttr ( "_clr_method_name_" ) )
387391 methodName = func . GetAttr ( "_clr_method_name_" ) . ToString ( ) ;
388392
389- PyObject pyReturnType = func . GetAttr ( "_clr_return_type_" ) ;
390- Type returnType = pyReturnType . AsManagedObject ( typeof ( Type ) ) as Type ;
391- if ( returnType == null )
392- returnType = typeof ( void ) ;
393-
394- PyObject pyArgTypes = func . GetAttr ( "_clr_arg_types_" ) ;
395- if ( ! pyArgTypes . IsIterable ( ) )
396- throw new ArgumentException ( "_clr_arg_types_ must be a list or tuple of CLR types" ) ;
397-
398- List < Type > argTypes = new List < Type > ( ) ;
399- foreach ( PyObject pyArgType in pyArgTypes )
393+ using ( PyObject pyReturnType = func . GetAttr ( "_clr_return_type_" ) )
394+ using ( PyObject pyArgTypes = func . GetAttr ( "_clr_arg_types_" ) )
400395 {
401- Type argType = pyArgType . AsManagedObject ( typeof ( Type ) ) as Type ;
402- if ( argType == null )
396+ Type returnType = pyReturnType . AsManagedObject ( typeof ( Type ) ) as Type ;
397+ if ( returnType == null )
398+ returnType = typeof ( void ) ;
399+
400+ if ( ! pyArgTypes . IsIterable ( ) )
403401 throw new ArgumentException ( "_clr_arg_types_ must be a list or tuple of CLR types" ) ;
404- argTypes . Add ( argType ) ;
405- }
406402
407- // add the method to call back into python
408- MethodAttributes methodAttribs = MethodAttributes . Public |
409- MethodAttributes . Virtual |
410- MethodAttributes . ReuseSlot |
411- MethodAttributes . HideBySig ;
403+ List < Type > argTypes = new List < Type > ( ) ;
404+ foreach ( PyObject pyArgType in pyArgTypes )
405+ {
406+ Type argType = pyArgType . AsManagedObject ( typeof ( Type ) ) as Type ;
407+ if ( argType == null )
408+ throw new ArgumentException ( "_clr_arg_types_ must be a list or tuple of CLR types" ) ;
409+ argTypes . Add ( argType ) ;
410+ }
412411
413- MethodBuilder methodBuilder = typeBuilder . DefineMethod ( methodName ,
414- methodAttribs ,
415- returnType ,
416- argTypes . ToArray ( ) ) ;
412+ // add the method to call back into python
413+ MethodAttributes methodAttribs = MethodAttributes . Public |
414+ MethodAttributes . Virtual |
415+ MethodAttributes . ReuseSlot |
416+ MethodAttributes . HideBySig ;
417417
418- ILGenerator il = methodBuilder . GetILGenerator ( ) ;
419- il . DeclareLocal ( typeof ( Object [ ] ) ) ;
420- il . Emit ( OpCodes . Ldarg_0 ) ;
421- il . Emit ( OpCodes . Ldstr , methodName ) ;
422- il . Emit ( OpCodes . Ldnull ) ; // don't fall back to the base type's method
423- il . Emit ( OpCodes . Ldc_I4 , argTypes . Count ) ;
424- il . Emit ( OpCodes . Newarr , typeof ( System . Object ) ) ;
425- il . Emit ( OpCodes . Stloc_0 ) ;
426- for ( int i = 0 ; i < argTypes . Count ; ++ i )
427- {
418+ MethodBuilder methodBuilder = typeBuilder . DefineMethod ( methodName ,
419+ methodAttribs ,
420+ returnType ,
421+ argTypes . ToArray ( ) ) ;
422+
423+ ILGenerator il = methodBuilder . GetILGenerator ( ) ;
424+ il . DeclareLocal ( typeof ( Object [ ] ) ) ;
425+ il . Emit ( OpCodes . Ldarg_0 ) ;
426+ il . Emit ( OpCodes . Ldstr , methodName ) ;
427+ il . Emit ( OpCodes . Ldnull ) ; // don't fall back to the base type's method
428+ il . Emit ( OpCodes . Ldc_I4 , argTypes . Count ) ;
429+ il . Emit ( OpCodes . Newarr , typeof ( System . Object ) ) ;
430+ il . Emit ( OpCodes . Stloc_0 ) ;
431+ for ( int i = 0 ; i < argTypes . Count ; ++ i )
432+ {
433+ il . Emit ( OpCodes . Ldloc_0 ) ;
434+ il . Emit ( OpCodes . Ldc_I4 , i ) ;
435+ il . Emit ( OpCodes . Ldarg , i + 1 ) ;
436+ if ( argTypes [ i ] . IsValueType )
437+ il . Emit ( OpCodes . Box , argTypes [ i ] ) ;
438+ il . Emit ( OpCodes . Stelem , typeof ( Object ) ) ;
439+ }
428440 il . Emit ( OpCodes . Ldloc_0 ) ;
429- il . Emit ( OpCodes . Ldc_I4 , i ) ;
430- il . Emit ( OpCodes . Ldarg , i + 1 ) ;
431- if ( argTypes [ i ] . IsValueType )
432- il . Emit ( OpCodes . Box , argTypes [ i ] ) ;
433- il . Emit ( OpCodes . Stelem , typeof ( Object ) ) ;
434- }
435- il . Emit ( OpCodes . Ldloc_0 ) ;
436- if ( returnType == typeof ( void ) )
437- {
438- il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeMethodVoid" ) ) ;
439- }
440- else
441- {
442- il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeMethod" ) . MakeGenericMethod ( returnType ) ) ;
441+ if ( returnType == typeof ( void ) )
442+ {
443+ il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeMethodVoid" ) ) ;
444+ }
445+ else
446+ {
447+ il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeMethod" ) . MakeGenericMethod ( returnType ) ) ;
448+ }
449+ il . Emit ( OpCodes . Ret ) ;
443450 }
444- il . Emit ( OpCodes . Ret ) ;
445451 }
446452
447453 /// <summary>
@@ -460,47 +466,49 @@ private static void AddPythonProperty(string propertyName, PyObject func, TypeBu
460466 MethodAttributes . HideBySig |
461467 MethodAttributes . SpecialName ;
462468
463- PyObject pyPropertyType = func . GetAttr ( "_clr_property_type_" ) ;
464- Type propertyType = pyPropertyType . AsManagedObject ( typeof ( Type ) ) as Type ;
465- if ( propertyType == null )
466- throw new ArgumentException ( "_clr_property_type must be a CLR type" ) ;
467-
468- PropertyBuilder propertyBuilder = typeBuilder . DefineProperty ( propertyName ,
469- PropertyAttributes . None ,
470- propertyType ,
471- null ) ;
472-
473- if ( func . HasAttr ( "fget" ) && func . GetAttr ( "fget" ) . IsTrue ( ) )
469+ using ( PyObject pyPropertyType = func . GetAttr ( "_clr_property_type_" ) )
474470 {
475- MethodBuilder methodBuilder = typeBuilder . DefineMethod ( "get_" + propertyName ,
476- methodAttribs ,
477- propertyType ,
478- null ) ;
479-
480- ILGenerator il = methodBuilder . GetILGenerator ( ) ;
481- il . Emit ( OpCodes . Ldarg_0 ) ;
482- il . Emit ( OpCodes . Ldstr , propertyName ) ;
483- il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeGetProperty" ) . MakeGenericMethod ( propertyType ) ) ;
484- il . Emit ( OpCodes . Ret ) ;
471+ Type propertyType = pyPropertyType . AsManagedObject ( typeof ( Type ) ) as Type ;
472+ if ( propertyType == null )
473+ throw new ArgumentException ( "_clr_property_type must be a CLR type" ) ;
485474
486- propertyBuilder . SetGetMethod ( methodBuilder ) ;
487- }
488-
489- if ( func . HasAttr ( "fset" ) && func . GetAttr ( "fset" ) . IsTrue ( ) )
490- {
491- MethodBuilder methodBuilder = typeBuilder . DefineMethod ( "set_" + propertyName ,
492- methodAttribs ,
493- null ,
494- new Type [ ] { propertyType } ) ;
475+ PropertyBuilder propertyBuilder = typeBuilder . DefineProperty ( propertyName ,
476+ PropertyAttributes . None ,
477+ propertyType ,
478+ null ) ;
495479
496- ILGenerator il = methodBuilder . GetILGenerator ( ) ;
497- il . Emit ( OpCodes . Ldarg_0 ) ;
498- il . Emit ( OpCodes . Ldstr , propertyName ) ;
499- il . Emit ( OpCodes . Ldarg_1 ) ;
500- il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeSetProperty" ) . MakeGenericMethod ( propertyType ) ) ;
501- il . Emit ( OpCodes . Ret ) ;
480+ if ( func . HasAttr ( "fget" ) && func . GetAttr ( "fget" ) . IsTrue ( ) )
481+ {
482+ MethodBuilder methodBuilder = typeBuilder . DefineMethod ( "get_" + propertyName ,
483+ methodAttribs ,
484+ propertyType ,
485+ null ) ;
486+
487+ ILGenerator il = methodBuilder . GetILGenerator ( ) ;
488+ il . Emit ( OpCodes . Ldarg_0 ) ;
489+ il . Emit ( OpCodes . Ldstr , propertyName ) ;
490+ il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeGetProperty" ) . MakeGenericMethod ( propertyType ) ) ;
491+ il . Emit ( OpCodes . Ret ) ;
492+
493+ propertyBuilder . SetGetMethod ( methodBuilder ) ;
494+ }
502495
503- propertyBuilder . SetSetMethod ( methodBuilder ) ;
496+ if ( func . HasAttr ( "fset" ) && func . GetAttr ( "fset" ) . IsTrue ( ) )
497+ {
498+ MethodBuilder methodBuilder = typeBuilder . DefineMethod ( "set_" + propertyName ,
499+ methodAttribs ,
500+ null ,
501+ new Type [ ] { propertyType } ) ;
502+
503+ ILGenerator il = methodBuilder . GetILGenerator ( ) ;
504+ il . Emit ( OpCodes . Ldarg_0 ) ;
505+ il . Emit ( OpCodes . Ldstr , propertyName ) ;
506+ il . Emit ( OpCodes . Ldarg_1 ) ;
507+ il . Emit ( OpCodes . Call , typeof ( PythonDerivedType ) . GetMethod ( "InvokeSetProperty" ) . MakeGenericMethod ( propertyType ) ) ;
508+ il . Emit ( OpCodes . Ret ) ;
509+
510+ propertyBuilder . SetSetMethod ( methodBuilder ) ;
511+ }
504512 }
505513 }
506514
@@ -681,25 +689,16 @@ public static T InvokeGetProperty<T>(IPythonDerivedType obj, string propertyName
681689 if ( null == self )
682690 throw new NullReferenceException ( "Instance must be specified when getting a property" ) ;
683691
684- List < PyObject > disposeList = new List < PyObject > ( ) ;
685692 IntPtr gs = Runtime . PyGILState_Ensure ( ) ;
686693 try
687694 {
688695 Runtime . Incref ( self . pyHandle ) ;
689- PyObject pyself = new PyObject ( self . pyHandle ) ;
690- disposeList . Add ( pyself ) ;
691-
692- PyObject pyvalue = pyself . GetAttr ( propertyName ) ;
693- disposeList . Add ( pyvalue ) ;
694- return ( T ) pyvalue . AsManagedObject ( typeof ( T ) ) ;
696+ using ( PyObject pyself = new PyObject ( self . pyHandle ) )
697+ using ( PyObject pyvalue = pyself . GetAttr ( propertyName ) )
698+ return ( T ) pyvalue . AsManagedObject ( typeof ( T ) ) ;
695699 }
696700 finally
697701 {
698- foreach ( PyObject x in disposeList )
699- {
700- if ( x != null )
701- x . Dispose ( ) ;
702- }
703702 Runtime . PyGILState_Release ( gs ) ;
704703 }
705704 }
@@ -712,26 +711,16 @@ public static void InvokeSetProperty<T>(IPythonDerivedType obj, string propertyN
712711 if ( null == self )
713712 throw new NullReferenceException ( "Instance must be specified when setting a property" ) ;
714713
715- List < PyObject > disposeList = new List < PyObject > ( ) ;
716714 IntPtr gs = Runtime . PyGILState_Ensure ( ) ;
717715 try
718716 {
719717 Runtime . Incref ( self . pyHandle ) ;
720- PyObject pyself = new PyObject ( self . pyHandle ) ;
721- disposeList . Add ( pyself ) ;
722-
723- PyObject pyvalue = new PyObject ( Converter . ToPythonImplicit ( value ) ) ;
724- disposeList . Add ( pyvalue ) ;
725-
726- pyself . SetAttr ( propertyName , pyvalue ) ;
718+ using ( PyObject pyself = new PyObject ( self . pyHandle ) )
719+ using ( PyObject pyvalue = new PyObject ( Converter . ToPythonImplicit ( value ) ) )
720+ pyself . SetAttr ( propertyName , pyvalue ) ;
727721 }
728722 finally
729723 {
730- foreach ( PyObject x in disposeList )
731- {
732- if ( x != null )
733- x . Dispose ( ) ;
734- }
735724 Runtime . PyGILState_Release ( gs ) ;
736725 }
737726 }
0 commit comments