The usual (and some new modules).
This commit is contained in:
parent
d57548023f
commit
a11ccccd24
|
@ -0,0 +1,221 @@
|
|||
#
|
||||
# DSA.py : Stupid name. Should really be called qNEW.py or something.
|
||||
# Suggestions for a better name would be welcome.
|
||||
#
|
||||
# Maintained by A.M. Kuchling (amk@magnet.com)
|
||||
# Date: 1997/09/03
|
||||
#
|
||||
# Distribute and use freely; there are no restrictions on further
|
||||
# dissemination and usage except those imposed by the laws of your
|
||||
# country of residence.
|
||||
#
|
||||
|
||||
# TODO :
|
||||
# Change the name
|
||||
# Add more comments and docstrings
|
||||
# Write documentation
|
||||
# Add better RNG (?)
|
||||
|
||||
import types, md5
|
||||
|
||||
error = 'DSA module error'
|
||||
|
||||
def RandomNumber(N, randfunc):
|
||||
"Get an N-bit random number"
|
||||
str=randfunc(N/8)
|
||||
char=ord(randfunc(1))>>(8-(N%8))
|
||||
return Str2Int(chr(char)+str)
|
||||
|
||||
def Int2Str(n):
|
||||
"Convert an integer to a string form"
|
||||
s=''
|
||||
while n>0:
|
||||
s=chr(n & 255)+s
|
||||
n=n>>8
|
||||
return s
|
||||
|
||||
def Str2Int(s):
|
||||
"Convert a string to a long integer"
|
||||
if type(s)!=types.StringType: return s # Integers will be left alone
|
||||
return reduce(lambda x,y : x*256+ord(y), s, 0L)
|
||||
|
||||
|
||||
def getPrime(N, randfunc):
|
||||
"Find a prime number measuring N bits"
|
||||
number=RandomNumber(N, randfunc) | 1
|
||||
while (not isPrime(number)):
|
||||
number=number+2
|
||||
return number
|
||||
|
||||
sieve=[2,3,5,7,11,13,17,19,23,29,31,37,41]
|
||||
def isPrime(N):
|
||||
"""Test if a number N is prime, using a simple sieve check,
|
||||
followed by a more elaborate Rabin-Miller test."""
|
||||
for i in sieve:
|
||||
if (N % i)==0: return 0
|
||||
N1=N - 1L ; n=1L
|
||||
while (n<N): n=n<<1L # Compute number of bits in N
|
||||
for j in sieve:
|
||||
a=long(j) ; d=1L ; t=n
|
||||
while (t): # Iterate over the bits in N1
|
||||
x=(d*d) % N
|
||||
if x==1L and d!=1L and d!=N1: return 0 # Square root of 1 found
|
||||
if N1 & t: d=(x*a) % N
|
||||
else: d=x
|
||||
t=t>>1L
|
||||
if d!=1L: return 0
|
||||
return 1
|
||||
|
||||
class DSAobj:
|
||||
def size(self):
|
||||
"Return the max. number of bits that can be handled by this key"
|
||||
bits, power = 0,1L
|
||||
while (power<self.p): bits, power = bits+1, power<<1
|
||||
return bits-1
|
||||
|
||||
def hasprivate(self):
|
||||
"""Return a Boolean denoting whether the object contains private components"""
|
||||
if hasattr(self, 'x'): return 1
|
||||
else: return 0
|
||||
|
||||
def cansign(self):
|
||||
return self.hasprivate()
|
||||
def canencrypt(self):
|
||||
return 0
|
||||
|
||||
def publickey(self):
|
||||
new=DSAobj()
|
||||
for i in 'pqgy': setattr(new, i, getattr(self, i))
|
||||
return new
|
||||
|
||||
def _sign(self, M, K):
|
||||
if (self.q<=K):
|
||||
raise error, 'K is greater than q'
|
||||
r=pow(self.g, K, self.p) % self.q
|
||||
s=(K- (r*M*self.x % self.q)) % self.q
|
||||
return (r,s)
|
||||
def _verify(self, M, sig):
|
||||
r, s = sig
|
||||
if r<=0 or r>=self.q or s<=0 or s>=self.q: return 0
|
||||
v1=pow(self.g, s, self.p)
|
||||
v2=pow(self.y, M*r, self.p)
|
||||
v=((v1*v2) % self.p)
|
||||
v=v % self.q
|
||||
if v==r: return 1
|
||||
return 0
|
||||
|
||||
def sign(self, M, K):
|
||||
if (not self.hasprivate()):
|
||||
raise error, 'Private key not available in this object'
|
||||
if type(M)==types.StringType: M=Str2Int(M)
|
||||
if type(K)==types.StringType: K=Str2Int(K)
|
||||
return self._sign(M, K)
|
||||
def verify(self, M, signature):
|
||||
if type(M)==types.StringType: M=Str2Int(M)
|
||||
return self._verify(M, signature)
|
||||
validate=verify
|
||||
|
||||
def generate(self, L, randfunc, progress_func=None):
|
||||
"""Generate a private key with L bits"""
|
||||
HASHBITS=128 # Number of bits in the hashing algorithm used
|
||||
# (128 for MD5; change to 160 for SHA)
|
||||
|
||||
if L<512: raise error, 'Key length <512 bits'
|
||||
# Generate string S and prime q
|
||||
if progress_func: apply(progress_func, ('p,q\n',))
|
||||
while (1):
|
||||
self.q = getPrime(160, randfunc)
|
||||
S = Int2Str(self.q)
|
||||
n=(L-1)/HASHBITS
|
||||
C, N, V = 0, 2, {}
|
||||
# b=(self.q >> 5) & 15
|
||||
b= (L-1) % HASHBITS
|
||||
powb=pow(long(2), b)
|
||||
powL1=pow(long(2), L-1)
|
||||
while C<4096:
|
||||
for k in range(0, n+1):
|
||||
V[k]=Str2Int(md5.new(S+str(N)+str(k)).digest())
|
||||
W=V[n] % powb
|
||||
for k in range(n-1, -1, -1):
|
||||
W=(W<< long(HASHBITS) )+V[k]
|
||||
X=W+powL1
|
||||
p=X-(X%(2*self.q)-1)
|
||||
if powL1<=p and isPrime(p): break
|
||||
C, N = C+1, N+n+1
|
||||
if C<4096: break
|
||||
if progress_func: apply(progress_func, ('4096 multiples failed\n',) )
|
||||
self.p = p
|
||||
power=(p-1)/self.q
|
||||
if progress_func: apply(progress_func, ('h,g\n',))
|
||||
while (1):
|
||||
h=Str2Int(randfunc(L)) % (p-1)
|
||||
g=pow(h, power, p)
|
||||
if 1<h<p-1 and g>1: break
|
||||
self.g=g
|
||||
if progress_func: apply(progress_func, ('x,y\n',))
|
||||
while (1):
|
||||
x=Str2Int(randfunc(20))
|
||||
if 0<x<self.q: break
|
||||
self.x, self.y=x, pow(g, x, p)
|
||||
return self
|
||||
|
||||
object=DSAobj
|
||||
|
||||
# XXX this random number generation function sucks, since it isn't
|
||||
# cryptographically strong! But it'll do for this first release...
|
||||
|
||||
def randfunc(N):
|
||||
import os, string
|
||||
if string.lower(os.uname()[0])=='linux':
|
||||
# On Linux, use /dev/urandom
|
||||
f=open('/dev/urandom', 'r')
|
||||
return f.read(N)
|
||||
else:
|
||||
import time
|
||||
s=""
|
||||
while len(s)<N:
|
||||
rand=md5.new(str(time.time())).digest()
|
||||
s=s+rand
|
||||
return s[0:N]
|
||||
|
||||
if __name__=='__main__':
|
||||
import sys, string
|
||||
BITS=512
|
||||
if len(sys.argv)>1:
|
||||
BITS=string.atoi(sys.argv[1])
|
||||
print ' Generating', BITS, 'bit key'
|
||||
key=DSAobj()
|
||||
key.generate(BITS, randfunc, sys.stdout.write)
|
||||
print ' Key data: (the private key is x)'
|
||||
for i in 'xygqp': print '\t', i, ':', hex(getattr(key, i))
|
||||
plaintext="Hello"
|
||||
|
||||
if key.cansign():
|
||||
print ' Signature test'
|
||||
print "Plaintext:", plaintext
|
||||
K=getPrime(30, randfunc)
|
||||
signature=key.sign(plaintext, K)
|
||||
print "Signature:", signature
|
||||
result=key.verify(plaintext, signature)
|
||||
if not result:
|
||||
print " Sig. verification failed when it should have succeeded"
|
||||
else: print 'Signature verified'
|
||||
|
||||
# Test on a mangled plaintext
|
||||
result=key.verify(plaintext[:-1], signature)
|
||||
if result:
|
||||
print " Sig. verification succeeded when it should have failed"
|
||||
|
||||
# Change a single bit in the plaintext
|
||||
badtext=plaintext[:-3]+chr( 1 ^ ord(plaintext[-3]) )+plaintext[-3:]
|
||||
result=key.verify(badtext, signature)
|
||||
if result:
|
||||
print " Sig. verification succeeded when it should have failed"
|
||||
|
||||
print 'Removing private key data'
|
||||
pubonly=key.publickey()
|
||||
result=pubonly.verify(plaintext, signature)
|
||||
if not result:
|
||||
print " Sig. verification failed when it should have succeeded"
|
||||
else:
|
||||
print 'Signature verified'
|
|
@ -0,0 +1,155 @@
|
|||
"""Class based built-in exception hierarchy.
|
||||
|
||||
This is a new feature whereby all the standard built-in exceptions,
|
||||
traditionally string objects, are replaced with classes. This gives
|
||||
Python's exception handling mechanism a more object-oriented feel.
|
||||
|
||||
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.
|
||||
|
||||
To disable this feature, start the Python executable with the -X option.
|
||||
|
||||
Here is a rundown of the class hierarchy. You can change this by
|
||||
editing this file, but it isn't recommended. The classes with a `*'
|
||||
are new with this feature. They are defined as tuples containing the
|
||||
derived exceptions when string-based exceptions are used.
|
||||
|
||||
Exception(*)
|
||||
|
|
||||
+-- StandardError(*)
|
||||
|
|
||||
+-- SystemExit
|
||||
+-- KeyboardInterrupt
|
||||
+-- ImportError
|
||||
+-- IOError
|
||||
+-- EOFError
|
||||
+-- RuntimeError
|
||||
+-- NameError
|
||||
+-- AttributeError
|
||||
+-- SyntaxError
|
||||
+-- TypeError
|
||||
+-- AssertionError
|
||||
+-- LookupError(*)
|
||||
| |
|
||||
| +-- IndexError
|
||||
| +-- KeyError
|
||||
|
|
||||
+-- ArithmeticError(*)
|
||||
| |
|
||||
| +-- OverflowError
|
||||
| +-- ZeroDivisionError
|
||||
| +-- FloatingPointError
|
||||
|
|
||||
+-- ValueError
|
||||
+-- SystemError
|
||||
+-- MemoryError
|
||||
"""
|
||||
|
||||
class Exception:
|
||||
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):
|
||||
pass
|
||||
|
||||
class SyntaxError(StandardError):
|
||||
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 IOError(StandardError):
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
self.errno = None
|
||||
self.strerror = None
|
||||
if len(args) == 2:
|
||||
# common case: PyErr_SetFromErrno()
|
||||
self.errno = args[0]
|
||||
self.strerror = args[1]
|
||||
|
||||
class RuntimeError(StandardError):
|
||||
pass
|
||||
|
||||
class SystemError(StandardError):
|
||||
pass
|
||||
|
||||
class EOFError(StandardError):
|
||||
pass
|
||||
|
||||
class ImportError(StandardError):
|
||||
pass
|
||||
|
||||
class TypeError(StandardError):
|
||||
pass
|
||||
|
||||
class ValueError(StandardError):
|
||||
pass
|
||||
|
||||
class KeyboardInterrupt(StandardError):
|
||||
pass
|
||||
|
||||
class AssertionError(StandardError):
|
||||
pass
|
||||
|
||||
class ArithmeticError(StandardError):
|
||||
pass
|
||||
|
||||
class OverflowError(ArithmeticError):
|
||||
pass
|
||||
|
||||
class FloatingPointError(ArithmeticError):
|
||||
pass
|
||||
|
||||
class ZeroDivisionError(ArithmeticError):
|
||||
pass
|
||||
|
||||
class LookupError(StandardError):
|
||||
pass
|
||||
|
||||
class IndexError(LookupError):
|
||||
pass
|
||||
|
||||
class KeyError(LookupError):
|
||||
pass
|
||||
|
||||
class AttributeError(StandardError):
|
||||
pass
|
||||
|
||||
class NameError(StandardError):
|
||||
pass
|
||||
|
||||
class MemoryError(StandardError):
|
||||
pass
|
||||
|
||||
class SystemExit(Exception):
|
||||
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,190 @@
|
|||
"""Guess the MIME type of a file.
|
||||
|
||||
This module defines one useful function:
|
||||
|
||||
guess_type(url) -- guess the MIME type and encoding of a URL.
|
||||
|
||||
It also contains the following, for tuning the behavior:
|
||||
|
||||
Data:
|
||||
|
||||
knownfiles -- list of files to parse
|
||||
inited -- flag set when init() has been called
|
||||
suffixes_map -- dictionary mapping suffixes to suffixes
|
||||
encodings_map -- dictionary mapping suffixes to encodings
|
||||
types_map -- dictionary mapping suffixes to types
|
||||
|
||||
Functions:
|
||||
|
||||
init([files]) -- parse a list of files, default knownfiles
|
||||
read_mime_types(file) -- parse one file, return a dictionary or None
|
||||
|
||||
"""
|
||||
|
||||
import string
|
||||
import posixpath
|
||||
|
||||
knownfiles = [
|
||||
"/usr/local/etc/httpd/conf/mime.types",
|
||||
"/usr/local/lib/netscape/mime.types",
|
||||
]
|
||||
|
||||
inited = 0
|
||||
|
||||
def guess_type(url):
|
||||
"""Guess the type of a file based on its URL.
|
||||
|
||||
Return value is a tuple (type, encoding) where type is None if the
|
||||
type can't be guessed (no or unknown suffix) or a string of the
|
||||
form type/subtype, usable for a MIME Content-type header; and
|
||||
encoding is None for no encoding or the name of the program used
|
||||
to encode (e.g. compress or gzip). The mappings are table
|
||||
driven. Encoding suffixes are case sensitive; type suffixes are
|
||||
first tried case sensitive, then case insensitive.
|
||||
|
||||
The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped
|
||||
to ".tar.gz". (This is table-driven too, using the dictionary
|
||||
suffixes_map).
|
||||
|
||||
"""
|
||||
if not inited:
|
||||
init()
|
||||
base, ext = posixpath.splitext(url)
|
||||
while suffix_map.has_key(ext):
|
||||
base, ext = posixpath.splitext(base + suffix_map[ext])
|
||||
if encodings_map.has_key(ext):
|
||||
encoding = encodings_map[ext]
|
||||
base, ext = posixpath.splitext(base)
|
||||
else:
|
||||
encoding = None
|
||||
if types_map.has_key(ext):
|
||||
return types_map[ext], encoding
|
||||
elif types_map.has_key(string.lower(ext)):
|
||||
return types_map[string.lower(ext)], encoding
|
||||
else:
|
||||
return None, encoding
|
||||
|
||||
def init(files=None):
|
||||
global inited
|
||||
for file in files or knownfiles:
|
||||
s = read_mime_types(file)
|
||||
if s:
|
||||
for key, value in s.items():
|
||||
types_map[key] = value
|
||||
inited = 1
|
||||
|
||||
def read_mime_types(file):
|
||||
try:
|
||||
f = open(file)
|
||||
except IOError:
|
||||
return None
|
||||
map = {}
|
||||
while 1:
|
||||
line = f.readline()
|
||||
if not line: break
|
||||
words = string.split(line)
|
||||
for i in range(len(words)):
|
||||
if words[i][0] == '#':
|
||||
del words[i:]
|
||||
break
|
||||
if not words: continue
|
||||
type, suffixes = words[0], words[1:]
|
||||
for suff in suffixes:
|
||||
map['.'+suff] = type
|
||||
f.close()
|
||||
return map
|
||||
|
||||
suffix_map = {
|
||||
'.tgz': '.tar.gz',
|
||||
'.taz': '.tar.gz',
|
||||
'.tz': '.tar.gz',
|
||||
}
|
||||
|
||||
encodings_map = {
|
||||
'.gz': 'gzip',
|
||||
'.Z': 'compress',
|
||||
}
|
||||
|
||||
types_map = {
|
||||
'.a': 'application/octet-stream',
|
||||
'.ai': 'application/postscript',
|
||||
'.aif': 'audio/x-aiff',
|
||||
'.aifc': 'audio/x-aiff',
|
||||
'.aiff': 'audio/x-aiff',
|
||||
'.au': 'audio/basic',
|
||||
'.avi': 'video/x-msvideo',
|
||||
'.bcpio': 'application/x-bcpio',
|
||||
'.bin': 'application/octet-stream',
|
||||
'.cdf': 'application/x-netcdf',
|
||||
'.cpio': 'application/x-cpio',
|
||||
'.csh': 'application/x-csh',
|
||||
'.dll': 'application/octet-stream',
|
||||
'.dvi': 'application/x-dvi',
|
||||
'.exe': 'application/octet-stream',
|
||||
'.eps': 'application/postscript',
|
||||
'.etx': 'text/x-setext',
|
||||
'.gif': 'image/gif',
|
||||
'.gtar': 'application/x-gtar',
|
||||
'.hdf': 'application/x-hdf',
|
||||
'.htm': 'text/html',
|
||||
'.html': 'text/html',
|
||||
'.ief': 'image/ief',
|
||||
'.jpe': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.latex': 'application/x-latex',
|
||||
'.man': 'application/x-troff-man',
|
||||
'.me': 'application/x-troff-me',
|
||||
'.mif': 'application/x-mif',
|
||||
'.mov': 'video/quicktime',
|
||||
'.movie': 'video/x-sgi-movie',
|
||||
'.mpe': 'video/mpeg',
|
||||
'.mpeg': 'video/mpeg',
|
||||
'.mpg': 'video/mpeg',
|
||||
'.ms': 'application/x-troff-ms',
|
||||
'.nc': 'application/x-netcdf',
|
||||
'.o': 'application/octet-stream',
|
||||
'.obj': 'application/octet-stream',
|
||||
'.oda': 'application/oda',
|
||||
'.pbm': 'image/x-portable-bitmap',
|
||||
'.pdf': 'application/pdf',
|
||||
'.pgm': 'image/x-portable-graymap',
|
||||
'.pnm': 'image/x-portable-anymap',
|
||||
'.png': 'image/png',
|
||||
'.ppm': 'image/x-portable-pixmap',
|
||||
'.py': 'text/x-python',
|
||||
'.pyc': 'application/x-python-code',
|
||||
'.ps': 'application/postscript',
|
||||
'.qt': 'video/quicktime',
|
||||
'.ras': 'image/x-cmu-raster',
|
||||
'.rgb': 'image/x-rgb',
|
||||
'.roff': 'application/x-troff',
|
||||
'.rtf': 'application/rtf',
|
||||
'.rtx': 'text/richtext',
|
||||
'.sgm': 'text/x-sgml',
|
||||
'.sgml': 'text/x-sgml',
|
||||
'.sh': 'application/x-sh',
|
||||
'.shar': 'application/x-shar',
|
||||
'.snd': 'audio/basic',
|
||||
'.so': 'application/octet-stream',
|
||||
'.src': 'application/x-wais-source',
|
||||
'.sv4cpio': 'application/x-sv4cpio',
|
||||
'.sv4crc': 'application/x-sv4crc',
|
||||
'.t': 'application/x-troff',
|
||||
'.tar': 'application/x-tar',
|
||||
'.tcl': 'application/x-tcl',
|
||||
'.tex': 'application/x-tex',
|
||||
'.texi': 'application/x-texinfo',
|
||||
'.texinfo': 'application/x-texinfo',
|
||||
'.tif': 'image/tiff',
|
||||
'.tiff': 'image/tiff',
|
||||
'.tr': 'application/x-troff',
|
||||
'.tsv': 'text/tab-separated-values',
|
||||
'.txt': 'text/plain',
|
||||
'.ustar': 'application/x-ustar',
|
||||
'.wav': 'audio/x-wav',
|
||||
'.xbm': 'image/x-xbitmap',
|
||||
'.xpm': 'image/x-xpixmap',
|
||||
'.xwd': 'image/x-xwindowdump',
|
||||
'.zip': 'application/zip',
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
"""Word completion for GNU readline 2.0.
|
||||
|
||||
This requires the latest extension to the readline module (the
|
||||
set_completer() function). When completing a simple identifier, it
|
||||
completes keywords, built-ins and globals in __main__; when completing
|
||||
NAME.NAME..., it evaluates (!) the expression up to the last dot and
|
||||
completes its attributes.
|
||||
|
||||
It's very cool to do "import string" type "string.", hit the
|
||||
completion key (twice), and see the list of names defined by the
|
||||
string module!
|
||||
|
||||
Tip: to use the tab key as the completion key, call
|
||||
|
||||
readline.parse_and_bind("tab: complete")
|
||||
|
||||
Notes:
|
||||
|
||||
- Exceptions raised by the completer function are *ignored* (and
|
||||
generally cause the completion to fail). This is a feature -- since
|
||||
readline sets the tty device in raw (or cbreak) mode, printing a
|
||||
traceback wouldn't work well without some complicated hoopla to save,
|
||||
reset and restore the tty state.
|
||||
|
||||
- The evaluation of the NAME.NAME... form may cause arbitrary
|
||||
application defined code to be executed if an object with a
|
||||
__getattr__ hook is found. Since it is the responsibility of the
|
||||
application (or the user) to enable this feature, I consider this an
|
||||
acceptable risk. More complicated expressions (e.g. function calls or
|
||||
indexing operations) are *not* evaluated.
|
||||
|
||||
- GNU readline is also used by the built-in functions input() and
|
||||
raw_input(), and thus these also benefit/suffer from the completer
|
||||
features. Clearly an interactive application can benefit by
|
||||
specifying its own completer function and using raw_input() for all
|
||||
its input.
|
||||
|
||||
- When the original stdin is not a tty device, GNU readline is never
|
||||
used, and this module (and the readline module) are silently inactive.
|
||||
|
||||
"""
|
||||
|
||||
import readline
|
||||
import keyword
|
||||
import __builtin__
|
||||
import __main__
|
||||
import string
|
||||
import re
|
||||
import traceback
|
||||
|
||||
class Completer:
|
||||
|
||||
def complete(self, text, state):
|
||||
"""Return the next possible completion for 'text'.
|
||||
|
||||
This is called successively with state == 0, 1, 2, ... until it
|
||||
returns None. The completion should begin with 'text'.
|
||||
|
||||
"""
|
||||
if state == 0:
|
||||
if "." in text:
|
||||
self.matches = self.attr_matches(text)
|
||||
else:
|
||||
self.matches = self.global_matches(text)
|
||||
return self.matches[state]
|
||||
|
||||
def global_matches(self, text):
|
||||
"""Compute matches when text is a simple name.
|
||||
|
||||
Return a list of all keywords, built-in functions and names
|
||||
currently defines in __main__ that match.
|
||||
|
||||
"""
|
||||
matches = []
|
||||
n = len(text)
|
||||
for list in [keyword.kwlist,
|
||||
__builtin__.__dict__.keys(),
|
||||
__main__.__dict__.keys()]:
|
||||
for word in list:
|
||||
if word[:n] == text:
|
||||
matches.append(word)
|
||||
return matches
|
||||
|
||||
def attr_matches(self, text):
|
||||
"""Compute matches when text contains a dot.
|
||||
|
||||
Assuming the text is of the form NAME.NAME....[NAME], and is
|
||||
evaluabable in the globals of __main__, it will be evaluated
|
||||
and its attributes (as revealed by dir()) are used as possible
|
||||
completions.
|
||||
|
||||
WARNING: this can still invoke arbitrary C code, if an object
|
||||
with a __getattr__ hook is evaluated.
|
||||
|
||||
"""
|
||||
m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
|
||||
if not m:
|
||||
return
|
||||
expr, attr = m.group(1, 3)
|
||||
words = dir(eval(expr, __main__.__dict__))
|
||||
matches = []
|
||||
n = len(attr)
|
||||
for word in words:
|
||||
if word[:n] == attr:
|
||||
matches.append("%s.%s" % (expr, word))
|
||||
return matches
|
||||
|
||||
readline.set_completer(Completer().complete)
|
|
@ -0,0 +1,2 @@
|
|||
import sys
|
||||
sys.modules['ni'] = sys.modules[__name__]
|
|
@ -248,12 +248,11 @@ class TCPServer:
|
|||
The default is to print a traceback and continue.
|
||||
|
||||
"""
|
||||
exc, value, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
|
||||
print '-'*40
|
||||
print 'Exception happened during processing of request from',
|
||||
print client_address
|
||||
import traceback
|
||||
traceback.print_exception(exc, value, tb)
|
||||
traceback.print_exc()
|
||||
print '-'*40
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
# Python test set -- part 5, built-in exceptions
|
||||
|
||||
from test_support import *
|
||||
from types import ClassType
|
||||
|
||||
print '5. Built-in exceptions'
|
||||
# XXX This is not really enough, each *operation* should be tested!
|
||||
|
||||
def r(name): print name
|
||||
def r(thing):
|
||||
if type(thing) == ClassType:
|
||||
print thing.__name__
|
||||
else:
|
||||
print thing
|
||||
|
||||
r(AttributeError)
|
||||
import sys
|
||||
|
|
|
@ -155,7 +155,12 @@ def get_qualified_path(name):
|
|||
""" return a more qualified path to name"""
|
||||
import sys
|
||||
import os
|
||||
for dir in sys.path:
|
||||
path = sys.path
|
||||
try:
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
except NameError:
|
||||
pass
|
||||
for dir in path:
|
||||
fullname = os.path.join(dir, name)
|
||||
if os.path.exists(fullname):
|
||||
return fullname
|
||||
|
|
|
@ -28,6 +28,9 @@ print '2.2 raise class exceptions'
|
|||
class AClass: pass
|
||||
class BClass(AClass): pass
|
||||
class CClass: pass
|
||||
class DClass(AClass):
|
||||
def __init__(self, ignore):
|
||||
pass
|
||||
|
||||
try: raise AClass()
|
||||
except: pass
|
||||
|
@ -46,18 +49,22 @@ a = AClass()
|
|||
b = BClass()
|
||||
|
||||
try: raise AClass, b
|
||||
except BClass, v: raise TestFailed
|
||||
except AClass, v:
|
||||
except BClass, v:
|
||||
if v != b: raise TestFailed
|
||||
|
||||
else: raise TestFailed
|
||||
|
||||
try: raise b
|
||||
except AClass, v:
|
||||
if v != b: raise TestFailed
|
||||
|
||||
# not enough arguments
|
||||
try: raise BClass, a
|
||||
except TypeError: pass
|
||||
|
||||
try: raise DClass, a
|
||||
except DClass, v:
|
||||
if not isinstance(v, DClass):
|
||||
raise TestFailed
|
||||
|
||||
print '2.3 comparing function objects'
|
||||
|
||||
|
|
|
@ -11,7 +11,12 @@ print 'RGBimg test suite:'
|
|||
def findfile(file):
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
for dn in sys.path:
|
||||
path = sys.path
|
||||
try:
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
except NameError:
|
||||
pass
|
||||
for dn in path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
|
|
|
@ -9,7 +9,7 @@ B = 'cheese shop'
|
|||
a = r.encrypt(A)
|
||||
print `a`
|
||||
b = r.encryptmore(B)
|
||||
print b
|
||||
print `b`
|
||||
|
||||
A1 = r.decrypt(a)
|
||||
print A1
|
||||
|
|
|
@ -20,7 +20,8 @@ def missing_ok(str):
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
print socket.error
|
||||
try: raise socket.error
|
||||
except socket.error: print "socket.error"
|
||||
|
||||
socket.AF_INET
|
||||
|
||||
|
|
|
@ -16,8 +16,11 @@ tt = time.gmtime(t)
|
|||
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
|
||||
'j', 'm', 'M', 'p', 'S',
|
||||
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
|
||||
format = '%' + directive
|
||||
time.strftime(format, tt)
|
||||
format = ' %' + directive
|
||||
try:
|
||||
time.strftime(format, tt)
|
||||
except ValueError:
|
||||
print 'conversion specifier:', format, ' failed.'
|
||||
|
||||
time.timezone
|
||||
time.tzname
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
from test_support import *
|
||||
|
||||
t = (1, 2, 3)
|
||||
l = [4, 5, 6]
|
||||
|
||||
class Seq:
|
||||
def __getitem__(self, i):
|
||||
if i >= 0 and i < 3: return i
|
||||
raise IndexError
|
||||
|
||||
a = -1
|
||||
b = -1
|
||||
c = -1
|
||||
|
||||
# unpack tuple
|
||||
if verbose:
|
||||
print 'unpack tuple'
|
||||
a, b, c = t
|
||||
if a <> 1 or b <> 2 or c <> 3:
|
||||
raise TestFailed
|
||||
|
||||
# unpack list
|
||||
if verbose:
|
||||
print 'unpack list'
|
||||
a, b, c = l
|
||||
if a <> 4 or b <> 5 or c <> 6:
|
||||
raise TestFailed
|
||||
|
||||
# unpack implied tuple
|
||||
if verbose:
|
||||
print 'unpack implied tuple'
|
||||
a, b, c = 7, 8, 9
|
||||
if a <> 7 or b <> 8 or c <> 9:
|
||||
raise TestFailed
|
||||
|
||||
# unpack string... fun!
|
||||
if verbose:
|
||||
print 'unpack string'
|
||||
a, b, c = 'one'
|
||||
if a <> 'o' or b <> 'n' or c <> 'e':
|
||||
raise TestFailed
|
||||
|
||||
# unpack generic sequence
|
||||
if verbose:
|
||||
print 'unpack sequence'
|
||||
a, b, c = Seq()
|
||||
if a <> 0 or b <> 1 or c <> 2:
|
||||
raise TestFailed
|
||||
|
||||
# now for some failures
|
||||
|
||||
# unpacking non-sequence
|
||||
if verbose:
|
||||
print 'unpack non-sequence'
|
||||
try:
|
||||
a, b, c = 7
|
||||
raise TestFailed
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
# unpacking tuple of wrong size
|
||||
if verbose:
|
||||
print 'unpack tuple wrong size'
|
||||
try:
|
||||
a, b = t
|
||||
raise TestFailed
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# unpacking list of wrong size
|
||||
if verbose:
|
||||
print 'unpack list wrong size'
|
||||
try:
|
||||
a, b = l
|
||||
raise TestFailed
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
# unpacking sequence too short
|
||||
if verbose:
|
||||
print 'unpack sequence too short'
|
||||
try:
|
||||
a, b, c, d = Seq()
|
||||
raise TestFailed
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
# unpacking sequence too long
|
||||
if verbose:
|
||||
print 'unpack sequence too long'
|
||||
try:
|
||||
a, b = Seq()
|
||||
raise TestFailed
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
# unpacking a sequence where the test for too long raises a different
|
||||
# kind of error
|
||||
BozoError = 'BozoError'
|
||||
|
||||
class BadSeq:
|
||||
def __getitem__(self, i):
|
||||
if i >= 0 and i < 3:
|
||||
return i
|
||||
elif i == 3:
|
||||
raise BozoError
|
||||
else:
|
||||
raise IndexError
|
||||
|
||||
|
||||
# trigger code while not expecting an IndexError
|
||||
if verbose:
|
||||
print 'unpack sequence too long, wrong error'
|
||||
try:
|
||||
a, b, c, d, e = BadSeq()
|
||||
raise TestFailed
|
||||
except BozoError:
|
||||
pass
|
||||
|
||||
# trigger code while expecting an IndexError
|
||||
if verbose:
|
||||
print 'unpack sequence too short, wrong error'
|
||||
try:
|
||||
a, b, c = BadSeq()
|
||||
raise TestFailed
|
||||
except BozoError:
|
||||
pass
|
|
@ -0,0 +1,145 @@
|
|||
import zlib
|
||||
import sys
|
||||
import imp
|
||||
import string
|
||||
|
||||
t = imp.find_module('test_zlib')
|
||||
file = t[0]
|
||||
buf = file.read() * 8
|
||||
file.close()
|
||||
|
||||
# test the chucksums
|
||||
print zlib.crc32('penguin'), zlib.crc32('penguin', 1)
|
||||
print zlib.adler32('penguin'), zlib.adler32('penguin', 1)
|
||||
|
||||
# make sure we generate some expected errors
|
||||
try:
|
||||
zlib.compress('ERROR', zlib.MAX_WBITS + 1)
|
||||
except zlib.error, msg:
|
||||
print "expecting", msg
|
||||
try:
|
||||
zlib.compressobj(1, 8, 0)
|
||||
except ValueError, msg:
|
||||
print "expecting", msg
|
||||
try:
|
||||
zlib.decompressobj(0)
|
||||
except ValueError, msg:
|
||||
print "expecting", msg
|
||||
|
||||
x = zlib.compress(buf)
|
||||
y = zlib.decompress(x)
|
||||
if buf != y:
|
||||
print "normal compression/decompression failed"
|
||||
else:
|
||||
print "normal compression/decompression succeeded"
|
||||
|
||||
buf = buf * 16
|
||||
|
||||
co = zlib.compressobj(8, 8, -15)
|
||||
x1 = co.compress(buf)
|
||||
x2 = co.flush()
|
||||
x = x1 + x2
|
||||
|
||||
dc = zlib.decompressobj(-15)
|
||||
y1 = dc.decompress(x)
|
||||
y2 = dc.flush()
|
||||
y = y1 + y2
|
||||
if buf != y:
|
||||
print "compress/decompression obj failed"
|
||||
else:
|
||||
print "compress/decompression obj succeeded"
|
||||
|
||||
co = zlib.compressobj(2, 8, -12, 9, 1)
|
||||
bufs = []
|
||||
for i in range(0, len(buf), 256):
|
||||
bufs.append(co.compress(buf[i:i+256]))
|
||||
bufs.append(co.flush())
|
||||
combuf = string.join(bufs, '')
|
||||
|
||||
decomp1 = zlib.decompress(combuf, -12, -5)
|
||||
if decomp1 != buf:
|
||||
print "decompress with init options failed"
|
||||
else:
|
||||
print "decompress with init options succeeded"
|
||||
|
||||
deco = zlib.decompressobj(-12)
|
||||
bufs = []
|
||||
for i in range(0, len(combuf), 128):
|
||||
bufs.append(deco.decompress(combuf[i:i+128]))
|
||||
bufs.append(deco.flush())
|
||||
decomp2 = string.join(buf, '')
|
||||
if decomp2 != buf:
|
||||
print "decompressobj with init options failed"
|
||||
else:
|
||||
print "decompressobj with init options succeeded"
|
||||
|
||||
def ignore():
|
||||
"""An empty function with a big string.
|
||||
|
||||
Make the compression algorithm work a little harder.
|
||||
"""
|
||||
|
||||
"""
|
||||
LAERTES
|
||||
|
||||
O, fear me not.
|
||||
I stay too long: but here my father comes.
|
||||
|
||||
Enter POLONIUS
|
||||
|
||||
A double blessing is a double grace,
|
||||
Occasion smiles upon a second leave.
|
||||
|
||||
LORD POLONIUS
|
||||
|
||||
Yet here, Laertes! aboard, aboard, for shame!
|
||||
The wind sits in the shoulder of your sail,
|
||||
And you are stay'd for. There; my blessing with thee!
|
||||
And these few precepts in thy memory
|
||||
See thou character. Give thy thoughts no tongue,
|
||||
Nor any unproportioned thought his act.
|
||||
Be thou familiar, but by no means vulgar.
|
||||
Those friends thou hast, and their adoption tried,
|
||||
Grapple them to thy soul with hoops of steel;
|
||||
But do not dull thy palm with entertainment
|
||||
Of each new-hatch'd, unfledged comrade. Beware
|
||||
Of entrance to a quarrel, but being in,
|
||||
Bear't that the opposed may beware of thee.
|
||||
Give every man thy ear, but few thy voice;
|
||||
Take each man's censure, but reserve thy judgment.
|
||||
Costly thy habit as thy purse can buy,
|
||||
But not express'd in fancy; rich, not gaudy;
|
||||
For the apparel oft proclaims the man,
|
||||
And they in France of the best rank and station
|
||||
Are of a most select and generous chief in that.
|
||||
Neither a borrower nor a lender be;
|
||||
For loan oft loses both itself and friend,
|
||||
And borrowing dulls the edge of husbandry.
|
||||
This above all: to thine ownself be true,
|
||||
And it must follow, as the night the day,
|
||||
Thou canst not then be false to any man.
|
||||
Farewell: my blessing season this in thee!
|
||||
|
||||
LAERTES
|
||||
|
||||
Most humbly do I take my leave, my lord.
|
||||
|
||||
LORD POLONIUS
|
||||
|
||||
The time invites you; go; your servants tend.
|
||||
|
||||
LAERTES
|
||||
|
||||
Farewell, Ophelia; and remember well
|
||||
What I have said to you.
|
||||
|
||||
OPHELIA
|
||||
|
||||
'Tis in my memory lock'd,
|
||||
And you yourself shall keep the key of it.
|
||||
|
||||
LAERTES
|
||||
|
||||
Farewell.
|
||||
"""
|
||||
|
|
@ -37,7 +37,7 @@ def print_tb(tb, limit=None, file=None):
|
|||
n = 0
|
||||
while tb is not None and (limit is None or n < limit):
|
||||
f = tb.tb_frame
|
||||
lineno = tb.tb_lineno
|
||||
lineno = tb_lineno(tb)
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
|
@ -59,7 +59,7 @@ def extract_tb(tb, limit = None):
|
|||
n = 0
|
||||
while tb is not None and (limit is None or n < limit):
|
||||
f = tb.tb_frame
|
||||
lineno = tb.tb_lineno
|
||||
lineno = tb_lineno(tb)
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
|
@ -169,7 +169,7 @@ def extract_stack(f=None, limit = None):
|
|||
list = []
|
||||
n = 0
|
||||
while f is not None and (limit is None or n < limit):
|
||||
lineno = f.f_lineno
|
||||
lineno = f.f_lineno # XXX Too bad if -O is used
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
|
@ -181,3 +181,21 @@ def extract_stack(f=None, limit = None):
|
|||
n = n+1
|
||||
list.reverse()
|
||||
return list
|
||||
|
||||
# Calculate the correct line number of the traceback given in tb (even
|
||||
# with -O on).
|
||||
# Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
|
||||
# in compile.c.
|
||||
|
||||
def tb_lineno(tb):
|
||||
c = tb.tb_frame.f_code
|
||||
tab = c.co_lnotab
|
||||
line = c.co_firstlineno
|
||||
stopat = tb.tb_lasti
|
||||
addr = 0
|
||||
for i in range(0, len(tab), 2):
|
||||
addr = addr + ord(tab[i])
|
||||
if addr > stopat:
|
||||
break
|
||||
line = line + ord(tab[i+1])
|
||||
return line
|
||||
|
|
|
@ -1,270 +1 @@
|
|||
# This module contains several routines that help recognizing sound
|
||||
# files.
|
||||
#
|
||||
# Function whathdr() recognizes various types of sound file headers.
|
||||
# It understands almost all headers that SOX can decode.
|
||||
#
|
||||
# The return tuple contains the following items, in this order:
|
||||
# - file type (as SOX understands it)
|
||||
# - sampling rate (0 if unknown or hard to decode)
|
||||
# - number of channels (0 if unknown or hard to decode)
|
||||
# - number of frames in the file (-1 if unknown or hard to decode)
|
||||
# - number of bits/sample, or 'U' for U-LAW, or 'A' for A-LAW
|
||||
#
|
||||
# If the file doesn't have a recognizable type, it returns None.
|
||||
# If the file can't be opened, IOError is raised.
|
||||
#
|
||||
# To compute the total time, divide the number of frames by the
|
||||
# sampling rate (a frame contains a sample for each channel).
|
||||
#
|
||||
# Function whatraw() calls the "whatsound" program and interprets its
|
||||
# output. You'll have to guess the sampling rate by listening though!
|
||||
#
|
||||
# Function what() calls whathdr() and if it doesn't recognize the file
|
||||
# then calls whatraw().
|
||||
#
|
||||
# Finally, the function test() is a simple main program that calls
|
||||
# what() for all files mentioned on the argument list. For directory
|
||||
# arguments it calls what() for all files in that directory. Default
|
||||
# argument is "." (testing all files in the current directory). The
|
||||
# option -r tells it to recurse down directories found inside
|
||||
# explicitly given directories.
|
||||
#
|
||||
# The file structure is top-down except that the test program and its
|
||||
# subroutine come last.
|
||||
|
||||
|
||||
#------------------------------------------------------#
|
||||
# Guess the type of any sound file, raw or with header #
|
||||
#------------------------------------------------------#
|
||||
|
||||
def what(filename):
|
||||
res = whathdr(filename)
|
||||
if not res:
|
||||
res = whatraw(filename)
|
||||
return res
|
||||
|
||||
|
||||
#-----------------------------#
|
||||
# Guess the type of raw sound #
|
||||
#-----------------------------#
|
||||
|
||||
def whatraw(filename):
|
||||
# Assume it's always 1 channel, byte-sized samples
|
||||
# Don't assume anything about the rate
|
||||
import os
|
||||
from stat import ST_SIZE
|
||||
# XXX "whatsound" should be part of the distribution somehow...
|
||||
cmd = 'whatsound ' + filename + ' 2>/dev/null'
|
||||
cmd = 'PATH=$PATH:/ufs/guido/bin/sgi\n' + cmd
|
||||
pipe = os.popen(cmd, 'r')
|
||||
data = pipe.read()
|
||||
sts = pipe.close()
|
||||
if sts:
|
||||
return None
|
||||
if data[:13] == '-t raw -b -s ':
|
||||
type = 'sb'
|
||||
sample_size = 8
|
||||
elif data[:13] == '-t raw -b -u ':
|
||||
type = 'ub'
|
||||
sample_size = 8
|
||||
elif data[:13] == '-t raw -b -U ':
|
||||
type = 'ul'
|
||||
sample_size = 'U'
|
||||
else:
|
||||
return None
|
||||
try:
|
||||
frame_count = os.stat(filename)[ST_SIZE]
|
||||
except IOError:
|
||||
frame_count = -1
|
||||
return type, 0, 1, frame_count, sample_size
|
||||
|
||||
|
||||
#-------------------------#
|
||||
# Recognize sound headers #
|
||||
#-------------------------#
|
||||
|
||||
def whathdr(filename):
|
||||
f = open(filename, 'r')
|
||||
h = f.read(512)
|
||||
for tf in tests:
|
||||
res = tf(h, f)
|
||||
if res:
|
||||
return res
|
||||
return None
|
||||
|
||||
|
||||
#-----------------------------------#
|
||||
# Subroutines per sound header type #
|
||||
#-----------------------------------#
|
||||
|
||||
tests = []
|
||||
|
||||
def test_aifc(h, f):
|
||||
import aifc
|
||||
if h[:4] <> 'FORM':
|
||||
return None
|
||||
if h[8:12] == 'AIFC':
|
||||
fmt = 'aifc'
|
||||
elif h[8:12] == 'AIFF':
|
||||
fmt = 'aiff'
|
||||
else:
|
||||
return None
|
||||
f.seek(0)
|
||||
try:
|
||||
a = aifc.openfp(f, 'r')
|
||||
except (EOFError, aifc.Error):
|
||||
return None
|
||||
return (fmt, a.getframerate(), a.getnchannels(), \
|
||||
a.getnframes(), 8*a.getsampwidth())
|
||||
|
||||
tests.append(test_aifc)
|
||||
|
||||
|
||||
def test_au(h, f):
|
||||
if h[:4] == '.snd':
|
||||
f = get_long_be
|
||||
elif h[:4] in ('\0ds.', 'dns.'):
|
||||
f = get_long_le
|
||||
else:
|
||||
return None
|
||||
type = 'au'
|
||||
hdr_size = f(h[4:8])
|
||||
data_size = f(h[8:12])
|
||||
encoding = f(h[12:16])
|
||||
rate = f(h[16:20])
|
||||
nchannels = f(h[20:24])
|
||||
sample_size = 1 # default
|
||||
if encoding == 1:
|
||||
sample_bits = 'U'
|
||||
elif encoding == 2:
|
||||
sample_bits = 8
|
||||
elif encoding == 3:
|
||||
sample_bits = 16
|
||||
sample_size = 2
|
||||
else:
|
||||
sample_bits = '?'
|
||||
frame_size = sample_size * nchannels
|
||||
return type, rate, nchannels, data_size/frame_size, sample_bits
|
||||
|
||||
tests.append(test_au)
|
||||
|
||||
|
||||
def test_hcom(h, f):
|
||||
if h[65:69] <> 'FSSD' or h[128:132] <> 'HCOM':
|
||||
return None
|
||||
divisor = get_long_be(h[128+16:128+20])
|
||||
return 'hcom', 22050/divisor, 1, -1, 8
|
||||
|
||||
tests.append(test_hcom)
|
||||
|
||||
|
||||
def test_voc(h, f):
|
||||
if h[:20] <> 'Creative Voice File\032':
|
||||
return None
|
||||
sbseek = get_short_le(h[20:22])
|
||||
rate = 0
|
||||
if 0 <= sbseek < 500 and h[sbseek] == '\1':
|
||||
ratecode = ord(h[sbseek+4])
|
||||
rate = int(1000000.0 / (256 - ratecode))
|
||||
return 'voc', rate, 1, -1, 8
|
||||
|
||||
tests.append(test_voc)
|
||||
|
||||
|
||||
def test_wav(h, f):
|
||||
# 'RIFF' <len> 'WAVE' 'fmt ' <len>
|
||||
if h[:4] <> 'RIFF' or h[8:12] <> 'WAVE' or h[12:16] <> 'fmt ':
|
||||
return None
|
||||
style = get_short_le(h[20:22])
|
||||
nchannels = get_short_le(h[22:24])
|
||||
rate = get_long_le(h[24:28])
|
||||
sample_bits = get_short_le(h[34:36])
|
||||
return 'wav', rate, nchannels, -1, sample_bits
|
||||
|
||||
tests.append(test_wav)
|
||||
|
||||
|
||||
def test_8svx(h, f):
|
||||
if h[:4] <> 'FORM' or h[8:12] <> '8SVX':
|
||||
return None
|
||||
# Should decode it to get #channels -- assume always 1
|
||||
return '8svx', 0, 1, 0, 8
|
||||
|
||||
tests.append(test_8svx)
|
||||
|
||||
|
||||
def test_sndt(h, f):
|
||||
if h[:5] == 'SOUND':
|
||||
nsamples = get_long_le(h[8:12])
|
||||
rate = get_short_le(h[20:22])
|
||||
return 'sndt', rate, 1, nsamples, 8
|
||||
|
||||
tests.append(test_sndt)
|
||||
|
||||
|
||||
def test_sndr(h, f):
|
||||
if h[:2] == '\0\0':
|
||||
rate = get_short_le(h[2:4])
|
||||
if 4000 <= rate <= 25000:
|
||||
return 'sndr', rate, 1, -1, 8
|
||||
|
||||
tests.append(test_sndr)
|
||||
|
||||
|
||||
#---------------------------------------------#
|
||||
# Subroutines to extract numbers from strings #
|
||||
#---------------------------------------------#
|
||||
|
||||
def get_long_be(s):
|
||||
return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
|
||||
|
||||
def get_long_le(s):
|
||||
return (ord(s[3])<<24) | (ord(s[2])<<16) | (ord(s[1])<<8) | ord(s[0])
|
||||
|
||||
def get_short_be(s):
|
||||
return (ord(s[0])<<8) | ord(s[1])
|
||||
|
||||
def get_short_le(s):
|
||||
return (ord(s[1])<<8) | ord(s[0])
|
||||
|
||||
|
||||
#--------------------#
|
||||
# Small test program #
|
||||
#--------------------#
|
||||
|
||||
def test():
|
||||
import sys
|
||||
recursive = 0
|
||||
if sys.argv[1:] and sys.argv[1] == '-r':
|
||||
del sys.argv[1:2]
|
||||
recursive = 1
|
||||
try:
|
||||
if sys.argv[1:]:
|
||||
testall(sys.argv[1:], recursive, 1)
|
||||
else:
|
||||
testall(['.'], recursive, 1)
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write('\n[Interrupted]\n')
|
||||
sys.exit(1)
|
||||
|
||||
def testall(list, recursive, toplevel):
|
||||
import sys
|
||||
import os
|
||||
for filename in list:
|
||||
if os.path.isdir(filename):
|
||||
print filename + '/:',
|
||||
if recursive or toplevel:
|
||||
print 'recursing down:'
|
||||
import glob
|
||||
names = glob.glob(os.path.join(filename, '*'))
|
||||
testall(names, recursive, 0)
|
||||
else:
|
||||
print '*** directory (use -r) ***'
|
||||
else:
|
||||
print filename + ':',
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
print what(filename)
|
||||
except IOError:
|
||||
print '*** not found ***'
|
||||
from sndhdr import *
|
||||
|
|
Loading…
Reference in New Issue