SF.net SVN: jython:[7242] trunk/jython/Lib

[email protected] Thu, 17 Mar 2011 22:18:37 +0000
Newsgroups gmane.comp.lang.jython.cvs
Message-ID <[email protected]>
Revision: 7242
          http://jython.svn.sourceforge.net/jython/?rev=7242&view=rev
Author:   pjenvey
Date:     2011-03-17 22:18:37 +0000 (Thu, 17 Mar 2011)

Log Message:
-----------
update inspect/test_inspect to 2.6
we now pass test_inspect's test_getargspec_method and all of its
test_excluding_predicates

Modified Paths:
--------------
    trunk/jython/Lib/inspect.py
    trunk/jython/Lib/test/test_inspect.py

Modified: trunk/jython/Lib/inspect.py
===================================================================
--- trunk/jython/Lib/inspect.py	2011-03-16 05:44:13 UTC (rev 7241)
+++ trunk/jython/Lib/inspect.py	2011-03-17 22:18:37 UTC (rev 7242)
@@ -7,8 +7,9 @@
 
 Here are some of the useful functions provided by this module:
 
-    ismodule(), isclass(), ismethod(), isfunction(), istraceback(),
-        isframe(), iscode(), isbuiltin(), isroutine() - check object types
+    ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
+        isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
+        isroutine() - check object types
     getmembers() - get members of an object that satisfy a given condition
 
     getfile(), getsourcefile(), getsource() - find an object's source code
@@ -28,12 +29,27 @@
 __author__ = 'Ka-Ping Yee <[email protected]>'
 __date__ = '1 Jan 2001'
 
-import sys, os, types, string, re, dis, imp, tokenize, linecache
+import sys
+import os
+import types
+import string
+import re
+import dis
+import imp
+import tokenize
+import linecache
 from operator import attrgetter
+from collections import namedtuple
 _jython = sys.platform.startswith('java')
 if _jython:
     _ReflectedFunctionType = type(os.listdir)
 
+# These constants are from Include/code.h.
+CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 0x1, 0x2, 0x4, 0x8
+CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40
+# See Include/object.h
+TPFLAGS_IS_ABSTRACT = 1 << 20
+
 # ----------------------------------------------------------- type-checking
 def ismodule(object):
     """Return true if the object is a module.
@@ -139,6 +155,32 @@
         func_name       (same as __name__)"""
     return isinstance(object, types.FunctionType)
 
+def isgeneratorfunction(object):
+    """Return true if the object is a user-defined generator function.
+
+    Generator function objects provides same attributes as functions.
+
+    See isfunction.__doc__ for attributes listing."""
+    return bool((isfunction(object) or ismethod(object)) and
+                object.func_code.co_flags & CO_GENERATOR)
+
+def isgenerator(object):
+    """Return true if the object is a generator.
+
+    Generator objects provide these attributes:
+        __iter__        defined to support interation over container
+        close           raises a new GeneratorExit exception inside the
+                        generator to terminate the iteration
+        gi_code         code object
+        gi_frame        frame object or possibly None once the generator has
+                        been exhausted
+        gi_running      set to 1 when generator is executing, 0 otherwise
+        next            return the next item from the container
+        send            resumes the generator and "sends" a value that becomes
+                        the result of the current yield-expression
+        throw           used to raise an exception inside the generator"""
+    return isinstance(object, types.GeneratorType)
+
 def istraceback(object):
     """Return true if the object is a traceback.
 
@@ -202,6 +244,10 @@
             or ismethoddescriptor(object)
             or (_jython and isinstance(object, _ReflectedFunctionType)))
 
+def isabstract(object):
+    """Return true if the object is an abstract base class (ABC)."""
+    return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT
+
 def getmembers(object, predicate=None):
     """Return all members of an object as (name, value) pairs sorted by name.
     Optionally, only return members that satisfy a given predicate."""
@@ -213,6 +259,8 @@
     results.sort()
     return results
 
+Attribute = namedtuple('Attribute', 'name kind defining_class object')
+
 def classify_class_attrs(cls):
     """Return list of attribute-descriptor tuples.
 
@@ -279,7 +327,7 @@
         else:
             kind = "data"
 
-        result.append((name, kind, homecls, obj))
+        result.append(Attribute(name, kind, homecls, obj))
 
     return result
 
@@ -374,15 +422,18 @@
     raise TypeError('arg is not a module, class, method, '
                     'function, traceback, frame, or code object')
 
+ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')
+
 def getmoduleinfo(path):
     """Get the module name, suffix, mode, and module type for a given file."""
     filename = os.path.basename(path)
