]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Another batch of updates...
authorGuido van Rossum <guido@python.org>
Mon, 26 Aug 1996 18:33:32 +0000 (18:33 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 26 Aug 1996 18:33:32 +0000 (18:33 +0000)
20 files changed:
Lib/dos-8x3/ast.py
Lib/dos-8x3/bastion.py
Lib/dos-8x3/compilea.py
Lib/dos-8x3/formatte.py
Lib/dos-8x3/mimetool.py
Lib/dos-8x3/mimewrit.py [new file with mode: 0644]
Lib/dos-8x3/posixfil.py
Lib/dos-8x3/posixpat.py
Lib/dos-8x3/test_mat.py [new file with mode: 0644]
Lib/dos-8x3/tracebac.py
Lib/dos_8x3/ast.py
Lib/dos_8x3/bastion.py
Lib/dos_8x3/compilea.py
Lib/dos_8x3/formatte.py
Lib/dos_8x3/mimetool.py
Lib/dos_8x3/mimewrit.py [new file with mode: 0644]
Lib/dos_8x3/posixfil.py
Lib/dos_8x3/posixpat.py
Lib/dos_8x3/test_mat.py [new file with mode: 0644]
Lib/dos_8x3/tracebac.py

index 6f92beeaa180886c60f12bb239492b2f068b2246..370cfe4f46c0a1322b9c9f4be12873dcba04b4d7 100755 (executable)
@@ -1,13 +1,13 @@
 """Object-oriented interface to the parser module.
 
-This module exports three classes which together provide an interface
+This module exports four classes which together provide an interface
 to the parser module.  Together, the three classes represent two ways
 to create parsed representations of Python source and the two starting
 data types (source text and tuple representations).  Each class
 provides interfaces which are identical other than the constructors.
 The constructors are described in detail in the documentation for each
 class and the remaining, shared portion of the interface is documented
-below.  Briefly, the three classes provided are:
+below.  Briefly, the classes provided are:
 
 AST
     Defines the primary interface to the AST objects and supports creation
@@ -23,6 +23,9 @@ FileSuiteAST
     Convenience subclass of the `SuiteAST' class; loads source text of the
     suite from an external file.
 
+Common Methods
+--------------
+
 Aside from the constructors, several methods are provided to allow
 access to the various interpretations of the parse tree and to check
 conditions of the construct represented by the parse tree.
@@ -68,8 +71,8 @@ class AST:
     This base class provides all of the query methods for subclass
     objects defined in this module.
     """
-    _p = __import__('parser')          # import internally to avoid
-                                       # namespace pollution at the
+    import parser                      # import internally to avoid
+    _p = parser                                # namespace pollution at the
                                        # top level
     _text = None
     _code = None
@@ -84,7 +87,8 @@ class AST:
            The tuple tree to convert.
 
        The tuple-tree may represent either an expression or a suite; the
-       type will be determined automatically.
+       type will be determined automatically.  Line number information may
+       optionally be present for any subset of the terminal tokens.
        """
        if type(tuple) is not type(()):
            raise TypeError, 'Base AST class requires tuple parameter.'
@@ -93,11 +97,24 @@ class AST:
        self._ast  = self._p.tuple2ast(tuple)
        self._type = (self._p.isexpr(self._ast) and 'expression') or 'suite'
 
-    def tuple(self):
+    def list(self, line_info = 0):
+       """Returns a fresh list representing the parse tree.
+
+       line_info
+           If true, includes line number information for terminal tokens in
+           the output data structure,
+       """
+       return self._p.ast2list(self._ast, line_info)
+
+    def tuple(self, line_info = 0):
        """Returns the tuple representing the parse tree.
+
+       line_info
+           If true, includes line number information for terminal tokens in
+           the output data structure,
        """
        if self._tupl is None:
-           self._tupl = self._p.ast2tuple(self._ast)
+           self._tupl = self._p.ast2tuple(self._ast, line_info)
        return self._tupl
 
     def code(self):
index 7ddd93e3ccbaeeaa9d67b89ddad8097a9c22980e..cb54be9159578d6dcda65592eee732108a7bbe03 100755 (executable)
@@ -141,6 +141,7 @@ def _test():
            return self.sum
     o = Original()
     b = Bastion(o)
+    testcode = """if 1:
     b.add(81)
     b.add(18)
     print "b.total() =", b.total()
@@ -156,6 +157,20 @@ def _test():
        print "inaccessible"
     else:
        print "accessible"
+    try:
+       print "b._get_.func_defaults =", b._get_.func_defaults,
+    except:
+       print "inaccessible"
+    else:
+       print "accessible"
+    \n"""
+    exec testcode
+    print '='*20, "Using rexec:", '='*20
+    import rexec
+    r = rexec.RExec()
+    m = r.add_module('__main__')
+    m.b = b
+    r.r_exec(testcode)
 
 
 if __name__ == '__main__':
index 312028407dd5b97ad26defdb7b36cdd0c84f5a84..9947569eb3d6aa9cfe0efa6cde075eb526a2e88f 100755 (executable)
@@ -43,7 +43,7 @@ def compile_dir(dir, maxlevels = 10):
 
 def compile_path(skip_curdir = 1):
        for dir in sys.path:
-               if dir == os.curdir and skip_curdir:
+               if (not dir or dir == os.curdir) and skip_curdir:
                        print 'Skipping current directory'
                else:
                        compile_dir(dir, 0)
index 026637940e5ad65761596d3313a409970b5c67dc..c192e20ddb567525a77fe1af219237fb33e628ee 100755 (executable)
@@ -10,7 +10,7 @@ AS_IS = None
 
 class NullFormatter:
 
-    def __init__(self): pass
+    def __init__(self, writer): pass
     def end_paragraph(self, blankline): pass
     def add_line_break(self): pass
     def add_hor_rule(self, abswidth=None, percentwidth=1.0,
@@ -33,6 +33,11 @@ class NullFormatter:
 
 class AbstractFormatter:
 
+    #  Space handling policy:  blank spaces at the boundary between elements
+    #  are handled by the outermost context.  "Literal" data is not checked
+    #  to determine context, so spaces in literal data are handled directly
+    #  in all circumstances.
+
     def __init__(self, writer):
        self.writer = writer            # Output device
        self.align = None               # Current alignment
@@ -162,7 +167,8 @@ class AbstractFormatter:
 
     def add_literal_data(self, data):
        if not data: return
-       #  Caller is expected to cause flush_softspace() if needed.
+       if self.softspace:
+           self.writer.send_flowing_data(" ")
        self.hard_break = data[-1:] == '\n'
        self.nospace = self.para_end = self.softspace = \
                       self.parskip = self.have_label = 0
@@ -170,8 +176,9 @@ class AbstractFormatter:
 
     def flush_softspace(self):
        if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.parskip = \
+           self.hard_break = self.para_end = self.parskip = \
                              self.have_label = self.softspace = 0
+           self.nospace = 1
            self.writer.send_flowing_data(' ')
 
     def push_alignment(self, align):
@@ -194,7 +201,8 @@ class AbstractFormatter:
 
     def push_font(self, (size, i, b, tt)):
        if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
+           self.hard_break = self.para_end = self.softspace = 0
+           self.nospace = 1
            self.writer.send_flowing_data(' ')
        if self.font_stack:
            csize, ci, cb, ctt = self.font_stack[-1]
@@ -207,9 +215,6 @@ class AbstractFormatter:
        self.writer.new_font(font)
 
     def pop_font(self):
-       if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
-           self.writer.send_flowing_data(' ')
        if self.font_stack:
            del self.font_stack[-1]
        if self.font_stack:
@@ -241,22 +246,20 @@ class AbstractFormatter:
 
     def push_style(self, *styles):
        if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
+           self.hard_break = self.para_end = self.softspace = 0
+           self.nospace = 1
            self.writer.send_flowing_data(' ')
        for style in styles:
            self.style_stack.append(style)
        self.writer.new_styles(tuple(self.style_stack))
 
     def pop_style(self, n=1):
-       if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
-           self.writer.send_flowing_data(' ')
        del self.style_stack[-n:]
        self.writer.new_styles(tuple(self.style_stack))
 
     def assert_line_data(self, flag=1):
        self.nospace = self.hard_break = not flag
-       self.para_end = self.have_label = 0
+       self.para_end = self.parskip = self.have_label = 0
 
 
 class NullWriter:
index da33a7777b9713f76fc48fb95cdddb8cc21b1979..baf9379f537a52eba04713ee6aaea76f84b738ed 100755 (executable)
@@ -106,8 +106,14 @@ def choose_boundary():
                import socket
                import os
                hostid = socket.gethostbyname(socket.gethostname())
-               uid = `os.getuid()`
-               pid = `os.getpid()`
+               try:
+                   uid = `os.getuid()`
+               except:
+                   uid = '1'
+               try:
+                   pid = `os.getpid()`
+               except:
+                   pid = '1'
                seed = `rand.rand()`
                _prefix = hostid + '.' + uid + '.' + pid
        timestamp = `int(time.time())`
diff --git a/Lib/dos-8x3/mimewrit.py b/Lib/dos-8x3/mimewrit.py
new file mode 100644 (file)
index 0000000..6fbcb65
--- /dev/null
@@ -0,0 +1,131 @@
+"""Generic MIME writer.
+
+Classes:
+
+MimeWriter - the only thing here.
+
+"""
+
+__version__ = '$Revision$'
+# $Source$
+
+
+import string
+import mimetools
+
+
+class MimeWriter:
+
+    """Generic MIME writer.
+
+    Methods:
+
+    __init__()
+    addheader()
+    flushheaders()
+    startbody()
+    startmultipartbody()
+    nextpart()
+    lastpart()
+
+    A MIME writer is much more primitive than a MIME parser.  It
+    doesn't seek around on the output file, and it doesn't use large
+    amounts of buffer space, so you have to write the parts in the
+    order they should occur on the output file.  It does buffer the
+    headers you add, allowing you to rearrange their order.
+    
+    General usage is:
+
+    f = <open the output file>
+    w = MimeWriter(f)
+    ...call w.addheader(key, value) 0 or more times...
+
+    followed by either:
+
+    f = w.startbody(content_type)
+    ...call f.write(data) for body data...
+
+    or:
+
+    w.startmultipartbody(subtype)
+    for each part:
+        subwriter = w.nextpart()
+       ...use the subwriter's methods to create the subpart...
+    w.lastpart()
+
+    The subwriter is another MimeWriter instance, and should be
+    treated in the same way as the toplevel MimeWriter.  This way,
+    writing recursive body parts is easy.
+
+    Warning: don't forget to call lastpart()!
+
+    XXX There should be more state so calls made in the wrong order
+    are detected.
+
+    Some special cases:
+
+    - startbody() just returns the file passed to the constructor;
+      but don't use this knowledge, as it may be changed.
+
+    - startmultipartbody() actually returns a file as well;
+      this can be used to write the initial 'if you can read this your
+      mailer is not MIME-aware' message.
+
+    - If you call flushheaders(), the headers accumulated so far are
+      written out (and forgotten); this is useful if you don't need a
+      body part at all, e.g. for a subpart of type message/rfc822
+      that's (mis)used to store some header-like information.
+
+    - Passing a keyword argument 'prefix=<flag>' to addheader(),
+      start*body() affects where the header is inserted; 0 means
+      append at the end, 1 means insert at the start; default is
+      append for addheader(), but insert for start*body(), which use
+      it to determine where the Content-Type header goes.
+
+    """
+
+    def __init__(self, fp):
+       self._fp = fp
+       self._headers = []
+
+    def addheader(self, key, value, prefix=0):
+       lines = string.splitfields(value, "\n")
+       while lines and not lines[-1]: del lines[-1]
+       while lines and not lines[0]: del lines[0]
+       for i in range(1, len(lines)):
+           lines[i] = "    " + string.strip(lines[i])
+       value = string.joinfields(lines, "\n") + "\n"
+       line = key + ": " + value
+       if prefix:
+           self._headers.insert(0, line)
+       else:
+           self._headers.append(line)
+
+    def flushheaders(self):
+       self._fp.writelines(self._headers)
+       self._headers = []
+
+    def startbody(self, ctype, plist=[], prefix=1):
+       for name, value in plist:
+           ctype = ctype + ';\n %s=\"%s\"' % (name, value)
+       self.addheader("Content-Type", ctype, prefix=prefix)
+       self.flushheaders()
+       self._fp.write("\n")
+       return self._fp
+
+    def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
+       self._boundary = boundary or mimetools.choose_boundary()
+       return self.startbody("multipart/" + subtype,
+                             [("boundary", self._boundary)] + plist,
+                             prefix=prefix)
+
+    def nextpart(self):
+       self._fp.write("\n--" + self._boundary + "\n")
+       return self.__class__(self._fp)
+
+    def lastpart(self):
+       self._fp.write("\n--" + self._boundary + "--\n")
+
+
+if __name__ == '__main__':
+    print "To test the MimeWriter module, run TestMimeWriter.py."
index 64cda986223f373a1cc10d43c712e67dd1ef55ec..f0df5433aa0c1c2be180fc35755df60b631c46e8 100755 (executable)
@@ -174,11 +174,15 @@ class _posixfile_:
        elif len(args) > 3:
            raise TypeError, 'too many arguments'
 
-       # Hack by davem@magnet.com to get locking to go on freebsd
+       # Hack by davem@magnet.com to get locking to go on freebsd;
+       # additions for AIX by Vladimir.Marangozov@imag.fr
         import sys, os
         if sys.platform == 'freebsd2':
            flock = struct.pack('lxxxxlxxxxlhh', \
                  l_start, l_len, os.getpid(), l_type, l_whence) 
+        elif sys.platform in ['aix3', 'aix4']:
+            flock = struct.pack('hhlllii', \
+                  l_type, l_whence, l_start, l_len, 0, 0, 0)
        else:
            flock = struct.pack('hhllhh', \
                  l_type, l_whence, l_start, l_len, 0, 0)
@@ -189,6 +193,9 @@ class _posixfile_:
            if sys.platform == 'freebsd2':
                l_start, l_len, l_pid, l_type, l_whence = \
                    struct.unpack('lxxxxlxxxxlhh', flock)
+            elif sys.platform in ['aix3', 'aix4']:
+                l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
+                    struct.unpack('hhlllii', flock)
            else:
                l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
                    struct.unpack('hhllhh', flock)
index 4590f8dc31e42b903b09cac50810b234a40dca28..014dfe2798390f5e1058e3d561906c38a3c88863 100755 (executable)
@@ -53,7 +53,7 @@ def split(p):
 
 
 # Split a path in root and extension.
-# The extension is everything starting at the first dot in the last
+# The extension is everything starting at the last dot in the last
 # pathname component; the root is everything before that.
 # It is always true that root + ext == p.
 
diff --git a/Lib/dos-8x3/test_mat.py b/Lib/dos-8x3/test_mat.py
new file mode 100644 (file)
index 0000000..af84d2a
--- /dev/null
@@ -0,0 +1,153 @@
+# Python test set -- math module
+# XXXX Should not do tests around zero only
+
+from test_support import *
+
+eps=1e-5
+print 'math module, testing with eps', eps
+import math
+
+def testit(name, value, expected):
+       if abs(value-expected) > eps:
+               raise TestFailed, '%s returned %f, expected %f'%\
+                     (name, value, expected)
+
+print 'constants'
+testit('pi', math.pi, 3.1415926)
+testit('e', math.e, 2.7182818)
+
+print 'acos'
+testit('acos(-1)', math.acos(-1), math.pi)
+testit('acos(0)', math.acos(0), math.pi/2)
+testit('acos(1)', math.acos(1), 0)
+
+print 'asin'
+testit('asin(-1)', math.asin(-1), -math.pi/2)
+testit('asin(0)', math.asin(0), 0)
+testit('asin(1)', math.asin(1), math.pi/2)
+
+print 'atan'
+testit('atan(-1)', math.atan(-1), -math.pi/4)
+testit('atan(0)', math.atan(0), 0)
+testit('atan(1)', math.atan(1), math.pi/4)
+
+print 'atan2'
+testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
+testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
+testit('atan2(0, 1)', math.atan2(0, 1), 0)
+testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
+testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
+
+print 'ceil'
+testit('ceil(0.5)', math.ceil(0.5), 1)
+testit('ceil(1.0)', math.ceil(1.0), 1)
+testit('ceil(1.5)', math.ceil(1.5), 2)
+testit('ceil(-0.5)', math.ceil(-0.5), 0)
+testit('ceil(-1.0)', math.ceil(-1.0), -1)
+testit('ceil(-1.5)', math.ceil(-1.5), -1)
+
+print 'cos'
+testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
+testit('cos(0)', math.cos(0), 1)
+testit('cos(pi/2)', math.cos(math.pi/2), 0)
+testit('cos(pi)', math.cos(math.pi), -1)
+
+print 'cosh'
+testit('cosh(0)', math.cosh(0), 1)
+testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
+
+print 'exp'
+testit('exp(-1)', math.exp(-1), 1/math.e)
+testit('exp(0)', math.exp(0), 1)
+testit('exp(1)', math.exp(1), math.e)
+
+print 'fabs'
+testit('fabs(-1)', math.fabs(-1), 1)
+testit('fabs(0)', math.fabs(0), 0)
+testit('fabs(1)', math.fabs(1), 1)
+
+print 'floor'
+testit('floor(0.5)', math.floor(0.5), 0)
+testit('floor(1.0)', math.floor(1.0), 1)
+testit('floor(1.5)', math.floor(1.5), 1)
+testit('floor(-0.5)', math.floor(-0.5), -1)
+testit('floor(-1.0)', math.floor(-1.0), -1)
+testit('floor(-1.5)', math.floor(-1.5), -2)
+
+print 'fmod'
+testit('fmod(10,1)', math.fmod(10,1), 0)
+testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
+testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
+testit('fmod(-10,1)', math.fmod(-10,1), 0)
+testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
+testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
+
+print 'frexp'
+def testfrexp(name, (mant, exp), (emant, eexp)):
+       if abs(mant-emant) > eps or exp <> eexp:
+               raise TestFailed, '%s returned %s, expected %s'%\
+                     (name, `mant, exp`, `emant,eexp`)
+
+testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
+testfrexp('frexp(0)', math.frexp(0), (0, 0))
+testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
+testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
+
+print 'hypot'
+testit('hypot(0,0)', math.hypot(0,0), 0)
+testit('hypot(3,4)', math.hypot(3,4), 5)
+
+print 'ldexp'
+testit('ldexp(0,1)', math.ldexp(0,1), 0)
+testit('ldexp(1,1)', math.ldexp(1,1), 2)
+testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
+testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
+
+print 'log'
+testit('log(1/e)', math.log(1/math.e), -1)
+testit('log(1)', math.log(1), 0)
+testit('log(e)', math.log(math.e), 1)
+
+print 'log10'
+testit('log10(0.1)', math.log10(0.1), -1)
+testit('log10(1)', math.log10(1), 0)
+testit('log10(10)', math.log10(10), 1)
+
+print 'modf'
+def testmodf(name, (v1, v2), (e1, e2)):
+       if abs(v1-e1) > eps or abs(v2-e2):
+               raise TestFailed, '%s returned %s, expected %s'%\
+                     (name, `v1,v2`, `e1,e2`)
+
+testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
+testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
+
+print 'pow'
+testit('pow(0,1)', math.pow(0,1), 0)
+testit('pow(1,0)', math.pow(1,0), 1)
+testit('pow(2,1)', math.pow(2,1), 2)
+testit('pow(2,-1)', math.pow(2,-1), 0.5)
+
+print 'sin'
+testit('sin(0)', math.sin(0), 0)
+testit('sin(pi/2)', math.sin(math.pi/2), 1)
+testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
+
+print 'sinh'
+testit('sinh(0)', math.sinh(0), 0)
+testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
+testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
+
+print 'sqrt'
+testit('sqrt(0)', math.sqrt(0), 0)
+testit('sqrt(1)', math.sqrt(1), 1)
+testit('sqrt(4)', math.sqrt(4), 2)
+
+print 'tan'
+testit('tan(0)', math.tan(0), 0)
+testit('tan(pi/4)', math.tan(math.pi/4), 1)
+testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
+
+print 'tanh'
+testit('tanh(0)', math.tanh(0), 0)
+testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
index 8d2dfdc379f1a6b8f25b94b0374d19e0381690f6..982310062df63a7a7411c6942e036828f9f0409f 100755 (executable)
@@ -7,6 +7,25 @@ import types
 
 def _print(file, str='', terminator='\n'):
        file.write(str+terminator)
+
+
+def print_list(extracted_list, file=None):
+       if not file:
+               file = sys.stderr
+       for filename, lineno, name, line in extracted_list:
+               _print(file,
+                      '  File "%s", line %d, in %s' % (filename,lineno,name))
+               if line:
+                       _print(file, '    %s' % string.strip(line))
+
+def format_list(extracted_list):
+       list = []
+       for filename, lineno, name, line in extracted_list:
+               item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
+               if line:
+                       item = item + '    %s\n' % string.strip(line)
+               list.append(item)
+       return list
        
 
 def print_tb(tb, limit=None, file=None):
@@ -30,13 +49,7 @@ def print_tb(tb, limit=None, file=None):
                n = n+1
 
 def format_tb(tb, limit = None):
-       list = []
-       for filename, lineno, name, line in extract_tb(tb, limit):
-               item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
-               if line:
-                       item = item + '    %s\n' % string.strip(line)
-               list.append(item)
-       return list
+       return format_list(extract_tb(tb, limit))
 
 def extract_tb(tb, limit = None):
        if limit is None:
@@ -123,3 +136,48 @@ def print_last(limit=None, file=None):
                file = sys.stderr
        print_exception(sys.last_type, sys.last_value, sys.last_traceback,
                        limit, file)
+
+
+def print_stack(f=None, limit=None, file=None):
+       if f is None:
+               try:
+                       raise ZeroDivisionError
+               except ZeroDivisionError:
+                       tb = sys.exc_traceback
+                       f = tb.tb_frame.f_back
+       print_list(extract_stack(f, limit), file)
+
+def format_stack(f=None, limit=None):
+       if f is None:
+               try:
+                       raise ZeroDivisionError
+               except ZeroDivisionError:
+                       tb = sys.exc_traceback
+                       f = tb.tb_frame.f_back
+       return format_list(extract_stack(t, limit))
+
+def extract_stack(f=None, limit = None):
+       if f is None:
+               try:
+                       raise ZeroDivisionError
+               except ZeroDivisionError:
+                       tb = sys.exc_traceback
+                       f = tb.tb_frame.f_back
+       if limit is None:
+               if hasattr(sys, 'tracebacklimit'):
+                       limit = sys.tracebacklimit
+       list = []
+       n = 0
+       while f is not None and (limit is None or n < limit):
+               lineno = f.f_lineno
+               co = f.f_code
+               filename = co.co_filename
+               name = co.co_name
+               line = linecache.getline(filename, lineno)
+               if line: line = string.strip(line)
+               else: line = None
+               list.append(filename, lineno, name, line)
+               f = f.f_back
+               n = n+1
+       list.reverse()
+       return list
index 6f92beeaa180886c60f12bb239492b2f068b2246..370cfe4f46c0a1322b9c9f4be12873dcba04b4d7 100755 (executable)
@@ -1,13 +1,13 @@
 """Object-oriented interface to the parser module.
 
-This module exports three classes which together provide an interface
+This module exports four classes which together provide an interface
 to the parser module.  Together, the three classes represent two ways
 to create parsed representations of Python source and the two starting
 data types (source text and tuple representations).  Each class
 provides interfaces which are identical other than the constructors.
 The constructors are described in detail in the documentation for each
 class and the remaining, shared portion of the interface is documented
-below.  Briefly, the three classes provided are:
+below.  Briefly, the classes provided are:
 
 AST
     Defines the primary interface to the AST objects and supports creation
@@ -23,6 +23,9 @@ FileSuiteAST
     Convenience subclass of the `SuiteAST' class; loads source text of the
     suite from an external file.
 
+Common Methods
+--------------
+
 Aside from the constructors, several methods are provided to allow
 access to the various interpretations of the parse tree and to check
 conditions of the construct represented by the parse tree.
@@ -68,8 +71,8 @@ class AST:
     This base class provides all of the query methods for subclass
     objects defined in this module.
     """
-    _p = __import__('parser')          # import internally to avoid
-                                       # namespace pollution at the
+    import parser                      # import internally to avoid
+    _p = parser                                # namespace pollution at the
                                        # top level
     _text = None
     _code = None
@@ -84,7 +87,8 @@ class AST:
            The tuple tree to convert.
 
        The tuple-tree may represent either an expression or a suite; the
-       type will be determined automatically.
+       type will be determined automatically.  Line number information may
+       optionally be present for any subset of the terminal tokens.
        """
        if type(tuple) is not type(()):
            raise TypeError, 'Base AST class requires tuple parameter.'
@@ -93,11 +97,24 @@ class AST:
        self._ast  = self._p.tuple2ast(tuple)
        self._type = (self._p.isexpr(self._ast) and 'expression') or 'suite'
 
-    def tuple(self):
+    def list(self, line_info = 0):
+       """Returns a fresh list representing the parse tree.
+
+       line_info
+           If true, includes line number information for terminal tokens in
+           the output data structure,
+       """
+       return self._p.ast2list(self._ast, line_info)
+
+    def tuple(self, line_info = 0):
        """Returns the tuple representing the parse tree.
+
+       line_info
+           If true, includes line number information for terminal tokens in
+           the output data structure,
        """
        if self._tupl is None:
-           self._tupl = self._p.ast2tuple(self._ast)
+           self._tupl = self._p.ast2tuple(self._ast, line_info)
        return self._tupl
 
     def code(self):
index 7ddd93e3ccbaeeaa9d67b89ddad8097a9c22980e..cb54be9159578d6dcda65592eee732108a7bbe03 100755 (executable)
@@ -141,6 +141,7 @@ def _test():
            return self.sum
     o = Original()
     b = Bastion(o)
+    testcode = """if 1:
     b.add(81)
     b.add(18)
     print "b.total() =", b.total()
@@ -156,6 +157,20 @@ def _test():
        print "inaccessible"
     else:
        print "accessible"
+    try:
+       print "b._get_.func_defaults =", b._get_.func_defaults,
+    except:
+       print "inaccessible"
+    else:
+       print "accessible"
+    \n"""
+    exec testcode
+    print '='*20, "Using rexec:", '='*20
+    import rexec
+    r = rexec.RExec()
+    m = r.add_module('__main__')
+    m.b = b
+    r.r_exec(testcode)
 
 
 if __name__ == '__main__':
index 312028407dd5b97ad26defdb7b36cdd0c84f5a84..9947569eb3d6aa9cfe0efa6cde075eb526a2e88f 100755 (executable)
@@ -43,7 +43,7 @@ def compile_dir(dir, maxlevels = 10):
 
 def compile_path(skip_curdir = 1):
        for dir in sys.path:
-               if dir == os.curdir and skip_curdir:
+               if (not dir or dir == os.curdir) and skip_curdir:
                        print 'Skipping current directory'
                else:
                        compile_dir(dir, 0)
index 026637940e5ad65761596d3313a409970b5c67dc..c192e20ddb567525a77fe1af219237fb33e628ee 100755 (executable)
@@ -10,7 +10,7 @@ AS_IS = None
 
 class NullFormatter:
 
-    def __init__(self): pass
+    def __init__(self, writer): pass
     def end_paragraph(self, blankline): pass
     def add_line_break(self): pass
     def add_hor_rule(self, abswidth=None, percentwidth=1.0,
@@ -33,6 +33,11 @@ class NullFormatter:
 
 class AbstractFormatter:
 
+    #  Space handling policy:  blank spaces at the boundary between elements
+    #  are handled by the outermost context.  "Literal" data is not checked
+    #  to determine context, so spaces in literal data are handled directly
+    #  in all circumstances.
+
     def __init__(self, writer):
        self.writer = writer            # Output device
        self.align = None               # Current alignment
@@ -162,7 +167,8 @@ class AbstractFormatter:
 
     def add_literal_data(self, data):
        if not data: return
-       #  Caller is expected to cause flush_softspace() if needed.
+       if self.softspace:
+           self.writer.send_flowing_data(" ")
        self.hard_break = data[-1:] == '\n'
        self.nospace = self.para_end = self.softspace = \
                       self.parskip = self.have_label = 0
@@ -170,8 +176,9 @@ class AbstractFormatter:
 
     def flush_softspace(self):
        if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.parskip = \
+           self.hard_break = self.para_end = self.parskip = \
                              self.have_label = self.softspace = 0
+           self.nospace = 1
            self.writer.send_flowing_data(' ')
 
     def push_alignment(self, align):
@@ -194,7 +201,8 @@ class AbstractFormatter:
 
     def push_font(self, (size, i, b, tt)):
        if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
+           self.hard_break = self.para_end = self.softspace = 0
+           self.nospace = 1
            self.writer.send_flowing_data(' ')
        if self.font_stack:
            csize, ci, cb, ctt = self.font_stack[-1]
@@ -207,9 +215,6 @@ class AbstractFormatter:
        self.writer.new_font(font)
 
     def pop_font(self):
-       if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
-           self.writer.send_flowing_data(' ')
        if self.font_stack:
            del self.font_stack[-1]
        if self.font_stack:
@@ -241,22 +246,20 @@ class AbstractFormatter:
 
     def push_style(self, *styles):
        if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
+           self.hard_break = self.para_end = self.softspace = 0
+           self.nospace = 1
            self.writer.send_flowing_data(' ')
        for style in styles:
            self.style_stack.append(style)
        self.writer.new_styles(tuple(self.style_stack))
 
     def pop_style(self, n=1):
-       if self.softspace:
-           self.hard_break = self.nospace = self.para_end = self.softspace = 0
-           self.writer.send_flowing_data(' ')
        del self.style_stack[-n:]
        self.writer.new_styles(tuple(self.style_stack))
 
     def assert_line_data(self, flag=1):
        self.nospace = self.hard_break = not flag
-       self.para_end = self.have_label = 0
+       self.para_end = self.parskip = self.have_label = 0
 
 
 class NullWriter:
index da33a7777b9713f76fc48fb95cdddb8cc21b1979..baf9379f537a52eba04713ee6aaea76f84b738ed 100755 (executable)
@@ -106,8 +106,14 @@ def choose_boundary():
                import socket
                import os
                hostid = socket.gethostbyname(socket.gethostname())
-               uid = `os.getuid()`
-               pid = `os.getpid()`
+               try:
+                   uid = `os.getuid()`
+               except:
+                   uid = '1'
+               try:
+                   pid = `os.getpid()`
+               except:
+                   pid = '1'
                seed = `rand.rand()`
                _prefix = hostid + '.' + uid + '.' + pid
        timestamp = `int(time.time())`
diff --git a/Lib/dos_8x3/mimewrit.py b/Lib/dos_8x3/mimewrit.py
new file mode 100644 (file)
index 0000000..6fbcb65
--- /dev/null
@@ -0,0 +1,131 @@
+"""Generic MIME writer.
+
+Classes:
+
+MimeWriter - the only thing here.
+
+"""
+
+__version__ = '$Revision$'
+# $Source$
+
+
+import string
+import mimetools
+
+
+class MimeWriter:
+
+    """Generic MIME writer.
+
+    Methods:
+
+    __init__()
+    addheader()
+    flushheaders()
+    startbody()
+    startmultipartbody()
+    nextpart()
+    lastpart()
+
+    A MIME writer is much more primitive than a MIME parser.  It
+    doesn't seek around on the output file, and it doesn't use large
+    amounts of buffer space, so you have to write the parts in the
+    order they should occur on the output file.  It does buffer the
+    headers you add, allowing you to rearrange their order.
+    
+    General usage is:
+
+    f = <open the output file>
+    w = MimeWriter(f)
+    ...call w.addheader(key, value) 0 or more times...
+
+    followed by either:
+
+    f = w.startbody(content_type)
+    ...call f.write(data) for body data...
+
+    or:
+
+    w.startmultipartbody(subtype)
+    for each part:
+        subwriter = w.nextpart()
+       ...use the subwriter's methods to create the subpart...
+    w.lastpart()
+
+    The subwriter is another MimeWriter instance, and should be
+    treated in the same way as the toplevel MimeWriter.  This way,
+    writing recursive body parts is easy.
+
+    Warning: don't forget to call lastpart()!
+
+    XXX There should be more state so calls made in the wrong order
+    are detected.
+
+    Some special cases:
+
+    - startbody() just returns the file passed to the constructor;
+      but don't use this knowledge, as it may be changed.
+
+    - startmultipartbody() actually returns a file as well;
+      this can be used to write the initial 'if you can read this your
+      mailer is not MIME-aware' message.
+
+    - If you call flushheaders(), the headers accumulated so far are
+      written out (and forgotten); this is useful if you don't need a
+      body part at all, e.g. for a subpart of type message/rfc822
+      that's (mis)used to store some header-like information.
+
+    - Passing a keyword argument 'prefix=<flag>' to addheader(),
+      start*body() affects where the header is inserted; 0 means
+      append at the end, 1 means insert at the start; default is
+      append for addheader(), but insert for start*body(), which use
+      it to determine where the Content-Type header goes.
+
+    """
+
+    def __init__(self, fp):
+       self._fp = fp
+       self._headers = []
+
+    def addheader(self, key, value, prefix=0):
+       lines = string.splitfields(value, "\n")
+       while lines and not lines[-1]: del lines[-1]
+       while lines and not lines[0]: del lines[0]
+       for i in range(1, len(lines)):
+           lines[i] = "    " + string.strip(lines[i])
+       value = string.joinfields(lines, "\n") + "\n"
+       line = key + ": " + value
+       if prefix:
+           self._headers.insert(0, line)
+       else:
+           self._headers.append(line)
+
+    def flushheaders(self):
+       self._fp.writelines(self._headers)
+       self._headers = []
+
+    def startbody(self, ctype, plist=[], prefix=1):
+       for name, value in plist:
+           ctype = ctype + ';\n %s=\"%s\"' % (name, value)
+       self.addheader("Content-Type", ctype, prefix=prefix)
+       self.flushheaders()
+       self._fp.write("\n")
+       return self._fp
+
+    def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
+       self._boundary = boundary or mimetools.choose_boundary()
+       return self.startbody("multipart/" + subtype,
+                             [("boundary", self._boundary)] + plist,
+                             prefix=prefix)
+
+    def nextpart(self):
+       self._fp.write("\n--" + self._boundary + "\n")
+       return self.__class__(self._fp)
+
+    def lastpart(self):
+       self._fp.write("\n--" + self._boundary + "--\n")
+
+
+if __name__ == '__main__':
+    print "To test the MimeWriter module, run TestMimeWriter.py."
index 64cda986223f373a1cc10d43c712e67dd1ef55ec..f0df5433aa0c1c2be180fc35755df60b631c46e8 100755 (executable)
@@ -174,11 +174,15 @@ class _posixfile_:
        elif len(args) > 3:
            raise TypeError, 'too many arguments'
 
-       # Hack by davem@magnet.com to get locking to go on freebsd
+       # Hack by davem@magnet.com to get locking to go on freebsd;
+       # additions for AIX by Vladimir.Marangozov@imag.fr
         import sys, os
         if sys.platform == 'freebsd2':
            flock = struct.pack('lxxxxlxxxxlhh', \
                  l_start, l_len, os.getpid(), l_type, l_whence) 
+        elif sys.platform in ['aix3', 'aix4']:
+            flock = struct.pack('hhlllii', \
+                  l_type, l_whence, l_start, l_len, 0, 0, 0)
        else:
            flock = struct.pack('hhllhh', \
                  l_type, l_whence, l_start, l_len, 0, 0)
@@ -189,6 +193,9 @@ class _posixfile_:
            if sys.platform == 'freebsd2':
                l_start, l_len, l_pid, l_type, l_whence = \
                    struct.unpack('lxxxxlxxxxlhh', flock)
+            elif sys.platform in ['aix3', 'aix4']:
+                l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
+                    struct.unpack('hhlllii', flock)
            else:
                l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
                    struct.unpack('hhllhh', flock)
index 4590f8dc31e42b903b09cac50810b234a40dca28..014dfe2798390f5e1058e3d561906c38a3c88863 100755 (executable)
@@ -53,7 +53,7 @@ def split(p):
 
 
 # Split a path in root and extension.
-# The extension is everything starting at the first dot in the last
+# The extension is everything starting at the last dot in the last
 # pathname component; the root is everything before that.
 # It is always true that root + ext == p.
 
diff --git a/Lib/dos_8x3/test_mat.py b/Lib/dos_8x3/test_mat.py
new file mode 100644 (file)
index 0000000..af84d2a
--- /dev/null
@@ -0,0 +1,153 @@
+# Python test set -- math module
+# XXXX Should not do tests around zero only
+
+from test_support import *
+
+eps=1e-5
+print 'math module, testing with eps', eps
+import math
+
+def testit(name, value, expected):
+       if abs(value-expected) > eps:
+               raise TestFailed, '%s returned %f, expected %f'%\
+                     (name, value, expected)
+
+print 'constants'
+testit('pi', math.pi, 3.1415926)
+testit('e', math.e, 2.7182818)
+
+print 'acos'
+testit('acos(-1)', math.acos(-1), math.pi)
+testit('acos(0)', math.acos(0), math.pi/2)
+testit('acos(1)', math.acos(1), 0)
+
+print 'asin'
+testit('asin(-1)', math.asin(-1), -math.pi/2)
+testit('asin(0)', math.asin(0), 0)
+testit('asin(1)', math.asin(1), math.pi/2)
+
+print 'atan'
+testit('atan(-1)', math.atan(-1), -math.pi/4)
+testit('atan(0)', math.atan(0), 0)
+testit('atan(1)', math.atan(1), math.pi/4)
+
+print 'atan2'
+testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
+testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
+testit('atan2(0, 1)', math.atan2(0, 1), 0)
+testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
+testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
+
+print 'ceil'
+testit('ceil(0.5)', math.ceil(0.5), 1)
+testit('ceil(1.0)', math.ceil(1.0), 1)
+testit('ceil(1.5)', math.ceil(1.5), 2)
+testit('ceil(-0.5)', math.ceil(-0.5), 0)
+testit('ceil(-1.0)', math.ceil(-1.0), -1)
+testit('ceil(-1.5)', math.ceil(-1.5), -1)
+
+print 'cos'
+testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
+testit('cos(0)', math.cos(0), 1)
+testit('cos(pi/2)', math.cos(math.pi/2), 0)
+testit('cos(pi)', math.cos(math.pi), -1)
+
+print 'cosh'
+testit('cosh(0)', math.cosh(0), 1)
+testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
+
+print 'exp'
+testit('exp(-1)', math.exp(-1), 1/math.e)
+testit('exp(0)', math.exp(0), 1)
+testit('exp(1)', math.exp(1), math.e)
+
+print 'fabs'
+testit('fabs(-1)', math.fabs(-1), 1)
+testit('fabs(0)', math.fabs(0), 0)
+testit('fabs(1)', math.fabs(1), 1)
+
+print 'floor'
+testit('floor(0.5)', math.floor(0.5), 0)
+testit('floor(1.0)', math.floor(1.0), 1)
+testit('floor(1.5)', math.floor(1.5), 1)
+testit('floor(-0.5)', math.floor(-0.5), -1)
+testit('floor(-1.0)', math.floor(-1.0), -1)
+testit('floor(-1.5)', math.floor(-1.5), -2)
+
+print 'fmod'
+testit('fmod(10,1)', math.fmod(10,1), 0)
+testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
+testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
+testit('fmod(-10,1)', math.fmod(-10,1), 0)
+testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
+testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
+
+print 'frexp'
+def testfrexp(name, (mant, exp), (emant, eexp)):
+       if abs(mant-emant) > eps or exp <> eexp:
+               raise TestFailed, '%s returned %s, expected %s'%\
+                     (name, `mant, exp`, `emant,eexp`)
+
+testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
+testfrexp('frexp(0)', math.frexp(0), (0, 0))
+testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
+testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
+
+print 'hypot'
+testit('hypot(0,0)', math.hypot(0,0), 0)
+testit('hypot(3,4)', math.hypot(3,4), 5)
+
+print 'ldexp'
+testit('ldexp(0,1)', math.ldexp(0,1), 0)
+testit('ldexp(1,1)', math.ldexp(1,1), 2)
+testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
+testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
+
+print 'log'
+testit('log(1/e)', math.log(1/math.e), -1)
+testit('log(1)', math.log(1), 0)
+testit('log(e)', math.log(math.e), 1)
+
+print 'log10'
+testit('log10(0.1)', math.log10(0.1), -1)
+testit('log10(1)', math.log10(1), 0)
+testit('log10(10)', math.log10(10), 1)
+
+print 'modf'
+def testmodf(name, (v1, v2), (e1, e2)):
+       if abs(v1-e1) > eps or abs(v2-e2):
+               raise TestFailed, '%s returned %s, expected %s'%\
+                     (name, `v1,v2`, `e1,e2`)
+
+testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
+testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
+
+print 'pow'
+testit('pow(0,1)', math.pow(0,1), 0)
+testit('pow(1,0)', math.pow(1,0), 1)
+testit('pow(2,1)', math.pow(2,1), 2)
+testit('pow(2,-1)', math.pow(2,-1), 0.5)
+
+print 'sin'
+testit('sin(0)', math.sin(0), 0)
+testit('sin(pi/2)', math.sin(math.pi/2), 1)
+testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
+
+print 'sinh'
+testit('sinh(0)', math.sinh(0), 0)
+testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
+testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
+
+print 'sqrt'
+testit('sqrt(0)', math.sqrt(0), 0)
+testit('sqrt(1)', math.sqrt(1), 1)
+testit('sqrt(4)', math.sqrt(4), 2)
+
+print 'tan'
+testit('tan(0)', math.tan(0), 0)
+testit('tan(pi/4)', math.tan(math.pi/4), 1)
+testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
+
+print 'tanh'
+testit('tanh(0)', math.tanh(0), 0)
+testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
index 8d2dfdc379f1a6b8f25b94b0374d19e0381690f6..982310062df63a7a7411c6942e036828f9f0409f 100755 (executable)
@@ -7,6 +7,25 @@ import types
 
 def _print(file, str='', terminator='\n'):
        file.write(str+terminator)
+
+
+def print_list(extracted_list, file=None):
+       if not file:
+               file = sys.stderr
+       for filename, lineno, name, line in extracted_list:
+               _print(file,
+                      '  File "%s", line %d, in %s' % (filename,lineno,name))
+               if line:
+                       _print(file, '    %s' % string.strip(line))
+
+def format_list(extracted_list):
+       list = []
+       for filename, lineno, name, line in extracted_list:
+               item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
+               if line:
+                       item = item + '    %s\n' % string.strip(line)
+               list.append(item)
+       return list
        
 
 def print_tb(tb, limit=None, file=None):
@@ -30,13 +49,7 @@ def print_tb(tb, limit=None, file=None):
                n = n+1
 
 def format_tb(tb, limit = None):
-       list = []
-       for filename, lineno, name, line in extract_tb(tb, limit):
-               item = '  File "%s", line %d, in %s\n' % (filename,lineno,name)
-               if line:
-                       item = item + '    %s\n' % string.strip(line)
-               list.append(item)
-       return list
+       return format_list(extract_tb(tb, limit))
 
 def extract_tb(tb, limit = None):
        if limit is None:
@@ -123,3 +136,48 @@ def print_last(limit=None, file=None):
                file = sys.stderr
        print_exception(sys.last_type, sys.last_value, sys.last_traceback,
                        limit, file)
+
+
+def print_stack(f=None, limit=None, file=None):
+       if f is None:
+               try:
+                       raise ZeroDivisionError
+               except ZeroDivisionError:
+                       tb = sys.exc_traceback
+                       f = tb.tb_frame.f_back
+       print_list(extract_stack(f, limit), file)
+
+def format_stack(f=None, limit=None):
+       if f is None:
+               try:
+                       raise ZeroDivisionError
+               except ZeroDivisionError:
+                       tb = sys.exc_traceback
+                       f = tb.tb_frame.f_back
+       return format_list(extract_stack(t, limit))
+
+def extract_stack(f=None, limit = None):
+       if f is None:
+               try:
+                       raise ZeroDivisionError
+               except ZeroDivisionError:
+                       tb = sys.exc_traceback
+                       f = tb.tb_frame.f_back
+       if limit is None:
+               if hasattr(sys, 'tracebacklimit'):
+                       limit = sys.tracebacklimit
+       list = []
+       n = 0
+       while f is not None and (limit is None or n < limit):
+               lineno = f.f_lineno
+               co = f.f_code
+               filename = co.co_filename
+               name = co.co_name
+               line = linecache.getline(filename, lineno)
+               if line: line = string.strip(line)
+               else: line = None
+               list.append(filename, lineno, name, line)
+               f = f.f_back
+               n = n+1
+       list.reverse()
+       return list