Tim Peters [Sun, 23 Sep 2001 21:29:55 +0000 (21:29 +0000)]
Part of a partial solution to SF bugs 463378, 463381, 463383, 463384.
This almost entirely replaces how pydoc pumps out class docs, but only
in text mode (like help(whatever) from a Python shell), not in GUI mode.
A class C's attrs are now grouped by the class in which they're defined,
attrs defined by C first, then inherited attrs grouped by alphabetic order
of the defining classes' names.
Within each of those groups, the attrs are subgrouped according to whether
they're plain methods, class methods, static methods, properties, or data.
Note that pydoc never dumped class data attrs before. If a class data
attr is implemented via a data descriptor, the data docstring (if any)
is also displayed (e.g., file.softspace).
Within a subgroup, the attrs are listed alphabetically.
This is a friggin' mess, and there are bound to be glitches. Please
beat on it and complain! Here are three glitches:
1. __new__ gets classifed as 'data', for some reason. This will
have to get fixed in inspect.py, but since the latter is already
looking for any clue that something is a method, pydoc will
almost certainly not know what to do with it when its classification
changes.
2. properties are special-cased to death. Unlike any other kind of
function or method, they don't have a __name__ attr, so none of
pydoc's usual code can deal with them. Worse, the getter and
setter and del'er methods associated with a property don't appear
to be discoverable from Python, so there's really nothing I can
think of to do here beyond just listing their names.
Note that a property can't be given a docstring, either (or at least
I've been unable to sneak one in) -- perhaps the property()
constructor could take an optional doc argument?
3. In a nested-scopes world, pydoc still doesn't know anything about
nesting, so e.g. classes nested in functions are effectively invisible.
Barry Warsaw [Sun, 23 Sep 2001 03:17:28 +0000 (03:17 +0000)]
The email package version 1.0, prototyped as mimelib
<http://sf.net/projects/mimelib>. There /are/ API differences between
mimelib and email, but most of the implementations are shared (except
where cool Py2.2 stuff like generators are used).
Tim Peters [Sun, 23 Sep 2001 02:00:29 +0000 (02:00 +0000)]
New function classify_class_attrs(). As a number of SF bug reports
point out, pydoc doesn't tell you where class attributes were defined,
gets several new 2.2 features wrong, and isn't aware of some new features
checked in on Thursday <wink>. pydoc is hampered in part because
inspect.py has the same limitations. Alas, I can't think of a way to
fix this within the current architecture of inspect/pydoc: it's simply
not possible in 2.2 to figure out everything needed just from examining
the object you get back from class.attr. You also need the class
context, and the method resolution order, and tests against various things
that simply didn't exist before. OTOH, knowledge of how to do that is
getting quite complex, so doesn't belong in pydoc.
classify_class_attrs takes a different approach, analyzing all
the class attrs "at once", and returning the most interesting stuff for
each, all in one gulp. pydoc needs to be reworked to use this for
classes (instead of the current "filter dir(class) umpteen times against
assorted predicates" approach).
Tim Peters [Sat, 22 Sep 2001 21:30:22 +0000 (21:30 +0000)]
Make difflib.ndiff() and difflib.Differ.compare() generators. This
restores the 2.1 ability of Tools/scripts/ndiff.py to start producing
output before the entire comparison is complete.
Tim Peters [Sat, 22 Sep 2001 06:10:55 +0000 (06:10 +0000)]
Add a function to compute a class's method resolution order. This is
easy for 2.2 new-style classes, but trickier for classic classes, and
different approaches are needed "depending". The function will allow
later code to treat all flavors of classes uniformly.
Tim Peters [Sat, 22 Sep 2001 05:31:03 +0000 (05:31 +0000)]
Since the most likely failure mode for an expected-output test is a change
somewhere inside a line, use ndiff so that intraline difference marking
can point out what changed within a line. I don't remember diff-style
abbreviations either (haven't used it since '94, except to produce
patches), so say the rest in English too.
Add the __getattr__ hook back. The rules are now:
- if __getattribute__ exists, it is called first;
if it doesn't exists, PyObject_GenericGetAttr is called first.
- if the above raises AttributeError, and __getattr__ exists,
it is called.
Oops. I didn't expect that some tests (test_cookie) have expected
output *and* doctest stuff. Assuming the doctest stuff comes after the
expected output, this fixes that.
Change the way unexpected output is reported: rather than stopping at
the first difference, let the test run till completion, then gather
all the output and compare it to the expected output using difflib.
XXX Still to do: produce diff output that only shows the sections that
differ; currently it produces ndiff-style output because that's the
easiest to produce with difflib, but this becomes a liability when the
output is voluminous and there are only a few differences.
Change the name of the __getattr__ special method for new-style
classes to __getattribute__, to make it crystal-clear that it doesn't
have the same semantics as overriding __getattr__ on classic classes.
This is a halfway checkin -- I'll proceed to add a __getattr__ hook
that works the way it works in classic classes.
Add optional docstrings to getset descriptors. Fortunately, there's
no backwards compatibility to worry about, so I just pushed the
'closure' struct member to the back -- it's never used in the current
code base (I may eliminate it, but that's more work because the getter
and setter signatures would have to change.)
As examples, I added actual docstrings to the getset attributes of a
few types: file.closed, xxsubtype.spamdict.state.
Fred Drake [Thu, 20 Sep 2001 21:33:42 +0000 (21:33 +0000)]
Change the PyUnit-based tests to use the test_main() approach. This
allows using the tests with unittest.py as a script. The tests will
still run when run as a script themselves.
Add optional docstrings to member descriptors. For backwards
compatibility, this required all places where an array of "struct
memberlist" structures was declared that is referenced from a type's
tp_members slot to change the type of the structure to PyMemberDef;
"struct memberlist" is now only used by old code that still calls
PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now
calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef
argument.
As examples, I added actual docstrings to the attributes of a few
types: file, complex, instance method, super, and xxsubtype.spamlist.
Tim Peters [Thu, 20 Sep 2001 19:55:29 +0000 (19:55 +0000)]
Document new file() constructor, with the body of open()'s text, plus a
"new in 2.2" blurb at the end. Replace open()'s text by pointing back
to file().
Fix Unicode .join() method to raise a TypeError for sequence
elements which are not Unicode objects or strings. (This matches
the string.join() behaviour.)
Fix a memory leak in the .join() method which occurs in case
the Unicode resize fails.
Implement the changes proposed in patch #413333. unicode(obj) now
works just like str(obj) in that it tries __str__/tp_str on the object
in case it finds that the object is not a string or buffer.
Patch #462635 by Andrew Kuchling correcting bugs in the new
codecs -- the self argument does matter for Python functions (it
does not for C functions which most other codecs use).
Barry Warsaw [Thu, 20 Sep 2001 06:30:41 +0000 (06:30 +0000)]
run_suite(): Factor this out of run_unittest() for tests that build
their own test suite from a multitude of classes (like test_email.py
will be doing).
run_unittest(): Call run_suite() after making a suite from the
testclass.
Tim Peters [Thu, 20 Sep 2001 06:08:24 +0000 (06:08 +0000)]
Since inspect.isfunction(obj) is a precondition for calling
inspect.getargspec(obj), test isfunction() directly in pydoc.py instead
of trying to indirectly deduce isfunction() in pydoc by virtue of
failing a combination of other tests. This shouldn't have any visible
effect, except perhaps to squash a TypeError death if there was some path
thru this code that was inferring isfunction() by mistake.
Tim Peters [Thu, 20 Sep 2001 05:47:55 +0000 (05:47 +0000)]
Ensure that isfunction(obj) and (the new) ismethoddescriptor(obj) never
both return true. This restores pydoc's ability to deduce argument lists
for functions and methods coded in Python.
Tim Peters [Thu, 20 Sep 2001 05:13:38 +0000 (05:13 +0000)]
After much thrashing, I believe this is a truly minimal patch to teach
pydoc how to do something sensible with 2.2 descriptors. To see the
difference, browse __builtin__ via pydoc before and after the patch.
Fixed search function error reporting in the encodings package
__init__.py module to raise errors which can be catched as LookupErrors
as well as SystemErrors.
Modified the error messages to include more information about the
failing module.
Enable two checks for comparing a complex to a complex subtype
instance.
Split a string comparison test in two halves, replacing "a==b==a" with
separate tests for a==b and b==a. (Reason: while experimenting, this
test failed, and I wanted to know if it was the first or the second ==
operator that failed.)
complex_coerce(): add explicit PyComplex_Check() test. Previously,
complex_coerce() would never be called with a complex argument,
because PyNumber_Coerce[Ex] doesn't bother calling the type's coercion
method if the values already have the same type. But now, of course,
it's possible to pass an instance of a complex *subtype*, and those
must be accepted.
Hopefully fix 3-way comparisons. This unfortunately adds yet another
hack, and it's even more disgusting than a PyInstance_Check() call.
If the tp_compare slot is the slot used for overrides in Python,
it's always called.
wrap_cmpfunc(): added a safety check for the __cmp__ wrapper. We can
only safely call a type's tp_compare slot if the second argument is
also an instance of the same type. I hate to think what
e.g. int_compare() would do with a second argument that's a float!
Tim Peters [Tue, 18 Sep 2001 05:40:24 +0000 (05:40 +0000)]
This module didn't work at all anymore -- blew up with AttributeError
on file.__methods__. Since the docs say "This module will become obsolete
in a future release", this is just a quick hack to stop it from blowing
up. If you care about this module, test it! It doesn't make much sense
on Windows.
Redo the PyMethod attributes using a dir()-friendly approach, creating
descriptors for each attribute. The getattr() implementation is
similar to PyObject_GenericGetAttr(), but delegates to im_self instead
of looking in __dict__; I couldn't do this as a wrapper around
PyObject_GenericGetAttr().
XXX A problem here is that this is a case of *delegation*. dir()
doesn't see exactly the same attributes that are actually defined;
e.g. if the delegate is a Python function object, it supports
attributes like func_code etc., but these are not visible to dir(); on
the other hand, dynamic function attributes (stored in the function's
__dict__) *are* visible to dir(). Maybe we need a mechanism to tell
dir() about the delegation mechanism? I vaguely recall seeing a
request in the newsgroup for a more formal definition of attribute
delegation too. Sigh, time for a new PEP.
- Some tests that check that assignments are not allowed expect this
to raise TypeError. In practice, a disallowed attribute assignment
can raise either TypeError or AttributeError (and it's unclear which
is better). So allow either. (Yes, this is in anticipation of a
code change that switches the exception raised. :-)
- Add a utility function, cantset(), which verifies that setting a
particular attribute to a given value is disallowed, and also that
deleting that same attribute is disallowed. Use this in the
test_func_*() tests.
- Add a new set of tests that test conformance of various instance
method attributes. (Also in anticipation of code that changes their
implementation.)
Sort the headers in PYTHON_HEADERS alphabetically. Add
structmember.h, which was missing (and caused me a snide comment by
Tim when he fixed something I missed because of the missed dependency
:-).
Tim Peters [Mon, 17 Sep 2001 23:56:20 +0000 (23:56 +0000)]
Rework akin to test_threaded_import, so that this can run under regrtest.
Also raise TestSkipped (intead of appearing to fail) if the import lock
is held.