|
30 | 30 |
|
31 | 31 | import ast |
32 | 32 | from six import string_types |
| 33 | +import inspect |
33 | 34 | from six.moves import builtins |
34 | 35 |
|
35 | 36 | from bpython import line as line_properties |
36 | 37 | from bpython._py3compat import py3 |
37 | | -from bpython.inspection import is_new_style |
| 38 | +from bpython.inspection import is_new_style, AttrCleaner |
38 | 39 |
|
39 | 40 | _string_type_nodes = (ast.Str, ast.Bytes) if py3 else (ast.Str,) |
40 | 41 | _numeric_types = (int, float, complex) + (() if py3 else (long,)) |
@@ -239,11 +240,12 @@ def evaluate_current_attribute(cursor_offset, line, namespace=None): |
239 | 240 | def safe_get_attribute(obj, attr): |
240 | 241 | """Gets attributes without triggering descriptors on new-style clases""" |
241 | 242 | if is_new_style(obj): |
242 | | - result = safe_get_attribute_new_style(obj, attr) |
243 | | - if isinstance(result, member_descriptor): |
244 | | - # will either be the same slot descriptor or the value |
245 | | - return getattr(obj, attr) |
246 | | - return result |
| 243 | + with AttrCleaner(obj): |
| 244 | + result = safe_get_attribute_new_style(obj, attr) |
| 245 | + if isinstance(result, member_descriptor): |
| 246 | + # will either be the same slot descriptor or the value |
| 247 | + return getattr(obj, attr) |
| 248 | + return result |
247 | 249 | return getattr(obj, attr) |
248 | 250 |
|
249 | 251 |
|
@@ -264,16 +266,12 @@ def safe_get_attribute_new_style(obj, attr): |
264 | 266 | """ |
265 | 267 | if not is_new_style(obj): |
266 | 268 | raise ValueError("%r is not a new-style class or object" % obj) |
267 | | - to_look_through = (obj.mro() |
268 | | - if hasattr(obj, 'mro') |
269 | | - else [obj] + type(obj).mro()) |
| 269 | + to_look_through = (obj.__mro__ |
| 270 | + if inspect.isclass(obj) |
| 271 | + else (obj,) + type(obj).__mro__) |
270 | 272 |
|
271 | | - found_in_slots = hasattr(obj, '__slots__') and attr in obj.__slots__ |
272 | 273 | for cls in to_look_through: |
273 | 274 | if hasattr(cls, '__dict__') and attr in cls.__dict__: |
274 | 275 | return cls.__dict__[attr] |
275 | 276 |
|
276 | | - if found_in_slots: |
277 | | - return AttributeIsEmptySlot |
278 | | - |
279 | 277 | raise AttributeError() |