-    suffixes = map(lambda (suffix, mode, mtype):
-                   (-len(suffix), suffix, mode, mtype), imp.get_suffixes())
+    suffixes = map(lambda info:
+                   (-len(info[0]), info[0], info[1], info[2]),
+                    imp.get_suffixes())
     suffixes.sort() # try longest suffixes first, in case they overlap
     for neglen, suffix, mode, mtype in suffixes:
         if filename[neglen:] == suffix:
-            return filename[:neglen], suffix, mode, mtype
+            return ModuleInfo(filename[:neglen], suffix, mode, mtype)
 
 def getmodulename(path):
     """Return the module name for a given file, or None."""
@@ -581,7 +632,9 @@
         self.passline = False
         self.last = 1
 
-    def tokeneater(self, type, token, (srow, scol), (erow, ecol), line):
+    def tokeneater(self, type, token, srow_scol, erow_ecol, line):
+        srow, scol = srow_scol
+        erow, ecol = erow_ecol
         if not self.started:
             # look for the first "def", "class" or "lambda"
             if token in ("def", "class", "lambda"):
@@ -679,8 +732,7 @@
     return walktree(roots, children, None)
 
 # ------------------------------------------------ argument list extraction
-# These constants are from Python's compile.h.
-CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
+Arguments = namedtuple('Arguments', 'args varargs keywords')
 
 def getargs(co):
     """Get information about the arguments accepted by a code object.
@@ -742,8 +794,10 @@
     varkw = None
     if co.co_flags & CO_VARKEYWORDS:
         varkw = co.co_varnames[nargs]
-    return args, varargs, varkw
+    return Arguments(args, varargs, varkw)
 
+ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
+
 def getargspec(func):
     """Get the names and default values of a function's arguments.
 
@@ -758,8 +812,10 @@
     if not isfunction(func):
         raise TypeError('arg is not a Python function')
     args, varargs, varkw = getargs(func.func_code)
-    return args, varargs, varkw, func.func_defaults
+    return ArgSpec(args, varargs, varkw, func.func_defaults)
 
+ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
+
 def getargvalues(frame):
     """Get information about arguments passed into a particular frame.
 
@@ -768,7 +824,7 @@
     'varargs' and 'varkw' are the names of the * and ** arguments or None.
     'locals' is the locals dictionary of the given frame."""
     args, varargs, varkw = getargs(frame.f_code)
-    return args, varargs, varkw, frame.f_locals
+    return ArgInfo(args, varargs, varkw, frame.f_locals)
 
 def joinseq(seq):
     if len(seq) == 1:
@@ -834,6 +890,9 @@
     return '(' + string.join(specs, ', ') + ')'
 
 # -------------------------------------------------- stack frame extraction
+
+Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
+
 def getframeinfo(frame, context=1):
     """Get information about a frame or traceback object.
 
@@ -865,7 +924,7 @@
     else:
         lines = index = None
 
-    return (filename, lineno, frame.f_code.co_name, lines, index)
+    return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
 
 def getlineno(frame):
     """Get the line number from a frame object, allowing for optimization."""
@@ -894,7 +953,10 @@
         tb = tb.tb_next
     return framelist
 
-currentframe = sys._getframe
+if hasattr(sys, '_getframe'):
+    currentframe = sys._getframe
+else:
+    currentframe = lambda _=None: None
 
 def stack(context=1):
     """Return a list of records for the stack above the caller's frame."""

Modified: trunk/jython/Lib/test/test_inspect.py
===================================================================
--- trunk/jython/Lib/test/test_inspect.py	2011-03-16 05:44:13 UTC (rev 7241)
+++ trunk/jython/Lib/test/test_inspect.py	2011-03-17 22:18:37 UTC (rev 7242)
@@ -4,19 +4,24 @@
 import inspect
 import datetime
 
-from test.test_support import TESTFN, run_unittest, is_jython
+from test.test_support import is_jython, run_unittest, _check_py3k_warnings
 
-from test import inspect_fodder as mod
-from test import inspect_fodder2 as mod2
-from test import test_support
+with _check_py3k_warnings(
+        ("tuple parameter unpacking has been removed", SyntaxWarning),
+        quiet=True):
+    from test import inspect_fodder as mod
+    from test import inspect_fodder2 as mod2
 
 # Functions tested in this suite:
 # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
-# isbuiltin, isroutine, getmembers, getdoc, getfile, getmodule,
-# getsourcefile, getcomments, getsource, getclasstree, getargspec,
-# getargvalues, formatargspec, formatargvalues, currentframe, stack, trace
-# isdatadescriptor
+# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
+# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
+# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
+# currentframe, stack, trace, isdatadescriptor
 
+# NOTE: There are some additional tests relating to interaction with
+#       zipimport in the test_zipimport_support test module.
+
 modfile = mod.__file__
 if modfile.endswith(('c', 'o')):
     modfile = modfile[:-1]
