The usual.
This commit is contained in:
parent
eebb1c6cd1
commit
e8d2f5589b
|
@ -91,6 +91,8 @@ import re
|
|||
|
||||
DEFAULTSECT = "DEFAULT"
|
||||
|
||||
MAX_INTERPOLATION_DEPTH = 10
|
||||
|
||||
|
||||
|
||||
# exception classes
|
||||
|
@ -130,15 +132,16 @@ class InterpolationError(Error):
|
|||
self.option = option
|
||||
self.section = section
|
||||
|
||||
class MissingSectionHeaderError(Error):
|
||||
def __init__(self, filename, lineno, line):
|
||||
Error.__init__(
|
||||
self,
|
||||
'File contains no section headers.\nfile: %s, line: %d\n%s' %
|
||||
(filename, lineno, line))
|
||||
self.filename = filename
|
||||
self.lineno = lineno
|
||||
self.line = line
|
||||
class InterpolationDepthError(Error):
|
||||
def __init__(self, option, section, rawval):
|
||||
Error.__init__(self,
|
||||
"Value interpolation too deeply recursive:\n"
|
||||
"\tsection: [%s]\n"
|
||||
"\toption : %s\n"
|
||||
"\trawval : %s\n"
|
||||
% (section, option, rawval))
|
||||
self.option = option
|
||||
self.section = section
|
||||
|
||||
class ParsingError(Error):
|
||||
def __init__(self, filename):
|
||||
|
@ -150,6 +153,16 @@ class ParsingError(Error):
|
|||
self.errors.append((lineno, line))
|
||||
self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
|
||||
|
||||
class MissingSectionHeaderError(ParsingError):
|
||||
def __init__(self, filename, lineno, line):
|
||||
Error.__init__(
|
||||
self,
|
||||
'File contains no section headers.\nfile: %s, line: %d\n%s' %
|
||||
(filename, lineno, line))
|
||||
self.filename = filename
|
||||
self.lineno = lineno
|
||||
self.line = line
|
||||
|
||||
|
||||
|
||||
class ConfigParser:
|
||||
|
@ -183,7 +196,7 @@ class ConfigParser:
|
|||
|
||||
The DEFAULT section is not acknowledged.
|
||||
"""
|
||||
return self.__sections.has_key(section)
|
||||
return section in self.sections()
|
||||
|
||||
def options(self, section):
|
||||
"""Return a list of option names for the given section name."""
|
||||
|
@ -192,15 +205,13 @@ class ConfigParser:
|
|||
except KeyError:
|
||||
raise NoSectionError(section)
|
||||
opts.update(self.__defaults)
|
||||
if opts.has_key('__name__'):
|
||||
del opts['__name__']
|
||||
return opts.keys()
|
||||
|
||||
def has_option(self, section, option):
|
||||
"""Return whether the given section has the given option."""
|
||||
try:
|
||||
opts = self.__sections[section]
|
||||
except KeyError:
|
||||
raise NoSectionError(section)
|
||||
return opts.has_key(option)
|
||||
return option in self.options(section)
|
||||
|
||||
def read(self, filenames):
|
||||
"""Read and parse a filename or a list of filenames.
|
||||
|
@ -266,10 +277,11 @@ class ConfigParser:
|
|||
rawval = d[option]
|
||||
except KeyError:
|
||||
raise NoOptionError(option, section)
|
||||
# do the string interpolation
|
||||
|
||||
if raw:
|
||||
return rawval
|
||||
|
||||
# do the string interpolation
|
||||
value = rawval # Make it a pretty variable name
|
||||
depth = 0
|
||||
while depth < 10: # Loop through this until it's done
|
||||
|
@ -280,7 +292,10 @@ class ConfigParser:
|
|||
except KeyError, key:
|
||||
raise InterpolationError(key, option, section, rawval)
|
||||
else:
|
||||
return value
|
||||
break
|
||||
if value.find("%(") >= 0:
|
||||
raise InterpolationDepthError(option, section, rawval)
|
||||
return value
|
||||
|
||||
def __get(self, section, conv, option):
|
||||
return conv(self.get(section, option))
|
||||
|
@ -365,7 +380,7 @@ class ConfigParser:
|
|||
# of \w, _ is allowed in section header names.
|
||||
SECTCRE = re.compile(
|
||||
r'\[' # [
|
||||
r'(?P<header>[-\w_.*,(){}]+)' # a lot of stuff found by IvL
|
||||
r'(?P<header>[-\w_.*,(){} ]+)' # a lot of stuff found by IvL
|
||||
r'\]' # ]
|
||||
)
|
||||
OPTCRE = re.compile(
|
||||
|
|
|
@ -141,7 +141,7 @@ def decode(input, output, encoding):
|
|||
import uu
|
||||
return uu.decode(input, output)
|
||||
if encoding in ('7bit', '8bit'):
|
||||
output.write(input.read())
|
||||
return output.write(input.read())
|
||||
if decodetab.has_key(encoding):
|
||||
pipethrough(input, decodetab[encoding], output)
|
||||
else:
|
||||
|
@ -160,7 +160,7 @@ def encode(input, output, encoding):
|
|||
import uu
|
||||
return uu.encode(input, output)
|
||||
if encoding in ('7bit', '8bit'):
|
||||
output.write(input.read())
|
||||
return output.write(input.read())
|
||||
if encodetab.has_key(encoding):
|
||||
pipethrough(input, encodetab[encoding], output)
|
||||
else:
|
||||
|
|
|
@ -56,9 +56,8 @@ def join(a, *p):
|
|||
|
||||
def split(p):
|
||||
"""Split a pathname. Returns tuple "(head, tail)" where "tail" is
|
||||
everything after the final slash. Either part may be empty"""
|
||||
import string
|
||||
i = string.rfind(p, '/') + 1
|
||||
everything after the final slash. Either part may be empty."""
|
||||
i = p.rfind('/') + 1
|
||||
head, tail = p[:i], p[i:]
|
||||
if head and head <> '/'*len(head):
|
||||
while head[-1] == '/':
|
||||
|
@ -73,7 +72,7 @@ everything after the final slash. Either part may be empty"""
|
|||
|
||||
def splitext(p):
|
||||
"""Split the extension from a pathname. Extension is everything from the
|
||||
last dot to the end. Returns "(root, ext)", either part may be empty"""
|
||||
last dot to the end. Returns "(root, ext)", either part may be empty."""
|
||||
root, ext = '', ''
|
||||
for c in p:
|
||||
if c == '/':
|
||||
|
@ -95,7 +94,7 @@ last dot to the end. Returns "(root, ext)", either part may be empty"""
|
|||
|
||||
def splitdrive(p):
|
||||
"""Split a pathname into drive and path. On Posix, drive is always
|
||||
empty"""
|
||||
empty."""
|
||||
return '', p
|
||||
|
||||
|
||||
|
@ -255,9 +254,9 @@ def ismount(path):
|
|||
|
||||
def walk(top, func, arg):
|
||||
"""walk(top,func,arg) calls func(arg, d, files) for each directory "d"
|
||||
in the tree rooted at "top" (including "top" itself). "files" is a list
|
||||
of all the files and subdirs in directory "d".
|
||||
"""
|
||||
in the tree rooted at "top" (including "top" itself). "files" is a list
|
||||
of all the files and subdirs in directory "d".
|
||||
"""
|
||||
try:
|
||||
names = os.listdir(top)
|
||||
except os.error:
|
||||
|
@ -281,12 +280,12 @@ of all the files and subdirs in directory "d".
|
|||
|
||||
def expanduser(path):
|
||||
"""Expand ~ and ~user constructions. If user or $HOME is unknown,
|
||||
do nothing"""
|
||||
do nothing."""
|
||||
if path[:1] <> '~':
|
||||
return path
|
||||
i, n = 1, len(path)
|
||||
while i < n and path[i] <> '/':
|
||||
i = i+1
|
||||
i = i + 1
|
||||
if i == 1:
|
||||
if not os.environ.has_key('HOME'):
|
||||
return path
|
||||
|
@ -298,7 +297,7 @@ do nothing"""
|
|||
except KeyError:
|
||||
return path
|
||||
userhome = pwent[5]
|
||||
if userhome[-1:] == '/': i = i+1
|
||||
if userhome[-1:] == '/': i = i + 1
|
||||
return userhome + path[i:]
|
||||
|
||||
|
||||
|
@ -310,7 +309,7 @@ _varprog = None
|
|||
|
||||
def expandvars(path):
|
||||
"""Expand shell variables of form $var and ${var}. Unknown variables
|
||||
are left unchanged"""
|
||||
are left unchanged."""
|
||||
global _varprog
|
||||
if '$' not in path:
|
||||
return path
|
||||
|
@ -344,9 +343,8 @@ def normpath(path):
|
|||
"""Normalize path, eliminating double slashes, etc."""
|
||||
if path == '':
|
||||
return '.'
|
||||
import string
|
||||
initial_slash = (path[0] == '/')
|
||||
comps = string.split(path, '/')
|
||||
comps = path.split('/')
|
||||
new_comps = []
|
||||
for comp in comps:
|
||||
if comp in ('', '.'):
|
||||
|
@ -357,7 +355,7 @@ def normpath(path):
|
|||
elif new_comps:
|
||||
new_comps.pop()
|
||||
comps = new_comps
|
||||
path = string.join(comps, '/')
|
||||
path = '/'.join(comps)
|
||||
if initial_slash:
|
||||
path = '/' + path
|
||||
return path or '.'
|
||||
|
|
|
@ -222,7 +222,7 @@ def _optimize_charset(charset, fixup):
|
|||
def _simple(av):
|
||||
# check if av is a "simple" operator
|
||||
lo, hi = av[2].getwidth()
|
||||
if lo == 0:
|
||||
if lo == 0 and hi == MAXREPEAT:
|
||||
raise error, "nothing to repeat"
|
||||
return lo == hi == 1 and av[2][0][0] != SUBPATTERN
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
# See the sre.py file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
MAXREPEAT = 65535
|
||||
|
||||
# should this really be here?
|
||||
|
||||
class error(Exception):
|
||||
|
|
|
@ -12,8 +12,6 @@ import string, sys
|
|||
|
||||
from sre_constants import *
|
||||
|
||||
MAXREPEAT = 65535
|
||||
|
||||
SPECIAL_CHARS = ".\\[{()*+?^$|"
|
||||
REPEAT_CHARS = "*+?{"
|
||||
|
||||
|
@ -393,6 +391,8 @@ def _parse(source, state):
|
|||
# potential range
|
||||
this = source.get()
|
||||
if this == "]":
|
||||
if code1[0] is IN:
|
||||
code1 = code1[1][0]
|
||||
set.append(code1)
|
||||
set.append((LITERAL, ord("-")))
|
||||
break
|
||||
|
@ -593,6 +593,11 @@ def parse(str, flags=0, pattern=None):
|
|||
|
||||
# p.dump()
|
||||
|
||||
if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
|
||||
# the VERBOSE flag was switched on inside the pattern. to be
|
||||
# on the safe side, we'll parse the whole thing again...
|
||||
return parse(str, p.pattern.flags)
|
||||
|
||||
return p
|
||||
|
||||
def parse_template(source, pattern):
|
||||
|
|
|
@ -13,6 +13,7 @@ buf = f.read() # read until EOF
|
|||
buf = f.read(n) # read up to n bytes
|
||||
buf = f.readline() # read until end of line ('\n') or EOF
|
||||
list = f.readlines()# list of f.readline() results until EOF
|
||||
f.truncate([size]) # truncate file at to at most size (default: current pos)
|
||||
f.write(buf) # write at current position
|
||||
f.writelines(list) # for line in list: f.write(line)
|
||||
f.getvalue() # return whole file's contents as a string
|
||||
|
@ -28,6 +29,7 @@ Notes:
|
|||
- There's a simple test set (see end of this file).
|
||||
"""
|
||||
|
||||
import errno
|
||||
import string
|
||||
|
||||
class StringIO:
|
||||
|
@ -102,6 +104,17 @@ class StringIO:
|
|||
break
|
||||
line = self.readline()
|
||||
return lines
|
||||
def truncate(self, size=None):
|
||||
if self.closed:
|
||||
raise ValueError, "I/O operation on closed file"
|
||||
if size is None:
|
||||
size = self.pos
|
||||
elif size < 0:
|
||||
raise IOError(errno.EINVAL,
|
||||
"Negative size not allowed")
|
||||
elif size < self.pos:
|
||||
self.pos = size
|
||||
self.buf = self.getvalue()[:size]
|
||||
def write(self, s):
|
||||
if self.closed:
|
||||
raise ValueError, "I/O operation on closed file"
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
import ConfigParser
|
||||
import StringIO
|
||||
|
||||
def basic(src):
|
||||
print
|
||||
print "Testing basic accessors..."
|
||||
cf = ConfigParser.ConfigParser()
|
||||
sio = StringIO.StringIO(src)
|
||||
cf.readfp(sio)
|
||||
L = cf.sections()
|
||||
L.sort()
|
||||
print L
|
||||
for s in L:
|
||||
print "%s: %s" % (s, cf.options(s))
|
||||
|
||||
# The use of spaces in the section names serves as a regression test for
|
||||
# SourceForge bug #115357.
|
||||
# http://sourceforge.net/bugs/?func=detailbug&group_id=5470&bug_id=115357
|
||||
print `cf.get('Foo Bar', 'foo', raw=1)`
|
||||
print `cf.get('Spacey Bar', 'foo', raw=1)`
|
||||
print `cf.get('Commented Bar', 'foo', raw=1)`
|
||||
|
||||
if '__name__' in cf.options("Foo Bar"):
|
||||
print '__name__ "option" should not be exposed by the API!'
|
||||
else:
|
||||
print '__name__ "option" properly hidden by the API.'
|
||||
|
||||
def interpolation(src):
|
||||
print
|
||||
print "Testing value interpolation..."
|
||||
cf = ConfigParser.ConfigParser({"getname": "%(__name__)s"})
|
||||
sio = StringIO.StringIO(src)
|
||||
cf.readfp(sio)
|
||||
print `cf.get("Foo", "getname")`
|
||||
print `cf.get("Foo", "bar")`
|
||||
print `cf.get("Foo", "bar9")`
|
||||
print `cf.get("Foo", "bar10")`
|
||||
expect_get_error(cf, ConfigParser.InterpolationDepthError, "Foo", "bar11")
|
||||
|
||||
def parse_errors():
|
||||
print
|
||||
print "Testing for parsing errors..."
|
||||
expect_parse_error(ConfigParser.ParsingError,
|
||||
"""[Foo]\n extra-spaces: splat\n""")
|
||||
expect_parse_error(ConfigParser.ParsingError,
|
||||
"""[Foo]\n extra-spaces= splat\n""")
|
||||
expect_parse_error(ConfigParser.ParsingError,
|
||||
"""[Foo]\noption-without-value\n""")
|
||||
expect_parse_error(ConfigParser.ParsingError,
|
||||
"""[Foo]\n:value-without-option-name\n""")
|
||||
expect_parse_error(ConfigParser.ParsingError,
|
||||
"""[Foo]\n=value-without-option-name\n""")
|
||||
expect_parse_error(ConfigParser.MissingSectionHeaderError,
|
||||
"""No Section!\n""")
|
||||
|
||||
def query_errors():
|
||||
print
|
||||
print "Testing query interface..."
|
||||
cf = ConfigParser.ConfigParser()
|
||||
print cf.sections()
|
||||
print "Has section 'Foo'?", cf.has_section("Foo")
|
||||
try:
|
||||
cf.options("Foo")
|
||||
except ConfigParser.NoSectionError, e:
|
||||
print "Caught expected NoSectionError:", e
|
||||
else:
|
||||
print "Failed to catch expected NoSectionError from options()"
|
||||
try:
|
||||
cf.set("foo", "bar", "value")
|
||||
except ConfigParser.NoSectionError, e:
|
||||
print "Caught expected NoSectionError:", e
|
||||
else:
|
||||
print "Failed to catch expected NoSectionError from set()"
|
||||
expect_get_error(cf, ConfigParser.NoSectionError, "foo", "bar")
|
||||
cf.add_section("foo")
|
||||
expect_get_error(cf, ConfigParser.NoOptionError, "foo", "bar")
|
||||
|
||||
def weird_errors():
|
||||
print
|
||||
print "Testing miscellaneous error conditions..."
|
||||
cf = ConfigParser.ConfigParser()
|
||||
cf.add_section("Foo")
|
||||
try:
|
||||
cf.add_section("Foo")
|
||||
except ConfigParser.DuplicateSectionError, e:
|
||||
print "Caught expected DuplicateSectionError:", e
|
||||
else:
|
||||
print "Failed to catch expected DuplicateSectionError"
|
||||
|
||||
def expect_get_error(cf, exctype, section, option, raw=0):
|
||||
try:
|
||||
cf.get(section, option, raw=raw)
|
||||
except exctype, e:
|
||||
print "Caught expected", exctype.__name__, ":"
|
||||
print e
|
||||
else:
|
||||
print "Failed to catch expected", exctype.__name__
|
||||
|
||||
def expect_parse_error(exctype, src):
|
||||
cf = ConfigParser.ConfigParser()
|
||||
sio = StringIO.StringIO(src)
|
||||
try:
|
||||
cf.readfp(sio)
|
||||
except exctype, e:
|
||||
print "Caught expected exception:", e
|
||||
else:
|
||||
print "Failed to catch expected", exctype.__name__
|
||||
|
||||
basic(r"""
|
||||
[Foo Bar]
|
||||
foo=bar
|
||||
[Spacey Bar]
|
||||
foo = bar
|
||||
[Commented Bar]
|
||||
foo: bar ; comment
|
||||
""")
|
||||
interpolation(r"""
|
||||
[Foo]
|
||||
bar=something %(with1)s interpolation (1 step)
|
||||
bar9=something %(with9)s lots of interpolation (9 steps)
|
||||
bar10=something %(with10)s lots of interpolation (10 steps)
|
||||
bar11=something %(with11)s lots of interpolation (11 steps)
|
||||
with11=%(with10)s
|
||||
with10=%(with9)s
|
||||
with9=%(with8)s
|
||||
with8=%(with7)s
|
||||
with7=%(with6)s
|
||||
with6=%(with5)s
|
||||
with5=%(with4)s
|
||||
with4=%(with3)s
|
||||
with3=%(with2)s
|
||||
with2=%(with1)s
|
||||
with1=with
|
||||
|
||||
[Mutual Recursion]
|
||||
foo=%(bar)s
|
||||
bar=%(foo)s
|
||||
""")
|
||||
parse_errors()
|
||||
query_errors()
|
||||
weird_errors()
|
|
@ -71,7 +71,7 @@ class AllTests:
|
|||
|
||||
def __hash__(self, *args):
|
||||
print "__hash__:", args
|
||||
return id(self)
|
||||
return hash(id(self))
|
||||
|
||||
def __str__(self, *args):
|
||||
print "__str__:", args
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
from test_support import TESTFN
|
||||
|
||||
import os
|
||||
import random
|
||||
|
||||
source = TESTFN + ".py"
|
||||
pyc = TESTFN + ".pyc"
|
||||
pyo = TESTFN + ".pyo"
|
||||
|
||||
f = open(source, "w")
|
||||
print >> f, "# This will test Python's ability to import a .py file"
|
||||
a = random.randrange(1000)
|
||||
b = random.randrange(1000)
|
||||
print >> f, "a =", a
|
||||
print >> f, "b =", b
|
||||
f.close()
|
||||
|
||||
try:
|
||||
try:
|
||||
mod = __import__(TESTFN)
|
||||
except ImportError, err:
|
||||
raise ValueError, "import from .py failed: %s" % err
|
||||
|
||||
if mod.a != a or mod.b != b:
|
||||
print a, "!=", mod.a
|
||||
print b, "!=", mod.b
|
||||
raise ValueError, "module loaded (%s) but contents invalid" % mod
|
||||
finally:
|
||||
os.unlink(source)
|
||||
|
||||
try:
|
||||
try:
|
||||
reload(mod)
|
||||
except ImportError, err:
|
||||
raise ValueError, "import from .pyc/.pyo failed: %s" % err
|
||||
finally:
|
||||
try:
|
||||
os.unlink(pyc)
|
||||
except os.error:
|
||||
pass
|
||||
try:
|
||||
os.unlink(pyo)
|
||||
except os.error:
|
||||
pass
|
|
@ -1,23 +1,89 @@
|
|||
from test_support import verbose, findfile, TestFailed, TestSkipped
|
||||
import linuxaudiodev
|
||||
|
||||
import errno
|
||||
import fcntl
|
||||
import linuxaudiodev
|
||||
import os
|
||||
import sys
|
||||
import select
|
||||
import sunaudio
|
||||
import time
|
||||
import audioop
|
||||
|
||||
SND_FORMAT_MULAW_8 = 1
|
||||
|
||||
def play_sound_file(path):
|
||||
fp = open(path, 'r')
|
||||
size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
|
||||
data = fp.read()
|
||||
fp.close()
|
||||
|
||||
if enc != SND_FORMAT_MULAW_8:
|
||||
print "Expect .au file with 8-bit mu-law samples"
|
||||
return
|
||||
|
||||
try:
|
||||
a = linuxaudiodev.open('w')
|
||||
except linuxaudiodev.error, msg:
|
||||
if msg[0] in (errno.EACCES, errno.ENODEV):
|
||||
raise TestSkipped, msg
|
||||
raise TestFailed, msg
|
||||
|
||||
# convert the data to 16-bit signed
|
||||
data = audioop.ulaw2lin(data, 2)
|
||||
|
||||
# set the data format
|
||||
if sys.byteorder == 'little':
|
||||
fmt = linuxaudiodev.AFMT_S16_LE
|
||||
else:
|
||||
a.write(data)
|
||||
a.close()
|
||||
fmt = linuxaudiodev.AFMT_S16_BE
|
||||
|
||||
# at least check that these methods can be invoked
|
||||
a.bufsize()
|
||||
a.obufcount()
|
||||
a.obuffree()
|
||||
a.getptr()
|
||||
a.fileno()
|
||||
|
||||
# set parameters based on .au file headers
|
||||
a.setparameters(rate, 16, nchannels, fmt)
|
||||
a.write(data)
|
||||
a.flush()
|
||||
a.close()
|
||||
|
||||
def test_errors():
|
||||
a = linuxaudiodev.open("w")
|
||||
size = 8
|
||||
fmt = linuxaudiodev.AFMT_U8
|
||||
rate = 8000
|
||||
nchannels = 1
|
||||
try:
|
||||
a.setparameters(-1, size, nchannels, fmt)
|
||||
except ValueError, msg:
|
||||
print msg
|
||||
try:
|
||||
a.setparameters(rate, -2, nchannels, fmt)
|
||||
except ValueError, msg:
|
||||
print msg
|
||||
try:
|
||||
a.setparameters(rate, size, 3, fmt)
|
||||
except ValueError, msg:
|
||||
print msg
|
||||
try:
|
||||
a.setparameters(rate, size, nchannels, 177)
|
||||
except ValueError, msg:
|
||||
print msg
|
||||
try:
|
||||
a.setparameters(rate, size, nchannels, linuxaudiodev.AFMT_U16_LE)
|
||||
except ValueError, msg:
|
||||
print msg
|
||||
try:
|
||||
a.setparameters(rate, 16, nchannels, fmt)
|
||||
except ValueError, msg:
|
||||
print msg
|
||||
|
||||
def test():
|
||||
play_sound_file(findfile('audiotest.au'))
|
||||
test_errors()
|
||||
|
||||
test()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# test for xml.dom.minidom
|
||||
|
||||
from xml.dom.minidom import parse, Node, Document, parseString
|
||||
import xml.parsers.expat
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
|
@ -34,8 +35,6 @@ def testGetElementsByTagName( ):
|
|||
confirm( dom.getElementsByTagName( "LI" )==\
|
||||
dom.documentElement.getElementsByTagName( "LI" ) )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm (len( Node.allnodes )==0)
|
||||
|
||||
def testInsertBefore( ):
|
||||
dom=parse( tstfile )
|
||||
|
@ -49,9 +48,6 @@ def testInsertBefore( ):
|
|||
#confirm( docel.childNodes[0].tet=="a" )
|
||||
#confirm( docel.childNodes[2].tet=="a" )
|
||||
dom.unlink()
|
||||
del dom
|
||||
del docel
|
||||
confirm( len( Node.allnodes )==0)
|
||||
|
||||
def testAppendChild():
|
||||
dom=parse( tstfile )
|
||||
|
@ -59,8 +55,6 @@ def testAppendChild():
|
|||
confirm( dom.documentElement.childNodes[-1].nodeName=="#comment" )
|
||||
confirm( dom.documentElement.childNodes[-1].data=="Hello" )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testNonZero():
|
||||
dom=parse( tstfile )
|
||||
|
@ -68,29 +62,22 @@ def testNonZero():
|
|||
dom.appendChild( dom.createComment( "foo" ) )
|
||||
confirm( not dom.childNodes[-1].childNodes )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testUnlink():
|
||||
dom=parse( tstfile )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testElement():
|
||||
dom=Document()
|
||||
dom.appendChild( dom.createElement( "abc" ) )
|
||||
confirm( dom.documentElement )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm( 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/>" )
|
||||
|
@ -98,7 +85,6 @@ def testAAB():
|
|||
el.setAttribute( "spam", "jam" )
|
||||
el.setAttribute( "spam", "jam2" )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
|
||||
def testAddAttr():
|
||||
dom=Document()
|
||||
|
@ -119,10 +105,7 @@ def testAddAttr():
|
|||
confirm( child.attributes["def"].value=="newval" )
|
||||
|
||||
confirm( len( child.attributes )==2 )
|
||||
|
||||
dom.unlink()
|
||||
dom=None
|
||||
child=None
|
||||
|
||||
def testDeleteAttr():
|
||||
dom=Document()
|
||||
|
@ -134,7 +117,6 @@ def testDeleteAttr():
|
|||
del child.attributes["def"]
|
||||
confirm( len( child.attributes)==0 )
|
||||
dom.unlink()
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testRemoveAttr():
|
||||
dom=Document()
|
||||
|
@ -159,7 +141,6 @@ def testRemoveAttrNS():
|
|||
confirm( len( child.attributes )==1 )
|
||||
|
||||
dom.unlink()
|
||||
dom=None
|
||||
|
||||
def testRemoveAttributeNode():
|
||||
dom=Document()
|
||||
|
@ -171,8 +152,6 @@ def testRemoveAttributeNode():
|
|||
confirm( len( child.attributes )==0 )
|
||||
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testChangeAttr():
|
||||
dom=parseString( "<abc/>" )
|
||||
|
@ -188,8 +167,6 @@ def testChangeAttr():
|
|||
el.attributes[ "spam2"]= "bam2"
|
||||
confirm( len( el.attributes )==2 )
|
||||
dom.unlink()
|
||||
dom=None
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testGetAttrList():
|
||||
pass
|
||||
|
@ -235,6 +212,7 @@ def _testElementReprAndStrUnicodeNS():
|
|||
confirm( string1==string2 )
|
||||
confirm( string1.find("slash:abc" )!=-1 )
|
||||
dom.unlink()
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testAttributeRepr():
|
||||
dom=Document()
|
||||
|
@ -242,10 +220,17 @@ def testAttributeRepr():
|
|||
node=el.setAttribute( "abc", "def" )
|
||||
confirm( str( node ) == repr( node ) )
|
||||
dom.unlink()
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testTextNodeRepr(): pass
|
||||
|
||||
def testWriteXML(): pass
|
||||
def testWriteXML():
|
||||
str = '<a b="c"/>'
|
||||
dom = parseString(str)
|
||||
domstr = dom.toxml()
|
||||
dom.unlink()
|
||||
confirm(str == domstr)
|
||||
confirm( len( Node.allnodes )==0 )
|
||||
|
||||
def testProcessingInstruction(): pass
|
||||
|
||||
|
@ -335,6 +320,8 @@ for name in names:
|
|||
try:
|
||||
func()
|
||||
print "Test Succeeded", name
|
||||
confirm(len(Node.allnodes) == 0,
|
||||
"assertion: len(Node.allnodes) == 0")
|
||||
if len( Node.allnodes ):
|
||||
print "Garbage left over:"
|
||||
if verbose:
|
||||
|
|
|
@ -1,15 +1,134 @@
|
|||
# Tests StringIO and cStringIO
|
||||
#! /usr/bin/env python
|
||||
|
||||
import string
|
||||
# Sanity checker for time.strftime
|
||||
|
||||
def do_test(module):
|
||||
s = (string.letters+'\n')*5
|
||||
f = module.StringIO(s)
|
||||
print f.read(10)
|
||||
print f.readline()
|
||||
print len(f.readlines(60))
|
||||
import time, calendar, sys, string, os, re
|
||||
from test_support import verbose
|
||||
|
||||
# Don't bother testing cStringIO without
|
||||
import StringIO, cStringIO
|
||||
do_test(StringIO)
|
||||
do_test(cStringIO)
|
||||
def main():
|
||||
global verbose
|
||||
now = time.time()
|
||||
strftest(now)
|
||||
verbose = 0
|
||||
# Try a bunch of dates and times, chosen to vary through time of
|
||||
# day and daylight saving time
|
||||
for j in range(-5, 5):
|
||||
for i in range(25):
|
||||
strftest(now + (i + j*100)*23*3603)
|
||||
|
||||
def strftest(now):
|
||||
if verbose:
|
||||
print "strftime test for", time.ctime(now)
|
||||
nowsecs = str(long(now))[:-1]
|
||||
gmt = time.gmtime(now)
|
||||
now = time.localtime(now)
|
||||
|
||||
if now[3] < 12: ampm='(AM|am)'
|
||||
else: ampm='(PM|pm)'
|
||||
|
||||
jan1 = time.localtime(time.mktime((now[0], 1, 1) + (0,)*6))
|
||||
|
||||
try:
|
||||
if now[8]: tz = time.tzname[1]
|
||||
else: tz = time.tzname[0]
|
||||
except AttributeError:
|
||||
tz = ''
|
||||
|
||||
if now[3] > 12: clock12 = now[3] - 12
|
||||
elif now[3] > 0: clock12 = now[3]
|
||||
else: clock12 = 12
|
||||
|
||||
expectations = (
|
||||
('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'),
|
||||
('%A', calendar.day_name[now[6]], 'full weekday name'),
|
||||
('%b', calendar.month_abbr[now[1]], 'abbreviated month name'),
|
||||
('%B', calendar.month_name[now[1]], 'full month name'),
|
||||
# %c see below
|
||||
('%d', '%02d' % now[2], 'day of month as number (00-31)'),
|
||||
('%H', '%02d' % now[3], 'hour (00-23)'),
|
||||
('%I', '%02d' % clock12, 'hour (01-12)'),
|
||||
('%j', '%03d' % now[7], 'julian day (001-366)'),
|
||||
('%m', '%02d' % now[1], 'month as number (01-12)'),
|
||||
('%M', '%02d' % now[4], 'minute, (00-59)'),
|
||||
('%p', ampm, 'AM or PM as appropriate'),
|
||||
('%S', '%02d' % now[5], 'seconds of current time (00-60)'),
|
||||
('%U', '%02d' % ((now[7] + jan1[6])/7),
|
||||
'week number of the year (Sun 1st)'),
|
||||
('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'),
|
||||
('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)/7),
|
||||
'week number of the year (Mon 1st)'),
|
||||
# %x see below
|
||||
('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
|
||||
('%y', '%02d' % (now[0]%100), 'year without century'),
|
||||
('%Y', '%d' % now[0], 'year with century'),
|
||||
# %Z see below
|
||||
('%%', '%', 'single percent sign'),
|
||||
)
|
||||
|
||||
nonstandard_expectations = (
|
||||
# These are standard but don't have predictable output
|
||||
('%c', fixasctime(time.asctime(now)), 'near-asctime() format'),
|
||||
('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)),
|
||||
'%m/%d/%y %H:%M:%S'),
|
||||
('%Z', '%s' % tz, 'time zone name'),
|
||||
|
||||
# These are some platform specific extensions
|
||||
('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'),
|
||||
('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'),
|
||||
('%h', calendar.month_abbr[now[1]], 'abbreviated month name'),
|
||||
('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'),
|
||||
('%n', '\n', 'newline character'),
|
||||
('%r', '%02d:%02d:%02d %s' % (clock12, now[4], now[5], ampm),
|
||||
'%I:%M:%S %p'),
|
||||
('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'),
|
||||
('%s', nowsecs, 'seconds since the Epoch in UCT'),
|
||||
('%t', '\t', 'tab character'),
|
||||
('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
|
||||
('%3y', '%03d' % (now[0]%100),
|
||||
'year without century rendered using fieldwidth'),
|
||||
)
|
||||
|
||||
if verbose:
|
||||
print "Strftime test, platform: %s, Python version: %s" % \
|
||||
(sys.platform, string.split(sys.version)[0])
|
||||
|
||||
for e in expectations:
|
||||
try:
|
||||
result = time.strftime(e[0], now)
|
||||
except ValueError, error:
|
||||
print "Standard '%s' format gave error:" % e[0], error
|
||||
continue
|
||||
if re.match(e[1], result): continue
|
||||
if not result or result[0] == '%':
|
||||
print "Does not support standard '%s' format (%s)" % (e[0], e[2])
|
||||
else:
|
||||
print "Conflict for %s (%s):" % (e[0], e[2])
|
||||
print " Expected %s, but got %s" % (e[1], result)
|
||||
|
||||
for e in nonstandard_expectations:
|
||||
try:
|
||||
result = time.strftime(e[0], now)
|
||||
except ValueError, result:
|
||||
if verbose:
|
||||
print "Error for nonstandard '%s' format (%s): %s" % \
|
||||
(e[0], e[2], str(result))
|
||||
continue
|
||||
if re.match(e[1], result):
|
||||
if verbose:
|
||||
print "Supports nonstandard '%s' format (%s)" % (e[0], e[2])
|
||||
elif not result or result[0] == '%':
|
||||
if verbose:
|
||||
print "Does not appear to support '%s' format (%s)" % (e[0],
|
||||
e[2])
|
||||
else:
|
||||
if verbose:
|
||||
print "Conflict for nonstandard '%s' format (%s):" % (e[0],
|
||||
e[2])
|
||||
print " Expected %s, but got %s" % (e[1], result)
|
||||
|
||||
def fixasctime(s):
|
||||
if s[8] == ' ':
|
||||
s = s[:8] + '0' + s[9:]
|
||||
return s
|
||||
|
||||
main()
|
||||
|
|
|
@ -341,6 +341,7 @@ assert '...%(foo)s...' % {u'foo':u"abc"} == u'...abc...'
|
|||
assert '...%(foo)s...' % {u'foo':u"abc",'def':123} == u'...abc...'
|
||||
assert '...%(foo)s...' % {u'foo':u"abc",u'def':123} == u'...abc...'
|
||||
assert '...%s...%s...%s...%s...' % (1,2,3,u"abc") == u'...1...2...3...abc...'
|
||||
assert '...%%...%%s...%s...%s...%s...%s...' % (1,2,3,u"abc") == u'...%...%s...1...2...3...abc...'
|
||||
assert '...%s...' % u"abc" == u'...abc...'
|
||||
print 'done.'
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
# Minimal test of the quote function
|
||||
import urllib
|
||||
|
||||
chars = 'abcdefghijklmnopqrstuvwxyz'\
|
||||
'\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356' \
|
||||
'\357\360\361\362\363\364\365\366\370\371\372\373\374\375\376\377' \
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
|
||||
'\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317' \
|
||||
'\320\321\322\323\324\325\326\330\331\332\333\334\335\336'
|
||||
|
||||
expected = 'abcdefghijklmnopqrstuvwxyz%df%e0%e1%e2%e3%e4%e5%e6%e7%e8%e9%ea%eb%ec%ed%ee%ef%f0%f1%f2%f3%f4%f5%f6%f8%f9%fa%fb%fc%fd%fe%ffABCDEFGHIJKLMNOPQRSTUVWXYZ%c0%c1%c2%c3%c4%c5%c6%c7%c8%c9%ca%cb%cc%cd%ce%cf%d0%d1%d2%d3%d4%d5%d6%d8%d9%da%db%dc%dd%de'
|
||||
|
||||
test = urllib.quote(chars)
|
||||
assert test == expected, "urllib.quote problem"
|
||||
test2 = urllib.unquote(expected)
|
||||
assert test2 == chars
|
||||
|
||||
in1 = "abc/def"
|
||||
out1_1 = "abc/def"
|
||||
out1_2 = "abc%2fdef"
|
||||
|
||||
assert urllib.quote(in1) == out1_1, "urllib.quote problem"
|
||||
assert urllib.quote(in1, '') == out1_2, "urllib.quote problem"
|
||||
|
||||
in2 = "abc?def"
|
||||
out2_1 = "abc%3fdef"
|
||||
out2_2 = "abc?def"
|
||||
|
||||
assert urllib.quote(in2) == out2_1, "urllib.quote problem"
|
||||
assert urllib.quote(in2, '?') == out2_2, "urllib.quote problem"
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
from test_support import TestFailed
|
||||
import os, tempfile
|
||||
import wave
|
||||
|
||||
def check(t, msg=None):
|
||||
if not t:
|
||||
raise TestFailed, msg
|
||||
|
||||
nchannels = 2
|
||||
sampwidth = 2
|
||||
framerate = 8000
|
||||
nframes = 100
|
||||
|
||||
testfile = tempfile.mktemp()
|
||||
|
||||
f = wave.open(testfile, 'w')
|
||||
f.setnchannels(nchannels)
|
||||
f.setsampwidth(sampwidth)
|
||||
f.setframerate(framerate)
|
||||
f.setnframes(nframes)
|
||||
output = '\0' * nframes * nchannels * sampwidth
|
||||
f.writeframes(output)
|
||||
f.close()
|
||||
|
||||
f = wave.open(testfile, 'r')
|
||||
check(nchannels == f.getnchannels(), "nchannels")
|
||||
check(sampwidth == f.getsampwidth(), "sampwidth")
|
||||
check(framerate == f.getframerate(), "framerate")
|
||||
check(nframes == f.getnframes(), "nframes")
|
||||
input = f.readframes(nframes)
|
||||
check(input == output, "data")
|
||||
f.close()
|
||||
|
||||
os.remove(testfile)
|
|
@ -1,147 +1,7 @@
|
|||
# Test the windows specific win32reg module.
|
||||
# Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey
|
||||
# Ridiculously simple test of the winsound module for Windows.
|
||||
|
||||
from _winreg import *
|
||||
import os, sys
|
||||
|
||||
test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
|
||||
|
||||
test_data = [
|
||||
("Int Value", 45, REG_DWORD),
|
||||
("String Val", "A string value", REG_SZ,),
|
||||
(u"Unicode Val", u"A Unicode value", REG_SZ,),
|
||||
("StringExpand", "The path is %path%", REG_EXPAND_SZ),
|
||||
("UnicodeExpand", u"The path is %path%", REG_EXPAND_SZ),
|
||||
("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ),
|
||||
("Multi-unicode", [u"Lots", u"of", u"unicode", u"values"], REG_MULTI_SZ),
|
||||
("Multi-mixed", [u"Unicode", u"and", "string", "values"],REG_MULTI_SZ),
|
||||
("Raw Data", ("binary"+chr(0)+"data"), REG_BINARY),
|
||||
]
|
||||
|
||||
def WriteTestData(root_key):
|
||||
# Set the default value for this key.
|
||||
SetValue(root_key, test_key_name, REG_SZ, "Default value")
|
||||
key = CreateKey(root_key, test_key_name)
|
||||
# Create a sub-key
|
||||
sub_key = CreateKey(key, "sub_key")
|
||||
# Give the sub-key some named values
|
||||
|
||||
for value_name, value_data, value_type in test_data:
|
||||
SetValueEx(sub_key, value_name, 0, value_type, value_data)
|
||||
|
||||
# Check we wrote as many items as we thought.
|
||||
nkeys, nvalues, since_mod = QueryInfoKey(key)
|
||||
assert nkeys==1, "Not the correct number of sub keys"
|
||||
assert nvalues==1, "Not the correct number of values"
|
||||
nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
|
||||
assert nkeys==0, "Not the correct number of sub keys"
|
||||
assert nvalues==len(test_data), "Not the correct number of values"
|
||||
# Close this key this way...
|
||||
# (but before we do, copy the key as an integer - this allows
|
||||
# us to test that the key really gets closed).
|
||||
int_sub_key = int(sub_key)
|
||||
CloseKey(sub_key)
|
||||
try:
|
||||
QueryInfoKey(int_sub_key)
|
||||
raise RuntimeError, "It appears the CloseKey() function does not close the actual key!"
|
||||
except EnvironmentError:
|
||||
pass
|
||||
# ... and close that key that way :-)
|
||||
int_key = int(key)
|
||||
key.Close()
|
||||
try:
|
||||
QueryInfoKey(int_key)
|
||||
raise RuntimeError, "It appears the key.Close() function does not close the actual key!"
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
def ReadTestData(root_key):
|
||||
# Check we can get default value for this key.
|
||||
val = QueryValue(root_key, test_key_name)
|
||||
assert val=="Default value", "Registry didn't give back the correct value"
|
||||
|
||||
key = OpenKey(root_key, test_key_name)
|
||||
# Read the sub-keys
|
||||
sub_key = OpenKey(key, "sub_key")
|
||||
# Check I can enumerate over the values.
|
||||
index = 0
|
||||
while 1:
|
||||
try:
|
||||
data = EnumValue(sub_key, index)
|
||||
except EnvironmentError:
|
||||
break
|
||||
assert data in test_data, "Didn't read back the correct test data"
|
||||
index = index + 1
|
||||
assert index==len(test_data), "Didn't read the correct number of items"
|
||||
# Check I can directly access each item
|
||||
for value_name, value_data, value_type in test_data:
|
||||
read_val, read_typ = QueryValueEx(sub_key, value_name)
|
||||
assert read_val==value_data and read_typ == value_type, \
|
||||
"Could not directly read the value"
|
||||
sub_key.Close()
|
||||
# Enumerate our main key.
|
||||
read_val = EnumKey(key, 0)
|
||||
assert read_val == "sub_key", "Read subkey value wrong"
|
||||
try:
|
||||
EnumKey(key, 1)
|
||||
assert 0, "Was able to get a second key when I only have one!"
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
key.Close()
|
||||
|
||||
def DeleteTestData(root_key):
|
||||
key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
|
||||
sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
|
||||
# It is not necessary to delete the values before deleting
|
||||
# the key (although subkeys must not exist). We delete them
|
||||
# manually just to prove we can :-)
|
||||
for value_name, value_data, value_type in test_data:
|
||||
DeleteValue(sub_key, value_name)
|
||||
|
||||
nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
|
||||
assert nkeys==0 and nvalues==0, "subkey not empty before delete"
|
||||
sub_key.Close()
|
||||
DeleteKey(key, "sub_key")
|
||||
|
||||
try:
|
||||
# Shouldnt be able to delete it twice!
|
||||
DeleteKey(key, "sub_key")
|
||||
assert 0, "Deleting the key twice succeeded"
|
||||
except EnvironmentError:
|
||||
pass
|
||||
key.Close()
|
||||
DeleteKey(root_key, test_key_name)
|
||||
# Opening should now fail!
|
||||
try:
|
||||
key = OpenKey(root_key, test_key_name)
|
||||
assert 0, "Could open the non-existent key"
|
||||
except WindowsError: # Use this error name this time
|
||||
pass
|
||||
|
||||
def TestAll(root_key):
|
||||
WriteTestData(root_key)
|
||||
ReadTestData(root_key)
|
||||
DeleteTestData(root_key)
|
||||
|
||||
# Test on my local machine.
|
||||
TestAll(HKEY_CURRENT_USER)
|
||||
print "Local registry tests worked"
|
||||
try:
|
||||
remote_name = sys.argv[sys.argv.index("--remote")+1]
|
||||
except (IndexError, ValueError):
|
||||
remote_name = None
|
||||
|
||||
if remote_name is not None:
|
||||
try:
|
||||
remote_key = ConnectRegistry(remote_name, HKEY_CURRENT_USER)
|
||||
except EnvironmentError, exc:
|
||||
print "Could not connect to the remote machine -", exc.strerror
|
||||
remote_key = None
|
||||
if remote_key is not None:
|
||||
TestAll(remote_key)
|
||||
print "Remote registry tests worked"
|
||||
else:
|
||||
print "Remote registry calls can be tested using",
|
||||
print "'test_winreg.py --remote \\\\machine_name'"
|
||||
import winsound
|
||||
for i in range(100, 2000, 100):
|
||||
winsound.Beep(i, 75)
|
||||
print "Hopefully you heard some sounds increasing in frequency!"
|
||||
|
||||
|
|
|
@ -24,9 +24,7 @@ class UserList:
|
|||
def __delitem__(self, i): del self.data[i]
|
||||
def __getslice__(self, i, j):
|
||||
i = max(i, 0); j = max(j, 0)
|
||||
userlist = self.__class__()
|
||||
userlist.data[:] = self.data[i:j]
|
||||
return userlist
|
||||
return self.__class__(self.data[i:j])
|
||||
def __setslice__(self, i, j, other):
|
||||
i = max(i, 0); j = max(j, 0)
|
||||
if isinstance(other, UserList):
|
||||
|
|
|
@ -196,9 +196,7 @@ if sys.platform[:3] == "win":
|
|||
register("windows-default", WindowsDefault)
|
||||
DEFAULT_BROWSER = "windows-default"
|
||||
elif os.environ.get("DISPLAY"):
|
||||
if os.environ.get("KDEDIR"):
|
||||
DEFAULT_BROWSER = "kfm"
|
||||
elif _iscommand("netscape"):
|
||||
if _iscommand("netscape"):
|
||||
DEFAULT_BROWSER = "netscape"
|
||||
|
||||
# If the $BROWSER environment variable is set and true, let that be
|
||||
|
|
Loading…
Reference in New Issue