[Python-checkins] CVS: python/dist/src/Lib builtin.py,NONE,1.1.2.1 macstat.py,NONE,1.1.2.1 persist.py,NONE,1.6.4.1 __future__.py,1.5.4.1,1.5.4.2 doctest.py,1.10.4.1,1.10.4.2 inspect.py,1.16,1.16.4.1 sgmllib.py,1.30.4.2,1.30.4.3 tokenize.py,1.22.4.1,1.22.4.2 types.py,1.14.10.6,1.14.10.7

Tim Peters tim_one@users.sourceforge.net
Mon, 16 Jul 2001 14:39:43 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv11584/descr/dist/src/Lib

Modified Files:
      Tag: descr-branch
	__future__.py doctest.py inspect.py sgmllib.py tokenize.py 
	types.py 
Added Files:
      Tag: descr-branch
	builtin.py macstat.py persist.py 
Log Message:
Resuming interrupted merge checkin.


--- NEW FILE: builtin.py ---
# B/W compat hack so code that says "import builtin" won't break after
# name change from builtin to __builtin__.
from __builtin__ import *

--- NEW FILE: macstat.py ---
# Module 'stat'
#
# Defines constants and functions for interpreting stat/lstat struct
# as returned by os.stat() and os.lstat() (if it exists).
#
# Suggested usage: from stat import *
#
# XXX Strictly spoken, this module may have to be adapted for each POSIX
# implementation; in practice, however, the numeric constants used by
# stat() are almost universal (even for stat() emulations on non-UNIX
# systems like MS-DOS).

# Indices for stat struct members in tuple returned by os.stat()

ST_MODE  = 0
ST_INO   = 1
ST_DEV   = 2
ST_NLINK = 3
ST_UID   = 4
ST_GID   = 5
ST_SIZE  = 6
ST_ATIME = 7
ST_MTIME = 8
ST_CTIME = 9

# Extract bits from the mode

def S_IMODE(mode):
	return 0

def S_IFMT(mode):
	return mode & 0xFFFF

# Constants used as S_IFMT() for various file types
# (not all are implemented on all systems)

S_IFDIR  = 0x0000
S_IFREG  = 0x0003

# Functions to test for each file type

def S_ISDIR(mode):
	return S_IFMT(mode) == S_IFDIR

def S_ISCHR(mode):
	return 0

def S_ISBLK(mode):
	return 0

def S_ISREG(mode):
	return S_IFMT(mode) == S_IFREG

def S_ISFIFO(mode):
	return 0

def S_ISLNK(mode):
	return 0

def S_ISSOCK(mode):
	return 0

# Names for permission bits

S_ISUID = 04000
S_ISGID = 02000
S_ENFMT = S_ISGID
S_ISVTX = 01000
S_IREAD = 00400
S_IWRITE = 00200
S_IEXEC = 00100
S_IRWXU = 00700
S_IRUSR = 00400
S_IWUSR = 00200
S_IXUSR = 00100
S_IRWXG = 00070
S_IRGRP = 00040
S_IWGRP = 00020
S_IXGRP = 00010
S_IRWXO = 00007
S_IROTH = 00004
S_IWOTH = 00002
S_IXOTH = 00001

--- NEW FILE: persist.py ---
# persist.py
#
# Implement limited persistence.
#
# Simple interface:
#	persist.save()		save __main__ module on file (overwrite)
#	persist.load()		load __main__ module from file (merge)
#
# These use the filename persist.defaultfile, initialized to 'wsrestore.py'.
#
# A raw interface also exists:
#	persist.writedict(dict, fp)	save dictionary to open file
#	persist.readdict(dict, fp)	read (merge) dictionary from open file
#
# Internally, the function dump() and a whole bunch of support of functions
# traverse a graph of objects and print them in a restorable form
# (which happens to be a Python module).
#
# XXX Limitations:
# - Volatile objects are dumped as strings:
#   - open files, windows etc.
# - Other 'obscure' objects are dumped as strings:
#   - classes, instances and methods
#   - compiled regular expressions
#   - anything else reasonably obscure (e.g., capabilities)
#   - type objects for obscure objects
# - It's slow when there are many of lists or dictionaries
#   (This could be fixed if there were a quick way to compute a hash
#   function of any object, even if recursive)

defaultfile = 'wsrestore.py'

def save():
	import __main__
	import os
	# XXX On SYSV, if len(defaultfile) >= 14, this is wrong!
	backup = defaultfile + '~'
	try:
		os.unlink(backup)
	except os.error:
		pass
	try:
		os.rename(defaultfile, backup)
	except os.error:
		pass
	fp = open(defaultfile, 'w')
	writedict(__main__.__dict__, fp)
	fp.close()

