| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f55d7d5 commit fb3dc22
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,11 +30,12 @@ | |||
| 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() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -162,6 +162,24 @@ def s4(self): | |||
| 162 | 162 | raise AssertionError('Property __get__ executed') | |
| 163 | 163 | ||
| 164 | 164 | ||
| 165 | + class OverridenGetattr(object): | ||
| 166 | + def __getattr__(self, attr): | ||
| 167 | + raise AssertionError('custom __getattr__ executed') | ||
| 168 | + a = 1 | ||
| 169 | + | ||
| 170 | + | ||
| 171 | + class OverridenGetattribute(object): | ||
| 172 | + def __getattribute__(self, attr): | ||
| 173 | + raise AssertionError('custom __getattrribute__ executed') | ||
| 174 | + a = 1 | ||
| 175 | + | ||
| 176 | + | ||
| 177 | + class OverridenMRO(object): | ||
| 178 | + def __mro__(self): | ||
| 179 | + raise AssertionError('custom mro executed') | ||
| 180 | + a = 1 | ||
| 181 | + | ||
| 182 | + | ||
| 165 | 183 | member_descriptor = type(Slots.s1) | |
| 166 | 184 | ||
| 167 | 185 | ||
@@ -218,5 +236,17 @@ def test_lookup_with_property_and_slots(self): | |||
| 218 | 236 | Slots.__dict__['s3']) | |
| 219 | 237 | self.assertIsInstance(sga(SlotsSubclass, 's3'), property) | |
| 220 | 238 | ||
| 239 | + def test_lookup_on_overriden_methods(self): | ||
| 240 | + sga = safe_get_attribute | ||
| 241 | + self.assertEqual(sga(OverridenGetattr(), 'a'), 1) | ||
| 242 | + self.assertEqual(sga(OverridenGetattribute(), 'a'), 1) | ||
| 243 | + self.assertEqual(sga(OverridenMRO(), 'a'), 1) | ||
| 244 | + with self.assertRaises(AttributeError): | ||
| 245 | + sga(OverridenGetattr(), 'b') | ||
| 246 | + with self.assertRaises(AttributeError): | ||
| 247 | + sga(OverridenGetattribute(), 'b') | ||
| 248 | + with self.assertRaises(AttributeError): | ||
| 249 | + sga(OverridenMRO(), 'b') | ||
| 250 | + | ||
| 221 | 251 | if __name__ == '__main__': | |
| 222 | 252 | unittest.main() | |
| Back | FazBrowse Home | New Git URL |
0 commit comments