diff options
Diffstat (limited to 'Lib')
| -rwxr-xr-x | Lib/pydoc.py | 19 | ||||
| -rw-r--r-- | Lib/test/test_pydoc.py | 16 | 
2 files changed, 31 insertions, 4 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py index ee558bfea3..f4f253010f 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -209,6 +209,18 @@ def classify_class_attrs(object):          results.append((name, kind, cls, value))      return results +def sort_attributes(attrs, object): +    'Sort the attrs list in-place by _fields and then alphabetically by name' +    # This allows data descriptors to be ordered according +    # to a _fields attribute if present. +    fields = getattr(object, '_fields', []) +    try: +        field_order = {name : i-len(fields) for (i, name) in enumerate(fields)} +    except TypeError: +        field_order = {} +    keyfunc = lambda attr: (field_order.get(attr[0], 0), attr[0]) +    attrs.sort(key=keyfunc) +  # ----------------------------------------------------- module manipulation  def ispackage(path): @@ -867,8 +879,7 @@ class HTMLDoc(Doc):                                                             object.__module__)              tag += ':<br>\n' -            # Sort attrs by name. -            attrs.sort(key=lambda t: t[0]) +            sort_attributes(attrs, object)              # Pump out the attrs, segregated by kind.              attrs = spill('Methods %s' % tag, attrs, @@ -1286,8 +1297,8 @@ location listed above.              else:                  tag = "inherited from %s" % classname(thisclass,                                                        object.__module__) -            # Sort attrs by name. -            attrs.sort() + +            sort_attributes(attrs, object)              # Pump out the attrs, segregated by kind.              attrs = spill("Methods %s:\n" % tag, attrs, diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index ec5c31ba72..0533a03fa7 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -811,6 +811,22 @@ class TestDescriptions(unittest.TestCase):          self.assertEqual(self._get_summary_line(t.wrap),              "wrap(text) method of textwrap.TextWrapper instance") +    def test_field_order_for_named_tuples(self): +        Person = namedtuple('Person', ['nickname', 'firstname', 'agegroup']) +        s = pydoc.render_doc(Person) +        self.assertLess(s.index('nickname'), s.index('firstname')) +        self.assertLess(s.index('firstname'), s.index('agegroup')) + +        class NonIterableFields: +            _fields = None + +        class NonHashableFields: +            _fields = [[]] + +        # Make sure these doesn't fail +        pydoc.render_doc(NonIterableFields) +        pydoc.render_doc(NonHashableFields) +      @requires_docstrings      def test_bound_builtin_method(self):          s = StringIO()  | 
