@@ -309,21 +309,36 @@ public PyObject GetAttr(string name)
309309
310310
311311 /// <summary>
312- /// GetAttr Method. Returns fallback value if getting attribute fails for any reason.
312+ /// Returns the named attribute of the Python object, or the given
313+ /// default object if the attribute access throws AttributeError.
313314 /// </summary>
314315 /// <remarks>
315- /// Returns the named attribute of the Python object, or the given
316- /// default object if the attribute access fails.
316+ /// This method ignores any AttrubiteError(s), even ones
317+ /// not raised due to missing requested attribute.
318+ ///
319+ /// For example, if attribute getter calls other Python code, and
320+ /// that code happens to cause AttributeError elsewhere, it will be ignored
321+ /// and <paramref name="_default"/> value will be returned instead.
317322 /// </remarks>
323+ /// <param name="name">Name of the attribute.</param>
324+ /// <param name="_default">The object to return on AttributeError.</param>
325+ [ Obsolete ( "See remarks" ) ]
318326 public PyObject GetAttr ( string name , PyObject _default )
319327 {
320328 if ( name == null ) throw new ArgumentNullException ( nameof ( name ) ) ;
321329
322330 IntPtr op = Runtime . PyObject_GetAttrString ( obj , name ) ;
323331 if ( op == IntPtr . Zero )
324332 {
325- Runtime . PyErr_Clear ( ) ;
326- return _default ;
333+ if ( Exceptions . ExceptionMatches ( Exceptions . AttributeError ) )
334+ {
335+ Runtime . PyErr_Clear ( ) ;
336+ return _default ;
337+ }
338+ else
339+ {
340+ throw PythonException . ThrowLastAsClrException ( ) ;
341+ }
327342 }
328343 return new PyObject ( op ) ;
329344 }
@@ -351,22 +366,36 @@ public PyObject GetAttr(PyObject name)
351366
352367
353368 /// <summary>
354- /// GetAttr Method
369+ /// Returns the named attribute of the Python object, or the given
370+ /// default object if the attribute access throws AttributeError.
355371 /// </summary>
356372 /// <remarks>
357- /// Returns the named attribute of the Python object, or the given
358- /// default object if the attribute access fails. The name argument
359- /// is a PyObject wrapping a Python string or unicode object.
373+ /// This method ignores any AttrubiteError(s), even ones
374+ /// not raised due to missing requested attribute.
375+ ///
376+ /// For example, if attribute getter calls other Python code, and
377+ /// that code happens to cause AttributeError elsewhere, it will be ignored
378+ /// and <paramref name="_default"/> value will be returned instead.
360379 /// </remarks>
380+ /// <param name="name">Name of the attribute. Must be of Python type 'str'.</param>
381+ /// <param name="_default">The object to return on AttributeError.</param>
382+ [ Obsolete ( "See remarks" ) ]
361383 public PyObject GetAttr ( PyObject name , PyObject _default )
362384 {
363385 if ( name == null ) throw new ArgumentNullException ( nameof ( name ) ) ;
364386
365387 IntPtr op = Runtime . PyObject_GetAttr ( obj , name . obj ) ;
366388 if ( op == IntPtr . Zero )
367389 {
368- Runtime . PyErr_Clear ( ) ;
369- return _default ;
390+ if ( Exceptions . ExceptionMatches ( Exceptions . AttributeError ) )
391+ {
392+ Runtime . PyErr_Clear ( ) ;
393+ return _default ;
394+ }
395+ else
396+ {
397+ throw PythonException . ThrowLastAsClrException ( ) ;
398+ }
370399 }
371400 return new PyObject ( op ) ;
372401 }
0 commit comments