def load():
	import __main__
	fp = open(defaultfile, 'r')
	readdict(__main__.__dict__, fp)

def writedict(dict, fp):
	import sys
	savestdout = sys.stdout
	try:
		sys.stdout = fp
		dump(dict)	# Writes to sys.stdout
	finally:
		sys.stdout = savestdout

def readdict(dict, fp):
	contents = fp.read()
	globals = {}
	exec(contents, globals)
	top = globals['top']
	for key in top.keys():
		if dict.has_key(key):
			print 'warning:', key, 'not overwritten'
		else:
			dict[key] = top[key]


# Function dump(x) prints (on sys.stdout!) a sequence of Python statements
# that, when executed in an empty environment, will reconstruct the
# contents of an arbitrary dictionary.

import sys

# Name used for objects dict on output.
#
FUNNYNAME = FN = 'A'

# Top-level function.  Call with the object you want to dump.
#
def dump(x):
	types = {}
	stack = []			# Used by test for recursive objects
	print FN, '= {}'
	topuid = dumpobject(x, types, stack)
	print 'top =', FN, '[', `topuid`, ']'

# Generic function to dump any object.
#
dumpswitch = {}
#
def dumpobject(x, types, stack):
	typerepr = `type(x)`
	if not types.has_key(typerepr):
		types[typerepr] = {}
	typedict = types[typerepr]
	if dumpswitch.has_key(typerepr):
		return dumpswitch[typerepr](x, typedict, types, stack)
	else:
		return dumpbadvalue(x, typedict, types, stack)

# Generic function to dump unknown values.
# This assumes that the Python interpreter prints such values as
# <foo object at xxxxxxxx>.
# The object will be read back as a string: '<foo object at xxxxxxxx>'.
# In some cases it may be possible to fix the dump manually;
# to ease the editing, these cases are labeled with an XXX comment.
#
def dumpbadvalue(x, typedict, types, stack):
	xrepr = `x`
	if typedict.has_key(xrepr):
		return typedict[xrepr]
	uid = genuid()
	typedict[xrepr] = uid
	print FN, '[', `uid`, '] =', `xrepr`, '# XXX'
	return uid

# Generic function to dump pure, simple values, except strings
#
def dumpvalue(x, typedict, types, stack):
	xrepr = `x`
	if typedict.has_key(xrepr):
		return typedict[xrepr]
	uid = genuid()
	typedict[xrepr] = uid
	print FN, '[', `uid`, '] =', `x`
	return uid

# Functions to dump string objects
#
def dumpstring(x, typedict, types, stack):
	# XXX This can break if strings have embedded '\0' bytes
	# XXX because of a bug in the dictionary module
	if typedict.has_key(x):
		return typedict[x]
	uid = genuid()
	typedict[x] = uid
	print FN, '[', `uid`, '] =', `x`
	return uid

# Function to dump type objects
#
typeswitch = {}
class some_class:
	def method(self): pass
some_instance = some_class()
#
def dumptype(x, typedict, types, stack):
	xrepr = `x`
	if typedict.has_key(xrepr):
		return typedict[xrepr]
	uid = genuid()
	typedict[xrepr] = uid
	if typeswitch.has_key(xrepr):
		print FN, '[', `uid`, '] =', typeswitch[xrepr]
	elif x == type(sys):
		print 'import sys'
		print FN, '[', `uid`, '] = type(sys)'
	elif x == type(sys.stderr):
		print 'import sys'
		print FN, '[', `uid`, '] = type(sys.stderr)'
	elif x == type(dumptype):
		print 'def some_function(): pass'
		print FN, '[', `uid`, '] = type(some_function)'
	elif x == type(some_class):
		print 'class some_class: pass'
		print FN, '[', `uid`, '] = type(some_class)'
	elif x == type(some_instance):
		print 'class another_class: pass'
		print 'some_instance = another_class()'
		print FN, '[', `uid`, '] = type(some_instance)'
	elif x == type(some_instance.method):
		print 'class yet_another_class:'
		print '    def method(): pass'
		print 'another_instance = yet_another_class()'
		print FN, '[', `uid`, '] = type(another_instance.method)'
	else:
		# Unknown type
		print FN, '[', `uid`, '] =', `xrepr`, '# XXX'
	return uid

# Initialize the typeswitch
#
for x in None, 0, 0.0, '', (), [], {}:
	typeswitch[`type(x)`] = 'type(' + `x` + ')'
for s in 'type(0)', 'abs', '[].append':
	typeswitch[`type(eval(s))`] = 'type(' + s + ')'

