Show More
@@ -1,89 +1,86 b'' | |||||
1 | # encoding: utf-8 |
|
1 | # encoding: utf-8 | |
2 | """A fancy version of Python's builtin :func:`dir` function. |
|
2 | """A fancy version of Python's builtin :func:`dir` function. | |
3 | """ |
|
3 | """ | |
4 |
|
4 | |||
5 | #----------------------------------------------------------------------------- |
|
5 | #----------------------------------------------------------------------------- | |
6 | # Copyright (C) 2008-2011 The IPython Development Team |
|
6 | # Copyright (C) 2008-2011 The IPython Development Team | |
7 | # |
|
7 | # | |
8 | # Distributed under the terms of the BSD License. The full license is in |
|
8 | # Distributed under the terms of the BSD License. The full license is in | |
9 | # the file COPYING, distributed as part of this software. |
|
9 | # the file COPYING, distributed as part of this software. | |
10 | #----------------------------------------------------------------------------- |
|
10 | #----------------------------------------------------------------------------- | |
11 |
|
11 | |||
12 | #----------------------------------------------------------------------------- |
|
12 | #----------------------------------------------------------------------------- | |
13 | # Imports |
|
13 | # Imports | |
14 | #----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 | from .py3compat import string_types |
|
15 | from .py3compat import string_types | |
16 |
|
16 | |||
17 | #----------------------------------------------------------------------------- |
|
17 | #----------------------------------------------------------------------------- | |
18 | # Code |
|
18 | # Code | |
19 | #----------------------------------------------------------------------------- |
|
19 | #----------------------------------------------------------------------------- | |
20 |
|
20 | |||
21 |
|
21 | |||
22 | def safe_hasattr(obj, attr): |
|
22 | def safe_hasattr(obj, attr): | |
23 | """In recent versions of Python, hasattr() only catches AttributeError. |
|
23 | """In recent versions of Python, hasattr() only catches AttributeError. | |
24 | This catches all errors. |
|
24 | This catches all errors. | |
25 | """ |
|
25 | """ | |
26 | try: |
|
26 | try: | |
27 | getattr(obj, attr) |
|
27 | getattr(obj, attr) | |
28 | return True |
|
28 | return True | |
29 | except: |
|
29 | except: | |
30 | return False |
|
30 | return False | |
31 |
|
31 | |||
32 |
|
32 | |||
33 | def get_class_members(cls): |
|
33 | def get_class_members(cls): | |
34 | ret = dir(cls) |
|
34 | ret = dir(cls) | |
35 | if safe_hasattr(cls, '__bases__'): |
|
35 | if safe_hasattr(cls, '__bases__'): | |
36 | try: |
|
36 | try: | |
37 | bases = cls.__bases__ |
|
37 | bases = cls.__bases__ | |
38 | except AttributeError: |
|
38 | except AttributeError: | |
39 | # `obj` lied to hasattr (e.g. Pyro), ignore |
|
39 | # `obj` lied to hasattr (e.g. Pyro), ignore | |
40 | pass |
|
40 | pass | |
41 | else: |
|
41 | else: | |
42 | for base in bases: |
|
42 | for base in bases: | |
43 | ret.extend(get_class_members(base)) |
|
43 | ret.extend(get_class_members(base)) | |
44 | return ret |
|
44 | return ret | |
45 |
|
45 | |||
46 |
|
46 | |||
47 | def dir2(obj): |
|
47 | def dir2(obj): | |
48 | """dir2(obj) -> list of strings |
|
48 | """dir2(obj) -> list of strings | |
49 |
|
49 | |||
50 | Extended version of the Python builtin dir(), which does a few extra |
|
50 | Extended version of the Python builtin dir(), which does a few extra | |
51 |
checks, and |
|
51 | checks, and handles Traits objects, which can confuse dir(). | |
52 | dir(), such as Traits and PyCrust. |
|
|||
53 |
|
52 | |||
54 | This version is guaranteed to return only a list of true strings, whereas |
|
53 | This version is guaranteed to return only a list of true strings, whereas | |
55 | dir() returns anything that objects inject into themselves, even if they |
|
54 | dir() returns anything that objects inject into themselves, even if they | |
56 | are later not really valid for attribute access (many extension libraries |
|
55 | are later not really valid for attribute access (many extension libraries | |
57 | have such bugs). |
|
56 | have such bugs). | |
58 | """ |
|
57 | """ | |
59 |
|
58 | |||
60 | # Start building the attribute list via dir(), and then complete it |
|
59 | # Start building the attribute list via dir(), and then complete it | |
61 | # with a few extra special-purpose calls. |
|
60 | # with a few extra special-purpose calls. | |
62 |
|
61 | |||
63 | try: |
|
62 | try: | |
64 | words = set(dir(obj)) |
|
63 | words = set(dir(obj)) | |
65 | except Exception: |
|
64 | except Exception: | |
66 | # TypeError: dir(obj) does not return a list |
|
65 | # TypeError: dir(obj) does not return a list | |
67 | words = set() |
|
66 | words = set() | |
68 |
|
67 | |||
69 | if safe_hasattr(obj, '__class__'): |
|
68 | if safe_hasattr(obj, '__class__'): | |
70 | #words.add('__class__') |
|
69 | #words.add('__class__') | |
71 | words |= set(get_class_members(obj.__class__)) |
|
70 | words |= set(get_class_members(obj.__class__)) | |
72 |
|
71 | |||
73 |
|
72 | |||
74 | # for objects with Enthought's traits, add trait_names() list |
|
73 | # for objects with Enthought's traits, add trait_names() list | |
75 | # for PyCrust-style, add _getAttributeNames() magic method list |
|
74 | try: | |
76 | for attr in ('trait_names', '_getAttributeNames'): |
|
75 | func = getattr(obj, 'trait_names') | |
77 | try: |
|
76 | if callable(func): | |
78 | func = getattr(obj, attr) |
|
77 | words |= set(func()) | |
79 | if callable(func): |
|
78 | except: | |
80 | words |= set(func()) |
|
79 | # TypeError: obj is class not instance | |
81 |
|
|
80 | pass | |
82 | # TypeError: obj is class not instance |
|
|||
83 | pass |
|
|||
84 |
|
81 | |||
85 | # filter out non-string attributes which may be stuffed by dir() calls |
|
82 | # filter out non-string attributes which may be stuffed by dir() calls | |
86 | # and poor coding in third-party modules |
|
83 | # and poor coding in third-party modules | |
87 |
|
84 | |||
88 | words = [w for w in words if isinstance(w, string_types)] |
|
85 | words = [w for w in words if isinstance(w, string_types)] | |
89 | return sorted(words) |
|
86 | return sorted(words) |
General Comments 0
You need to be logged in to leave comments.
Login now