@@ -26,7 +31,7 @@
 import __builtin__
 
 try:
-    1/0
+    1 // 0
 except:
     tb = sys.exc_traceback
 
@@ -44,27 +49,37 @@
 class IsTestBase(unittest.TestCase):
     predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
                       inspect.isframe, inspect.isfunction, inspect.ismethod,
-                      inspect.ismodule, inspect.istraceback])
+                      inspect.ismodule, inspect.istraceback,
+                      inspect.isgenerator, inspect.isgeneratorfunction])
 
     def istest(self, predicate, exp):
         obj = eval(exp)
         self.failUnless(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
 
         for other in self.predicates - set([predicate]):
+            if predicate == inspect.isgeneratorfunction and\
+               other == inspect.isfunction:
+                continue
             self.failIf(other(obj), 'not %s(%s)' % (other.__name__, exp))
 
+def generator_function_example(self):
+    for i in xrange(2):
+        yield i
+
 class TestPredicates(IsTestBase):
-    def test_thirteen(self):
+    def test_sixteen(self):
         count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
-        # Doc/lib/libinspect.tex claims there are 13 such functions
-        expected = 13
+        # This test is here for remember you to update Doc/library/inspect.rst
+        # which claims there are 16 such functions
+        expected = 16
         err_msg = "There are %d (not %d) is* functions" % (count, expected)
         self.assertEqual(count, expected, err_msg)
 
+
     def test_excluding_predicates(self):
-        #XXX: Jython's PySystemState needs more work before this
-        #will be doable.
-        if not test_support.is_jython:
+        # XXX: Jython's PySystemState needs more work before this will
+        # be doable.
+        if not is_jython:
             self.istest(inspect.isbuiltin, 'sys.exit')
         self.istest(inspect.isbuiltin, '[].append')
         self.istest(inspect.isclass, 'mod.StupidGit')
@@ -77,11 +92,12 @@
         self.istest(inspect.istraceback, 'tb')
         self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
         self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
+        self.istest(inspect.isgenerator, '(x for x in xrange(2))')
+        self.istest(inspect.isgeneratorfunction, 'generator_function_example')
         if hasattr(types, 'GetSetDescriptorType'):
             self.istest(inspect.isgetsetdescriptor,
                         'type(tb.tb_frame).f_locals')
-        #XXX: This detail of PyFrames is not yet supported in Jython
-        elif not test_support.is_jython:
+        else:
             self.failIf(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
         if hasattr(types, 'MemberDescriptorType'):
             self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
@@ -120,7 +136,7 @@
         self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
                                          ['    eggs(b + d, c + f)\n'], 0))
         self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
-                                         ['    q = y / 0\n'], 0))
+                                         ['    q = y // 0\n'], 0))
 
     def test_frame(self):
         args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
@@ -194,6 +210,10 @@
         self.assertEqual(inspect.getdoc(git.abuse),
                          'Another\n\ndocstring\n\ncontaining\n\ntabs')
 
+    def test_cleandoc(self):
+        self.assertEqual(inspect.cleandoc('An\n    indented\n    docstring.'),
+                         'An\nindented\ndocstring.')
+
     def test_getcomments(self):
         self.assertEqual(inspect.getcomments(mod), '# line 1\n')
         self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
@@ -224,9 +244,9 @@
         self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
 
     def test_getmodule_recursion(self):
-        from new import module
+        from types import ModuleType
         name = '__inspect_dummy'
-        m = sys.modules[name] = module(name)
+        m = sys.modules[name] = ModuleType(name)
         m.__file__ = "<string>" # hopefully not a real filename...
         m.__loader__ = "dummy"  # pretend the filename is understood by a loader
         exec "def x(): pass" in m.__dict__
@@ -357,7 +377,6 @@
                                  'g', 'h', (3, (4, (5,))),
                                  '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
 
-    @na_for_jython
     def test_getargspec_method(self):
         class A(object):
             def m(self):
@@ -366,11 +385,14 @@
 
     @na_for_jython
     def test_getargspec_sublistofone(self):
-        def sublistOfOne((foo,)): return 1
-        self.assertArgSpecEquals(sublistOfOne, [['foo']])
+        with _check_py3k_warnings(
+                ("tuple parameter unpacking has been removed", SyntaxWarning),
+                ("parenthesized argument names are invalid", SyntaxWarning)):
+            exec 'def sublistOfOne((foo,)): return 1'
+            self.assertArgSpecEquals(sublistOfOne, [['foo']])
 
-        def fakeSublistOfOne((foo)): return 1
-        self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
+            exec 'def fakeSublistOfOne((foo)): return 1'
+            self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
 
     def test_classify_oldstyle(self):
         class A:


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d