# Dump a tuple object
#
def dumptuple(x, typedict, types, stack):
	item_uids = []
	xrepr = ''
	for item in x:
		item_uid = dumpobject(item, types, stack)
		item_uids.append(item_uid)
		xrepr = xrepr + ' ' + item_uid
	del stack[-1:]
	if typedict.has_key(xrepr):
		return typedict[xrepr]
	uid = genuid()
	typedict[xrepr] = uid
	print FN, '[', `uid`, '] = (',
	for item_uid in item_uids:
		print FN, '[', `item_uid`, '],',
	print ')'
	return uid

# Dump a list object
#
def dumplist(x, typedict, types, stack):
	# Check for recursion
	for x1, uid1 in stack:
		if x is x1: return uid1
	# Check for occurrence elsewhere in the typedict
	for uid1 in typedict.keys():
		if x is typedict[uid1]: return uid1
	# This uses typedict differently!
	uid = genuid()
	typedict[uid] = x
	print FN, '[', `uid`, '] = []'
	stack.append(x, uid)
	item_uids = []
	for item in x:
		item_uid = dumpobject(item, types, stack)
		item_uids.append(item_uid)
	del stack[-1:]
	for item_uid in item_uids:
		print FN, '[', `uid`, '].append(', FN, '[', `item_uid`, '])'
	return uid

# Dump a dictionary object
#
def dumpdict(x, typedict, types, stack):
	# Check for recursion
	for x1, uid1 in stack:
		if x is x1: return uid1
	# Check for occurrence elsewhere in the typedict
	for uid1 in typedict.keys():
		if x is typedict[uid1]: return uid1
	# This uses typedict differently!
	uid = genuid()
	typedict[uid] = x
	print FN, '[', `uid`, '] = {}'
	stack.append(x, uid)
	item_uids = []
	for key in x.keys():
		val_uid = dumpobject(x[key], types, stack)
		item_uids.append(key, val_uid)
	del stack[-1:]
	for key, val_uid in item_uids:
		print FN, '[', `uid`, '][', `key`, '] =',
		print FN, '[', `val_uid`, ']'
	return uid

# Dump a module object
#
def dumpmodule(x, typedict, types, stack):
	xrepr = `x`
	if typedict.has_key(xrepr):
		return typedict[xrepr]
	from string import split
	# `x` has the form <module 'foo'>
	name = xrepr[9:-2]
	uid = genuid()
	typedict[xrepr] = uid
	print 'import', name
	print FN, '[', `uid`, '] =', name
	return uid


# Initialize dumpswitch, a table of functions to dump various objects,
# indexed by `type(x)`.
#
for x in None, 0, 0.0:
	dumpswitch[`type(x)`] = dumpvalue
for x, f in ('', dumpstring), (type(0), dumptype), ((), dumptuple), \
		([], dumplist), ({}, dumpdict), (sys, dumpmodule):
	dumpswitch[`type(x)`] = f


# Generate the next unique id; a string consisting of digits.
# The seed is stored as seed[0].
#
seed = [0]
#
def genuid():
	x = seed[0]
	seed[0] = seed[0] + 1
	return `x`

Index: __future__.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/__future__.py,v
retrieving revision 1.5.4.1
retrieving revision 1.5.4.2
diff -C2 -r1.5.4.1 -r1.5.4.2
*** __future__.py	2001/07/14 07:47:34	1.5.4.1
--- __future__.py	2001/07/16 21:39:41	1.5.4.2
***************
*** 68,69 ****
--- 68,70 ----
  
  nested_scopes = _Feature((2, 1, 0, "beta", 1), (2, 2, 0, "alpha", 0))
+ generators = _Feature((2, 2, 0, "alpha", 1), (2, 3, 0, "final", 0))

Index: doctest.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v
retrieving revision 1.10.4.1
retrieving revision 1.10.4.2
diff -C2 -r1.10.4.1 -r1.10.4.2
*** doctest.py	2001/07/07 22:55:27	1.10.4.1
--- doctest.py	2001/07/16 21:39:41	1.10.4.2
***************
*** 349,352 ****
--- 349,361 ----
  #    string method conversion
  
+ # XXX Until generators are part of the language, examples in doctest'ed
+ #     modules will inherit doctest's __future__ settings (see PEP 236 for
+ #     more on that).  In the absence of a better working idea, the std
+ #     test suite needs generators, while the set of doctest'ed modules that
+ #     don't use "yield" in a generator context may well be empty.  So
+ #     enable generators here.  This can go away when generators are no
+ #     longer optional.
+ from __future__ import generators
+ 
  __version__ = 0, 9, 7
  

