Adding new files, removing some.
This commit is contained in:
parent
9acdd3aed8
commit
6f8f92f535
|
@ -0,0 +1,726 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
|
||||
####
|
||||
# Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>
|
||||
#
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software
|
||||
# and its documentation for any purpose and without fee is hereby
|
||||
# granted, provided that the above copyright notice appear in all
|
||||
# copies and that both that copyright notice and this permission
|
||||
# notice appear in supporting documentation, and that the name of
|
||||
# Timothy O'Malley not be used in advertising or publicity
|
||||
# pertaining to distribution of the software without specific, written
|
||||
# prior permission.
|
||||
#
|
||||
# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
|
||||
# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
####
|
||||
#
|
||||
# Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp
|
||||
# by Timothy O'Malley <timo@alum.mit.edu>
|
||||
#
|
||||
# Cookie.py is a Python module for the handling of HTTP
|
||||
# cookies as a Python dictionary. See RFC 2109 for more
|
||||
# information on cookies.
|
||||
#
|
||||
# The original idea to treat Cookies as a dictionary came from
|
||||
# Dave Mitchell (davem@magnet.com) in 1995, when he released the
|
||||
# first version of nscookie.py.
|
||||
#
|
||||
####
|
||||
|
||||
"""
|
||||
Here's a sample session to show how to use this module.
|
||||
At the moment, this is the only documentation.
|
||||
|
||||
The Basics
|
||||
----------
|
||||
|
||||
Importing is easy..
|
||||
|
||||
>>> import Cookie
|
||||
|
||||
Most of the time you start by creating a cookie. Cookies come in
|
||||
three flavors, each with slighly different encoding semanitcs, but
|
||||
more on that later.
|
||||
|
||||
>>> C = Cookie.SimpleCookie()
|
||||
>>> C = Cookie.SerialCookie()
|
||||
>>> C = Cookie.SmartCookie()
|
||||
|
||||
[Note: Long-time users of Cookie.py will remember using
|
||||
Cookie.Cookie() to create an Cookie object. Although deprecated, it
|
||||
is still supported by the code. See the Backward Compatibility notes
|
||||
for more information.]
|
||||
|
||||
Once you've created your Cookie, you can add values just as if it were
|
||||
a dictionary.
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C["fig"] = "newton"
|
||||
>>> C["sugar"] = "wafer"
|
||||
>>> print C
|
||||
Set-Cookie: sugar=wafer;
|
||||
Set-Cookie: fig=newton;
|
||||
|
||||
Notice that the printable representation of a Cookie is the
|
||||
appropriate format for a Set-Cookie: header. This is the
|
||||
default behavior. You can change the header and printed
|
||||
attributes by using the the .output() function
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C["rocky"] = "road"
|
||||
>>> C["rocky"]["path"] = "/cookie"
|
||||
>>> print C.output(header="Cookie:")
|
||||
Cookie: rocky=road; Path=/cookie;
|
||||
>>> print C.output(attrs=[], header="Cookie:")
|
||||
Cookie: rocky=road;
|
||||
|
||||
The load() method of a Cookie extracts cookies from a string. In a
|
||||
CGI script, you would use this method to extract the cookies from the
|
||||
HTTP_COOKIE environment variable.
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C.load("chips=ahoy; vienna=finger")
|
||||
>>> print C
|
||||
Set-Cookie: vienna=finger;
|
||||
Set-Cookie: chips=ahoy;
|
||||
|
||||
The load() method is darn-tootin smart about identifying cookies
|
||||
within a string. Escaped quotation marks, nested semicolons, and other
|
||||
such trickeries do not confuse it.
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
|
||||
>>> print C
|
||||
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
|
||||
|
||||
Each element of the Cookie also supports all of the RFC 2109
|
||||
Cookie attributes. Here's an example which sets the Path
|
||||
attribute.
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C["oreo"] = "doublestuff"
|
||||
>>> C["oreo"]["path"] = "/"
|
||||
>>> print C
|
||||
Set-Cookie: oreo="doublestuff"; Path=/;
|
||||
|
||||
Each dictionary element has a 'value' attribute, which gives you
|
||||
back the value associated with the key.
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C["twix"] = "none for you"
|
||||
>>> C["twix"].value
|
||||
'none for you'
|
||||
|
||||
|
||||
A Bit More Advanced
|
||||
-------------------
|
||||
|
||||
As mentioned before, there are three different flavors of Cookie
|
||||
objects, each with different encoding/decoding semantics. This
|
||||
section briefly discusses the differences.
|
||||
|
||||
SimpleCookie
|
||||
|
||||
The SimpleCookie expects that all values should be standard strings.
|
||||
Just to be sure, SimpleCookie invokes the str() builtin to convert
|
||||
the value to a string, when the values are set dictionary-style.
|
||||
|
||||
>>> C = Cookie.SimpleCookie()
|
||||
>>> C["number"] = 7
|
||||
>>> C["string"] = "seven"
|
||||
>>> C["number"].value
|
||||
'7'
|
||||
>>> C["string"].value
|
||||
'seven'
|
||||
>>> print C
|
||||
Set-Cookie: number=7;
|
||||
Set-Cookie: string=seven;
|
||||
|
||||
|
||||
SerialCookie
|
||||
|
||||
The SerialCookie expects that all values should be serialized using
|
||||
cPickle (or pickle, if cPickle isn't available). As a result of
|
||||
serializing, SerialCookie can save almost any Python object to a
|
||||
value, and recover the exact same object when the cookie has been
|
||||
returned. (SerialCookie can yield some strange-looking cookie
|
||||
values, however.)
|
||||
|
||||
>>> C = Cookie.SerialCookie()
|
||||
>>> C["number"] = 7
|
||||
>>> C["string"] = "seven"
|
||||
>>> C["number"].value
|
||||
7
|
||||
>>> C["string"].value
|
||||
'seven'
|
||||
>>> print C
|
||||
Set-Cookie: number="I7\012.";
|
||||
Set-Cookie: string="S'seven'\012p1\012.";
|
||||
|
||||
Be warned, however, if SerialCookie cannot de-serialize a value (because
|
||||
it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
|
||||
|
||||
|
||||
SmartCookie
|
||||
|
||||
The SmartCookie combines aspects of each of the other two flavors.
|
||||
When setting a value in a dictionary-fashion, the SmartCookie will
|
||||
serialize (ala cPickle) the value *if and only if* it isn't a
|
||||
Python string. String objects are *not* serialized. Similarly,
|
||||
when the load() method parses out values, it attempts to de-serialize
|
||||
the value. If it fails, then it fallsback to treating the value
|
||||
as a string.
|
||||
|
||||
>>> C = Cookie.SmartCookie()
|
||||
>>> C["number"] = 7
|
||||
>>> C["string"] = "seven"
|
||||
>>> C["number"].value
|
||||
7
|
||||
>>> C["string"].value
|
||||
'seven'
|
||||
>>> print C
|
||||
Set-Cookie: number="I7\012.";
|
||||
Set-Cookie: string=seven;
|
||||
|
||||
|
||||
Backwards Compatibility
|
||||
-----------------------
|
||||
|
||||
In order to keep compatibilty with earlier versions of Cookie.py,
|
||||
it is still possible to use Cookie.Cookie() to create a Cookie. In
|
||||
fact, this simply returns a SmartCookie.
|
||||
|
||||
>>> C = Cookie.Cookie()
|
||||
>>> C.__class__
|
||||
<class Cookie.SmartCookie at 99f88>
|
||||
|
||||
|
||||
Finis.
|
||||
""" #"
|
||||
# ^
|
||||
# |----helps out font-lock
|
||||
|
||||
#
|
||||
# Import our required modules
|
||||
#
|
||||
import string, sys
|
||||
from UserDict import UserDict
|
||||
|
||||
try:
|
||||
from cPickle import dumps, loads
|
||||
except ImportError:
|
||||
from pickle import dumps, loads
|
||||
|
||||
try:
|
||||
import re
|
||||
except ImportError:
|
||||
raise ImportError, "Cookie.py requires 're' from Python 1.5 or later"
|
||||
|
||||
|
||||
#
|
||||
# Define an exception visible to External modules
|
||||
#
|
||||
class CookieError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# These quoting routines conform to the RFC2109 specification, which in
|
||||
# turn references the character definitions from RFC2068. They provide
|
||||
# a two-way quoting algorithm. Any non-text character is translated
|
||||
# into a 4 character sequence: a forward-slash followed by the
|
||||
# three-digit octal equivalent of the character. Any '\' or '"' is
|
||||
# quoted with a preceeding '\' slash.
|
||||
#
|
||||
# These are taken from RFC2068 and RFC2109.
|
||||
# _LegalChars is the list of chars which don't require "'s
|
||||
# _Translator hash-table for fast quoting
|
||||
#
|
||||
_LegalChars = string.letters + string.digits + "!#$%&'*+-.^_`|~"
|
||||
_Translator = {
|
||||
'\000' : '\\000', '\001' : '\\001', '\002' : '\\002',
|
||||
'\003' : '\\003', '\004' : '\\004', '\005' : '\\005',
|
||||
'\006' : '\\006', '\007' : '\\007', '\010' : '\\010',
|
||||
'\011' : '\\011', '\012' : '\\012', '\013' : '\\013',
|
||||
'\014' : '\\014', '\015' : '\\015', '\016' : '\\016',
|
||||
'\017' : '\\017', '\020' : '\\020', '\021' : '\\021',
|
||||
'\022' : '\\022', '\023' : '\\023', '\024' : '\\024',
|
||||
'\025' : '\\025', '\026' : '\\026', '\027' : '\\027',
|
||||
'\030' : '\\030', '\031' : '\\031', '\032' : '\\032',
|
||||
'\033' : '\\033', '\034' : '\\034', '\035' : '\\035',
|
||||
'\036' : '\\036', '\037' : '\\037',
|
||||
|
||||
'"' : '\\"', '\\' : '\\\\',
|
||||
|
||||
'\177' : '\\177', '\200' : '\\200', '\201' : '\\201',
|
||||
'\202' : '\\202', '\203' : '\\203', '\204' : '\\204',
|
||||
'\205' : '\\205', '\206' : '\\206', '\207' : '\\207',
|
||||
'\210' : '\\210', '\211' : '\\211', '\212' : '\\212',
|
||||
'\213' : '\\213', '\214' : '\\214', '\215' : '\\215',
|
||||
'\216' : '\\216', '\217' : '\\217', '\220' : '\\220',
|
||||
'\221' : '\\221', '\222' : '\\222', '\223' : '\\223',
|
||||
'\224' : '\\224', '\225' : '\\225', '\226' : '\\226',
|
||||
'\227' : '\\227', '\230' : '\\230', '\231' : '\\231',
|
||||
'\232' : '\\232', '\233' : '\\233', '\234' : '\\234',
|
||||
'\235' : '\\235', '\236' : '\\236', '\237' : '\\237',
|
||||
'\240' : '\\240', '\241' : '\\241', '\242' : '\\242',
|
||||
'\243' : '\\243', '\244' : '\\244', '\245' : '\\245',
|
||||
'\246' : '\\246', '\247' : '\\247', '\250' : '\\250',
|
||||
'\251' : '\\251', '\252' : '\\252', '\253' : '\\253',
|
||||
'\254' : '\\254', '\255' : '\\255', '\256' : '\\256',
|
||||
'\257' : '\\257', '\260' : '\\260', '\261' : '\\261',
|
||||
'\262' : '\\262', '\263' : '\\263', '\264' : '\\264',
|
||||
'\265' : '\\265', '\266' : '\\266', '\267' : '\\267',
|
||||
'\270' : '\\270', '\271' : '\\271', '\272' : '\\272',
|
||||
'\273' : '\\273', '\274' : '\\274', '\275' : '\\275',
|
||||
'\276' : '\\276', '\277' : '\\277', '\300' : '\\300',
|
||||
'\301' : '\\301', '\302' : '\\302', '\303' : '\\303',
|
||||
'\304' : '\\304', '\305' : '\\305', '\306' : '\\306',
|
||||
'\307' : '\\307', '\310' : '\\310', '\311' : '\\311',
|
||||
'\312' : '\\312', '\313' : '\\313', '\314' : '\\314',
|
||||
'\315' : '\\315', '\316' : '\\316', '\317' : '\\317',
|
||||
'\320' : '\\320', '\321' : '\\321', '\322' : '\\322',
|
||||
'\323' : '\\323', '\324' : '\\324', '\325' : '\\325',
|
||||
'\326' : '\\326', '\327' : '\\327', '\330' : '\\330',
|
||||
'\331' : '\\331', '\332' : '\\332', '\333' : '\\333',
|
||||
'\334' : '\\334', '\335' : '\\335', '\336' : '\\336',
|
||||
'\337' : '\\337', '\340' : '\\340', '\341' : '\\341',
|
||||
'\342' : '\\342', '\343' : '\\343', '\344' : '\\344',
|
||||
'\345' : '\\345', '\346' : '\\346', '\347' : '\\347',
|
||||
'\350' : '\\350', '\351' : '\\351', '\352' : '\\352',
|
||||
'\353' : '\\353', '\354' : '\\354', '\355' : '\\355',
|
||||
'\356' : '\\356', '\357' : '\\357', '\360' : '\\360',
|
||||
'\361' : '\\361', '\362' : '\\362', '\363' : '\\363',
|
||||
'\364' : '\\364', '\365' : '\\365', '\366' : '\\366',
|
||||
'\367' : '\\367', '\370' : '\\370', '\371' : '\\371',
|
||||
'\372' : '\\372', '\373' : '\\373', '\374' : '\\374',
|
||||
'\375' : '\\375', '\376' : '\\376', '\377' : '\\377'
|
||||
}
|
||||
|
||||
def _quote(str, LegalChars=_LegalChars,
|
||||
join=string.join, idmap=string._idmap, translate=string.translate):
|
||||
#
|
||||
# If the string does not need to be double-quoted,
|
||||
# then just return the string. Otherwise, surround
|
||||
# the string in doublequotes and precede quote (with a \)
|
||||
# special characters.
|
||||
#
|
||||
if "" == translate(str, idmap, LegalChars):
|
||||
return str
|
||||
else:
|
||||
return '"' + join( map(_Translator.get, str, str), "" ) + '"'
|
||||
# end _quote
|
||||
|
||||
|
||||
_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]")
|
||||
_QuotePatt = re.compile(r"[\\].")
|
||||
|
||||
def _unquote(str, join=string.join, atoi=string.atoi):
|
||||
# If there aren't any doublequotes,
|
||||
# then there can't be any special characters. See RFC 2109.
|
||||
if len(str) < 2:
|
||||
return str
|
||||
if str[0] != '"' or str[-1] != '"':
|
||||
return str
|
||||
|
||||
# We have to assume that we must decode this string.
|
||||
# Down to work.
|
||||
|
||||
# Remove the "s
|
||||
str = str[1:-1]
|
||||
|
||||
# Check for special sequences. Examples:
|
||||
# \012 --> \n
|
||||
# \" --> "
|
||||
#
|
||||
i = 0
|
||||
n = len(str)
|
||||
res = []
|
||||
while 0 <= i < n:
|
||||
Omatch = _OctalPatt.search(str, i)
|
||||
Qmatch = _QuotePatt.search(str, i)
|
||||
if not Omatch and not Qmatch: # Neither matched
|
||||
res.append(str[i:])
|
||||
break
|
||||
# else:
|
||||
j = k = -1
|
||||
if Omatch: j = Omatch.start(0)
|
||||
if Qmatch: k = Qmatch.start(0)
|
||||
if Qmatch and ( not Omatch or k < j ): # QuotePatt matched
|
||||
res.append(str[i:k])
|
||||
res.append(str[k+1])
|
||||
i = k+2
|
||||
else: # OctalPatt matched
|
||||
res.append(str[i:j])
|
||||
res.append( chr( atoi(str[j+1:j+4], 8) ) )
|
||||
i = j+4
|
||||
return join(res, "")
|
||||
# end _unquote
|
||||
|
||||
# The _getdate() routine is used to set the expiration time in
|
||||
# the cookie's HTTP header. By default, _getdate() returns the
|
||||
# current time in the appropriate "expires" format for a
|
||||
# Set-Cookie header. The one optional argument is an offset from
|
||||
# now, in seconds. For example, an offset of -3600 means "one hour ago".
|
||||
# The offset may be a floating point number.
|
||||
#
|
||||
|
||||
_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
|
||||
_monthname = [None,
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
|
||||
def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):
|
||||
from time import gmtime, time
|
||||
now = time()
|
||||
year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
|
||||
return "%s, %02d-%3s-%4d %02d:%02d:%02d GMT" % \
|
||||
(weekdayname[wd], day, monthname[month], year, hh, mm, ss)
|
||||
|
||||
|
||||
#
|
||||
# A class to hold ONE key,value pair.
|
||||
# In a cookie, each such pair may have several attributes.
|
||||
# so this class is used to keep the attributes associated
|
||||
# with the appropriate key,value pair.
|
||||
# This class also includes a coded_value attribute, which
|
||||
# is used to hold the network representation of the
|
||||
# value. This is most useful when Python objects are
|
||||
# pickled for network transit.
|
||||
#
|
||||
|
||||
class Morsel(UserDict):
|
||||
# RFC 2109 lists these attributes as reserved:
|
||||
# path comment domain
|
||||
# max-age secure version
|
||||
#
|
||||
# For historical reasons, these attributes are also reserved:
|
||||
# expires
|
||||
#
|
||||
# This dictionary provides a mapping from the lowercase
|
||||
# variant on the left to the appropriate traditional
|
||||
# formatting on the right.
|
||||
_reserved = { "expires" : "expires",
|
||||
"path" : "Path",
|
||||
"comment" : "Comment",
|
||||
"domain" : "Domain",
|
||||
"max-age" : "Max-Age",
|
||||
"secure" : "secure",
|
||||
"version" : "Version",
|
||||
}
|
||||
_reserved_keys = _reserved.keys()
|
||||
|
||||
def __init__(self):
|
||||
# Set defaults
|
||||
self.key = self.value = self.coded_value = None
|
||||
UserDict.__init__(self)
|
||||
|
||||
# Set default attributes
|
||||
for K in self._reserved_keys:
|
||||
UserDict.__setitem__(self, K, "")
|
||||
# end __init__
|
||||
|
||||
def __setitem__(self, K, V):
|
||||
K = string.lower(K)
|
||||
if not K in self._reserved_keys:
|
||||
raise CookieError("Invalid Attribute %s" % K)
|
||||
UserDict.__setitem__(self, K, V)
|
||||
# end __setitem__
|
||||
|
||||
def isReservedKey(self, K):
|
||||
return string.lower(K) in self._reserved_keys
|
||||
# end isReservedKey
|
||||
|
||||
def set(self, key, val, coded_val,
|
||||
LegalChars=_LegalChars,
|
||||
idmap=string._idmap, translate=string.translate ):
|
||||
# First we verify that the key isn't a reserved word
|
||||
# Second we make sure it only contains legal characters
|
||||
if string.lower(key) in self._reserved_keys:
|
||||
raise CookieError("Attempt to set a reserved key: %s" % key)
|
||||
if "" != translate(key, idmap, LegalChars):
|
||||
raise CookieError("Illegal key value: %s" % key)
|
||||
|
||||
# It's a good key, so save it.
|
||||
self.key = key
|
||||
self.value = val
|
||||
self.coded_value = coded_val
|
||||
# end set
|
||||
|
||||
def output(self, attrs=None, header = "Set-Cookie:"):
|
||||
return "%s %s" % ( header, self.OutputString(attrs) )
|
||||
|
||||
__str__ = output
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s=%s>' % (self.__class__.__name__,
|
||||
self.key, repr(self.value) )
|
||||
|
||||
def js_output(self, attrs=None):
|
||||
# Print javascript
|
||||
return """
|
||||
<SCRIPT LANGUAGE="JavaScript">
|
||||
<!-- begin hiding
|
||||
document.cookie = \"%s\"
|
||||
// end hiding -->
|
||||
</script>
|
||||
""" % ( self.OutputString(attrs), )
|
||||
# end js_output()
|
||||
|
||||
def OutputString(self, attrs=None):
|
||||
# Build up our result
|
||||
#
|
||||
result = []
|
||||
RA = result.append
|
||||
|
||||
# First, the key=value pair
|
||||
RA("%s=%s;" % (self.key, self.coded_value))
|
||||
|
||||
# Now add any defined attributes
|
||||
if attrs == None:
|
||||
attrs = self._reserved_keys
|
||||
for K,V in self.items():
|
||||
if V == "": continue
|
||||
if K not in attrs: continue
|
||||
if K == "expires" and type(V) == type(1):
|
||||
RA("%s=%s;" % (self._reserved[K], _getdate(V)))
|
||||
elif K == "max-age" and type(V) == type(1):
|
||||
RA("%s=%d;" % (self._reserved[K], V))
|
||||
elif K == "secure":
|
||||
RA("%s;" % self._reserved[K])
|
||||
else:
|
||||
RA("%s=%s;" % (self._reserved[K], V))
|
||||
|
||||
# Return the result
|
||||
return string.join(result, " ")
|
||||
# end OutputString
|
||||
# end Morsel class
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Pattern for finding cookie
|
||||
#
|
||||
# This used to be strict parsing based on the RFC2109 and RFC2068
|
||||
# specifications. I have since discovered that MSIE 3.0x doesn't
|
||||
# follow the character rules outlined in those specs. As a
|
||||
# result, the parsing rules here are less strict.
|
||||
#
|
||||
|
||||
_LegalCharsPatt = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{]"
|
||||
_CookiePattern = re.compile(
|
||||
r"(?x)" # This is a Verbose pattern
|
||||
r"(?P<key>" # Start of group 'key'
|
||||
""+ _LegalCharsPatt +"+" # Any word of at least one letter
|
||||
r")" # End of group 'key'
|
||||
r"\s*=\s*" # Equal Sign
|
||||
r"(?P<val>" # Start of group 'val'
|
||||
r'"(?:[^\\"]|\\.)*"' # Any doublequoted string
|
||||
r"|" # or
|
||||
""+ _LegalCharsPatt +"*" # Any word or empty string
|
||||
r")" # End of group 'val'
|
||||
r"\s*;?" # Probably ending in a semi-colon
|
||||
)
|
||||
|
||||
|
||||
# At long last, here is the cookie class.
|
||||
# Using this class is almost just like using a dictionary.
|
||||
# See this module's docstring for example usage.
|
||||
#
|
||||
class BaseCookie(UserDict):
|
||||
# A container class for a set of Morsels
|
||||
#
|
||||
|
||||
def value_decode(self, val):
|
||||
"""real_value, coded_value = value_decode(STRING)
|
||||
Called prior to setting a cookie's value from the network
|
||||
representation. The VALUE is the value read from HTTP
|
||||
header.
|
||||
Override this function to modify the behavior of cookies.
|
||||
"""
|
||||
return val, val
|
||||
# end value_encode
|
||||
|
||||
def value_encode(self, val):
|
||||
"""real_value, coded_value = value_encode(VALUE)
|
||||
Called prior to setting a cookie's value from the dictionary
|
||||
representation. The VALUE is the value being assigned.
|
||||
Override this function to modify the behavior of cookies.
|
||||
"""
|
||||
strval = str(val)
|
||||
return strval, strval
|
||||
# end value_encode
|
||||
|
||||
def __init__(self, input=None):
|
||||
UserDict.__init__(self)
|
||||
if input: self.load(input)
|
||||
# end __init__
|
||||
|
||||
def __set(self, key, real_value, coded_value):
|
||||
"""Private method for setting a cookie's value"""
|
||||
M = self.get(key, Morsel())
|
||||
M.set(key, real_value, coded_value)
|
||||
UserDict.__setitem__(self, key, M)
|
||||
# end __set
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
"""Dictionary style assignment."""
|
||||
rval, cval = self.value_encode(value)
|
||||
self.__set(key, rval, cval)
|
||||
# end __setitem__
|
||||
|
||||
def output(self, attrs=None, header="Set-Cookie:", sep="\n"):
|
||||
"""Return a string suitable for HTTP."""
|
||||
result = []
|
||||
for K,V in self.items():
|
||||
result.append( V.output(attrs, header) )
|
||||
return string.join(result, sep)
|
||||
# end output
|
||||
|
||||
__str__ = output
|
||||
|
||||
def __repr__(self):
|
||||
L = []
|
||||
for K,V in self.items():
|
||||
L.append( '%s=%s' % (K,repr(V.value) ) )
|
||||
return '<%s: %s>' % (self.__class__.__name__, string.join(L))
|
||||
|
||||
def js_output(self, attrs=None):
|
||||
"""Return a string suitable for JavaScript."""
|
||||
result = []
|
||||
for K,V in self.items():
|
||||
result.append( V.js_output(attrs) )
|
||||
return string.join(result, "")
|
||||
# end js_output
|
||||
|
||||
def load(self, rawdata):
|
||||
"""Load cookies from a string (presumably HTTP_COOKIE) or
|
||||
from a dictionary. Loading cookies from a dictionary 'd'
|
||||
is equivalent to calling:
|
||||
map(Cookie.__setitem__, d.keys(), d.values())
|
||||
"""
|
||||
if type(rawdata) == type(""):
|
||||
self.__ParseString(rawdata)
|
||||
else:
|
||||
self.update(rawdata)
|
||||
return
|
||||
# end load()
|
||||
|
||||
def __ParseString(self, str, patt=_CookiePattern):
|
||||
i = 0 # Our starting point
|
||||
n = len(str) # Length of string
|
||||
M = None # current morsel
|
||||
|
||||
while 0 <= i < n:
|
||||
# Start looking for a cookie
|
||||
match = patt.search(str, i)
|
||||
if not match: break # No more cookies
|
||||
|
||||
K,V = match.group("key"), match.group("val")
|
||||
i = match.end(0)
|
||||
|
||||
# Parse the key, value in case it's metainfo
|
||||
if K[0] == "$":
|
||||
# We ignore attributes which pertain to the cookie
|
||||
# mechanism as a whole. See RFC 2109.
|
||||
# (Does anyone care?)
|
||||
if M:
|
||||
M[ K[1:] ] = V
|
||||
elif string.lower(K) in Morsel._reserved_keys:
|
||||
if M:
|
||||
M[ K ] = _unquote(V)
|
||||
else:
|
||||
rval, cval = self.value_decode(V)
|
||||
self.__set(K, rval, cval)
|
||||
M = self[K]
|
||||
# end __ParseString
|
||||
# end BaseCookie class
|
||||
|
||||
class SimpleCookie(BaseCookie):
|
||||
"""SimpleCookie
|
||||
SimpleCookie supports strings as cookie values. When setting
|
||||
the value using the dictionary assignment notation, SimpleCookie
|
||||
calls the builtin str() to convert the value to a string. Values
|
||||
received from HTTP are kept as strings.
|
||||
"""
|
||||
def value_decode(self, val):
|
||||
return _unquote( val ), val
|
||||
def value_encode(self, val):
|
||||
strval = str(val)
|
||||
return strval, _quote( strval )
|
||||
# end SimpleCookie
|
||||
|
||||
class SerialCookie(BaseCookie):
|
||||
"""SerialCookie
|
||||
SerialCookie supports arbitrary objects as cookie values. All
|
||||
values are serialized (using cPickle) before being sent to the
|
||||
client. All incoming values are assumed to be valid Pickle
|
||||
representations. IF AN INCOMING VALUE IS NOT IN A VALID PICKLE
|
||||
FORMAT, THEN AN EXCEPTION WILL BE RAISED.
|
||||
|
||||
Note: Large cookie values add overhead because they must be
|
||||
retransmitted on every HTTP transaction.
|
||||
|
||||
Note: HTTP has a 2k limit on the size of a cookie. This class
|
||||
does not check for this limit, so be careful!!!
|
||||
"""
|
||||
def value_decode(self, val):
|
||||
# This could raise an exception!
|
||||
return loads( _unquote(val) ), val
|
||||
def value_encode(self, val):
|
||||
return val, _quote( dumps(val) )
|
||||
# end SerialCookie
|
||||
|
||||
class SmartCookie(BaseCookie):
|
||||
"""SmartCookie
|
||||
SmartCookie supports arbitrary objects as cookie values. If the
|
||||
object is a string, then it is quoted. If the object is not a
|
||||
string, however, then SmartCookie will use cPickle to serialize
|
||||
the object into a string representation.
|
||||
|
||||
Note: Large cookie values add overhead because they must be
|
||||
retransmitted on every HTTP transaction.
|
||||
|
||||
Note: HTTP has a 2k limit on the size of a cookie. This class
|
||||
does not check for this limit, so be careful!!!
|
||||
"""
|
||||
def value_decode(self, val):
|
||||
strval = _unquote(val)
|
||||
try:
|
||||
return loads(strval), val
|
||||
except:
|
||||
return strval, val
|
||||
def value_encode(self, val):
|
||||
if type(val) == type(""):
|
||||
return val, _quote(val)
|
||||
else:
|
||||
return val, _quote( dumps(val) )
|
||||
# end SmartCookie
|
||||
|
||||
|
||||
###########################################################
|
||||
# Backwards Compatibility: Don't break any existing code!
|
||||
|
||||
# We provide Cookie() as an alias for SmartCookie()
|
||||
Cookie = SmartCookie
|
||||
|
||||
#
|
||||
###########################################################
|
||||
|
||||
|
||||
|
||||
#Local Variables:
|
||||
#tab-width: 4
|
||||
#end:
|
|
@ -1,247 +0,0 @@
|
|||
"""Class based built-in exception hierarchy.
|
||||
|
||||
New with Python 1.5, all standard built-in exceptions are now class objects by
|
||||
default. This gives Python's exception handling mechanism a more
|
||||
object-oriented feel. Traditionally they were string objects. Python will
|
||||
fallback to string based exceptions if the interpreter is invoked with the -X
|
||||
option, or if some failure occurs during class exception initialization (in
|
||||
this case a warning will be printed).
|
||||
|
||||
Most existing code should continue to work with class based exceptions. Some
|
||||
tricky uses of IOError may break, but the most common uses should work.
|
||||
|
||||
Here is a rundown of the class hierarchy. You can change this by editing this
|
||||
file, but it isn't recommended because the old string based exceptions won't
|
||||
be kept in sync. The class names described here are expected to be found by
|
||||
the bltinmodule.c file. If you add classes here, you must modify
|
||||
bltinmodule.c or the exceptions won't be available in the __builtin__ module,
|
||||
nor will they be accessible from C.
|
||||
|
||||
The classes with a `*' are new since Python 1.5. They are defined as tuples
|
||||
containing the derived exceptions when string-based exceptions are used. If
|
||||
you define your own class based exceptions, they should be derived from
|
||||
Exception.
|
||||
|
||||
Exception(*)
|
||||
|
|
||||
+-- SystemExit
|
||||
+-- StandardError(*)
|
||||
|
|
||||
+-- KeyboardInterrupt
|
||||
+-- ImportError
|
||||
+-- EnvironmentError(*)
|
||||
| |
|
||||
| +-- IOError
|
||||
| +-- OSError(*)
|
||||
| |
|
||||
| +-- WindowsError(*)
|
||||
|
|
||||
+-- EOFError
|
||||
+-- RuntimeError
|
||||
| |
|
||||
| +-- NotImplementedError(*)
|
||||
|
|
||||
+-- NameError
|
||||
| |
|
||||
| +-- UnboundLocalError(*)
|
||||
|
|
||||
+-- AttributeError
|
||||
+-- SyntaxError
|
||||
+-- TypeError
|
||||
+-- AssertionError
|
||||
+-- LookupError(*)
|
||||
| |
|
||||
| +-- IndexError
|
||||
| +-- KeyError
|
||||
|
|
||||
+-- ArithmeticError(*)
|
||||
| |
|
||||
| +-- OverflowError
|
||||
| +-- ZeroDivisionError
|
||||
| +-- FloatingPointError
|
||||
|
|
||||
+-- ValueError
|
||||
| |
|
||||
| +-- UnicodeError(*)
|
||||
|
|
||||
+-- SystemError
|
||||
+-- MemoryError
|
||||
"""
|
||||
|
||||
class Exception:
|
||||
"""Proposed base class for all exceptions."""
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
|
||||
def __str__(self):
|
||||
if not self.args:
|
||||
return ''
|
||||
elif len(self.args) == 1:
|
||||
return str(self.args[0])
|
||||
else:
|
||||
return str(self.args)
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.args[i]
|
||||
|
||||
class StandardError(Exception):
|
||||
"""Base class for all standard Python exceptions."""
|
||||
pass
|
||||
|
||||
class SyntaxError(StandardError):
|
||||
"""Invalid syntax."""
|
||||
filename = lineno = offset = text = None
|
||||
msg = ""
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
if len(self.args) >= 1:
|
||||
self.msg = self.args[0]
|
||||
if len(self.args) == 2:
|
||||
info = self.args[1]
|
||||
try:
|
||||
self.filename, self.lineno, self.offset, self.text = info
|
||||
except:
|
||||
pass
|
||||
def __str__(self):
|
||||
return str(self.msg)
|
||||
|
||||
class EnvironmentError(StandardError):
|
||||
"""Base class for I/O related errors."""
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
self.errno = None
|
||||
self.strerror = None
|
||||
self.filename = None
|
||||
if len(args) == 3:
|
||||
# open() errors give third argument which is the filename. BUT,
|
||||
# so common in-place unpacking doesn't break, e.g.:
|
||||
#
|
||||
# except IOError, (errno, strerror):
|
||||
#
|
||||
# we hack args so that it only contains two items. This also
|
||||
# means we need our own __str__() which prints out the filename
|
||||
# when it was supplied.
|
||||
self.errno, self.strerror, self.filename = args
|
||||
self.args = args[0:2]
|
||||
if len(args) == 2:
|
||||
# common case: PyErr_SetFromErrno()
|
||||
self.errno, self.strerror = args
|
||||
|
||||
def __str__(self):
|
||||
if self.filename is not None:
|
||||
return '[Errno %s] %s: %s' % (self.errno, self.strerror,
|
||||
repr(self.filename))
|
||||
elif self.errno and self.strerror:
|
||||
return '[Errno %s] %s' % (self.errno, self.strerror)
|
||||
else:
|
||||
return StandardError.__str__(self)
|
||||
|
||||
class IOError(EnvironmentError):
|
||||
"""I/O operation failed."""
|
||||
pass
|
||||
|
||||
class OSError(EnvironmentError):
|
||||
"""OS system call failed."""
|
||||
pass
|
||||
|
||||
class WindowsError(OSError):
|
||||
"""MS-Windows OS system call failed."""
|
||||
pass
|
||||
|
||||
class RuntimeError(StandardError):
|
||||
"""Unspecified run-time error."""
|
||||
pass
|
||||
|
||||
class NotImplementedError(RuntimeError):
|
||||
"""Method or function hasn't been implemented yet."""
|
||||
pass
|
||||
|
||||
class SystemError(StandardError):
|
||||
"""Internal error in the Python interpreter.
|
||||
|
||||
Please report this to the Python maintainer, along with the traceback,
|
||||
the Python version, and the hardware/OS platform and version."""
|
||||
pass
|
||||
|
||||
class EOFError(StandardError):
|
||||
"""Read beyond end of file."""
|
||||
pass
|
||||
|
||||
class ImportError(StandardError):
|
||||
"""Import can't find module, or can't find name in module."""
|
||||
pass
|
||||
|
||||
class TypeError(StandardError):
|
||||
"""Inappropriate argument type."""
|
||||
pass
|
||||
|
||||
class ValueError(StandardError):
|
||||
"""Inappropriate argument value (of correct type)."""
|
||||
pass
|
||||
|
||||
class KeyboardInterrupt(StandardError):
|
||||
"""Program interrupted by user."""
|
||||
pass
|
||||
|
||||
class AssertionError(StandardError):
|
||||
"""Assertion failed."""
|
||||
pass
|
||||
|
||||
class ArithmeticError(StandardError):
|
||||
"""Base class for arithmetic errors."""
|
||||
pass
|
||||
|
||||
class OverflowError(ArithmeticError):
|
||||
"""Result too large to be represented."""
|
||||
pass
|
||||
|
||||
class FloatingPointError(ArithmeticError):
|
||||
"""Floating point operation failed."""
|
||||
pass
|
||||
|
||||
class ZeroDivisionError(ArithmeticError):
|
||||
"""Second argument to a division or modulo operation was zero."""
|
||||
pass
|
||||
|
||||
class LookupError(StandardError):
|
||||
"""Base class for lookup errors."""
|
||||
pass
|
||||
|
||||
class IndexError(LookupError):
|
||||
"""Sequence index out of range."""
|
||||
pass
|
||||
|
||||
class KeyError(LookupError):
|
||||
"""Mapping key not found."""
|
||||
pass
|
||||
|
||||
class AttributeError(StandardError):
|
||||
"""Attribute not found."""
|
||||
pass
|
||||
|
||||
class NameError(StandardError):
|
||||
"""Name not found globally."""
|
||||
pass
|
||||
|
||||
class UnboundLocalError(NameError):
|
||||
"""Local name referenced but not bound to a value."""
|
||||
pass
|
||||
|
||||
class UnicodeError(ValueError):
|
||||
"""Unicode related error."""
|
||||
pass
|
||||
|
||||
class MemoryError(StandardError):
|
||||
"""Out of memory."""
|
||||
pass
|
||||
|
||||
class SystemExit(Exception):
|
||||
"""Request to exit from the interpreter."""
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
if len(args) == 0:
|
||||
self.code = None
|
||||
elif len(args) == 1:
|
||||
self.code = args[0]
|
||||
else:
|
||||
self.code = args
|
|
@ -0,0 +1,202 @@
|
|||
"""Common tests shared by test_string and test_userstring"""
|
||||
|
||||
import string
|
||||
|
||||
transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
|
||||
|
||||
from UserList import UserList
|
||||
|
||||
class Sequence:
|
||||
def __init__(self): self.seq = 'wxyz'
|
||||
def __len__(self): return len(self.seq)
|
||||
def __getitem__(self, i): return self.seq[i]
|
||||
|
||||
class BadSeq1(Sequence):
|
||||
def __init__(self): self.seq = [7, 'hello', 123L]
|
||||
|
||||
class BadSeq2(Sequence):
|
||||
def __init__(self): self.seq = ['a', 'b', 'c']
|
||||
def __len__(self): return 8
|
||||
|
||||
def run_module_tests(test):
|
||||
"""Run all tests that exercise a function in the string module"""
|
||||
|
||||
test('atoi', " 1 ", 1)
|
||||
test('atoi', " 1x", ValueError)
|
||||
test('atoi', " x1 ", ValueError)
|
||||
test('atol', " 1 ", 1L)
|
||||
test('atol', " 1x ", ValueError)
|
||||
test('atol', " x1 ", ValueError)
|
||||
test('atof', " 1 ", 1.0)
|
||||
test('atof', " 1x ", ValueError)
|
||||
test('atof', " x1 ", ValueError)
|
||||
|
||||
test('maketrans', 'abc', transtable, 'xyz')
|
||||
test('maketrans', 'abc', ValueError, 'xyzq')
|
||||
|
||||
# join now works with any sequence type
|
||||
test('join', ['a', 'b', 'c', 'd'], 'a b c d')
|
||||
test('join', ('a', 'b', 'c', 'd'), 'abcd', '')
|
||||
test('join', Sequence(), 'w x y z')
|
||||
test('join', 7, TypeError)
|
||||
|
||||
test('join', BadSeq1(), TypeError)
|
||||
test('join', BadSeq2(), 'a b c')
|
||||
|
||||
# try a few long ones
|
||||
print string.join(['x' * 100] * 100, ':')
|
||||
print string.join(('x' * 100,) * 100, ':')
|
||||
|
||||
|
||||
def run_method_tests(test):
|
||||
"""Run all tests that exercise a method of a string object"""
|
||||
|
||||
test('capitalize', ' hello ', ' hello ')
|
||||
test('capitalize', 'hello ', 'Hello ')
|
||||
test('find', 'abcdefghiabc', 0, 'abc')
|
||||
test('find', 'abcdefghiabc', 9, 'abc', 1)
|
||||
test('find', 'abcdefghiabc', -1, 'def', 4)
|
||||
test('rfind', 'abcdefghiabc', 9, 'abc')
|
||||
test('lower', 'HeLLo', 'hello')
|
||||
test('lower', 'hello', 'hello')
|
||||
test('upper', 'HeLLo', 'HELLO')
|
||||
test('upper', 'HELLO', 'HELLO')
|
||||
|
||||
test('title', ' hello ', ' Hello ')
|
||||
test('title', 'hello ', 'Hello ')
|
||||
test('title', "fOrMaT thIs aS titLe String", 'Format This As Title String')
|
||||
test('title', "fOrMaT,thIs-aS*titLe;String", 'Format,This-As*Title;String')
|
||||
test('title', "getInt", 'Getint')
|
||||
|
||||
test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab def\ng hi')
|
||||
test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab def\ng hi', 8)
|
||||
test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab def\ng hi', 4)
|
||||
test('expandtabs', 'abc\r\nab\tdef\ng\thi', 'abc\r\nab def\ng hi', 4)
|
||||
|
||||
test('islower', 'a', 1)
|
||||
test('islower', 'A', 0)
|
||||
test('islower', '\n', 0)
|
||||
test('islower', 'abc', 1)
|
||||
test('islower', 'aBc', 0)
|
||||
test('islower', 'abc\n', 1)
|
||||
|
||||
test('isupper', 'a', 0)
|
||||
test('isupper', 'A', 1)
|
||||
test('isupper', '\n', 0)
|
||||
test('isupper', 'ABC', 1)
|
||||
test('isupper', 'AbC', 0)
|
||||
test('isupper', 'ABC\n', 1)
|
||||
|
||||
test('istitle', 'a', 0)
|
||||
test('istitle', 'A', 1)
|
||||
test('istitle', '\n', 0)
|
||||
test('istitle', 'A Titlecased Line', 1)
|
||||
test('istitle', 'A\nTitlecased Line', 1)
|
||||
test('istitle', 'A Titlecased, Line', 1)
|
||||
test('istitle', 'Not a capitalized String', 0)
|
||||
test('istitle', 'Not\ta Titlecase String', 0)
|
||||
test('istitle', 'Not--a Titlecase String', 0)
|
||||
|
||||
test('isalpha', 'a', 1)
|
||||
test('isalpha', 'A', 1)
|
||||
test('isalpha', '\n', 0)
|
||||
test('isalpha', 'abc', 1)
|
||||
test('isalpha', 'aBc123', 0)
|
||||
test('isalpha', 'abc\n', 0)
|
||||
|
||||
test('isalnum', 'a', 1)
|
||||
test('isalnum', 'A', 1)
|
||||
test('isalnum', '\n', 0)
|
||||
test('isalnum', '123abc456', 1)
|
||||
test('isalnum', 'a1b3c', 1)
|
||||
test('isalnum', 'aBc000 ', 0)
|
||||
test('isalnum', 'abc\n', 0)
|
||||
|
||||
# join now works with any sequence type
|
||||
test('join', ' ', 'a b c d', ['a', 'b', 'c', 'd'])
|
||||
test('join', '', 'abcd', ('a', 'b', 'c', 'd'))
|
||||
test('join', ' ', 'w x y z', Sequence())
|
||||
test('join', 'a', 'abc', ('abc',))
|
||||
test('join', 'a', 'z', UserList(['z']))
|
||||
test('join', u'.', u'a.b.c', ['a', 'b', 'c'])
|
||||
test('join', '.', u'a.b.c', [u'a', 'b', 'c'])
|
||||
test('join', '.', u'a.b.c', ['a', u'b', 'c'])
|
||||
test('join', '.', u'a.b.c', ['a', 'b', u'c'])
|
||||
test('join', '.', TypeError, ['a', u'b', 3])
|
||||
for i in [5, 25, 125]:
|
||||
test('join', '-', ((('a' * i) + '-') * i)[:-1],
|
||||
['a' * i] * i)
|
||||
|
||||
test('join', ' ', TypeError, BadSeq1())
|
||||
test('join', ' ', 'a b c', BadSeq2())
|
||||
|
||||
test('splitlines', "abc\ndef\n\rghi", ['abc', 'def', '', 'ghi'])
|
||||
test('splitlines', "abc\ndef\n\r\nghi", ['abc', 'def', '', 'ghi'])
|
||||
test('splitlines', "abc\ndef\r\nghi", ['abc', 'def', 'ghi'])
|
||||
test('splitlines', "abc\ndef\r\nghi\n", ['abc', 'def', 'ghi'])
|
||||
test('splitlines', "abc\ndef\r\nghi\n\r", ['abc', 'def', 'ghi', ''])
|
||||
test('splitlines', "\nabc\ndef\r\nghi\n\r", ['', 'abc', 'def', 'ghi', ''])
|
||||
test('splitlines', "\nabc\ndef\r\nghi\n\r", ['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], 1)
|
||||
|
||||
test('split', 'this is the split function',
|
||||
['this', 'is', 'the', 'split', 'function'])
|
||||
test('split', 'a|b|c|d', ['a', 'b', 'c', 'd'], '|')
|
||||
test('split', 'a|b|c|d', ['a', 'b', 'c|d'], '|', 2)
|
||||
test('split', 'a b c d', ['a', 'b c d'], None, 1)
|
||||
test('split', 'a b c d', ['a', 'b', 'c d'], None, 2)
|
||||
test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 3)
|
||||
test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 4)
|
||||
test('split', 'a b c d', ['a b c d'], None, 0)
|
||||
test('split', 'a b c d', ['a', 'b', 'c d'], None, 2)
|
||||
test('split', 'a b c d ', ['a', 'b', 'c', 'd'])
|
||||
|
||||
test('strip', ' hello ', 'hello')
|
||||
test('lstrip', ' hello ', 'hello ')
|
||||
test('rstrip', ' hello ', ' hello')
|
||||
test('strip', 'hello', 'hello')
|
||||
|
||||
test('swapcase', 'HeLLo cOmpUteRs', 'hEllO CoMPuTErS')
|
||||
test('translate', 'xyzabcdef', 'xyzxyz', transtable, 'def')
|
||||
|
||||
table = string.maketrans('a', 'A')
|
||||
test('translate', 'abc', 'Abc', table)
|
||||
test('translate', 'xyz', 'xyz', table)
|
||||
|
||||
test('replace', 'one!two!three!', 'one@two!three!', '!', '@', 1)
|
||||
test('replace', 'one!two!three!', 'onetwothree', '!', '')
|
||||
test('replace', 'one!two!three!', 'one@two@three!', '!', '@', 2)
|
||||
test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 3)
|
||||
test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 4)
|
||||
test('replace', 'one!two!three!', 'one!two!three!', '!', '@', 0)
|
||||
test('replace', 'one!two!three!', 'one@two@three@', '!', '@')
|
||||
test('replace', 'one!two!three!', 'one!two!three!', 'x', '@')
|
||||
test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2)
|
||||
|
||||
test('startswith', 'hello', 1, 'he')
|
||||
test('startswith', 'hello', 1, 'hello')
|
||||
test('startswith', 'hello', 0, 'hello world')
|
||||
test('startswith', 'hello', 1, '')
|
||||
test('startswith', 'hello', 0, 'ello')
|
||||
test('startswith', 'hello', 1, 'ello', 1)
|
||||
test('startswith', 'hello', 1, 'o', 4)
|
||||
test('startswith', 'hello', 0, 'o', 5)
|
||||
test('startswith', 'hello', 1, '', 5)
|
||||
test('startswith', 'hello', 0, 'lo', 6)
|
||||
test('startswith', 'helloworld', 1, 'lowo', 3)
|
||||
test('startswith', 'helloworld', 1, 'lowo', 3, 7)
|
||||
test('startswith', 'helloworld', 0, 'lowo', 3, 6)
|
||||
|
||||
test('endswith', 'hello', 1, 'lo')
|
||||
test('endswith', 'hello', 0, 'he')
|
||||
test('endswith', 'hello', 1, '')
|
||||
test('endswith', 'hello', 0, 'hello world')
|
||||
test('endswith', 'helloworld', 0, 'worl')
|
||||
test('endswith', 'helloworld', 1, 'worl', 3, 9)
|
||||
test('endswith', 'helloworld', 1, 'world', 3, 12)
|
||||
test('endswith', 'helloworld', 1, 'lowo', 1, 7)
|
||||
test('endswith', 'helloworld', 1, 'lowo', 2, 7)
|
||||
test('endswith', 'helloworld', 1, 'lowo', 3, 7)
|
||||
test('endswith', 'helloworld', 0, 'lowo', 4, 7)
|
||||
test('endswith', 'helloworld', 0, 'lowo', 3, 8)
|
||||
test('endswith', 'ab', 0, 'ab', 0, 1)
|
||||
test('endswith', 'ab', 0, 'ab', 0, 0)
|
|
@ -0,0 +1,232 @@
|
|||
|
||||
# Augmented assignment test.
|
||||
|
||||
x = 2
|
||||
x += 1
|
||||
x *= 2
|
||||
x **= 2
|
||||
x -= 8
|
||||
x /= 2
|
||||
x %= 12
|
||||
x &= 2
|
||||
x |= 5
|
||||
x ^= 1
|
||||
|
||||
print x
|
||||
|
||||
x = [2]
|
||||
x[0] += 1
|
||||
x[0] *= 2
|
||||
x[0] **= 2
|
||||
x[0] -= 8
|
||||
x[0] /= 2
|
||||
x[0] %= 12
|
||||
x[0] &= 2
|
||||
x[0] |= 5
|
||||
x[0] ^= 1
|
||||
|
||||
print x
|
||||
|
||||
x = {0: 2}
|
||||
x[0] += 1
|
||||
x[0] *= 2
|
||||
x[0] **= 2
|
||||
x[0] -= 8
|
||||
x[0] /= 2
|
||||
x[0] %= 12
|
||||
x[0] &= 2
|
||||
x[0] |= 5
|
||||
x[0] ^= 1
|
||||
|
||||
print x[0]
|
||||
|
||||
x = [1,2]
|
||||
x += [3,4]
|
||||
x *= 2
|
||||
|
||||
print x
|
||||
|
||||
x = [1, 2, 3]
|
||||
y = x
|
||||
x[1:2] *= 2
|
||||
y[1:2] += [1]
|
||||
|
||||
print x
|
||||
print x is y
|
||||
|
||||
class aug_test:
|
||||
def __init__(self, value):
|
||||
self.val = value
|
||||
def __radd__(self, val):
|
||||
return self.val + val
|
||||
def __add__(self, val):
|
||||
return aug_test(self.val + val)
|
||||
|
||||
|
||||
class aug_test2(aug_test):
|
||||
def __iadd__(self, val):
|
||||
self.val = self.val + val
|
||||
return self
|
||||
|
||||
class aug_test3(aug_test):
|
||||
def __iadd__(self, val):
|
||||
return aug_test3(self.val + val)
|
||||
|
||||
x = aug_test(1)
|
||||
y = x
|
||||
x += 10
|
||||
|
||||
print isinstance(x, aug_test)
|
||||
print y is not x
|
||||
print x.val
|
||||
|
||||
x = aug_test2(2)
|
||||
y = x
|
||||
x += 10
|
||||
|
||||
print y is x
|
||||
print x.val
|
||||
|
||||
x = aug_test3(3)
|
||||
y = x
|
||||
x += 10
|
||||
|
||||
print isinstance(x, aug_test3)
|
||||
print y is not x
|
||||
print x.val
|
||||
|
||||
class testall:
|
||||
|
||||
def __add__(self, val):
|
||||
print "__add__ called"
|
||||
def __radd__(self, val):
|
||||
print "__radd__ called"
|
||||
def __iadd__(self, val):
|
||||
print "__iadd__ called"
|
||||
return self
|
||||
|
||||
def __sub__(self, val):
|
||||
print "__sub__ called"
|
||||
def __rsub__(self, val):
|
||||
print "__rsub__ called"
|
||||
def __isub__(self, val):
|
||||
print "__isub__ called"
|
||||
return self
|
||||
|
||||
def __mul__(self, val):
|
||||
print "__mul__ called"
|
||||
def __rmul__(self, val):
|
||||
print "__rmul__ called"
|
||||
def __imul__(self, val):
|
||||
print "__imul__ called"
|
||||
return self
|
||||
|
||||
def __div__(self, val):
|
||||
print "__div__ called"
|
||||
def __rdiv__(self, val):
|
||||
print "__rdiv__ called"
|
||||
def __idiv__(self, val):
|
||||
print "__idiv__ called"
|
||||
return self
|
||||
|
||||
def __mod__(self, val):
|
||||
print "__mod__ called"
|
||||
def __rmod__(self, val):
|
||||
print "__rmod__ called"
|
||||
def __imod__(self, val):
|
||||
print "__imod__ called"
|
||||
return self
|
||||
|
||||
def __pow__(self, val):
|
||||
print "__pow__ called"
|
||||
def __rpow__(self, val):
|
||||
print "__rpow__ called"
|
||||
def __ipow__(self, val):
|
||||
print "__ipow__ called"
|
||||
return self
|
||||
|
||||
def __or__(self, val):
|
||||
print "__or__ called"
|
||||
def __ror__(self, val):
|
||||
print "__ror__ called"
|
||||
def __ior__(self, val):
|
||||
print "__ior__ called"
|
||||
return self
|
||||
|
||||
def __and__(self, val):
|
||||
print "__and__ called"
|
||||
def __rand__(self, val):
|
||||
print "__rand__ called"
|
||||
def __iand__(self, val):
|
||||
print "__iand__ called"
|
||||
return self
|
||||
|
||||
def __xor__(self, val):
|
||||
print "__xor__ called"
|
||||
def __rxor__(self, val):
|
||||
print "__rxor__ called"
|
||||
def __ixor__(self, val):
|
||||
print "__ixor__ called"
|
||||
return self
|
||||
|
||||
def __rshift__(self, val):
|
||||
print "__rshift__ called"
|
||||
def __rrshift__(self, val):
|
||||
print "__rrshift__ called"
|
||||
def __irshift__(self, val):
|
||||
print "__irshift__ called"
|
||||
return self
|
||||
|
||||
def __lshift__(self, val):
|
||||
print "__lshift__ called"
|
||||
def __rlshift__(self, val):
|
||||
print "__rlshift__ called"
|
||||
def __ilshift__(self, val):
|
||||
print "__ilshift__ called"
|
||||
return self
|
||||
|
||||
x = testall()
|
||||
x + 1
|
||||
1 + x
|
||||
x += 1
|
||||
|
||||
x - 1
|
||||
1 - x
|
||||
x -= 1
|
||||
|
||||
x * 1
|
||||
1 * x
|
||||
x *= 1
|
||||
|
||||
x / 1
|
||||
1 / x
|
||||
x /= 1
|
||||
|
||||
x % 1
|
||||
1 % x
|
||||
x %= 1
|
||||
|
||||
x ** 1
|
||||
1 ** x
|
||||
x **= 1
|
||||
|
||||
x | 1
|
||||
1 | x
|
||||
x |= 1
|
||||
|
||||
x & 1
|
||||
1 & x
|
||||
x &= 1
|
||||
|
||||
x ^ 1
|
||||
1 ^ x
|
||||
x ^= 1
|
||||
|
||||
x >> 1
|
||||
1 >> x
|
||||
x >>= 1
|
||||
|
||||
x << 1
|
||||
1 << x
|
||||
x <<= 1
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
"Test the functionality of Python classes implementing operators."
|
||||
|
||||
|
||||
testmeths = [
|
||||
|
||||
# Binary operations
|
||||
"add",
|
||||
"radd",
|
||||
"sub",
|
||||
"rsub",
|
||||
"mul",
|
||||
"rmul",
|
||||
"div",
|
||||
"rdiv",
|
||||
"mod",
|
||||
"rmod",
|
||||
"divmod",
|
||||
"rdivmod",
|
||||
"pow",
|
||||
"rpow",
|
||||
"rshift",
|
||||
"rrshift",
|
||||
"lshift",
|
||||
"rlshift",
|
||||
"and",
|
||||
"rand",
|
||||
"or",
|
||||
"ror",
|
||||
"xor",
|
||||
"rxor",
|
||||
|
||||
# List/dict operations
|
||||
"contains",
|
||||
"getitem",
|
||||
"getslice",
|
||||
"setitem",
|
||||
"setslice",
|
||||
"delitem",
|
||||
"delslice",
|
||||
|
||||
# Unary operations
|
||||
"neg",
|
||||
"pos",
|
||||
"abs",
|
||||
"int",
|
||||
"long",
|
||||
"float",
|
||||
"oct",
|
||||
"hex",
|
||||
|
||||
# generic operations
|
||||
"init",
|
||||
"del",
|
||||
]
|
||||
|
||||
# These need to return something other than None
|
||||
# "coerce",
|
||||
# "hash",
|
||||
# "str",
|
||||
# "repr",
|
||||
|
||||
# These are separate because they can influence the test of other methods.
|
||||
# "getattr",
|
||||
# "setattr",
|
||||
# "delattr",
|
||||
|
||||
class AllTests:
|
||||
def __coerce__(self, *args):
|
||||
print "__coerce__:", args
|
||||
return (self,) + args
|
||||
|
||||
def __hash__(self, *args):
|
||||
print "__hash__:", args
|
||||
return id(self)
|
||||
|
||||
def __str__(self, *args):
|
||||
print "__str__:", args
|
||||
return "AllTests"
|
||||
|
||||
def __repr__(self, *args):
|
||||
print "__repr__:", args
|
||||
return "AllTests"
|
||||
|
||||
def __cmp__(self, *args):
|
||||
print "__cmp__:", args
|
||||
return 0
|
||||
|
||||
for method in testmeths:
|
||||
exec("""def __%(method)s__(self, *args):
|
||||
print "__%(method)s__:", args
|
||||
"""%locals(), AllTests.__dict__);
|
||||
|
||||
# this also tests __init__ of course.
|
||||
testme = AllTests()
|
||||
|
||||
# Binary operations
|
||||
|
||||
testme + 1
|
||||
1 + testme
|
||||
|
||||
testme - 1
|
||||
1 - testme
|
||||
|
||||
testme * 1
|
||||
1 * testme
|
||||
|
||||
testme / 1
|
||||
1 / testme
|
||||
|
||||
testme % 1
|
||||
1 % testme
|
||||
|
||||
divmod(testme,1)
|
||||
divmod(1, testme)
|
||||
|
||||
testme ** 1
|
||||
1 ** testme
|
||||
|
||||
testme >> 1
|
||||
1 >> testme
|
||||
|
||||
testme << 1
|
||||
1 << testme
|
||||
|
||||
testme & 1
|
||||
1 & testme
|
||||
|
||||
testme | 1
|
||||
1 | testme
|
||||
|
||||
testme ^ 1
|
||||
1 ^ testme
|
||||
|
||||
|
||||
# List/dict operations
|
||||
|
||||
1 in testme
|
||||
|
||||
testme[1]
|
||||
testme[1] = 1
|
||||
del testme[1]
|
||||
|
||||
testme[:42]
|
||||
testme[:42] = "The Answer"
|
||||
del testme[:42]
|
||||
|
||||
testme[2:1024:10]
|
||||
testme[2:1024:10] = "A lot"
|
||||
del testme[2:1024:10]
|
||||
|
||||
testme[:42, ..., :24:, 24, 100]
|
||||
testme[:42, ..., :24:, 24, 100] = "Strange"
|
||||
del testme[:42, ..., :24:, 24, 100]
|
||||
|
||||
|
||||
# Now remove the slice hooks to see if converting normal slices to slice
|
||||
# object works.
|
||||
|
||||
del AllTests.__getslice__
|
||||
del AllTests.__setslice__
|
||||
del AllTests.__delslice__
|
||||
|
||||
testme[:42]
|
||||
testme[:42] = "The Answer"
|
||||
del testme[:42]
|
||||
|
||||
|
||||
# Unary operations
|
||||
|
||||
-testme
|
||||
+testme
|
||||
abs(testme)
|
||||
int(testme)
|
||||
long(testme)
|
||||
float(testme)
|
||||
oct(testme)
|
||||
hex(testme)
|
||||
|
||||
|
||||
# And the rest...
|
||||
|
||||
hash(testme)
|
||||
repr(testme)
|
||||
str(testme)
|
||||
|
||||
testme == 1
|
||||
testme < 1
|
||||
testme > 1
|
||||
testme <> 1
|
||||
testme != 1
|
||||
1 == testme
|
||||
1 < testme
|
||||
1 > testme
|
||||
1 <> testme
|
||||
1 != testme
|
||||
|
||||
# This test has to be last (duh.)
|
||||
|
||||
del testme
|
||||
|
||||
|
||||
# Interfering tests
|
||||
|
||||
class ExtraTests:
|
||||
def __getattr__(self, *args):
|
||||
print "__getattr__:", args
|
||||
return "SomeVal"
|
||||
|
||||
def __setattr__(self, *args):
|
||||
print "__setattr__:", args
|
||||
|
||||
def __delattr__(self, *args):
|
||||
print "__delattr__:", args
|
||||
|
||||
testme = ExtraTests()
|
||||
testme.spam
|
||||
testme.eggs = "spam, spam, spam and ham"
|
||||
del testme.cardinal
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
from test_support import verbose, TestFailed
|
||||
|
||||
if verbose:
|
||||
print 'Running test on duplicate arguments'
|
||||
|
||||
try:
|
||||
exec('def f(a, a): pass')
|
||||
raise TestFailed, "duplicate arguments"
|
||||
except SyntaxError:
|
||||
pass
|
||||
|
||||
try:
|
||||
exec('def f(a = 0, a = 1): pass')
|
||||
raise TestFailed, "duplicate keyword arguments"
|
||||
except SyntaxError:
|
||||
pass
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
# Simple test suite for Cookie.py
|
||||
|
||||
import Cookie
|
||||
|
||||
# Currently this only tests SimpleCookie
|
||||
|
||||
cases = [
|
||||
('chips=ahoy; vienna=finger', {'chips':'ahoy', 'vienna':'finger'}),
|
||||
('keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;";',
|
||||
{'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}),
|
||||
]
|
||||
|
||||
for data, dict in cases:
|
||||
C = Cookie.SimpleCookie() ; C.load(data)
|
||||
print repr(C)
|
||||
print str(C)
|
||||
for k, v in dict.items():
|
||||
print ' ', k, repr( C[k].value ), repr(v)
|
||||
assert C[k].value == v
|
||||
print C[k]
|
||||
|
||||
C = Cookie.SimpleCookie()
|
||||
C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
|
||||
|
||||
assert C['Customer'].value == 'WILE_E_COYOTE'
|
||||
assert C['Customer']['version'] == '1'
|
||||
assert C['Customer']['path'] == '/acme'
|
||||
|
||||
print C.output(['path'])
|
||||
print C.js_output()
|
||||
print C.js_output(['path'])
|
||||
|
||||
# Try cookie with quoted meta-data
|
||||
C = Cookie.SimpleCookie()
|
||||
C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
|
||||
assert C['Customer'].value == 'WILE_E_COYOTE'
|
||||
assert C['Customer']['version'] == '1'
|
||||
assert C['Customer']['path'] == '/acme'
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import dospath
|
||||
import string
|
||||
import os
|
||||
|
||||
errors = 0
|
||||
|
||||
def tester(fn, wantResult):
|
||||
fn = string.replace(fn, "\\", "\\\\")
|
||||
gotResult = eval(fn)
|
||||
if wantResult != gotResult:
|
||||
print "error!"
|
||||
print "evaluated: " + str(fn)
|
||||
print "should be: " + str(wantResult)
|
||||
print " returned: " + str(gotResult)
|
||||
print ""
|
||||
global errors
|
||||
errors = errors + 1
|
||||
|
||||
tester('dospath.splitdrive("c:\\foo\\bar")', ('c:', '\\foo\\bar'))
|
||||
tester('dospath.splitdrive("c:/foo/bar")', ('c:', '/foo/bar'))
|
||||
|
||||
tester('dospath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
|
||||
tester('dospath.split("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint\\foo', 'bar'))
|
||||
|
||||
tester('dospath.split("c:\\")', ('c:\\', ''))
|
||||
tester('dospath.split("\\\\conky\\mountpoint\\")', ('\\\\conky\\mountpoint', ''))
|
||||
|
||||
tester('dospath.split("c:/")', ('c:/', ''))
|
||||
tester('dospath.split("//conky/mountpoint/")', ('//conky/mountpoint', ''))
|
||||
|
||||
tester('dospath.isabs("c:\\")', 1)
|
||||
tester('dospath.isabs("\\\\conky\\mountpoint\\")', 1)
|
||||
tester('dospath.isabs("\\foo")', 1)
|
||||
tester('dospath.isabs("\\foo\\bar")', 1)
|
||||
|
||||
tester('dospath.abspath("C:\\")', "C:\\")
|
||||
|
||||
tester('dospath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
|
||||
"/home/swen")
|
||||
tester('dospath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
|
||||
"\\home\\swen\\")
|
||||
tester('dospath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
|
||||
"/home/swen/spam")
|
||||
|
||||
if errors:
|
||||
print str(errors) + " errors."
|
||||
else:
|
||||
print "No errors. Thank your lucky stars."
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
from test_support import TESTFN
|
||||
from UserList import UserList
|
||||
|
||||
# verify writelines with instance sequence
|
||||
l = UserList(['1', '2'])
|
||||
f = open(TESTFN, 'wb')
|
||||
f.writelines(l)
|
||||
f.close()
|
||||
f = open(TESTFN, 'rb')
|
||||
buf = f.read()
|
||||
f.close()
|
||||
assert buf == '12'
|
||||
|
||||
# verify writelines with integers
|
||||
f = open(TESTFN, 'wb')
|
||||
try:
|
||||
f.writelines([1, 2, 3])
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
print "writelines accepted sequence of integers"
|
||||
f.close()
|
||||
|
||||
# verify writelines with integers in UserList
|
||||
f = open(TESTFN, 'wb')
|
||||
l = UserList([1,2,3])
|
||||
try:
|
||||
f.writelines(l)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
print "writelines accepted sequence of integers"
|
||||
f.close()
|
||||
|
||||
# verify writelines with non-string object
|
||||
class NonString: pass
|
||||
|
||||
f = open(TESTFN, 'wb')
|
||||
try:
|
||||
f.writelines([NonString(), NonString()])
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
print "writelines accepted sequence of non-string objects"
|
||||
f.close()
|
|
@ -0,0 +1,101 @@
|
|||
# test_getopt.py
|
||||
# David Goodger <dgoodger@bigfoot.com> 2000-08-19
|
||||
|
||||
import getopt
|
||||
from getopt import GetoptError
|
||||
from test_support import verbose
|
||||
|
||||
def expectException(teststr, expected, failure=AssertionError):
|
||||
"""Executes a statement passed in teststr, and raises an exception
|
||||
(failure) if the expected exception is *not* raised."""
|
||||
try:
|
||||
exec teststr
|
||||
except expected:
|
||||
pass
|
||||
else:
|
||||
raise failure
|
||||
|
||||
if verbose:
|
||||
print 'Running tests on getopt.short_has_arg'
|
||||
assert getopt.short_has_arg('a', 'a:')
|
||||
assert not getopt.short_has_arg('a', 'a')
|
||||
expectException("tmp = getopt.short_has_arg('a', 'b')", GetoptError)
|
||||
expectException("tmp = getopt.short_has_arg('a', '')", GetoptError)
|
||||
|
||||
if verbose:
|
||||
print 'Running tests on getopt.long_has_args'
|
||||
has_arg, option = getopt.long_has_args('abc', ['abc='])
|
||||
assert has_arg
|
||||
assert option == 'abc'
|
||||
has_arg, option = getopt.long_has_args('abc', ['abc'])
|
||||
assert not has_arg
|
||||
assert option == 'abc'
|
||||
has_arg, option = getopt.long_has_args('abc', ['abcd'])
|
||||
assert not has_arg
|
||||
assert option == 'abcd'
|
||||
expectException("has_arg, option = getopt.long_has_args('abc', ['def'])",
|
||||
GetoptError)
|
||||
expectException("has_arg, option = getopt.long_has_args('abc', [])",
|
||||
GetoptError)
|
||||
expectException("has_arg, option = " + \
|
||||
"getopt.long_has_args('abc', ['abcd','abcde'])",
|
||||
GetoptError)
|
||||
|
||||
if verbose:
|
||||
print 'Running tests on getopt.do_shorts'
|
||||
opts, args = getopt.do_shorts([], 'a', 'a', [])
|
||||
assert opts == [('-a', '')]
|
||||
assert args == []
|
||||
opts, args = getopt.do_shorts([], 'a1', 'a:', [])
|
||||
assert opts == [('-a', '1')]
|
||||
assert args == []
|
||||
#opts, args = getopt.do_shorts([], 'a=1', 'a:', [])
|
||||
#assert opts == [('-a', '1')]
|
||||
#assert args == []
|
||||
opts, args = getopt.do_shorts([], 'a', 'a:', ['1'])
|
||||
assert opts == [('-a', '1')]
|
||||
assert args == []
|
||||
opts, args = getopt.do_shorts([], 'a', 'a:', ['1', '2'])
|
||||
assert opts == [('-a', '1')]
|
||||
assert args == ['2']
|
||||
expectException("opts, args = getopt.do_shorts([], 'a1', 'a', [])",
|
||||
GetoptError)
|
||||
expectException("opts, args = getopt.do_shorts([], 'a', 'a:', [])",
|
||||
GetoptError)
|
||||
|
||||
if verbose:
|
||||
print 'Running tests on getopt.do_longs'
|
||||
opts, args = getopt.do_longs([], 'abc', ['abc'], [])
|
||||
assert opts == [('--abc', '')]
|
||||
assert args == []
|
||||
opts, args = getopt.do_longs([], 'abc=1', ['abc='], [])
|
||||
assert opts == [('--abc', '1')]
|
||||
assert args == []
|
||||
opts, args = getopt.do_longs([], 'abc=1', ['abcd='], [])
|
||||
assert opts == [('--abcd', '1')]
|
||||
assert args == []
|
||||
expectException("opts, args = getopt.do_longs([], 'abc=1', ['abc'], [])",
|
||||
GetoptError)
|
||||
expectException("opts, args = getopt.do_longs([], 'abc', ['abc='], [])",
|
||||
GetoptError)
|
||||
|
||||
# note: the empty string between '-a' and '--beta' is significant:
|
||||
# it simulates an empty string option argument ('-a ""') on the command line.
|
||||
cmdline = ['-a', '1', '-b', '--alpha=2', '--beta', '-a', '3', '-a', '',
|
||||
'--beta', 'arg1', 'arg2']
|
||||
|
||||
if verbose:
|
||||
print 'Running tests on getopt.getopt'
|
||||
opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta'])
|
||||
assert opts == [('-a', '1'), ('-b', ''), ('--alpha', '2'), ('--beta', ''),
|
||||
('-a', '3'), ('-a', ''), ('--beta', '')]
|
||||
# Note ambiguity of ('-b', '') and ('-a', '') above. This must be
|
||||
# accounted for in the code that calls getopt().
|
||||
assert args == ['arg1', 'arg2']
|
||||
|
||||
expectException(
|
||||
"opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])",
|
||||
GetoptError)
|
||||
|
||||
if verbose:
|
||||
print "Module getopt: tests completed successfully."
|
|
@ -0,0 +1,129 @@
|
|||
#!python
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# test largefile support on system where this makes sense
|
||||
#
|
||||
#XXX how to only run this when support is there
|
||||
#XXX how to only optionally run this, it will take along time
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
import test_support
|
||||
import os, struct, stat, sys
|
||||
|
||||
|
||||
# only run if the current system support large files
|
||||
f = open(test_support.TESTFN, 'w')
|
||||
try:
|
||||
# 2**31 == 2147483648
|
||||
f.seek(2147483649L)
|
||||
except OverflowError:
|
||||
raise test_support.TestSkipped, "platform does not have largefile support"
|
||||
else:
|
||||
f.close()
|
||||
|
||||
|
||||
# create >2GB file (2GB = 2147483648 bytes)
|
||||
size = 2500000000L
|
||||
name = test_support.TESTFN
|
||||
|
||||
|
||||
# on Windows this test comsumes large resources:
|
||||
# it takes a long time to build the >2GB file and takes >2GB of disk space
|
||||
# therefore test_support.use_large_resources must be defined to run this test
|
||||
if sys.platform[:3] == 'win' and not test_support.use_large_resources:
|
||||
raise test_support.TestSkipped, \
|
||||
"test requires %s bytes and a long time to run" % str(size)
|
||||
|
||||
|
||||
|
||||
def expect(got_this, expect_this):
|
||||
if test_support.verbose:
|
||||
print '%s =?= %s ...' % (`got_this`, `expect_this`),
|
||||
if got_this != expect_this:
|
||||
if test_support.verbose:
|
||||
print 'no'
|
||||
raise test_support.TestFailed, 'got %s, but expected %s' %\
|
||||
(str(got_this), str(expect_this))
|
||||
else:
|
||||
if test_support.verbose:
|
||||
print 'yes'
|
||||
|
||||
|
||||
# test that each file function works as expected for a large (i.e. >2GB, do
|
||||
# we have to check >4GB) files
|
||||
|
||||
if test_support.verbose:
|
||||
print 'create large file via seek (may be sparse file) ...'
|
||||
f = open(name, 'w')
|
||||
f.seek(size)
|
||||
f.write('a')
|
||||
f.flush()
|
||||
expect(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
|
||||
if test_support.verbose:
|
||||
print 'check file size with os.fstat'
|
||||
f.close()
|
||||
if test_support.verbose:
|
||||
print 'check file size with os.stat'
|
||||
expect(os.stat(name)[stat.ST_SIZE], size+1)
|
||||
|
||||
if test_support.verbose:
|
||||
print 'play around with seek() and read() with the built largefile'
|
||||
f = open(name, 'r')
|
||||
expect(f.tell(), 0)
|
||||
expect(f.read(1), '\000')
|
||||
expect(f.tell(), 1)
|
||||
f.seek(0)
|
||||
expect(f.tell(), 0)
|
||||
f.seek(0, 0)
|
||||
expect(f.tell(), 0)
|
||||
f.seek(42)
|
||||
expect(f.tell(), 42)
|
||||
f.seek(42, 0)
|
||||
expect(f.tell(), 42)
|
||||
f.seek(42, 1)
|
||||
expect(f.tell(), 84)
|
||||
f.seek(0, 1)
|
||||
expect(f.tell(), 84)
|
||||
f.seek(0, 2) # seek from the end
|
||||
expect(f.tell(), size + 1 + 0)
|
||||
f.seek(-10, 2)
|
||||
expect(f.tell(), size + 1 - 10)
|
||||
f.seek(-size-1, 2)
|
||||
expect(f.tell(), 0)
|
||||
f.seek(size)
|
||||
expect(f.tell(), size)
|
||||
expect(f.read(1), 'a') # the 'a' that was written at the end of the file above
|
||||
f.close()
|
||||
|
||||
if test_support.verbose:
|
||||
print 'play around with os.lseek() with the built largefile'
|
||||
f = open(name, 'r')
|
||||
expect(os.lseek(f.fileno(), 0, 0), 0)
|
||||
expect(os.lseek(f.fileno(), 42, 0), 42)
|
||||
expect(os.lseek(f.fileno(), 42, 1), 84)
|
||||
expect(os.lseek(f.fileno(), 0, 1), 84)
|
||||
expect(os.lseek(f.fileno(), 0, 2), size+1+0)
|
||||
expect(os.lseek(f.fileno(), -10, 2), size+1-10)
|
||||
expect(os.lseek(f.fileno(), -size-1, 2), 0)
|
||||
expect(os.lseek(f.fileno(), size, 0), size)
|
||||
expect(f.read(1), 'a') # the 'a' that was written at the end of the file above
|
||||
f.close()
|
||||
|
||||
|
||||
# XXX add tests for truncate if it exists
|
||||
# XXX has truncate ever worked on Windows? specifically on WinNT I get:
|
||||
# "IOError: [Errno 13] Permission denied"
|
||||
##try:
|
||||
## newsize = size - 10
|
||||
## f.seek(newsize)
|
||||
## f.truncate()
|
||||
## expect(f.tell(), newsize)
|
||||
## newsize = newsize - 1
|
||||
## f.seek(0)
|
||||
## f.truncate(newsize)
|
||||
## expect(f.tell(), newsize)
|
||||
##except AttributeError:
|
||||
## pass
|
||||
|
||||
os.unlink(name)
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
# test for xml.dom.minidom
|
||||
|
||||
from xml.dom.minidom import parse, Node, Document, parseString
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
if __name__ == "__main__":
|
||||
base = sys.argv[0]
|
||||
else:
|
||||
base = __file__
|
||||
tstfile = os.path.join(os.path.dirname(base), "test.xml")
|
||||
del base
|
||||
|
||||
Node._debug=1
|
||||
|
||||
def testGetElementsByTagName( ):
|
||||
dom=parse( tstfile )
|
||||
assert dom.getElementsByTagName( "LI" )==\
|
||||
dom.documentElement.getElementsByTagName( "LI" )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testInsertBefore( ):
|
||||
dom=parse( tstfile )
|
||||
docel=dom.documentElement
|
||||
#docel.insertBefore( dom.createProcessingInstruction("a", "b"),
|
||||
# docel.childNodes[1])
|
||||
|
||||
#docel.insertBefore( dom.createProcessingInstruction("a", "b"),
|
||||
# docel.childNodes[0])
|
||||
|
||||
#assert docel.childNodes[0].target=="a"
|
||||
#assert docel.childNodes[2].target=="a"
|
||||
dom.unlink()
|
||||
del dom
|
||||
del docel
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testAppendChild():
|
||||
dom=parse( tstfile )
|
||||
dom.documentElement.appendChild( dom.createComment( u"Hello" ))
|
||||
assert dom.documentElement.childNodes[-1].nodeName=="#comment"
|
||||
assert dom.documentElement.childNodes[-1].data=="Hello"
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testNonZero():
|
||||
dom=parse( tstfile )
|
||||
assert dom # should not be zero
|
||||
dom.appendChild( dom.createComment( "foo" ) )
|
||||
assert not dom.childNodes[-1].childNodes
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testUnlink():
|
||||
dom=parse( tstfile )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testElement():
|
||||
dom=Document()
|
||||
dom.appendChild( dom.createElement( "abc" ) )
|
||||
assert dom.documentElement
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testAAA():
|
||||
dom=parseString( "<abc/>" )
|
||||
el=dom.documentElement
|
||||
el.setAttribute( "spam", "jam2" )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
|
||||
def testAAB():
|
||||
dom=parseString( "<abc/>" )
|
||||
el=dom.documentElement
|
||||
el.setAttribute( "spam", "jam" )
|
||||
el.setAttribute( "spam", "jam2" )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
|
||||
def testAddAttr():
|
||||
dom=Document()
|
||||
child=dom.appendChild( dom.createElement( "abc" ) )
|
||||
|
||||
child.setAttribute( "def", "ghi" )
|
||||
assert child.getAttribute( "def" )=="ghi"
|
||||
assert child.attributes["def"].value=="ghi"
|
||||
|
||||
child.setAttribute( "jkl", "mno" )
|
||||
assert child.getAttribute( "jkl" )=="mno"
|
||||
assert child.attributes["jkl"].value=="mno"
|
||||
|
||||
assert len( child.attributes )==2
|
||||
|
||||
child.setAttribute( "def", "newval" )
|
||||
assert child.getAttribute( "def" )=="newval"
|
||||
assert child.attributes["def"].value=="newval"
|
||||
|
||||
assert len( child.attributes )==2
|
||||
|
||||
dom.unlink()
|
||||
dom=None
|
||||
child=None
|
||||
|
||||
def testDeleteAttr():
|
||||
dom=Document()
|
||||
child=dom.appendChild( dom.createElement( "abc" ) )
|
||||
|
||||
assert len( child.attributes)==0
|
||||
child.setAttribute( "def", "ghi" )
|
||||
assert len( child.attributes)==1
|
||||
del child.attributes["def"]
|
||||
assert len( child.attributes)==0
|
||||
dom.unlink()
|
||||
assert( len( Node.allnodes ))==0
|
||||
|
||||
def testRemoveAttr():
|
||||
dom=Document()
|
||||
child=dom.appendChild( dom.createElement( "abc" ) )
|
||||
|
||||
child.setAttribute( "def", "ghi" )
|
||||
assert len( child.attributes)==1
|
||||
child.removeAttribute("def" )
|
||||
assert len( child.attributes)==0
|
||||
|
||||
dom.unlink()
|
||||
|
||||
def testRemoveAttrNS():
|
||||
dom=Document()
|
||||
child=dom.appendChild(
|
||||
dom.createElementNS( "http://www.python.org", "python:abc" ) )
|
||||
child.setAttributeNS( "http://www.w3.org", "xmlns:python",
|
||||
"http://www.python.org" )
|
||||
child.setAttributeNS( "http://www.python.org", "python:abcattr", "foo" )
|
||||
assert len( child.attributes )==2
|
||||
child.removeAttributeNS( "http://www.python.org", "abcattr" )
|
||||
assert len( child.attributes )==1
|
||||
|
||||
dom.unlink()
|
||||
dom=None
|
||||
|
||||
def testRemoveAttributeNode():
|
||||
dom=Document()
|
||||
child=dom.appendChild( dom.createElement( "foo" ) )
|
||||
child.setAttribute( "spam", "jam" )
|
||||
assert len( child.attributes )==1
|
||||
node=child.getAttributeNode( "spam" )
|
||||
child.removeAttributeNode( node )
|
||||
assert len( child.attributes )==0
|
||||
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert len( Node.allnodes )==0
|
||||
|
||||
def testChangeAttr():
|
||||
dom=parseString( "<abc/>" )
|
||||
el=dom.documentElement
|
||||
el.setAttribute( "spam", "jam" )
|
||||
assert len( el.attributes )==1
|
||||
el.setAttribute( "spam", "bam" )
|
||||
assert len( el.attributes )==1
|
||||
el.attributes["spam"]="ham"
|
||||
assert len( el.attributes )==1
|
||||
el.setAttribute( "spam2", "bam" )
|
||||
assert len( el.attributes )==2
|
||||
el.attributes[ "spam2"]= "bam2"
|
||||
assert len( el.attributes )==2
|
||||
dom.unlink()
|
||||
dom=None
|
||||
assert len( Node.allnodes )==0
|
||||
|
||||
def testGetAttrList():
|
||||
pass
|
||||
|
||||
def testGetAttrValues(): pass
|
||||
|
||||
def testGetAttrLength(): pass
|
||||
|
||||
def testGetAttribute(): pass
|
||||
|
||||
def testGetAttributeNS(): pass
|
||||
|
||||
def testGetAttributeNode(): pass
|
||||
|
||||
def testGetElementsByTagNameNS(): pass
|
||||
|
||||
def testGetEmptyNodeListFromElementsByTagNameNS(): pass
|
||||
|
||||
def testElementReprAndStr():
|
||||
dom=Document()
|
||||
el=dom.appendChild( dom.createElement( "abc" ) )
|
||||
string1=repr( el )
|
||||
string2=str( el )
|
||||
assert string1==string2
|
||||
dom.unlink()
|
||||
|
||||
# commented out until Fredrick's fix is checked in
|
||||
def _testElementReprAndStrUnicode():
|
||||
dom=Document()
|
||||
el=dom.appendChild( dom.createElement( u"abc" ) )
|
||||
string1=repr( el )
|
||||
string2=str( el )
|
||||
assert string1==string2
|
||||
dom.unlink()
|
||||
|
||||
# commented out until Fredrick's fix is checked in
|
||||
def _testElementReprAndStrUnicodeNS():
|
||||
dom=Document()
|
||||
el=dom.appendChild(
|
||||
dom.createElementNS( u"http://www.slashdot.org", u"slash:abc" ))
|
||||
string1=repr( el )
|
||||
string2=str( el )
|
||||
assert string1==string2
|
||||
assert string1.find("slash:abc" )!=-1
|
||||
dom.unlink()
|
||||
|
||||
def testAttributeRepr():
|
||||
dom=Document()
|
||||
el=dom.appendChild( dom.createElement( u"abc" ) )
|
||||
node=el.setAttribute( "abc", "def" )
|
||||
assert str( node ) == repr( node )
|
||||
dom.unlink()
|
||||
|
||||
def testTextNodeRepr(): pass
|
||||
|
||||
def testWriteXML(): pass
|
||||
|
||||
def testProcessingInstruction(): pass
|
||||
|
||||
def testProcessingInstructionRepr(): pass
|
||||
|
||||
def testTextRepr(): pass
|
||||
|
||||
def testWriteText(): pass
|
||||
|
||||
def testDocumentElement(): pass
|
||||
|
||||
def testTooManyDocumentElements(): pass
|
||||
|
||||
def testCreateElementNS(): pass
|
||||
|
||||
def testCreatAttributeNS(): pass
|
||||
|
||||
def testParse(): pass
|
||||
|
||||
def testParseString(): pass
|
||||
|
||||
def testComment(): pass
|
||||
|
||||
def testAttrListItem(): pass
|
||||
|
||||
def testAttrListItems(): pass
|
||||
|
||||
def testAttrListItemNS(): pass
|
||||
|
||||
def testAttrListKeys(): pass
|
||||
|
||||
def testAttrListKeysNS(): pass
|
||||
|
||||
def testAttrListValues(): pass
|
||||
|
||||
def testAttrListLength(): pass
|
||||
|
||||
def testAttrList__getitem__(): pass
|
||||
|
||||
def testAttrList__setitem__(): pass
|
||||
|
||||
def testSetAttrValueandNodeValue(): pass
|
||||
|
||||
def testParseElement(): pass
|
||||
|
||||
def testParseAttributes(): pass
|
||||
|
||||
def testParseElementNamespaces(): pass
|
||||
|
||||
def testParseAttributeNamespaces(): pass
|
||||
|
||||
def testParseProcessingInstructions(): pass
|
||||
|
||||
def testChildNodes(): pass
|
||||
|
||||
def testFirstChild(): pass
|
||||
|
||||
def testHasChildNodes(): pass
|
||||
|
||||
def testCloneElementShallow(): pass
|
||||
|
||||
def testCloneElementShallowCopiesAttributes(): pass
|
||||
|
||||
def testCloneElementDeep(): pass
|
||||
|
||||
def testCloneDocumentShallow(): pass
|
||||
|
||||
def testCloneDocumentDeep(): pass
|
||||
|
||||
def testCloneAttributeShallow(): pass
|
||||
|
||||
def testCloneAttributeDeep(): pass
|
||||
|
||||
def testClonePIShallow(): pass
|
||||
|
||||
def testClonePIDeep(): pass
|
||||
|
||||
|
||||
names=globals().keys()
|
||||
names.sort()
|
||||
for name in names:
|
||||
if name.startswith( "test" ):
|
||||
func=globals()[name]
|
||||
try:
|
||||
func()
|
||||
print "Test Succeeded", name
|
||||
if len( Node.allnodes ):
|
||||
print "Garbage left over:"
|
||||
print Node.allnodes.items()[0:10]
|
||||
Node.allnodes={}
|
||||
except Exception, e :
|
||||
print "Test Failed: ", name
|
||||
apply( traceback.print_exception, sys.exc_info() )
|
||||
print `e`
|
||||
Node.allnodes={}
|
||||
raise
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
import os.path
|
||||
import parser
|
||||
import pprint
|
||||
import sys
|
||||
|
||||
from parser import expr, suite, sequence2ast
|
||||
from test_support import verbose
|
||||
|
||||
#
|
||||
# First, we test that we can generate trees from valid source fragments,
|
||||
# and that these valid trees are indeed allowed by the tree-loading side
|
||||
# of the parser module.
|
||||
#
|
||||
|
||||
def roundtrip(f, s):
|
||||
st1 = f(s)
|
||||
t = st1.totuple()
|
||||
st2 = parser.sequence2ast(t)
|
||||
|
||||
def roundtrip_fromfile(filename):
|
||||
roundtrip(suite, open(filename).read())
|
||||
|
||||
def test_expr(s):
|
||||
print "expr:", s
|
||||
roundtrip(expr, s)
|
||||
|
||||
def test_suite(s):
|
||||
print "suite:", s
|
||||
roundtrip(suite, s)
|
||||
|
||||
|
||||
print "Expressions:"
|
||||
|
||||
test_expr("foo(1)")
|
||||
test_expr("[1, 2, 3]")
|
||||
test_expr("[x**3 for x in range(20)]")
|
||||
test_expr("[x**3 for x in range(20) if x % 3]")
|
||||
test_expr("foo(*args)")
|
||||
test_expr("foo(*args, **kw)")
|
||||
test_expr("foo(**kw)")
|
||||
test_expr("foo(key=value)")
|
||||
test_expr("foo(key=value, *args)")
|
||||
test_expr("foo(key=value, *args, **kw)")
|
||||
test_expr("foo(key=value, **kw)")
|
||||
test_expr("foo(a, b, c, *args)")
|
||||
test_expr("foo(a, b, c, *args, **kw)")
|
||||
test_expr("foo(a, b, c, **kw)")
|
||||
test_expr("foo + bar")
|
||||
|
||||
print
|
||||
print "Statements:"
|
||||
test_suite("print")
|
||||
test_suite("print 1")
|
||||
test_suite("print 1,")
|
||||
test_suite("print >>fp")
|
||||
test_suite("print >>fp, 1")
|
||||
test_suite("print >>fp, 1,")
|
||||
|
||||
# expr_stmt
|
||||
test_suite("a")
|
||||
test_suite("a = b")
|
||||
test_suite("a = b = c = d = e")
|
||||
test_suite("a += b")
|
||||
test_suite("a -= b")
|
||||
test_suite("a *= b")
|
||||
test_suite("a /= b")
|
||||
test_suite("a %= b")
|
||||
test_suite("a &= b")
|
||||
test_suite("a |= b")
|
||||
test_suite("a ^= b")
|
||||
test_suite("a <<= b")
|
||||
test_suite("a >>= b")
|
||||
test_suite("a **= b")
|
||||
|
||||
#d = os.path.dirname(os.__file__)
|
||||
#roundtrip_fromfile(os.path.join(d, "os.py"))
|
||||
#roundtrip_fromfile(os.path.join(d, "test", "test_parser.py"))
|
||||
|
||||
#
|
||||
# Second, we take *invalid* trees and make sure we get ParserError
|
||||
# rejections for them.
|
||||
#
|
||||
|
||||
print
|
||||
print "Invalid parse trees:"
|
||||
|
||||
def check_bad_tree(tree, label):
|
||||
print
|
||||
print label
|
||||
try:
|
||||
sequence2ast(tree)
|
||||
except parser.ParserError:
|
||||
print "caught expected exception for invalid tree"
|
||||
pass
|
||||
else:
|
||||
print "test failed: did not properly detect invalid tree:"
|
||||
pprint.pprint(tree)
|
||||
|
||||
|
||||
# not even remotely valid:
|
||||
check_bad_tree((1, 2, 3), "<junk>")
|
||||
|
||||
# print >>fp,
|
||||
tree = \
|
||||
(257,
|
||||
(264,
|
||||
(265,
|
||||
(266,
|
||||
(268,
|
||||
(1, 'print'),
|
||||
(35, '>>'),
|
||||
(290,
|
||||
(291,
|
||||
(292,
|
||||
(293,
|
||||
(295,
|
||||
(296,
|
||||
(297,
|
||||
(298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))),
|
||||
(12, ','))),
|
||||
(4, ''))),
|
||||
(0, ''))
|
||||
|
||||
check_bad_tree(tree, "print >>fp,")
|
||||
|
||||
# a,,c
|
||||
tree = \
|
||||
(258,
|
||||
(311,
|
||||
(290,
|
||||
(291,
|
||||
(292,
|
||||
(293,
|
||||
(295,
|
||||
(296, (297, (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
|
||||
(12, ','),
|
||||
(12, ','),
|
||||
(290,
|
||||
(291,
|
||||
(292,
|
||||
(293,
|
||||
(295,
|
||||
(296, (297, (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
|
||||
(4, ''),
|
||||
(0, ''))
|
||||
|
||||
check_bad_tree(tree, "a,,c")
|
||||
|
||||
# a $= b
|
||||
tree = \
|
||||
(257,
|
||||
(264,
|
||||
(265,
|
||||
(266,
|
||||
(267,
|
||||
(312,
|
||||
(291,
|
||||
(292,
|
||||
(293,
|
||||
(294,
|
||||
(296,
|
||||
(297,
|
||||
(298,
|
||||
(299, (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
|
||||
(268, (37, '$=')),
|
||||
(312,
|
||||
(291,
|
||||
(292,
|
||||
(293,
|
||||
(294,
|
||||
(296,
|
||||
(297,
|
||||
(298,
|
||||
(299, (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
|
||||
(4, ''))),
|
||||
(0, ''))
|
||||
|
||||
check_bad_tree(tree, "a $= b")
|
|
@ -0,0 +1,172 @@
|
|||
# Test case for the os.poll() function
|
||||
|
||||
import sys, os, select, random
|
||||
from test_support import verbose, TestSkipped, TESTFN
|
||||
|
||||
try:
|
||||
select.poll
|
||||
except AttributeError:
|
||||
raise TestSkipped, "select.poll not defined -- skipping test_poll"
|
||||
|
||||
|
||||
def find_ready_matching(ready, flag):
|
||||
match = []
|
||||
for fd, mode in ready:
|
||||
if mode & flag:
|
||||
match.append(fd)
|
||||
return match
|
||||
|
||||
def test_poll1():
|
||||
"""Basic functional test of poll object
|
||||
|
||||
Create a bunch of pipe and test that poll works with them.
|
||||
"""
|
||||
print 'Running poll test 1'
|
||||
p = select.poll()
|
||||
|
||||
NUM_PIPES = 12
|
||||
MSG = " This is a test."
|
||||
MSG_LEN = len(MSG)
|
||||
readers = []
|
||||
writers = []
|
||||
r2w = {}
|
||||
w2r = {}
|
||||
|
||||
for i in range(NUM_PIPES):
|
||||
rd, wr = os.pipe()
|
||||
p.register(rd, select.POLLIN)
|
||||
p.register(wr, select.POLLOUT)
|
||||
readers.append(rd)
|
||||
writers.append(wr)
|
||||
r2w[rd] = wr
|
||||
w2r[wr] = rd
|
||||
|
||||
while writers:
|
||||
ready = p.poll()
|
||||
ready_writers = find_ready_matching(ready, select.POLLOUT)
|
||||
if not ready_writers:
|
||||
raise RuntimeError, "no pipes ready for writing"
|
||||
wr = random.choice(ready_writers)
|
||||
os.write(wr, MSG)
|
||||
|
||||
ready = p.poll()
|
||||
ready_readers = find_ready_matching(ready, select.POLLIN)
|
||||
if not ready_readers:
|
||||
raise RuntimeError, "no pipes ready for reading"
|
||||
rd = random.choice(ready_readers)
|
||||
buf = os.read(rd, MSG_LEN)
|
||||
assert len(buf) == MSG_LEN
|
||||
print buf
|
||||
os.close(r2w[rd]) ; os.close( rd )
|
||||
p.unregister( r2w[rd] )
|
||||
p.unregister( rd )
|
||||
writers.remove(r2w[rd])
|
||||
|
||||
poll_unit_tests()
|
||||
print 'Poll test 1 complete'
|
||||
|
||||
def poll_unit_tests():
|
||||
# returns NVAL for invalid file descriptor
|
||||
FD = 42
|
||||
try:
|
||||
os.close(FD)
|
||||
except OSError:
|
||||
pass
|
||||
p = select.poll()
|
||||
p.register(FD)
|
||||
r = p.poll()
|
||||
assert r[0] == (FD, select.POLLNVAL)
|
||||
|
||||
f = open(TESTFN, 'w')
|
||||
fd = f.fileno()
|
||||
p = select.poll()
|
||||
p.register(f)
|
||||
r = p.poll()
|
||||
assert r[0][0] == fd
|
||||
f.close()
|
||||
r = p.poll()
|
||||
assert r[0] == (fd, select.POLLNVAL)
|
||||
os.unlink(TESTFN)
|
||||
|
||||
# type error for invalid arguments
|
||||
p = select.poll()
|
||||
try:
|
||||
p.register(p)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
print "Bogus register call did not raise TypeError"
|
||||
try:
|
||||
p.unregister(p)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
print "Bogus unregister call did not raise TypeError"
|
||||
|
||||
# can't unregister non-existent object
|
||||
p = select.poll()
|
||||
try:
|
||||
p.unregister(3)
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
print "Bogus unregister call did not raise KeyError"
|
||||
|
||||
# Test error cases
|
||||
pollster = select.poll()
|
||||
class Nope:
|
||||
pass
|
||||
|
||||
class Almost:
|
||||
def fileno(self):
|
||||
return 'fileno'
|
||||
|
||||
try:
|
||||
pollster.register( Nope(), 0 )
|
||||
except TypeError: pass
|
||||
else: print 'expected TypeError exception, not raised'
|
||||
|
||||
try:
|
||||
pollster.register( Almost(), 0 )
|
||||
except TypeError: pass
|
||||
else: print 'expected TypeError exception, not raised'
|
||||
|
||||
|
||||
# Another test case for poll(). This is copied from the test case for
|
||||
# select(), modified to use poll() instead.
|
||||
|
||||
def test_poll2():
|
||||
print 'Running poll test 2'
|
||||
cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
|
||||
p = os.popen(cmd, 'r')
|
||||
pollster = select.poll()
|
||||
pollster.register( p, select.POLLIN )
|
||||
for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
|
||||
if verbose:
|
||||
print 'timeout =', tout
|
||||
fdlist = pollster.poll(tout)
|
||||
if (fdlist == []):
|
||||
continue
|
||||
fd, flags = fdlist[0]
|
||||
if flags & select.POLLHUP:
|
||||
line = p.readline()
|
||||
if line != "":
|
||||
print 'error: pipe seems to be closed, but still returns data'
|
||||
continue
|
||||
|
||||
elif flags & select.POLLIN:
|
||||
line = p.readline()
|
||||
if verbose:
|
||||
print `line`
|
||||
if not line:
|
||||
if verbose:
|
||||
print 'EOF'
|
||||
break
|
||||
continue
|
||||
else:
|
||||
print 'Unexpected return value from select.poll:', fdlist
|
||||
p.close()
|
||||
print 'Poll test 2 complete'
|
||||
|
||||
test_poll1()
|
||||
test_poll2()
|
|
@ -0,0 +1,42 @@
|
|||
import posixpath
|
||||
import string
|
||||
|
||||
errors = 0
|
||||
|
||||
def tester(fn, wantResult):
|
||||
gotResult = eval(fn)
|
||||
if wantResult != gotResult:
|
||||
print "error!"
|
||||
print "evaluated: " + str(fn)
|
||||
print "should be: " + str(wantResult)
|
||||
print " returned: " + str(gotResult)
|
||||
print ""
|
||||
global errors
|
||||
errors = errors + 1
|
||||
|
||||
tester('posixpath.splitdrive("/foo/bar")', ('', '/foo/bar'))
|
||||
|
||||
tester('posixpath.split("/foo/bar")', ('/foo', 'bar'))
|
||||
tester('posixpath.split("/")', ('/', ''))
|
||||
tester('posixpath.split("foo")', ('', 'foo'))
|
||||
|
||||
tester('posixpath.splitext("foo.ext")', ('foo', '.ext'))
|
||||
tester('posixpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
|
||||
|
||||
tester('posixpath.isabs("/")', 1)
|
||||
tester('posixpath.isabs("/foo")', 1)
|
||||
tester('posixpath.isabs("/foo/bar")', 1)
|
||||
tester('posixpath.isabs("foo/bar")', 0)
|
||||
|
||||
tester('posixpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
|
||||
"/home/swen")
|
||||
tester('posixpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"])',
|
||||
"/home/swen/")
|
||||
tester('posixpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
|
||||
"/home/swen/spam")
|
||||
|
||||
if errors:
|
||||
print str(errors) + " errors."
|
||||
else:
|
||||
print "No errors. Thank your lucky stars."
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import thread
|
||||
# Start empty thread to initialize thread mechanics (and global lock!)
|
||||
# This thread will finish immediately thus won't make much influence on
|
||||
# test results by itself, only by that fact that it initializes global lock
|
||||
thread.start_new_thread(lambda : 1, ())
|
||||
|
||||
import test.pystone
|
||||
test.pystone.main()
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
"""Remote-control interfaces to some browsers."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
PROCESS_CREATION_DELAY = 4
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
_browsers = {}
|
||||
|
||||
def register(name, klass, instance=None):
|
||||
"""Register a browser connector and, optionally, connection."""
|
||||
_browsers[name.lower()] = [klass, instance]
|
||||
|
||||
|
||||
def get(name=None):
|
||||
"""Retrieve a connection to a browser by type name, or the default
|
||||
browser."""
|
||||
name = name or DEFAULT_BROWSER
|
||||
try:
|
||||
L = _browsers[name.lower()]
|
||||
except KeyError:
|
||||
raise ValueError, "unknown browser type: " + `name`
|
||||
if L[1] is None:
|
||||
L[1] = L[0]()
|
||||
return L[1]
|
||||
|
||||
|
||||
# Please note: the following definition hides a builtin function.
|
||||
|
||||
def open(url, new=0):
|
||||
get().open(url, new)
|
||||
|
||||
|
||||
def open_new(url):
|
||||
get().open_new(url)
|
||||
|
||||
|
||||
def _iscommand(cmd):
|
||||
"""Return true if cmd can be found on the executable search path."""
|
||||
path = os.environ.get("PATH")
|
||||
if not path:
|
||||
return 0
|
||||
for d in path.split(os.pathsep):
|
||||
exe = os.path.join(d, cmd)
|
||||
if os.path.isfile(exe):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
class CommandLineBrowser:
|
||||
_browsers = []
|
||||
if os.environ.get("DISPLAY"):
|
||||
_browsers.extend([
|
||||
("netscape", "netscape %s >/dev/null &"),
|
||||
("mosaic", "mosaic %s >/dev/null &"),
|
||||
])
|
||||
_browsers.extend([
|
||||
("lynx", "lynx %s"),
|
||||
("w3m", "w3m %s"),
|
||||
])
|
||||
|
||||
def open(self, url, new=0):
|
||||
for exe, cmd in self._browsers:
|
||||
if _iscommand(exe):
|
||||
os.system(cmd % url)
|
||||
return
|
||||
raise Error("could not locate runnable browser")
|
||||
|
||||
def open_new(self, url):
|
||||
self.open(url)
|
||||
|
||||
register("command-line", CommandLineBrowser)
|
||||
|
||||
|
||||
class Netscape:
|
||||
autoRaise = 1
|
||||
|
||||
def _remote(self, action):
|
||||
raise_opt = ("-noraise", "-raise")[self.autoRaise]
|
||||
cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
|
||||
rc = os.system(cmd)
|
||||
if rc:
|
||||
import time
|
||||
os.system("netscape -no-about-splash &")
|
||||
time.sleep(PROCESS_CREATION_DELAY)
|
||||
rc = os.system(cmd)
|
||||
return not rc
|
||||
|
||||
def open(self, url, new=0):
|
||||
if new:
|
||||
self.open_new(url)
|
||||
else:
|
||||
self._remote("openURL(%s)" % url)
|
||||
|
||||
def open_new(self, url):
|
||||
self._remote("openURL(%s, new-window)" % url)
|
||||
|
||||
register("netscape", Netscape)
|
||||
|
||||
|
||||
class Konquerer:
|
||||
"""Controller for the KDE File Manager (kfm, or Konquerer).
|
||||
|
||||
See http://developer.kde.org/documentation/other/kfmclient.html
|
||||
for more information on the Konquerer remote-control interface.
|
||||
|
||||
"""
|
||||
def _remote(self, action):
|
||||
cmd = "kfmclient %s >/dev/null 2>&1" % action
|
||||
rc = os.system(cmd)
|
||||
if rc:
|
||||
import time
|
||||
os.system("kfm -d &")
|
||||
time.sleep(PROCESS_CREATION_DELAY)
|
||||
rc = os.system(cmd)
|
||||
return not rc
|
||||
|
||||
def open(self, url, new=1):
|
||||
# XXX currently I know no way to prevent KFM from opening a new win.
|
||||
self.open_new(url)
|
||||
|
||||
def open_new(self, url):
|
||||
self._remote("openURL %s" % url)
|
||||
|
||||
register("kfm", Konquerer)
|
||||
|
||||
|
||||
class Grail:
|
||||
# There should be a way to maintain a connection to Grail, but the
|
||||
# Grail remote control protocol doesn't really allow that at this
|
||||
# point. It probably never will!
|
||||
|
||||
def _find_grail_rc(self):
|
||||
import glob
|
||||
import pwd
|
||||
import socket
|
||||
import tempfile
|
||||
tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
|
||||
user = pwd.getpwuid(_os.getuid())[0]
|
||||
filename = os.path.join(tempdir, user + "-*")
|
||||
maybes = glob.glob(filename)
|
||||
if not maybes:
|
||||
return None
|
||||
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
for fn in maybes:
|
||||
# need to PING each one until we find one that's live
|
||||
try:
|
||||
s.connect(fn)
|
||||
except socket.error:
|
||||
# no good; attempt to clean it out, but don't fail:
|
||||
try:
|
||||
os.unlink(fn)
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
return s
|
||||
|
||||
def _remote(self, action):
|
||||
s = self._find_grail_rc()
|
||||
if not s:
|
||||
return 0
|
||||
s.send(action)
|
||||
s.close()
|
||||
return 1
|
||||
|
||||
def open(self, url, new=0):
|
||||
if new:
|
||||
self.open_new(url)
|
||||
else:
|
||||
self._remote("LOAD " + url)
|
||||
|
||||
def open_new(self, url):
|
||||
self._remote("LOADNEW " + url)
|
||||
|
||||
register("grail", Grail)
|
||||
|
||||
|
||||
class WindowsDefault:
|
||||
def open(self, url, new=0):
|
||||
import win32api, win32con
|
||||
win32api.ShellExecute(0, "open", url, None, ".",
|
||||
win32con.SW_SHOWNORMAL)
|
||||
|
||||
def open_new(self, url):
|
||||
self.open(url)
|
||||
|
||||
|
||||
DEFAULT_BROWSER = "command-line"
|
||||
|
||||
if sys.platform[:3] == "win":
|
||||
del _browsers["kfm"]
|
||||
register("windows-default", WindowsDefault)
|
||||
DEFAULT_BROWSER = "windows-default"
|
||||
elif os.environ.get("DISPLAY"):
|
||||
if os.environ.get("KDEDIR"):
|
||||
DEFAULT_BROWSER = "kfm"
|
||||
elif _iscommand("netscape"):
|
||||
DEFAULT_BROWSER = "netscape"
|
||||
|
||||
# If the $BROWSER environment variable is set and true, let that be
|
||||
# the name of the browser to use:
|
||||
#
|
||||
DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER
|
||||
|
||||
|
||||
# Now try to support the MacOS world. This is the only supported
|
||||
# controller on that platform, so don't mess with the default!
|
||||
|
||||
try:
|
||||
import ic
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
class InternetConfig:
|
||||
def open(self, url, new=0):
|
||||
ic.launcurl(url)
|
||||
|
||||
def open_new(self, url):
|
||||
self.open(url)
|
||||
|
||||
_browsers.clear()
|
||||
register("internet-config", InternetConfig)
|
||||
DEFAULT_BROWSER = "internet-config"
|
Loading…
Reference in New Issue