Index: inspect.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v
retrieving revision 1.16
retrieving revision 1.16.4.1
diff -C2 -r1.16 -r1.16.4.1
*** inspect.py	2001/04/13 14:04:02	1.16
--- inspect.py	2001/07/16 21:39:41	1.16.4.1
***************
*** 25,28 ****
--- 25,30 ----
  # This module is in the public domain.  No warranties.
  
+ from __future__ import generators
+ 
  __author__ = 'Ka-Ping Yee <ping@lfw.org>'
  __date__ = '1 Jan 2001'

Index: sgmllib.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v
retrieving revision 1.30.4.2
retrieving revision 1.30.4.3
diff -C2 -r1.30.4.2 -r1.30.4.3
*** sgmllib.py	2001/07/15 20:26:55	1.30.4.2
--- sgmllib.py	2001/07/16 21:39:41	1.30.4.3
***************
*** 6,10 ****
  # character data -- the normal case), RCDATA (replaceable character
  # data -- only char and entity references and end tags are special)
! # and CDATA (character data -- only end tags are special).
  
  
--- 6,11 ----
  # character data -- the normal case), RCDATA (replaceable character
  # data -- only char and entity references and end tags are special)
! # and CDATA (character data -- only end tags are special).  RCDATA is
! # not supported at all.
  
  
***************
*** 35,38 ****
--- 36,42 ----
  commentopen = re.compile('<!--')
  commentclose = re.compile(r'--\s*>')
+ declopen = re.compile('<!')
+ declname = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*')
+ declstringlit = re.compile(r'(\'[^\']*\'|"[^"]*")\s*')
  tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
  attrfind = re.compile(
***************
*** 161,164 ****
--- 165,172 ----
                      continue
              elif rawdata[i] == '&':
+                 if self.literal:
+                     self.handle_data(rawdata[i])
+                     i = i+1
+                     continue
                  match = charref.match(rawdata, i)
                  if match:
***************
*** 211,219 ****
      # Internal -- parse declaration.
      def parse_declaration(self, i):
          rawdata = self.rawdata
          j = i + 2
          n = len(rawdata)
          while j < n:
!             c = rawdata[j:j+1]
              if c == ">":
                  # end of declaration syntax
--- 219,236 ----
      # Internal -- parse declaration.
      def parse_declaration(self, i):
+         # This is some sort of declaration; in "HTML as
+         # deployed," this should only be the document type
+         # declaration ("<!DOCTYPE html...>").
          rawdata = self.rawdata
          j = i + 2
+         assert rawdata[i:j] == "<!", "unexpected call to parse_declaration"
+         if rawdata[j:j+1] in ("-", ""):
+             # Start of comment followed by buffer boundary,
+             # or just a buffer boundary.
+             return -1
+         # in practice, this should look like: ((name|stringlit) S*)+ '>'
          n = len(rawdata)
          while j < n:
!             c = rawdata[j]
              if c == ">":
                  # end of declaration syntax
***************
*** 223,235 ****
                  m = declstringlit.match(rawdata, j)
                  if not m:
!                     # incomplete or an error?
!                     return -1
                  j = m.end()
!             else:
!                 m = decldata.match(rawdata, j)
                  if not m:
!                     # incomplete or an error?
!                     return -1
                  j = m.end()
          # end of buffer between tokens
          return -1
--- 240,253 ----
                  m = declstringlit.match(rawdata, j)
                  if not m:
!                     return -1 # incomplete
                  j = m.end()
!             elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
!                 m = declname.match(rawdata, j)
                  if not m:
!                     return -1 # incomplete
                  j = m.end()
+             else:
+                 raise SGMLParseError(
+                     "unexpected char in declaration: %s" % `rawdata[j]`)
          # end of buffer between tokens
          return -1

Index: tokenize.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/tokenize.py,v
retrieving revision 1.22.4.1
retrieving revision 1.22.4.2
diff -C2 -r1.22.4.1 -r1.22.4.2
*** tokenize.py	2001/07/07 22:55:28	1.22.4.1
--- tokenize.py	2001/07/16 21:39:41	1.22.4.2
***************
*** 23,26 ****
--- 23,28 ----
  each time a new token is found."""
  
+ from __future__ import generators
+ 
  __author__ = 'Ka-Ping Yee <ping@lfw.org>'
  __credits__ = \

Index: types.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v
retrieving revision 1.14.10.6
retrieving revision 1.14.10.7
diff -C2 -r1.14.10.6 -r1.14.10.7
*** types.py	2001/07/07 22:55:28	1.14.10.6
--- types.py	2001/07/16 21:39:41	1.14.10.7
***************
*** 3,6 ****
--- 3,7 ----
  Types that are part of optional modules (e.g. array) are not listed.
  """
+ from __future__ import generators
  
  import sys