From python-checkins at python.org Fri Aug 25 14:55:13 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 25 Aug 2006 14:55:13 +0200 (CEST) Subject: [Stackless-checkins] r51610 - stackless/binaries-pc/python24.zip stackless/binaries-pc/python24.zip.md5.py Message-ID: <20060825125513.805E41E400B@bag.python.org> Author: richard.tew Date: Fri Aug 25 14:54:52 2006 New Revision: 51610 Modified: stackless/binaries-pc/python24.zip stackless/binaries-pc/python24.zip.md5.py Log: Binaries including r51609. Modified: stackless/binaries-pc/python24.zip ============================================================================== Binary files. No diff available. Modified: stackless/binaries-pc/python24.zip.md5.py ============================================================================== --- stackless/binaries-pc/python24.zip.md5.py (original) +++ stackless/binaries-pc/python24.zip.md5.py Fri Aug 25 14:54:52 2006 @@ -1,6 +1,6 @@ import md5 -expected = "e7a21e896dd56d37d3d794b6d9b8661b" +expected = "90c50615f5aa023a3d50d92eb59f3bb3" fname = r"python24.zip" print "expected digest", expected received = md5.md5(file(fname, "rb").read()).hexdigest() _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Wed Aug 23 11:10:25 2006 From: python-checkins at python.org (richard.tew) Date: Wed, 23 Aug 2006 11:10:25 +0200 (CEST) Subject: [Stackless-checkins] r51501 - stackless/trunk/PCbuild/uthread_ccp.py Message-ID: <20060823091025.99D401E4009@bag.python.org> Author: richard.tew Date: Wed Aug 23 11:10:23 2006 New Revision: 51501 Modified: stackless/trunk/PCbuild/uthread_ccp.py Log: An updated version of the uthread module which CCP uses internally. It still requires some changes, like the addition of Sleep and a BeNice methods, and the removal or replacement of some internal CCP functions like those related to local storage. Modified: stackless/trunk/PCbuild/uthread_ccp.py ============================================================================== --- stackless/trunk/PCbuild/uthread_ccp.py (original) +++ stackless/trunk/PCbuild/uthread_ccp.py Wed Aug 23 11:10:23 2006 @@ -29,225 +29,791 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.""" -#import continuation import stackless +import sys +import time +import types +import weakref +import traceback +import copy +import logging + +# This is a simple replacement for what CCP uses which is linked into our +# framework. +def WriteTraceback(text, tb): + logging.error(text) + for s in traceback.format_tb(tb): + logging.error(s.strip()) + logging.error(str(excInstance)) + +def LogTraceback(text): + if text is None: + text = "Traceback:" + tb = traceback.extract_stack() + WriteTraceback(text, tb) + +def StackTrace(text=None): + excClass, excInstance, tb = sys.exc_info() + if excClass: + if text is None: + text = "Stacktrace:" + WriteTraceback(text, tb) + else: + LogTraceback(text) -MAX_TIMESLICE = 20000000 +tasks = [] # bogus breyta -''' -tasks = [ ] -ghandler = None -''' - -''' -def endtask(): - """force this thread to die""" - continuation.uthread_lock(1) - sched = continuation.uthread_reset() - if sched != None: - sched() -''' -# not needed yet - -''' -def schedule(): - """force a context switch""" - continuation.uthread_lock(1) - sched = continuation.uthread_reset() - sched(continuation.caller()) -''' # handled internally schedule = stackless.schedule -''' +# We need to subclass it so that we can store attributes on it. +class Tasklet(stackless.tasklet): + pass + def new(func, *args, **kw): - """Start a new task""" - if func == None: - raise "Don't you make me try to call None" - global tasks - assert not kw + return Tasklet(func)(*args, **kw) - def wrapper(func, args): - continuation.return_current() - try: - apply(func, args) - except: - continuation.uthread_reset() - raise - endtask() - - tmp = continuation.uthread_lock(1) - task = wrapper(func, args) - task.caller = None - tasks.append(task) - continuation.uthread_lock(tmp) -''' -def new(func, *args, **kw): - """Start a new task""" - gen = stackless.taskoutlet(func) - t = gen(*args, **kw) - t.insert() - -''' -def run(): - """Run a bunch of tasks, until they all complete""" - global tasks - pop = tasks.pop - append = tasks.append - timeslice = continuation.timeslice - if not tasks: - # just enter the loop - append(None) - while tasks: - task = pop(0) - if task: - try: - task = timeslice(task, MAX_TIMESLICE) - except UserError, e: - global ghandler - if ghandler: - new(ghandler, e) - else: - print e - - if task: - import runner - runner.PostException( - task, - "THIS THREAD WAS PROBABLY STUCK IN AN INFINITE LOOP AND HAS BEEN NUKED!!!", - None) - - #append(task) -''' -def run(): - """Run a bunch of tasks, until they all complete""" - # have to add error handling like above - while stackless.getruncount() > 1: - try: - # running until the end or until something happens - victim = stackless.run_watchdog(MAX_TIMESLICE) - if victim: - print "THIS THREAD WAS PROBABLY STUCK IN AN INFINITE LOOP AND HAS BEEN NUKED!!!", - # todo: kill the task cleanly - except Exception, e: - print "Exception occoured:", e +def newWithoutTheStars(func, args, kw): + return Tasklet(func)(*args, **kw) idIndex = 0 -def sethandler(handler): - global ghandler - ghandler = handler - - def uniqueId(): """Microthread-safe way to get unique numbers, handy for giving things unique ID numbers""" global idIndex - tmp = stackless.scheduler_lock(1) + ## CCP is cutting out atomic as we never preemtivly schedule and stackless was crashing there + #tmp = stackless.atomic() z = idIndex - idIndex = z + 1 - stackless.scheduler_lock(tmp) + idIndex += 1 return z def irandom(n): """Microthread-safe version of random.randrange(0,n)""" import random - tmp = stackless.scheduler_lock(1) + ## CCP is cutting out atomic as we never preemtivly schedule and stackless was crashing there + #tmp = stackless.atomic() n = random.randrange(0, n) - stackless.scheduler_lock(tmp) return n -''' -class Semaphore: - """Semaphores protect globally accessible resources from - the effects of context switching.""" - __guid__ = 'uthread.Semaphore' - def __init__(self, maxcount=1): - self.count = maxcount - self.waiting = [] - def claim(self): - tmp = continuation.uthread_lock(1) - if self.count == 0: - self.waiting.append(continuation.caller()) - endtask() - else: - self.count = self.count - 1 - continuation.uthread_lock(tmp) - def release(self): - tmp = continuation.uthread_lock(1) - if self.waiting: - tasks.append(self.waiting.pop(0)) - else: - self.count = self.count + 1 - continuation.uthread_lock(tmp) -''' +synonyms = {} + +def MakeSynonymOf(threadid, synonym_threadid): + global synonyms + key = (threadid, synonym_threadid) + if key not in synonyms: + synonyms[key] = 1 + else: + synonyms[key] += 1 + +def MakeCurrentSynonymOf(synonym_threadid): + return MakeSynonymOf(id(stackless.getcurrent()), synonym_threadid) + +def RemoveSynonymOf(threadid, synonym_threadid): + global synonyms + key = (threadid, synonym_threadid) + if key not in synonyms: + StackTrace("RemoveSynonymOf unexpected call threadid:%s synonym_threadid:%s" % key) + return + synonyms[key] -= 1 + if 0 == synonyms[key]: + del synonyms[key] + +def RemoveCurrentSynonymOf(synonym_threadid): + return RemoveSynonymOf(id(stackless.getcurrent()), synonym_threadid) + +def IsSynonymOf(threadid, synonym_threadid): + global synonyms + key = (threadid, synonym_threadid) + return key in synonyms + +def IsCurrentSynonymOf(synonym_threadid): + return IsSynonymOf(id(stackless.getcurrent()), synonym_threadid) + + +semaphores = weakref.WeakKeyDictionary({}) + +def GetSemaphores(): + return semaphores class Semaphore: """Semaphores protect globally accessible resources from the effects of context switching.""" - __guid__ = 'uthread_ccp.Semaphore' - - def __init__(self, maxcount=1): - self.count = maxcount - self.waiting = stackless.channel() - + + def __init__(self, semaphoreName=None, maxcount=1, strict=True): + global semaphores + + semaphores[self] = 1 + + self.semaphoreName = semaphoreName + self.maxcount = maxcount + self.count = maxcount + self.waiting = stackless.channel() + self.thread = None + self.lockedWhen = None + self.strict = strict + + def IsCool(self): + ''' + returns true if and only if nobody has, or is waiting for, this lock + ''' + return self.count==self.maxcount + + def __str__(self): + return "Semaphore("+ str(self.semaphoreName) +")" + + def __del__(self): + if not self.IsCool(): + logger.error("Semaphore "+ str(self) +" is being destroyed in a locked or waiting state") + def acquire(self): - tmp = stackless.atomic() - if self.count == 0: + if self.strict: + assert self.thread is not stackless.getcurrent() + if self.thread is stackless.getcurrent(): + raise RuntimeError, "tasklet deadlock, acquiring tasklet holds strict semaphore" + self.count -= 1 + if self.count < 0: self.waiting.receive() - else: - self.count = self.count - 1 - + + self.lockedWhen = time.time() + self.thread = stackless.getcurrent() + claim = acquire - + def release(self): - tmp = stackless.atomic() - if self.waiting.queue: - self.waiting.send(None) + if self.strict: + assert self.thread is stackless.getcurrent() + if self.thread is not stackless.getcurrent(): + raise RuntimeError, "wrong tasklet releasing strict semaphore" + + self.count += 1 + self.thread = None + self.lockedWhen = None + if self.count <= 0: + PoolWorker("uthread::Semaphore::delayed_release",self.__delayed_release) + + #This allows the release thread to continue without being interrupted + def __delayed_release(self): + self.waiting.send(None) + +class CriticalSection(Semaphore): + def __init__(self, semaphoreName = None, strict=True): + Semaphore.__init__(self, semaphoreName) + self.__reentrantRefs = 0 + + def acquire(self): + # MEB: if (self.count<=0) and (self.thread is stackless.getcurrent() or stackless.getcurrent() is synonymof self.thread): + if (self.count<=0) and (self.thread is stackless.getcurrent() or IsCurrentSynonymOf(self.thread)): + self.__reentrantRefs += 1 + else: + Semaphore.acquire(self) + + def release(self): + if self.__reentrantRefs: + # MEB: assert self.thread is stackless.getcurrent() + assert self.thread is stackless.getcurrent() or IsCurrentSynonymOf(self.thread) + # MEB: if self.thread is not stackless.getcurrent(): + if not (self.thread is stackless.getcurrent() or IsCurrentSynonymOf(self.thread)): + raise RuntimeError, "wrong tasklet releasing reentrant CriticalSection" + self.__reentrantRefs -= 1 else: - self.count = self.count + 1 + Semaphore.release(self) + +def FNext(f): + first = stackless.getcurrent() + try: + cursor = first.next + while cursor != first: + if cursor.frame.f_back == f: + return FNext(cursor.frame) + cursor = cursor.next + return f + finally: + first = None + cursor = None + +class SquidgySemaphore: + ''' + This is a semaphore which allows exclusive locking + ''' + + def __init__(self, lockName): + self.__outer__ = Semaphore(lockName) + self.lockers = {} + self.__wierdo__ = 0 + + def IsCool(self): + ''' + returns true if and only if nobody has, or is waiting for, this lock + ''' + while 1: + lockers = [] + try: + for each in self.lockers: + return 0 + break + except: + StackTrace() + sys.exc_clear() + return self.__outer__.IsCool() and not self.__wierdo__ + + def acquire_pre_friendly(self): + ''' + Same as acquire, but with respect for pre_acquire_exclusive + ''' + while 1: + if self.__wierdo__: + Sleep(0.5) + else: + self.acquire() + if self.__wierdo__: + self.release() + else: + break + + def pre_acquire_exclusive(self): + ''' + Prepares the lock for an acquire_exclusive call, so that + acquire_pre_friendly will block on the dude. + ''' + self.__wierdo__ += 1 + + def acquire_exclusive(self): + i = 0 + while 1: + self.__outer__.acquire() + theLocker = None + try: + # self.lockers is a dict, and we just want one entry from it. + # for each in/break is a convenient way to get one entry. + for each in self.lockers: + theLocker = each + break + except: + StackTrace() + sys.exc_clear() + + if theLocker is not None: + self.__outer__.release() # yielding to the sucker is fine, since we're waiting for somebody anyhow. + if i and ((i%(3*4*60))==0): + logger.error("Acquire-exclusive is waiting for the inner lock (%d seconds total, lockcount=%d)" % (i/4, len(self.lockers))) + LogTraceback("This acquire_exclusive is taking a considerable amount of time") + logger.error("This dude has my lock:") + logger.error("tasklet: "+str(theLocker)) + for s in traceback.format_list(traceback.extract_stack(FNext(theLocker.frame),40)): + for n in range(0,10120,253): # forty lines max. + if n==0: + if len(s)<=255: + x = s + else: + x = s[:(n+253)] + else: + x = " - " + s[n:(n+253)] + logger.error(x, 4) + if (n+253)>=len(s): + break + Sleep(0.500) + else: + break + i += 1 + + def release_exclusive(self): + self.__outer__.release() + self.__wierdo__ -= 1 + + def acquire(self): + # you don't need the outer lock to re-acquire + self.__outer__.acquire() + self.__acquire_inner() + self.__outer__.release() + + def release(self, t=None): + if t is None: + t = stackless.getcurrent() + self.__release_inner(t) + + def __acquire_inner(self): + while 1: + try: + if self.lockers.has_key(stackless.getcurrent()): + self.lockers[stackless.getcurrent()] += 1 + else: + self.lockers[stackless.getcurrent()] = 1 + break + except: + StackTrace() + sys.exc_clear() + + def __release_inner(self, t): + while 1: + try: + if self.lockers.has_key(t): + self.lockers[t] -= 1 + if self.lockers[t]==0: + del self.lockers[t] + else: + StackTrace("You can't release a lock you didn't acquire") + break + except: + StackTrace() + sys.exc_clear() + +channels = weakref.WeakKeyDictionary() + +def GetChannels(): + return channels + +class Channel: + """ + A Channel is a stackless.channel() with administrative spunk + """ + + def __init__(self,channelName=None): + global channels + self.channelName = channelName + self.channel = stackless.channel() + self.send = self.channel.send + self.send_exception = self.channel.send_exception + channels[self] = 1 + + def receive(self): + return self.channel.receive() + + def __getattr__(self,k): + return getattr(self.channel,k) + + + + +# ----------------------------------------------------------------------------------- +# FIFO Class +# ----------------------------------------------------------------------------------- +class FIFO(object): + + __slots__ = ('data',) + + # ----------------------------------------------------------------------------------- + # FIFO - Constructor + # ----------------------------------------------------------------------------------- + def __init__(self): + self.data = [[], []] + + # ----------------------------------------------------------------------------------- + # FIFO - push + # ----------------------------------------------------------------------------------- + def push(self, v): + self.data[1].append(v) + + # ----------------------------------------------------------------------------------- + # FIFO - pop + # ----------------------------------------------------------------------------------- + def pop(self): + d = self.data + if not d[0]: + d.reverse() + d[0].reverse() + return d[0].pop() + + # ----------------------------------------------------------------------------------- + # FIFO - __nonzero__ + # ----------------------------------------------------------------------------------- + # NB: Please don't define this function, as it will break some legacy code in client + # Use the len() function instead + #def __nonzero__(self): + # d = self.data + # return not (not (d[0] or d[1])) + + # ----------------------------------------------------------------------------------- + # FIFO - __contains__ + # ----------------------------------------------------------------------------------- + def __contains__(self, o): + d = self.data + return (o in d[0]) or (o in d[1]) + + + # ----------------------------------------------------------------------------------- + # FIFO - Length + # ----------------------------------------------------------------------------------- + def Length(self): + d = self.data + return len(d[0]) + len(d[1]) + + # ----------------------------------------------------------------------------------- + # FIFO - clear + # ----------------------------------------------------------------------------------- + def clear(self): + self.data = [[], []] + + # ----------------------------------------------------------------------------------- + # FIFO - clear + # ----------------------------------------------------------------------------------- + def remove(self, o): + d = self.data + try: + d[0].remove(o) + except ValueError: + sys.exc_clear() -class Queue: + try: + d[1].remove(o) + except ValueError: + sys.exc_clear() + + +# ----------------------------------------------------------------------------------- +# Queue - QueueCheck +# ----------------------------------------------------------------------------------- +def QueueCheck(o): + + while True: + try: + o.pump() + except ReferenceError: + sys.exc_clear() + break + except StandardError: + StackTrace() + sys.exc_clear() + + Sleep(0.1) + + +# ----------------------------------------------------------------------------------- +# Queue Class +# ----------------------------------------------------------------------------------- +class Queue(FIFO): """A queue is a microthread-safe FIFO.""" - __guid__ = 'uthread_ccp.Queue' - + + # ----------------------------------------------------------------------------------- + # Queue - Constructor + # ----------------------------------------------------------------------------------- def __init__(self): - self.contents = [ ] - self.channel = stackless.channel() - + FIFO.__init__(self) + self.channel = stackless.channel() + self.blockingThreadRunning = False + + # ----------------------------------------------------------------------------------- + # Queue - put + # ----------------------------------------------------------------------------------- def put(self, x): - tmp = stackless.atomic() - self.contents.append(x) - while self.channel.queue and self.contents: - self.channel.send(self.contents.pop(0)) - + self.push(x) + self.pump() + + # ----------------------------------------------------------------------------------- + # Queue - pump + # ----------------------------------------------------------------------------------- + def pump(self): + + while self.channel.queue and self.Length() and self.channel.balance < 0: + o = self.pop() + self.channel.send(o) + + # ----------------------------------------------------------------------------------- + # Queue - non_blocking_put + # ----------------------------------------------------------------------------------- + def non_blocking_put(self, x): + + # Create a non blocking worker thread if this is the first time this gets called + if not self.blockingThreadRunning: + self.blockingThreadRunning = True + new(QueueCheck, weakref.proxy(self)).context = "uthread::QueueCheck" + + self.push(x) + + # ----------------------------------------------------------------------------------- + # Queue - get + # ----------------------------------------------------------------------------------- def get(self): - tmp = stackless.atomic() - if self.contents: - return self.contents.pop(0) + if self.Length(): + return self.pop() + return self.channel.receive() - - def unget(self, x): - tmp = stackless.atomic() - self.contents.insert(0, x) - - def cget(self): - return self.contents.pop(0) -exports = { - "uthread_ccp.new": new, - "uthread_ccp.irandom": irandom, - "uthread_ccp.uniqueId": uniqueId, - "uthread_ccp.run": run, - "uthread_ccp.schedule": schedule, - "uthread_ccp.sethandler": sethandler, - } - -def test(n): - global cnt - for cnt in xrange(n): - if cnt == 12345: - 1/0 - - \ No newline at end of file +# -------------------------------------------------------------------- +class Event: + + # -------------------------------------------------------------------- + def __init__(self, manual=1, signaled=0): + self.channel = stackless.channel() + self.manual = manual + self.signaled = signaled + + # -------------------------------------------------------------------- + def Wait(self, timeout=-1): + if timeout != -1: + raise RuntimeError("No timeouts supported in Event") + + if not self.signaled: + self.channel.receive() + + # -------------------------------------------------------------------- + def SetEvent(self): + if self.manual: + self.signaled = 1 + + while self.channel.queue: + self.channel.send(None) + + # -------------------------------------------------------------------- + def ResetEvent(self): + self.signaled = 0 + + + +def LockCheck(): + global semaphores + while 1: + each = None + Sleep(5 * 60) + now = time.time() + try: + for each in semaphores.keys(): + BeNice() + if (each.count<=0) and (each.waiting.balance < 0) and (each.lockedWhen and (now - each.lockedWhen)>=(5*MIN)): + logger.error("Semaphore %s appears to have threads in a locking conflict."%id(each)) + logger.error("holding thread:") + try: + for s in traceback.format_list(traceback.extract_stack(each.thread.frame,40)): + logger.error(s) + except: + sys.exc_clear() + first = each.waiting.queue + t = first + while t: + logger.error("waiting thread %s:"%id(t),4) + try: + for s in traceback.format_list(traceback.extract_stack(t.frame,40)): + logger.error(s,4) + except: + sys.exc_clear() + t = t.next + if t is first: + break + logger.error("End of locking conflict log") + except StandardError: + StackTrace() + sys.exc_clear() + +new(LockCheck).context = "uthread::LockCheck" + +__uthread__queue__ = None +def PoolHelper(queue): + t = stackless.getcurrent() + t.localStorage = {} + respawn = True + try: + try: + while 1: + BeNice() + ctx, callingContext, func, loc, args, keywords = queue.get() + if (queue.channel.balance >= 0): + new(PoolHelper, queue).context = "uthread::PoolHelper" + SetLocalStorage(loc) + # _tmpctx = t.PushTimer(ctx) + try: + apply( func, args, keywords ) + finally: + ctx = None + callingContext = None + func = None + t.localStorage = {} + loc = None + args = None + keywords = None + # t.PopTimer(_tmpctx) + except SystemExit: + respawn = False + raise + except: + if callingContext is not None: + extra = "spawned at %s %s(%s)"%callingContext + else: + extra = "" + StackTrace("Unhandled exception in %s%s" % (ctx, extra)) + sys.exc_clear() + finally: + if respawn: + del t + new(PoolHelper, queue).context = "uthread::PoolHelper" + +def PoolWorker(ctx,func,*args,**keywords): + ''' + Same as uthread.pool, but without copying local storage, thus resetting session, etc. + + Should be used for spawning worker threads. + ''' + return PoolWithoutTheStars(ctx,func,args,keywords,0,1) + +def PoolWorkerWithoutTheStars(ctx,func,args,keywords): + ''' + Same as uthread.worker, but without copying local storage, thus resetting session, etc. + + Should be used for spawning worker threads. + ''' + return PoolWithoutTheStars(ctx,func,args,keywords,0,1) + +def PoolWithoutTheStars(ctx,func,args,keywords,unsafe=0,worker=0): + if type(ctx) not in types.StringTypes: + StackTrace("uthread.pool must be called with a context string as the first parameter") + global __uthread__queue__ + callingContext = None + if ctx is None: + if unsafe: + ctx = "uthread::PoolHelper::UnsafeCrap" + else: + tb = traceback.extract_stack(limit=2)[0] + ctx = getattr(stackless.getcurrent(), "context", "") + callingContext = tb[2], tb[0], tb[1] #function , file, lineno + del tb + + if __uthread__queue__ is None: + __uthread__queue__ = Queue() + for i in range(60): + new(PoolHelper, __uthread__queue__).context = "uthread::PoolHelper" + if unsafe or worker: + st = None + else: + st = copy.copy(GetLocalStorage()) + __uthread__queue__.non_blocking_put( (str(ctx), callingContext, func, st, args, keywords,) ) + return None + +def Pool(ctx,func,*args,**keywords): + ''' + executes apply(args,keywords) on a new uthread. The uthread in question is taken + from a thread pool, rather than created one-per-shot call. ctx is used as the + thread context. This should generally be used for short-lived threads to reduce + overhead. + ''' + return PoolWithoutTheStars(ctx,func,args,keywords) + +def UnSafePool(ctx,func,*args,**keywords): + ''' + uthread.pool, but without any dangerous calls to stackless.getcurrent(), which could + have dramatic and drastic effects in the wrong context. + ''' + return PoolWithoutTheStars(ctx,func,args,keywords,1) + +def ParallelHelper(ch,idx,what): + ch, threadid = ch + MakeCurrentSynonymOf(threadid) + try: + ei = None + try: + if len(what)==3: + ret = (idx, apply(what[0], what[1], what[2] )) + if ch.balance < 0 : + ch.send( (1, ret) ) + else: + ret = (idx, apply(what[0], what[1] )) + if ch.balance < 0: + ch.send( (1, ret) ) + except StandardError: + ei = sys.exc_info() + sys.exc_clear() + + if ei: + if ch.balance < 0: + ch.send((0,ei)) + del ei + finally: + RemoveCurrentSynonymOf(threadid) + +def Parallel(funcs,exceptionHandler=None,maxcount=30): + ''' + Executes in parallel all the function calls specified in the list/tuple 'funcs', but returns the + return values in the order of the funcs list/tuple. If an exception occurs, only the first exception + will reach you. The rest will dissapear in a puff of logic. + + Each 'func' entry should be a tuple/list of: + 1. a function to call + 2. a tuple of arguments to call it with + 3. optionally, a dict of keyword args to call it with. + ''' + if not funcs: + return + + context = "ParallelHelper::"+getattr(stackless.getcurrent(),"context","???") + ch = stackless.channel(), id(stackless.getcurrent()) + ret = [ None ] * len(funcs) + n = len(funcs) + if n > maxcount: + n = maxcount + for i in range(n): + if type(funcs[i]) != types.TupleType: + raise RuntimeError("Parallel requires a list/tuple of (function, args tuple, optional keyword dict,)") + Pool(context, ParallelHelper, ch, i, funcs[i]) + for i in range(len(funcs)): + ok, bunch = ch[0].receive() + if ok: + idx,val = bunch + if len(funcs[i])==4: + ret[idx] = (funcs[i][3], val,) + else: + ret[idx] = val + else: + try: + raise bunch[0],bunch[1],bunch[2] + except StandardError: + if exceptionHandler: + exctype, exc, tb = sys.exc_info() + try: + try: + apply( exceptionHandler, (exc,) ) + except StandardError: + raise exc, None, tb + finally: + exctype, exc, tb = None, None, None + else: + StackTrace() + raise + + if n Author: richard.tew Date: Fri Aug 25 15:00:23 2006 New Revision: 51611 Modified: stackless/trunk/PCbuild/publish_binaries.py stackless/trunk/Stackless/module/stacklessmodule.c Log: Ported r51609. Added Jeff Senn's patch to allow running of stackless.run() on other threads other than the initial one. Corrected the publish_binaries.py script to handle the actual SVN structure rather than how I had it laid out on my harddrive. Modified: stackless/trunk/PCbuild/publish_binaries.py ============================================================================== --- stackless/trunk/PCbuild/publish_binaries.py (original) +++ stackless/trunk/PCbuild/publish_binaries.py Fri Aug 25 15:00:23 2006 @@ -1,7 +1,7 @@ from zipfile import * import os, sys, md5 -exp_path = r"..\..\binaries-pc" +exp_path = r"..\..\..\binaries-pc" prog = """ import md5 Modified: stackless/trunk/Stackless/module/stacklessmodule.c ============================================================================== --- stackless/trunk/Stackless/module/stacklessmodule.c (original) +++ stackless/trunk/Stackless/module/stacklessmodule.c Fri Aug 25 15:00:23 2006 @@ -216,9 +216,9 @@ int err; if (ts->st.main == NULL) return PyStackless_RunWatchdog_M(timeout); - if (ts != slp_initial_tstate || ts->st.current != ts->st.main) + if (ts->st.current != ts->st.main) RUNTIME_ERROR( - "run() must be run from the main thread's main tasklet.", + "run() must be run from the main tasklet.", NULL); if (timeout <= 0) { _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Aug 4 16:03:34 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 4 Aug 2006 16:03:34 +0200 (CEST) Subject: [Stackless-checkins] r51096 - stackless/trunk/Python/ceval.c Message-ID: <20060804140334.E3CED1E4003@bag.python.org> Author: richard.tew Date: Fri Aug 4 16:03:29 2006 New Revision: 51096 Modified: stackless/trunk/Python/ceval.c Log: Fix for an obscure Stackless bug (possibly present in 2.4.3). If any of the CALL_FUNCTION opcodes invoked something which soft switched and also changed the thread state frame value from the current frame, then if the frames f_execute variable was PyEval_EvalFrame_noval, the return value from the function call would not be on the stack (and therefore the stack would be corrupt) when the frame was invoked again. Modified: stackless/trunk/Python/ceval.c ============================================================================== --- stackless/trunk/Python/ceval.c (original) +++ stackless/trunk/Python/ceval.c Fri Aug 4 16:03:29 2006 @@ -2847,8 +2847,11 @@ return retval; STACKLESS_UNPACK(retval); retval = tstate->frame->f_execute(tstate->frame, 0, retval); - if (tstate->frame != f) + if (tstate->frame != f) { + assert(f->f_execute == PyEval_EvalFrame_value || f->f_execute == PyEval_EvalFrame_noval); + f->f_execute = PyEval_EvalFrame_value; return retval; + } if (STACKLESS_UNWINDING(retval)) STACKLESS_UNPACK(retval); _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Sun Aug 20 14:07:33 2006 From: python-checkins at python.org (richard.tew) Date: Sun, 20 Aug 2006 14:07:33 +0200 (CEST) Subject: [Stackless-checkins] r51415 - stackless/binaries-pc/python24.zip stackless/binaries-pc/python24.zip.md5.py Message-ID: <20060820120733.6D9891E4002@bag.python.org> Author: richard.tew Date: Sun Aug 20 14:05:45 2006 New Revision: 51415 Modified: stackless/binaries-pc/python24.zip stackless/binaries-pc/python24.zip.md5.py Log: As pointed out on the Stackless mailing list, the latest binaries for Windows do not contain all the fixes in SVN. This it an up-to-date build. Modified: stackless/binaries-pc/python24.zip ============================================================================== Binary files. No diff available. Modified: stackless/binaries-pc/python24.zip.md5.py ============================================================================== --- stackless/binaries-pc/python24.zip.md5.py (original) +++ stackless/binaries-pc/python24.zip.md5.py Sun Aug 20 14:05:45 2006 @@ -1,6 +1,6 @@ import md5 -expected = "44fdd18bec35f087efa4b608f24b21f0" +expected = "7ddbb149d33923e8352ec19b259a16c2" fname = r"python24.zip" print "expected digest", expected received = md5.md5(file(fname, "rb").read()).hexdigest() _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 14 12:39:05 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 14 Aug 2006 12:39:05 +0200 (CEST) Subject: [Stackless-checkins] r51275 - in stackless/trunk: Doc/api/api.tex Doc/api/exceptions.tex Doc/api/intro.tex Doc/api/refcounts.dat Doc/commontex/boilerplate.tex Doc/dist/dist.tex Doc/doc/doc.tex Doc/ext/newtypes.tex Doc/ext/windows.tex Doc/howto/doanddont.tex Doc/inst/inst.tex Doc/lib/email.tex Doc/lib/emailgenerator.tex Doc/lib/lib.tex Doc/lib/libanydbm.tex Doc/lib/libbase64.tex Doc/lib/libbinascii.tex Doc/lib/libbsddb.tex Doc/lib/libcompileall.tex Doc/lib/libcsv.tex Doc/lib/libctypes.tex Doc/lib/libfuncs.tex Doc/lib/libgettext.tex Doc/lib/libimp.tex Doc/lib/libinspect.tex Doc/lib/liblogging.tex Doc/lib/libmailbox.tex Doc/lib/libmimetypes.tex Doc/lib/libnew.tex Doc/lib/liboptparse.tex Doc/lib/libossaudiodev.tex Doc/lib/libpickle.tex Doc/lib/libpkgutil.tex Doc/lib/libposixpath.tex Doc/lib/librandom.tex Doc/lib/libre.tex Doc/lib/libreadline.tex Doc/lib/libshelve.tex Doc/lib/libsocket.tex Doc/lib/libsocksvr.tex Doc/lib/libsqlite3.tex Doc/lib/libstdtypes.tex Doc/lib/libstringio.tex Doc/lib/l! ibsubprocess.tex Doc/lib/libsys.tex Doc/lib/libtime.tex Doc/lib/libturtle.tex Doc/lib/libtypes.tex Doc/lib/libundoc.tex Doc/lib/libunicodedata.tex Doc/lib/liburllib.tex Doc/lib/liburllib2.tex Doc/lib/libuuid.tex Doc/lib/libweakref.tex Doc/lib/libwebbrowser.tex Doc/lib/libzipfile.tex Doc/lib/sqlite3/complete_statement.py Doc/lib/tkinter.tex Doc/mac/libmacfs.tex Doc/mac/libmacos.tex Doc/mac/using.tex Doc/ref/ref3.tex Doc/whatsnew/whatsnew20.tex Doc/whatsnew/whatsnew21.tex Doc/whatsnew/whatsnew23.tex Doc/whatsnew/whatsnew24.tex Doc/whatsnew/whatsnew25.tex Include/patchlevel.h Include/pyerrors.h Include/weakrefobject.h Lib/binhex.py Lib/bsddb/test/test_basics.py Lib/compiler/future.py Lib/compiler/transformer.py Lib/ctypes/__init__.py Lib/ctypes/test/test_varsize_struct.py Lib/ctypes/util.py Lib/distutils/__init__.py Lib/distutils/msvccompiler.py Lib/doctest.py Lib/email/__init__.py Lib/email/message.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py Lib/email! /utils.py Lib/encodings/mbcs.py Lib/gzip.py Lib/httplib.py Lib/idlelib/CREDITS.txt Lib/idlelib/CallTipWindow.py Lib/idlelib/CallTips.py Lib/idlelib/CodeContext.py Lib/idlelib/ColorDelegator.py Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/ParenMatch.py Lib/idlelib/PyShell.py Lib/idlelib/ScriptBinding.py Lib/id Message-ID: <20060814103905.D221C1E4002@bag.python.org> Author: richard.tew Date: Mon Aug 14 12:38:35 2006 New Revision: 51275 Added: stackless/trunk/Lib/test/crashers/recursion_limit_too_high.py - copied unchanged from r51065, python/trunk/Lib/test/crashers/recursion_limit_too_high.py stackless/trunk/Lib/xml/ (props changed) - copied from r51065, python/trunk/Lib/xml/ stackless/trunk/Mac/Modules/MacOS.c - copied unchanged from r51065, python/trunk/Mac/Modules/MacOS.c stackless/trunk/Misc/README.coverity - copied unchanged from r51065, python/trunk/Misc/README.coverity stackless/trunk/Misc/README.klocwork - copied unchanged from r51065, python/trunk/Misc/README.klocwork stackless/trunk/Modules/_typesmodule.c - copied unchanged from r51065, python/trunk/Modules/_typesmodule.c stackless/trunk/PC/os2emx/python25.def - copied unchanged from r51065, python/trunk/PC/os2emx/python25.def stackless/trunk/PCbuild/build_ssl.bat - copied unchanged from r51065, python/trunk/PCbuild/build_ssl.bat Removed: stackless/trunk/Lib/xml.py stackless/trunk/Lib/xmlcore/ stackless/trunk/Mac/Modules/macosmodule.c stackless/trunk/PC/os2emx/python24.def Modified: stackless/trunk/Doc/api/api.tex stackless/trunk/Doc/api/exceptions.tex stackless/trunk/Doc/api/intro.tex stackless/trunk/Doc/api/refcounts.dat stackless/trunk/Doc/commontex/boilerplate.tex stackless/trunk/Doc/dist/dist.tex stackless/trunk/Doc/doc/doc.tex stackless/trunk/Doc/ext/newtypes.tex stackless/trunk/Doc/ext/windows.tex stackless/trunk/Doc/howto/doanddont.tex stackless/trunk/Doc/inst/inst.tex stackless/trunk/Doc/lib/email.tex stackless/trunk/Doc/lib/emailgenerator.tex stackless/trunk/Doc/lib/lib.tex stackless/trunk/Doc/lib/libanydbm.tex stackless/trunk/Doc/lib/libbase64.tex stackless/trunk/Doc/lib/libbinascii.tex stackless/trunk/Doc/lib/libbsddb.tex stackless/trunk/Doc/lib/libcompileall.tex stackless/trunk/Doc/lib/libcsv.tex stackless/trunk/Doc/lib/libctypes.tex stackless/trunk/Doc/lib/libfuncs.tex stackless/trunk/Doc/lib/libgettext.tex stackless/trunk/Doc/lib/libimp.tex stackless/trunk/Doc/lib/libinspect.tex stackless/trunk/Doc/lib/liblogging.tex stackless/trunk/Doc/lib/libmailbox.tex stackless/trunk/Doc/lib/libmimetypes.tex stackless/trunk/Doc/lib/libnew.tex stackless/trunk/Doc/lib/liboptparse.tex stackless/trunk/Doc/lib/libossaudiodev.tex stackless/trunk/Doc/lib/libpickle.tex stackless/trunk/Doc/lib/libpkgutil.tex stackless/trunk/Doc/lib/libposixpath.tex stackless/trunk/Doc/lib/librandom.tex stackless/trunk/Doc/lib/libre.tex stackless/trunk/Doc/lib/libreadline.tex stackless/trunk/Doc/lib/libshelve.tex stackless/trunk/Doc/lib/libsocket.tex stackless/trunk/Doc/lib/libsocksvr.tex stackless/trunk/Doc/lib/libsqlite3.tex stackless/trunk/Doc/lib/libstdtypes.tex stackless/trunk/Doc/lib/libstringio.tex stackless/trunk/Doc/lib/libsubprocess.tex stackless/trunk/Doc/lib/libsys.tex stackless/trunk/Doc/lib/libtime.tex stackless/trunk/Doc/lib/libturtle.tex stackless/trunk/Doc/lib/libtypes.tex stackless/trunk/Doc/lib/libundoc.tex stackless/trunk/Doc/lib/libunicodedata.tex stackless/trunk/Doc/lib/liburllib.tex stackless/trunk/Doc/lib/liburllib2.tex stackless/trunk/Doc/lib/libuuid.tex stackless/trunk/Doc/lib/libweakref.tex stackless/trunk/Doc/lib/libwebbrowser.tex stackless/trunk/Doc/lib/libzipfile.tex stackless/trunk/Doc/lib/sqlite3/complete_statement.py stackless/trunk/Doc/lib/tkinter.tex stackless/trunk/Doc/mac/libmacfs.tex stackless/trunk/Doc/mac/libmacos.tex stackless/trunk/Doc/mac/using.tex stackless/trunk/Doc/ref/ref3.tex stackless/trunk/Doc/whatsnew/whatsnew20.tex stackless/trunk/Doc/whatsnew/whatsnew21.tex stackless/trunk/Doc/whatsnew/whatsnew23.tex stackless/trunk/Doc/whatsnew/whatsnew24.tex stackless/trunk/Doc/whatsnew/whatsnew25.tex stackless/trunk/Include/patchlevel.h stackless/trunk/Include/pyerrors.h stackless/trunk/Include/weakrefobject.h stackless/trunk/Lib/binhex.py stackless/trunk/Lib/bsddb/test/test_basics.py stackless/trunk/Lib/compiler/future.py stackless/trunk/Lib/compiler/transformer.py stackless/trunk/Lib/ctypes/__init__.py stackless/trunk/Lib/ctypes/test/test_varsize_struct.py stackless/trunk/Lib/ctypes/util.py stackless/trunk/Lib/distutils/__init__.py stackless/trunk/Lib/distutils/msvccompiler.py stackless/trunk/Lib/doctest.py stackless/trunk/Lib/email/__init__.py stackless/trunk/Lib/email/message.py stackless/trunk/Lib/email/test/test_email.py stackless/trunk/Lib/email/test/test_email_renamed.py stackless/trunk/Lib/email/utils.py stackless/trunk/Lib/encodings/mbcs.py stackless/trunk/Lib/gzip.py stackless/trunk/Lib/httplib.py stackless/trunk/Lib/idlelib/CREDITS.txt stackless/trunk/Lib/idlelib/CallTipWindow.py stackless/trunk/Lib/idlelib/CallTips.py stackless/trunk/Lib/idlelib/CodeContext.py stackless/trunk/Lib/idlelib/ColorDelegator.py stackless/trunk/Lib/idlelib/EditorWindow.py stackless/trunk/Lib/idlelib/NEWS.txt stackless/trunk/Lib/idlelib/ParenMatch.py stackless/trunk/Lib/idlelib/PyShell.py stackless/trunk/Lib/idlelib/ScriptBinding.py stackless/trunk/Lib/idlelib/config-keys.def stackless/trunk/Lib/idlelib/idlever.py stackless/trunk/Lib/idlelib/keybindingDialog.py stackless/trunk/Lib/idlelib/macosxSupport.py stackless/trunk/Lib/inspect.py stackless/trunk/Lib/lib-tk/Tkinter.py stackless/trunk/Lib/lib-tk/turtle.py stackless/trunk/Lib/logging/handlers.py stackless/trunk/Lib/mailbox.py stackless/trunk/Lib/optparse.py stackless/trunk/Lib/os.py stackless/trunk/Lib/pdb.py stackless/trunk/Lib/pkgutil.py stackless/trunk/Lib/popen2.py stackless/trunk/Lib/pydoc.py stackless/trunk/Lib/shutil.py stackless/trunk/Lib/socket.py stackless/trunk/Lib/struct.py stackless/trunk/Lib/subprocess.py stackless/trunk/Lib/tarfile.py stackless/trunk/Lib/test/crashers/README (props changed) stackless/trunk/Lib/test/crashers/bogus_code_obj.py stackless/trunk/Lib/test/crashers/gc_inspection.py stackless/trunk/Lib/test/crashers/recursive_call.py stackless/trunk/Lib/test/output/test_ossaudiodev stackless/trunk/Lib/test/string_tests.py stackless/trunk/Lib/test/test_bsddb.py stackless/trunk/Lib/test/test_compiler.py stackless/trunk/Lib/test/test_defaultdict.py stackless/trunk/Lib/test/test_dis.py stackless/trunk/Lib/test/test_doctest.py stackless/trunk/Lib/test/test_email_codecs.py stackless/trunk/Lib/test/test_filecmp.py stackless/trunk/Lib/test/test_generators.py stackless/trunk/Lib/test/test_getargs2.py stackless/trunk/Lib/test/test_grammar.py stackless/trunk/Lib/test/test_inspect.py stackless/trunk/Lib/test/test_iterlen.py stackless/trunk/Lib/test/test_mailbox.py stackless/trunk/Lib/test/test_mimetools.py stackless/trunk/Lib/test/test_mimetypes.py stackless/trunk/Lib/test/test_minidom.py stackless/trunk/Lib/test/test_optparse.py stackless/trunk/Lib/test/test_ossaudiodev.py stackless/trunk/Lib/test/test_sax.py stackless/trunk/Lib/test/test_shutil.py stackless/trunk/Lib/test/test_signal.py stackless/trunk/Lib/test/test_socket.py stackless/trunk/Lib/test/test_subprocess.py stackless/trunk/Lib/test/test_sys.py stackless/trunk/Lib/test/test_time.py stackless/trunk/Lib/test/test_traceback.py stackless/trunk/Lib/test/test_urllib2.py stackless/trunk/Lib/test/test_uuid.py stackless/trunk/Lib/test/test_winreg.py stackless/trunk/Lib/test/test_xml_etree.py stackless/trunk/Lib/test/test_xml_etree_c.py stackless/trunk/Lib/traceback.py stackless/trunk/Lib/types.py stackless/trunk/Lib/urllib.py stackless/trunk/Lib/urllib2.py stackless/trunk/Lib/uuid.py stackless/trunk/Lib/xml/dom/ (props changed) stackless/trunk/Lib/xml/parsers/ (props changed) stackless/trunk/Lib/xml/sax/ (props changed) stackless/trunk/Lib/zipfile.py stackless/trunk/Mac/BuildScript/README.txt stackless/trunk/Mac/BuildScript/scripts/postflight.patch-profile stackless/trunk/Mac/IDLE/config-main.def stackless/trunk/Mac/PythonLauncher/FileSettings.m stackless/trunk/Makefile.pre.in stackless/trunk/Misc/ACKS stackless/trunk/Misc/NEWS stackless/trunk/Misc/README.OpenBSD (props changed) stackless/trunk/Misc/RPM/python-2.5.spec stackless/trunk/Misc/build.sh stackless/trunk/Misc/python-config.in stackless/trunk/Modules/_bsddb.c stackless/trunk/Modules/_codecsmodule.c stackless/trunk/Modules/_ctypes/_ctypes.c stackless/trunk/Modules/_ctypes/callbacks.c stackless/trunk/Modules/_ctypes/callproc.c stackless/trunk/Modules/_ctypes/cfield.c stackless/trunk/Modules/_ctypes/ctypes.h stackless/trunk/Modules/_ctypes/libffi/configure stackless/trunk/Modules/_ctypes/libffi/configure.ac stackless/trunk/Modules/_ctypes/stgdict.c stackless/trunk/Modules/_cursesmodule.c stackless/trunk/Modules/_sqlite/cursor.c stackless/trunk/Modules/_sqlite/util.c stackless/trunk/Modules/_sqlite/util.h stackless/trunk/Modules/_struct.c stackless/trunk/Modules/_testcapimodule.c stackless/trunk/Modules/_tkinter.c stackless/trunk/Modules/_weakref.c stackless/trunk/Modules/bz2module.c stackless/trunk/Modules/cPickle.c stackless/trunk/Modules/collectionsmodule.c stackless/trunk/Modules/config.c.in stackless/trunk/Modules/fcntlmodule.c stackless/trunk/Modules/itertoolsmodule.c stackless/trunk/Modules/main.c stackless/trunk/Modules/posixmodule.c stackless/trunk/Modules/readline.c stackless/trunk/Modules/socketmodule.c stackless/trunk/Modules/spwdmodule.c stackless/trunk/Modules/timemodule.c stackless/trunk/Modules/unicodedata.c stackless/trunk/Modules/zlib/README (props changed) stackless/trunk/Objects/codeobject.c stackless/trunk/Objects/complexobject.c stackless/trunk/Objects/dictobject.c stackless/trunk/Objects/fileobject.c stackless/trunk/Objects/frameobject.c stackless/trunk/Objects/funcobject.c stackless/trunk/Objects/listsort.txt stackless/trunk/Objects/longobject.c stackless/trunk/Objects/setobject.c stackless/trunk/Objects/stringobject.c stackless/trunk/Objects/typeobject.c stackless/trunk/Objects/unicodeobject.c stackless/trunk/Objects/weakrefobject.c stackless/trunk/PC/_winreg.c stackless/trunk/PC/config.c stackless/trunk/PC/getpathp.c stackless/trunk/PC/os2emx/Makefile stackless/trunk/PC/os2emx/README.os2emx stackless/trunk/PC/os2emx/config.c stackless/trunk/PC/os2emx/pyconfig.h stackless/trunk/PC/winsound.c stackless/trunk/PCbuild/_ssl.vcproj stackless/trunk/PCbuild/build_ssl.py stackless/trunk/PCbuild/pythoncore.vcproj stackless/trunk/PCbuild/readme.txt stackless/trunk/Python/ast.c stackless/trunk/Python/compile.c stackless/trunk/Python/errors.c stackless/trunk/Python/future.c stackless/trunk/Python/getargs.c stackless/trunk/Python/getopt.c stackless/trunk/Python/import.c stackless/trunk/Python/mactoolboxglue.c stackless/trunk/Python/mystrtoul.c stackless/trunk/Python/pyarena.c stackless/trunk/Python/pystate.c stackless/trunk/Python/pythonrun.c stackless/trunk/Python/symtable.c stackless/trunk/Python/sysmodule.c stackless/trunk/Python/thread.c stackless/trunk/Python/thread_os2.h stackless/trunk/README stackless/trunk/Tools/buildbot/kill_python.c stackless/trunk/Tools/faqwiz/faqw.py stackless/trunk/Tools/msi/uuids.py stackless/trunk/Tools/scripts/README stackless/trunk/Tools/webchecker/webchecker.py stackless/trunk/configure stackless/trunk/configure.in stackless/trunk/pyconfig.h.in Log: Merged in the changes from 2.5b2 to 2.5b3 from the Python trunk. This was up to changelist 51065. A note for future merging efforts using tortoise svn, I need to specify the start revision (in this case the revision that 2.5b2 was branched to the tag at), otherwise it seems to do some strange backwards weirdo merge. Modified: stackless/trunk/Doc/api/api.tex ============================================================================== --- stackless/trunk/Doc/api/api.tex (original) +++ stackless/trunk/Doc/api/api.tex Mon Aug 14 12:38:35 2006 @@ -48,11 +48,6 @@ \input{newtypes} -% \chapter{Debugging \label{debugging}} -% -% XXX Explain Py_DEBUG, Py_TRACE_REFS, Py_REF_DEBUG. - - \appendix \chapter{Reporting Bugs} \input{reportingbugs} Modified: stackless/trunk/Doc/api/exceptions.tex ============================================================================== --- stackless/trunk/Doc/api/exceptions.tex (original) +++ stackless/trunk/Doc/api/exceptions.tex Mon Aug 14 12:38:35 2006 @@ -259,10 +259,14 @@ argument. It is mostly for internal use. \end{cfuncdesc} -\begin{cfuncdesc}{int}{PyErr_Warn}{PyObject *category, char *message} +\begin{cfuncdesc}{int}{PyErr_WarnEx}{PyObject *category, char *message, int stacklevel} Issue a warning message. The \var{category} argument is a warning category (see below) or \NULL; the \var{message} argument is a - message string. + message string. \var{stacklevel} is a positive number giving a + number of stack frames; the warning will be issued from the + currently executing line of code in that stack frame. A \var{stacklevel} + of 1 is the function calling \cfunction{PyErr_WarnEx()}, 2 is + the function above that, and so forth. This function normally prints a warning message to \var{sys.stderr}; however, it is also possible that the user has specified that @@ -294,6 +298,16 @@ command line documentation. There is no C API for warning control. \end{cfuncdesc} +\begin{cfuncdesc}{int}{PyErr_Warn}{PyObject *category, char *message} + Issue a warning message. The \var{category} argument is a warning + category (see below) or \NULL; the \var{message} argument is a + message string. The warning will appear to be issued from the function + calling \cfunction{PyErr_Warn()}, equivalent to calling + \cfunction{PyErr_WarnEx()} with a \var{stacklevel} of 1. + + Deprecated; use \cfunction{PyErr_WarnEx()} instead. +\end{cfuncdesc} + \begin{cfuncdesc}{int}{PyErr_WarnExplicit}{PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry} Modified: stackless/trunk/Doc/api/intro.tex ============================================================================== --- stackless/trunk/Doc/api/intro.tex (original) +++ stackless/trunk/Doc/api/intro.tex Mon Aug 14 12:38:35 2006 @@ -580,3 +580,59 @@ Notice that \cfunction{Py_Finalize} does \emph{not} free all memory allocated by the Python interpreter, e.g. memory allocated by extension modules currently cannot be released. + + +\section{Debugging Builds \label{debugging}} + +Python can be built with several macros to enable extra checks of the +interpreter and extension modules. These checks tend to add a large +amount of overhead to the runtime so they are not enabled by default. + +A full list of the various types of debugging builds is in the file +\file{Misc/SpecialBuilds.txt} in the Python source distribution. +Builds are available that support tracing of reference counts, +debugging the memory allocator, or low-level profiling of the main +interpreter loop. Only the most frequently-used builds will be +described in the remainder of this section. + +Compiling the interpreter with the \csimplemacro{Py_DEBUG} macro +defined produces what is generally meant by "a debug build" of Python. +\csimplemacro{Py_DEBUG} is enabled in the \UNIX{} build by adding +\longprogramopt{with-pydebug} to the \file{configure} command. It is also +implied by the presence of the not-Python-specific +\csimplemacro{_DEBUG} macro. When \csimplemacro{Py_DEBUG} is enabled +in the \UNIX{} build, compiler optimization is disabled. + +In addition to the reference count debugging described below, the +following extra checks are performed: + +\begin{itemize} + \item Extra checks are added to the object allocator. + \item Extra checks are added to the parser and compiler. + \item Downcasts from wide types to narrow types are checked for + loss of information. + \item A number of assertions are added to the dictionary and set + implementations. In addition, the set object acquires a + \method{test_c_api} method. + \item Sanity checks of the input arguments are added to frame + creation. + \item The storage for long ints is initialized with a known + invalid pattern to catch reference to uninitialized + digits. + \item Low-level tracing and extra exception checking are added + to the runtime virtual machine. + \item Extra checks are added to the memory arena implementation. + \item Extra debugging is added to the thread module. +\end{itemize} + +There may be additional checks not mentioned here. + +Defining \csimplemacro{Py_TRACE_REFS} enables reference tracing. When +defined, a circular doubly linked list of active objects is maintained +by adding two extra fields to every \ctype{PyObject}. Total +allocations are tracked as well. Upon exit, all existing references +are printed. (In interactive mode this happens after every statement +run by the interpreter.) Implied by \csimplemacro{Py_DEBUG}. + +Please refer to \file{Misc/SpecialBuilds.txt} in the Python source +distribution for more detailed information. Modified: stackless/trunk/Doc/api/refcounts.dat ============================================================================== --- stackless/trunk/Doc/api/refcounts.dat (original) +++ stackless/trunk/Doc/api/refcounts.dat Mon Aug 14 12:38:35 2006 @@ -303,6 +303,11 @@ PyErr_Warn:PyObject*:category:0: PyErr_Warn:char*:message:: +PyErr_WarnEx:int::: +PyErr_WarnEx:PyObject*:category:0: +PyErr_WarnEx:const char*:message:: +PyErr_WarnEx:Py_ssize_t:stack_level:: + PyEval_AcquireLock:void::: PyEval_AcquireThread:void::: Modified: stackless/trunk/Doc/commontex/boilerplate.tex ============================================================================== --- stackless/trunk/Doc/commontex/boilerplate.tex (original) +++ stackless/trunk/Doc/commontex/boilerplate.tex Mon Aug 14 12:38:35 2006 @@ -5,5 +5,5 @@ Email: \email{docs at python.org} } -\date{11th July, 2006} % XXX update before final release! +\date{3rd August, 2006} % XXX update before final release! \input{patchlevel} % include Python version information Modified: stackless/trunk/Doc/dist/dist.tex ============================================================================== --- stackless/trunk/Doc/dist/dist.tex (original) +++ stackless/trunk/Doc/dist/dist.tex Mon Aug 14 12:38:35 2006 @@ -530,7 +530,7 @@ you can take advantage of the fact that header files are installed in a consistent way by the Distutils \command{install\_header} command. For example, the Numerical Python header files are installed (on a standard -Unix installation) to \file{/usr/local/include/python1.5/Numerical}. +\UNIX{} installation) to \file{/usr/local/include/python1.5/Numerical}. (The exact location will differ according to your platform and Python installation.) Since the Python include directory---\file{/usr/local/include/python1.5} in this case---is always @@ -2317,7 +2317,7 @@ \lineiii{name}{the full name of the extension, including any packages --- ie. \emph{not} a filename or pathname, but Python dotted name}{string} \lineiii{sources}{list of source filenames, relative to the distribution -root (where the setup script lives), in Unix form (slash-separated) for +root (where the setup script lives), in \UNIX{} form (slash-separated) for portability. Source files may be C, \Cpp, SWIG (.i), platform-specific resource files, or whatever else is recognized by the \command{build_ext} command as source for a Python extension.}{string} @@ -3099,7 +3099,7 @@ Move file \var{src} to \var{dst}. If \var{dst} is a directory, the file will be moved into it with the same name; otherwise, \var{src} is just renamed to \var{dst}. Returns the new full name of the file. -\warning{Handles cross-device moves on Unix using \function{copy_file()}. +\warning{Handles cross-device moves on \UNIX{} using \function{copy_file()}. What about other systems???} \end{funcdesc} @@ -3142,7 +3142,7 @@ Return 'pathname' as a name that will work on the native filesystem, i.e. split it on '/' and put it back together again using the current directory separator. Needed because filenames in the setup script are -always supplied in Unix style, and have to be converted to the local +always supplied in \UNIX{} style, and have to be converted to the local convention before we can actually use them in the filesystem. Raises \exception{ValueError} on non-\UNIX-ish systems if \var{pathname} either starts or ends with a slash. @@ -3191,7 +3191,7 @@ \end{funcdesc} \begin{funcdesc}{split_quoted}{s} -Split a string up according to Unix shell-like rules for quotes and +Split a string up according to \UNIX{} shell-like rules for quotes and backslashes. In short: words are delimited by spaces, as long as those spaces are not escaped by a backslash, or inside a quoted string. Single and double quotes are equivalent, and the quote characters can Modified: stackless/trunk/Doc/doc/doc.tex ============================================================================== --- stackless/trunk/Doc/doc/doc.tex (original) +++ stackless/trunk/Doc/doc/doc.tex Mon Aug 14 12:38:35 2006 @@ -187,6 +187,20 @@ Topics which are not covered in the Apple's style guide will be discussed in this document if necessary. + Footnotes are generally discouraged due to the pain of using + footnotes in the HTML conversion of documents. Footnotes may be + used when they are the best way to present specific information. + When a footnote reference is added at the end of the sentence, it + should follow the sentence-ending punctuation. The \LaTeX{} markup + should appear something like this: + +\begin{verbatim} +This sentence has a footnote reference.% + \footnote{This is the footnote text.} +\end{verbatim} + + Footnotes may appear in the middle of sentences where appropriate. + Many special names are used in the Python documentation, including the names of operating systems, programming languages, standards bodies, and the like. Many of these were assigned \LaTeX{} macros @@ -281,10 +295,10 @@ to know about \LaTeX{} syntax. A \dfn{comment} is started by the ``percent'' character - (\character{\%}) and continues through the end of the line and all - leading whitespace on the following line. This is a little - different from any programming language I know of, so an example - is in order: + (\character{\%}) and continues through the end of the line + \emph{and all leading whitespace on the following line}. This is + a little different from any programming language I know of, so an + example is in order: \begin{verbatim} This is text.% comment Modified: stackless/trunk/Doc/ext/newtypes.tex ============================================================================== --- stackless/trunk/Doc/ext/newtypes.tex (original) +++ stackless/trunk/Doc/ext/newtypes.tex Mon Aug 14 12:38:35 2006 @@ -16,8 +16,9 @@ The way new types are defined changed dramatically (and for the better) in Python 2.2. This document documents how to define new types for Python 2.2 and later. If you need to support older -versions of Python, you will need to refer to older versions of this -documentation. +versions of Python, you will need to refer to +\ulink{older versions of this documentation} + {http://www.python.org/doc/versions/}. \end{notice} \section{The Basics @@ -479,7 +480,7 @@ 1 \item when we know that deallocation of the object\footnote{This is true when we know that the object is a basic type, like a string or - a float} will not cause any + a float.} will not cause any calls back into our type's code \item when decrementing a reference count in a \member{tp_dealloc} handler when garbage-collections is not supported\footnote{We relied @@ -791,9 +792,9 @@ In the second version of the \class{Noddy} example, we allowed any kind of object to be stored in the \member{first} or \member{last} -attributes\footnote{Even in the third version, we aren't guaranteed to +attributes.\footnote{Even in the third version, we aren't guaranteed to avoid cycles. Instances of string subclasses are allowed and string -subclasses could allow cycles even if normal strings don't.}. This +subclasses could allow cycles even if normal strings don't.} This means that \class{Noddy} objects can participate in cycles: \begin{verbatim} @@ -1563,6 +1564,85 @@ avoiding the exception can yield slightly better performance. If an actual error occurs, it should set an exception and return \NULL. + +\subsection{Weak Reference Support\label{weakref-support}} + +One of the goals of Python's weak-reference implementation is to allow +any type to participate in the weak reference mechanism without +incurring the overhead on those objects which do not benefit by weak +referencing (such as numbers). + +For an object to be weakly referencable, the extension must include a +\ctype{PyObject*} field in the instance structure for the use of the +weak reference mechanism; it must be initialized to \NULL{} by the +object's constructor. It must also set the \member{tp_weaklistoffset} +field of the corresponding type object to the offset of the field. +For example, the instance type is defined with the following +structure: + +\begin{verbatim} +typedef struct { + PyObject_HEAD + PyClassObject *in_class; /* The class object */ + PyObject *in_dict; /* A dictionary */ + PyObject *in_weakreflist; /* List of weak references */ +} PyInstanceObject; +\end{verbatim} + +The statically-declared type object for instances is defined this way: + +\begin{verbatim} +PyTypeObject PyInstance_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "module.instance", + + /* Lots of stuff omitted for brevity... */ + + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */ +}; +\end{verbatim} + +The type constructor is responsible for initializing the weak reference +list to \NULL: + +\begin{verbatim} +static PyObject * +instance_new() { + /* Other initialization stuff omitted for brevity */ + + self->in_weakreflist = NULL; + + return (PyObject *) self; +} +\end{verbatim} + +The only further addition is that the destructor needs to call the +weak reference manager to clear any weak references. This should be +done before any other parts of the destruction have occurred, but is +only required if the weak reference list is non-\NULL: + +\begin{verbatim} +static void +instance_dealloc(PyInstanceObject *inst) +{ + /* Allocate temporaries if needed, but do not begin + destruction just yet. + */ + + if (inst->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) inst); + + /* Proceed with object destruction normally. */ +} +\end{verbatim} + + \subsection{More Suggestions} Remember that you can omit most of these functions, in which case you Modified: stackless/trunk/Doc/ext/windows.tex ============================================================================== --- stackless/trunk/Doc/ext/windows.tex (original) +++ stackless/trunk/Doc/ext/windows.tex Mon Aug 14 12:38:35 2006 @@ -28,13 +28,15 @@ \section{A Cookbook Approach \label{win-cookbook}} There are two approaches to building extension modules on Windows, -just as there are on \UNIX: use the \refmodule{distutils} package to +just as there are on \UNIX: use the +\ulink{\module{distutils}}{../lib/module-distutils.html} package to control the build process, or do things manually. The distutils approach works well for most extensions; documentation on using -\refmodule{distutils} to build and package extension modules is -available in \citetitle[../dist/dist.html]{Distributing Python -Modules}. This section describes the manual approach to building -Python extensions written in C or \Cpp. +\ulink{\module{distutils}}{../lib/module-distutils.html} to build and +package extension modules is available in +\citetitle[../dist/dist.html]{Distributing Python Modules}. This +section describes the manual approach to building Python extensions +written in C or \Cpp. To build extensions using these instructions, you need to have a copy of the Python sources of the same version as your installed Python. Modified: stackless/trunk/Doc/howto/doanddont.tex ============================================================================== --- stackless/trunk/Doc/howto/doanddont.tex (original) +++ stackless/trunk/Doc/howto/doanddont.tex Mon Aug 14 12:38:35 2006 @@ -288,8 +288,9 @@ There are also many useful builtin functions people seem not to be aware of for some reason: \function{min()} and \function{max()} can find the minimum/maximum of any sequence with comparable semantics, -for example, yet many people write they own max/min. Another highly -useful function is \function{reduce()}. Classical use of \function{reduce()} +for example, yet many people write their own +\function{max()}/\function{min()}. Another highly useful function is +\function{reduce()}. A classical use of \function{reduce()} is something like \begin{verbatim} Modified: stackless/trunk/Doc/inst/inst.tex ============================================================================== --- stackless/trunk/Doc/inst/inst.tex (original) +++ stackless/trunk/Doc/inst/inst.tex Mon Aug 14 12:38:35 2006 @@ -262,7 +262,7 @@ \code{setup.py install}---then the \command{install} command installs to the standard location for third-party Python modules. This location varies by platform and by how you built/installed Python itself. On -\UNIX{} (and Mac OS X, which is also Unix-based), +\UNIX{} (and Mac OS X, which is also \UNIX-based), it also depends on whether the module distribution being installed is pure Python or contains extensions (``non-pure''): \begin{tableiv}{l|l|l|c}{textrm}% Modified: stackless/trunk/Doc/lib/email.tex ============================================================================== --- stackless/trunk/Doc/lib/email.tex (original) +++ stackless/trunk/Doc/lib/email.tex Mon Aug 14 12:38:35 2006 @@ -105,7 +105,7 @@ \lineiii{4.0}{Python 2.5}{Python 2.3 to 2.5} \end{tableiii} -Here are the major differences between \module{email} verson 4 and version 3: +Here are the major differences between \module{email} version 4 and version 3: \begin{itemize} \item All modules have been renamed according to \pep{8} standards. For @@ -126,6 +126,15 @@ \item Methods that were deprecated in version 3 have been removed. These include \method{Generator.__call__()}, \method{Message.get_type()}, \method{Message.get_main_type()}, \method{Message.get_subtype()}. + +\item Fixes have been added for \rfc{2231} support which can change some of + the return types for \function{Message.get_param()} and friends. Under + some circumstances, values which used to return a 3-tuple now return + simple strings (specifically, if all extended parameter segments were + unencoded, there is no language and charset designation expected, so the + return type is now a simple string). Also, \%-decoding used to be done + for both encoded and unencoded segments; this decoding is now done only + for encoded segments. \end{itemize} Here are the major differences between \module{email} version 3 and version 2: Modified: stackless/trunk/Doc/lib/emailgenerator.tex ============================================================================== --- stackless/trunk/Doc/lib/emailgenerator.tex (original) +++ stackless/trunk/Doc/lib/emailgenerator.tex Mon Aug 14 12:38:35 2006 @@ -31,11 +31,11 @@ \samp{>} character in front of any line in the body that starts exactly as \samp{From }, i.e. \code{From} followed by a space at the beginning of the line. This is the only guaranteed portable way to avoid having such -lines be mistaken for a Unix mailbox format envelope header separator (see +lines be mistaken for a \UNIX{} mailbox format envelope header separator (see \ulink{WHY THE CONTENT-LENGTH FORMAT IS BAD} {http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} for details). \var{mangle_from_} defaults to \code{True}, but you -might want to set this to \code{False} if you are not writing Unix +might want to set this to \code{False} if you are not writing \UNIX{} mailbox format files. Optional \var{maxheaderlen} specifies the longest length for a Modified: stackless/trunk/Doc/lib/lib.tex ============================================================================== --- stackless/trunk/Doc/lib/lib.tex (original) +++ stackless/trunk/Doc/lib/lib.tex Mon Aug 14 12:38:35 2006 @@ -71,12 +71,12 @@ % BUILT-INs % ============= -\input{libobjs} % Built-in Types, Exceptions and Functions +\input{libobjs} % Built-in Exceptions and Functions \input{libfuncs} -\input{libstdtypes} \input{libexcs} \input{libconsts} +\input{libstdtypes} % Built-in types % ============= @@ -154,8 +154,8 @@ % encoding stuff \input{libbase64} -\input{libbinascii} \input{libbinhex} +\input{libbinascii} \input{libquopri} \input{libuu} Modified: stackless/trunk/Doc/lib/libanydbm.tex ============================================================================== --- stackless/trunk/Doc/lib/libanydbm.tex (original) +++ stackless/trunk/Doc/lib/libanydbm.tex Mon Aug 14 12:38:35 2006 @@ -46,6 +46,32 @@ \method{keys()} methods are available. Keys and values must always be strings. +The following example records some hostnames and a corresponding title, +and then prints out the contents of the database: + +\begin{verbatim} +import anydbm + +# Open database, creating it if necessary. +db = anydbm.open('cache', 'c') + +# Record some values +db['www.python.org'] = 'Python Website' +db['www.cnn.com'] = 'Cable News Network' + +# Loop through contents. Other dictionary methods +# such as .keys(), .values() also work. +for k, v in db.iteritems(): + print k, '\t', v + +# Storing a non-string key or value will raise an exception (most +# likely a TypeError). +db['www.yahoo.com'] = 4 + +# Close when done. +db.close() +\end{verbatim} + \begin{seealso} \seemodule{dbhash}{BSD \code{db} database interface.} Modified: stackless/trunk/Doc/lib/libbase64.tex ============================================================================== --- stackless/trunk/Doc/lib/libbase64.tex (original) +++ stackless/trunk/Doc/lib/libbase64.tex Mon Aug 14 12:38:35 2006 @@ -146,6 +146,18 @@ always including an extra trailing newline (\code{'\e n'}). \end{funcdesc} +An example usage of the module: + +\begin{verbatim} +>>> import base64 +>>> encoded = base64.b64encode('data to be encoded') +>>> encoded +'ZGF0YSB0byBiZSBlbmNvZGVk' +>>> data = base64.b64decode(encoded) +>>> data +'data to be encoded' +\end{verbatim} + \begin{seealso} \seemodule{binascii}{Support module containing \ASCII-to-binary and binary-to-\ASCII{} conversions.} Modified: stackless/trunk/Doc/lib/libbinascii.tex ============================================================================== --- stackless/trunk/Doc/lib/libbinascii.tex (original) +++ stackless/trunk/Doc/lib/libbinascii.tex Mon Aug 14 12:38:35 2006 @@ -9,10 +9,11 @@ The \module{binascii} module contains a number of methods to convert between binary and various \ASCII-encoded binary representations. Normally, you will not use these functions directly -but use wrapper modules like \refmodule{uu}\refstmodindex{uu} or -\refmodule{binhex}\refstmodindex{binhex} instead, this module solely -exists because bit-manipulation of large amounts of data is slow in -Python. +but use wrapper modules like \refmodule{uu}\refstmodindex{uu}, +\refmodule{base64}\refstmodindex{base64}, or +\refmodule{binhex}\refstmodindex{binhex} instead. The \module{binascii} module +contains low-level functions written in C for greater speed +that are used by the higher-level modules. The \module{binascii} module defines the following functions: Modified: stackless/trunk/Doc/lib/libbsddb.tex ============================================================================== --- stackless/trunk/Doc/lib/libbsddb.tex (original) +++ stackless/trunk/Doc/lib/libbsddb.tex Mon Aug 14 12:38:35 2006 @@ -94,7 +94,7 @@ \begin{notice} -Beginning in 2.3 some Unix versions of Python may have a \module{bsddb185} +Beginning in 2.3 some \UNIX{} versions of Python may have a \module{bsddb185} module. This is present \emph{only} to allow backwards compatibility with systems which ship with the old Berkeley DB 1.85 database library. The \module{bsddb185} module should never be used directly in new code. Modified: stackless/trunk/Doc/lib/libcompileall.tex ============================================================================== --- stackless/trunk/Doc/lib/libcompileall.tex (original) +++ stackless/trunk/Doc/lib/libcompileall.tex Mon Aug 14 12:38:35 2006 @@ -44,6 +44,19 @@ \function{compile_dir()} function. \end{funcdesc} +To force a recompile of all the \file{.py} files in the \file{Lib/} +subdirectory and all its subdirectories: + +\begin{verbatim} +import compileall + +compileall.compile_dir('Lib/', force=True) + +# Perform same compilation, excluding files in .svn directories. +import re +compileall.compile_dir('Lib/', rx=re.compile('/[.]svn'), force=True) +\end{verbatim} + \begin{seealso} \seemodule[pycompile]{py_compile}{Byte-compile a single source file.} Modified: stackless/trunk/Doc/lib/libcsv.tex ============================================================================== --- stackless/trunk/Doc/lib/libcsv.tex (original) +++ stackless/trunk/Doc/lib/libcsv.tex Mon Aug 14 12:38:35 2006 @@ -55,7 +55,7 @@ Return a reader object which will iterate over lines in the given {}\var{csvfile}. \var{csvfile} can be any object which supports the iterator protocol and returns a string each time its \method{next} -method is called - file objects and list objects are both suitable. +method is called --- file objects and list objects are both suitable. If \var{csvfile} is a file object, it must be opened with the 'b' flag on platforms where that makes a difference. An optional {}\var{dialect} parameter can be given @@ -70,6 +70,18 @@ All data read are returned as strings. No automatic data type conversion is performed. + +\versionchanged[ +The parser is now stricter with respect to multi-line quoted +fields. Previously, if a line ended within a quoted field without a +terminating newline character, a newline would be inserted into the +returned field. This behavior caused problems when reading files +which contained carriage return characters within fields. The +behavior was changed to return the field without inserting newlines. As +a consequence, if newlines embedded within fields are important, the +input should be split into lines in a manner which preserves the newline +characters]{2.5} + \end{funcdesc} \begin{funcdesc}{writer}{csvfile\optional{, @@ -404,7 +416,7 @@ reader = csv.reader(open("passwd", "rb"), 'unixpwd') \end{verbatim} -A slightly more advanced use of the reader - catching and reporting errors: +A slightly more advanced use of the reader --- catching and reporting errors: \begin{verbatim} import csv, sys Modified: stackless/trunk/Doc/lib/libctypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libctypes.tex (original) +++ stackless/trunk/Doc/lib/libctypes.tex Mon Aug 14 12:38:35 2006 @@ -6,13 +6,13 @@ \modulesynopsis{A foreign function library for Python.} \versionadded{2.5} -\code{ctypes} is a foreign function library for Python. +\code{ctypes} is a foreign function library for Python. It provides C +compatible data types, and allows to call functions in dlls/shared +libraries. It can be used to wrap these libraries in pure Python. \subsection{ctypes tutorial\label{ctypes-ctypes-tutorial}} -This tutorial describes version 0.9.9 of \code{ctypes}. - Note: The code samples in this tutorial uses \code{doctest} to make sure that they actually work. Since some code samples behave differently under Linux, Windows, or Mac OS X, they contain doctest directives in @@ -150,8 +150,10 @@ \end{verbatim} \code{ctypes} tries to protect you from calling functions with the wrong -number of arguments. Unfortunately this only works on Windows. It -does this by examining the stack after the function returns: +number of arguments or the wrong calling convention. Unfortunately +this only works on Windows. It does this by examining the stack after +the function returns, so although an error is raised the function +\emph{has} been called: \begin{verbatim} >>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS Traceback (most recent call last): @@ -164,6 +166,25 @@ >>> \end{verbatim} +The same exception is raised when you call an \code{stdcall} function +with the \code{cdecl} calling convention, or vice versa: +\begin{verbatim} +>>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS +Traceback (most recent call last): + File "", line 1, in ? +ValueError: Procedure probably called with not enough arguments (4 bytes missing) +>>> + +>>> windll.msvcrt.printf("spam") # doctest: +WINDOWS +Traceback (most recent call last): + File "", line 1, in ? +ValueError: Procedure probably called with too many arguments (4 bytes in excess) +>>> +\end{verbatim} + +To find out the correct calling convention you have to look into the C +header file or the documentation for the function you want to call. + On Windows, \code{ctypes} uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values: @@ -790,10 +811,6 @@ \subsubsection{Pointers\label{ctypes-pointers}} -XXX Rewrite this section. Normally one only uses indexing, not the .contents -attribute! -List some recipes with pointers. bool(ptr), POINTER(tp)(), ...? - Pointer instances are created by calling the \code{pointer} function on a \code{ctypes} type: \begin{verbatim} @@ -826,7 +843,8 @@ attribute would cause the pointer to point to the memory location where this is stored: \begin{verbatim} ->>> pi.contents = c_int(99) +>>> i = c_int(99) +>>> pi.contents = i >>> pi.contents c_long(99) >>> @@ -855,9 +873,6 @@ pointer from a C function, and you \emph{know} that the pointer actually points to an array instead of a single item. - -\subsubsection{Pointer classes/types\label{ctypes-pointer-classestypes}} - Behind the scenes, the \code{pointer} function does more than simply create pointer instances, it has to create pointer \emph{types} first. This is done with the \code{POINTER} function, which accepts any @@ -875,6 +890,31 @@ >>> \end{verbatim} +Calling the pointer type without an argument creates a \code{NULL} +pointer. \code{NULL} pointers have a \code{False} boolean value: +\begin{verbatim} +>>> null_ptr = POINTER(c_int)() +>>> print bool(null_ptr) +False +>>> +\end{verbatim} + +\code{ctypes} checks for \code{NULL} when dereferencing pointers (but +dereferencing non-\code{NULL} pointers would crash Python): +\begin{verbatim} +>>> null_ptr[0] +Traceback (most recent call last): + .... +ValueError: NULL pointer access +>>> + +>>> null_ptr[0] = 1234 +Traceback (most recent call last): + .... +ValueError: NULL pointer access +>>> +\end{verbatim} + \subsubsection{Type conversions\label{ctypes-type-conversions}} @@ -1357,35 +1397,6 @@ >>> \end{verbatim} -The solution is to use 1-element arrays; as a special case ctypes does -no bounds checking on them: -\begin{verbatim} ->>> short_array = (c_short * 1)() ->>> print sizeof(short_array) -2 ->>> resize(short_array, 32) ->>> sizeof(short_array) -32 ->>> sizeof(type(short_array)) -2 ->>> short_array[0:8] -[0, 0, 0, 0, 0, 0, 0, 0] ->>> short_array[7] = 42 ->>> short_array[0:8] -[0, 0, 0, 0, 0, 0, 0, 42] ->>> -\end{verbatim} - -Using 1-element arrays as variable sized fields in structures works as -well, but they should be used as the last field in the structure -definition. This example shows a definition from the Windows header -files: -\begin{verbatim} -class SP_DEVICE_INTERFACE_DETAIL_DATA(Structure): - _fields_ = [("cbSize", c_int), - ("DevicePath", c_char * 1)] -\end{verbatim} - Another way to use variable-sized data types with \code{ctypes} is to use the dynamic nature of Python, and (re-)define the data type after the required size is already known, on a case by case basis. @@ -1474,13 +1485,13 @@ There are several ways to loaded shared libraries into the Python process. One way is to instantiate one of the following classes: -\begin{classdesc}{CDLL}{name, mode=RTLD_LOCAL, handle=None} +\begin{classdesc}{CDLL}{name, mode=DEFAULT_MODE, handle=None} Instances of this class represent loaded shared libraries. Functions in these libraries use the standard C calling convention, and are assumed to return \code{int}. \end{classdesc} -\begin{classdesc}{OleDLL}{name, mode=RTLD_LOCAL, handle=None} +\begin{classdesc}{OleDLL}{name, mode=DEFAULT_MODE, handle=None} Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the \code{stdcall} calling convention, and are assumed to return the windows specific @@ -1490,7 +1501,7 @@ failure, an \class{WindowsError} is automatically raised. \end{classdesc} -\begin{classdesc}{WinDLL}{name, mode=RTLD_LOCAL, handle=None} +\begin{classdesc}{WinDLL}{name, mode=DEFAULT_MODE, handle=None} Windows only: Instances of this class represent loaded shared libraries, functions in these libraries use the \code{stdcall} calling convention, and are assumed to return \code{int} by default. @@ -1503,7 +1514,7 @@ The Python GIL is released before calling any function exported by these libraries, and reaquired afterwards. -\begin{classdesc}{PyDLL}{name, mode=RTLD_LOCAL, handle=None} +\begin{classdesc}{PyDLL}{name, mode=DEFAULT_MODE, handle=None} Instances of this class behave like \class{CDLL} instances, except that the Python GIL is \emph{not} released during the function call, and after the function execution the Python error flag is checked. @@ -1533,6 +1544,12 @@ available, it is the same as \var{RTLD{\_}GLOBAL}. \end{datadescni} +\begin{datadescni}{DEFAULT_MODE} +The default mode which is used to load shared libraries. On OSX +10.3, this is \var{RTLD{\_}GLOBAL}, otherwise it is the same as +\var{RTLD{\_}LOCAL}. +\end{datadescni} + Instances of these classes have no public methods, however \method{{\_}{\_}getattr{\_}{\_}} and \method{{\_}{\_}getitem{\_}{\_}} have special behaviour: functions exported by the shared library can be accessed as attributes of by @@ -1566,10 +1583,9 @@ return the same library each time. \end{classdesc} -\begin{methoddesc}{LoadLibrary}{name, mode=RTLD_LOCAL, handle=None} +\begin{methoddesc}{LoadLibrary}{name} Load a shared library into the process and return it. This method -always creates a new instance of the library. All three -parameters are passed to the constructor of the library object. +always returns a new instance of the library. \end{methoddesc} These prefabricated library loaders are available: @@ -1810,8 +1826,8 @@ \begin{verbatim} WINUSERAPI BOOL WINAPI GetWindowRect( - HWND hWnd, - LPRECT lpRect); + HWND hWnd, + LPRECT lpRect); \end{verbatim} Here is the wrapping with \code{ctypes}: Modified: stackless/trunk/Doc/lib/libfuncs.tex ============================================================================== --- stackless/trunk/Doc/lib/libfuncs.tex (original) +++ stackless/trunk/Doc/lib/libfuncs.tex Mon Aug 14 12:38:35 2006 @@ -401,67 +401,17 @@ \end{funcdesc} \begin{funcdesc}{file}{filename\optional{, mode\optional{, bufsize}}} - Return a new file object (described in - section~\ref{bltin-file-objects}, ``\ulink{File - Objects}{bltin-file-objects.html}''). - The first two arguments are the same as for \code{stdio}'s - \cfunction{fopen()}: \var{filename} is the file name to be opened, - \var{mode} indicates how the file is to be opened: \code{'r'} for - reading, \code{'w'} for writing (truncating an existing file), and - \code{'a'} opens it for appending (which on \emph{some} \UNIX{} - systems means that \emph{all} writes append to the end of the file, - regardless of the current seek position). + Constructor function for the \class{file} type, described further + in section~\ref{bltin-file-objects}, ``\ulink{File + Objects}{bltin-file-objects.html}''. The constructor's arguments + are the same as those of the \function{open()} built-in function + described below. - Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for - updating (note that \code{'w+'} truncates the file). Append - \code{'b'} to the mode to open the file in binary mode, on systems - that differentiate between binary and text files (else it is - ignored). If the file cannot be opened, \exception{IOError} is - raised. - - In addition to the standard \cfunction{fopen()} values \var{mode} - may be \code{'U'} or \code{'rU'}. If Python is built with universal - newline support (the default) the file is opened as a text file, but - lines may be terminated by any of \code{'\e n'}, the Unix end-of-line - convention, - \code{'\e r'}, the Macintosh convention or \code{'\e r\e n'}, the Windows - convention. All of these external representations are seen as - \code{'\e n'} - by the Python program. If Python is built without universal newline support - \var{mode} \code{'U'} is the same as normal text mode. Note that - file objects so opened also have an attribute called - \member{newlines} which has a value of \code{None} (if no newlines - have yet been seen), \code{'\e n'}, \code{'\e r'}, \code{'\e r\e n'}, - or a tuple containing all the newline types seen. - - Python enforces that the mode, after stripping \code{'U'}, begins with - \code{'r'}, \code{'w'} or \code{'a'}. - - If \var{mode} is omitted, it defaults to \code{'r'}. When opening a - binary file, you should append \code{'b'} to the \var{mode} value - for improved portability. (It's useful even on systems which don't - treat binary and text files differently, where it serves as - documentation.) - \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O} - \index{I/O control!buffering} - The optional \var{bufsize} argument specifies the - file's desired buffer size: 0 means unbuffered, 1 means line - buffered, any other positive value means use a buffer of - (approximately) that size. A negative \var{bufsize} means to use - the system default, which is usually line buffered for tty - devices and fully buffered for other files. If omitted, the system - default is used.\footnote{ - Specifying a buffer size currently has no effect on systems that - don't have \cfunction{setvbuf()}. The interface to specify the - buffer size is not done using a method that calls - \cfunction{setvbuf()}, because that may dump core when called - after any I/O has been performed, and there's no reliable way to - determine whether this is the case.} + When opening a file, it's preferable to use \function{open()} instead of + invoking this constructor directly. \class{file} is more suited to + type testing (for example, writing \samp{isinstance(f, file)}). \versionadded{2.2} - - \versionchanged[Restriction on first letter of mode string - introduced]{2.5} \end{funcdesc} \begin{funcdesc}{filter}{function, list} @@ -726,10 +676,71 @@ \end{funcdesc} \begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}} - A wrapper for the \function{file()} function above. The intent is - for \function{open()} to be preferred for use as a factory function - returning a new \class{file} object. \class{file} is more suited to - type testing (for example, writing \samp{isinstance(f, file)}). + Open a file, returning an object of the \class{file} type described + in section~\ref{bltin-file-objects}, ``\ulink{File + Objects}{bltin-file-objects.html}''. If the file cannot be opened, + \exception{IOError} is raised. When opening a file, it's + preferable to use \function{open()} instead of invoking the + \class{file} constructor directly. + + The first two arguments are the same as for \code{stdio}'s + \cfunction{fopen()}: \var{filename} is the file name to be opened, + and \var{mode} is a string indicating how the file is to be opened. + + The most commonly-used values of \var{mode} are \code{'r'} for + reading, \code{'w'} for writing (truncating the file if it already + exists), and \code{'a'} for appending (which on \emph{some} \UNIX{} + systems means that \emph{all} writes append to the end of the file + regardless of the current seek position). If \var{mode} is omitted, + it defaults to \code{'r'}. When opening a binary file, you should + append \code{'b'} to the \var{mode} value to open the file in binary + mode, which will improve portability. (Appending \code{'b'} is + useful even on systems that don't treat binary and text files + differently, where it serves as documentation.) See below for more + possible values of \var{mode}. + + \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O} + \index{I/O control!buffering} + The optional \var{bufsize} argument specifies the + file's desired buffer size: 0 means unbuffered, 1 means line + buffered, any other positive value means use a buffer of + (approximately) that size. A negative \var{bufsize} means to use + the system default, which is usually line buffered for tty + devices and fully buffered for other files. If omitted, the system + default is used.\footnote{ + Specifying a buffer size currently has no effect on systems that + don't have \cfunction{setvbuf()}. The interface to specify the + buffer size is not done using a method that calls + \cfunction{setvbuf()}, because that may dump core when called + after any I/O has been performed, and there's no reliable way to + determine whether this is the case.} + + Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for + updating (note that \code{'w+'} truncates the file). Append + \code{'b'} to the mode to open the file in binary mode, on systems + that differentiate between binary and text files; on systems + that don't have this distinction, adding the \code{'b'} has no effect. + + In addition to the standard \cfunction{fopen()} values \var{mode} + may be \code{'U'} or \code{'rU'}. Python is usually built with universal + newline support; supplying \code{'U'} opens the file as a text file, but + lines may be terminated by any of the following: the \UNIX{} end-of-line + convention \code{'\e n'}, + the Macintosh convention \code{'\e r'}, or the Windows + convention \code{'\e r\e n'}. All of these external representations are seen as + \code{'\e n'} + by the Python program. If Python is built without universal newline support + a \var{mode} with \code{'U'} is the same as normal text mode. Note that + file objects so opened also have an attribute called + \member{newlines} which has a value of \code{None} (if no newlines + have yet been seen), \code{'\e n'}, \code{'\e r'}, \code{'\e r\e n'}, + or a tuple containing all the newline types seen. + + Python enforces that the mode, after stripping \code{'U'}, begins with + \code{'r'}, \code{'w'} or \code{'a'}. + + \versionchanged[Restriction on first letter of mode string + introduced]{2.5} \end{funcdesc} \begin{funcdesc}{ord}{c} Modified: stackless/trunk/Doc/lib/libgettext.tex ============================================================================== --- stackless/trunk/Doc/lib/libgettext.tex (original) +++ stackless/trunk/Doc/lib/libgettext.tex Mon Aug 14 12:38:35 2006 @@ -549,7 +549,7 @@ written a program called \program{xpot} which does a similar job. It is available as part of his \program{po-utils} package at -\url{http://www.iro.umontreal.ca/contrib/po-utils/HTML/}.} program +\url{http://po-utils.progiciels-bpi.ca/}.} program scans all your Python source code looking for the strings you previously marked as translatable. It is similar to the GNU \program{gettext} program except that it understands all the @@ -585,8 +585,8 @@ translation processing during run-time. How you use the \module{gettext} module in your code depends on -whether you are internationalizing your entire application or a single -module. +whether you are internationalizing a single module or your entire application. +The next two sections will discuss each case. \subsubsection{Localizing your module} Modified: stackless/trunk/Doc/lib/libimp.tex ============================================================================== --- stackless/trunk/Doc/lib/libimp.tex (original) +++ stackless/trunk/Doc/lib/libimp.tex Mon Aug 14 12:38:35 2006 @@ -232,6 +232,24 @@ source file. \end{funcdesc} +\begin{classdesc}{NullImporter}{path_string} +The \class{NullImporter} type is a \pep{302} import hook that handles +non-directory path strings by failing to find any modules. Calling this +type with an existing directory or empty string raises +\exception{ImportError}. Otherwise, a \class{NullImporter} instance is +returned. + +Python adds instances of this type to \code{sys.path_importer_cache} for +any path entries that are not directories and are not handled by any other +path hooks on \code{sys.path_hooks}. Instances have only one method: + +\begin{methoddesc}{find_module}{fullname \optional{, path}} +This method always returns \code{None}, indicating that the requested +module could not be found. +\end{methoddesc} + +\versionadded{2.5} +\end{classdesc} \subsection{Examples} \label{examples-imp} @@ -257,7 +275,7 @@ # there's a problem we can't handle -- let the caller handle it. fp, pathname, description = imp.find_module(name) - + try: return imp.load_module(name, fp, pathname, description) finally: Modified: stackless/trunk/Doc/lib/libinspect.tex ============================================================================== --- stackless/trunk/Doc/lib/libinspect.tex (original) +++ stackless/trunk/Doc/lib/libinspect.tex Mon Aug 14 12:38:35 2006 @@ -180,13 +180,32 @@ Return true if the object is a data descriptor. Data descriptors have both a __get__ and a __set__ attribute. Examples are - properties (defined in Python) and getsets and members (defined in C). - Typically, data descriptors will also have __name__ and __doc__ attributes - (properties, getsets, and members have both of these attributes), but this - is not guaranteed. + properties (defined in Python), getsets, and members. The latter two are + defined in C and there are more specific tests available for those types, + which is robust across Python implementations. Typically, data descriptors + will also have __name__ and __doc__ attributes (properties, getsets, and + members have both of these attributes), but this is not guaranteed. \versionadded{2.3} \end{funcdesc} +\begin{funcdesc}{isgetsetdescriptor}{object} + Return true if the object is a getset descriptor. + + getsets are attributes defined in extension modules via \code{PyGetSetDef} + structures. For Python implementations without such types, this method will + always return \code{False}. +\versionadded{2.5} +\end{funcdesc} + +\begin{funcdesc}{ismemberdescriptor}{object} + Return true if the object is a member descriptor. + + Member descriptors are attributes defined in extension modules via + \code{PyMemberDef} structures. For Python implementations without such + types, this method will always return \code{False}. +\versionadded{2.5} +\end{funcdesc} + \subsection{Retrieving source code \label{inspect-source}} Modified: stackless/trunk/Doc/lib/liblogging.tex ============================================================================== --- stackless/trunk/Doc/lib/liblogging.tex (original) +++ stackless/trunk/Doc/lib/liblogging.tex Mon Aug 14 12:38:35 2006 @@ -1068,13 +1068,11 @@ \end{tableii} If \var{backupCount} is non-zero, the system will save old log files by -appending the extensions ".1", ".2" etc., to the filename. For example, -with a \var{backupCount} of 5 and a base file name of \file{app.log}, -you would get \file{app.log}, \file{app.log.1}, \file{app.log.2}, up to -\file{app.log.5}. The file being written to is always \file{app.log}. -When this file is filled, it is closed and renamed to \file{app.log.1}, -and if files \file{app.log.1}, \file{app.log.2}, etc. exist, then they -are renamed to \file{app.log.2}, \file{app.log.3} etc. respectively. +appending extensions to the filename. The extensions are date-and-time +based, using the strftime format \code{\%Y-\%m-\%d_\%H-\%M-\%S} or a leading +portion thereof, depending on the rollover interval. At most \var{backupCount} +files will be kept, and if more would be created when rollover occurs, the +oldest one is deleted. \end{classdesc} \begin{methoddesc}{doRollover}{} @@ -1539,7 +1537,7 @@ To stop the server, call \function{stopListening()}. To send a configuration to the socket, read in the configuration file and send it to the socket as a string of bytes preceded by a four-byte length packed in binary using -struct.\code{pack(">L", n)}. +struct.\code{pack('>L', n)}. \end{funcdesc} \begin{funcdesc}{stopListening}{} Modified: stackless/trunk/Doc/lib/libmailbox.tex ============================================================================== --- stackless/trunk/Doc/lib/libmailbox.tex (original) +++ stackless/trunk/Doc/lib/libmailbox.tex Mon Aug 14 12:38:35 2006 @@ -1367,9 +1367,8 @@ print subject \end{verbatim} -A (surprisingly) simple example of copying all mail from a Babyl mailbox to an -MH mailbox, converting all of the format-specific information that can be -converted: +To copy all mail from a Babyl mailbox to an MH mailbox, converting all +of the format-specific information that can be converted: \begin{verbatim} import mailbox Modified: stackless/trunk/Doc/lib/libmimetypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libmimetypes.tex (original) +++ stackless/trunk/Doc/lib/libmimetypes.tex Mon Aug 14 12:38:35 2006 @@ -158,6 +158,20 @@ \versionadded{2.2} \end{classdesc} +An example usage of the module: + +\begin{verbatim} +>>> import mimetypes +>>> mimetypes.init() +>>> mimetypes.knownfiles +['/etc/mime.types', '/etc/httpd/mime.types', ... ] +>>> mimetypes.suffix_map['.tgz'] +'.tar.gz' +>>> mimetypes.encodings_map['.gz'] +'gzip' +>>> mimetypes.types_map['.tgz'] +'application/x-tar-gz' +\end{verbatim} \subsection{MimeTypes Objects \label{mimetypes-objects}} Modified: stackless/trunk/Doc/lib/libnew.tex ============================================================================== --- stackless/trunk/Doc/lib/libnew.tex (original) +++ stackless/trunk/Doc/lib/libnew.tex Mon Aug 14 12:38:35 2006 @@ -30,13 +30,16 @@ callable. \end{funcdesc} -\begin{funcdesc}{function}{code, globals\optional{, name\optional{, argdefs}}} +\begin{funcdesc}{function}{code, globals\optional{, name\optional{, + argdefs\optional{, closure}}}} Returns a (Python) function with the given code and globals. If \var{name} is given, it must be a string or \code{None}. If it is a string, the function will have the given name, otherwise the function name will be taken from \code{\var{code}.co_name}. If \var{argdefs} is given, it must be a tuple and will be used to -determine the default values of parameters. +determine the default values of parameters. If \var{closure} is given, +it must be \code{None} or a tuple of cell objects containing objects +to bind to the names in \code{\var{code}.co_freevars}. \end{funcdesc} \begin{funcdesc}{code}{argcount, nlocals, stacksize, flags, codestring, Modified: stackless/trunk/Doc/lib/liboptparse.tex ============================================================================== --- stackless/trunk/Doc/lib/liboptparse.tex (original) +++ stackless/trunk/Doc/lib/liboptparse.tex Mon Aug 14 12:38:35 2006 @@ -1390,7 +1390,7 @@ \end{verbatim} \end{itemize} -% $Id: reference.txt 505 2005-07-22 01:52:40Z gward $ +% $Id: reference.txt 519 2006-06-11 14:39:11Z gward $ \subsection{Option Callbacks\label{optparse-option-callbacks}} Modified: stackless/trunk/Doc/lib/libossaudiodev.tex ============================================================================== --- stackless/trunk/Doc/lib/libossaudiodev.tex (original) +++ stackless/trunk/Doc/lib/libossaudiodev.tex Mon Aug 14 12:38:35 2006 @@ -68,7 +68,7 @@ Open an audio device and return an OSS audio device object. This object supports many file-like methods, such as \method{read()}, \method{write()}, and \method{fileno()} (although there are subtle -differences between conventional Unix read/write semantics and those of +differences between conventional \UNIX{} read/write semantics and those of OSS audio devices). It also supports a number of audio-specific methods; see below for the complete list of methods. Modified: stackless/trunk/Doc/lib/libpickle.tex ============================================================================== --- stackless/trunk/Doc/lib/libpickle.tex (original) +++ stackless/trunk/Doc/lib/libpickle.tex Mon Aug 14 12:38:35 2006 @@ -725,7 +725,50 @@ \subsection{Example \label{pickle-example}} -Here's a simple example of how to modify pickling behavior for a +For the simplest code, use the \function{dump()} and \function{load()} +functions. Note that a self-referencing list is pickled and restored +correctly. + +\begin{verbatim} +import pickle + +data1 = {'a': [1, 2.0, 3, 4+6j], + 'b': ('string', u'Unicode string'), + 'c': None} + +selfref_list = [1, 2, 3] +selfref_list.append(selfref_list) + +output = open('data.pkl', 'wb') + +# Pickle dictionary using protocol 0. +pickle.dump(data1, output) + +# Pickle the list using the highest protocol available. +pickle.dump(selfref_list, output, -1) + +output.close() +\end{verbatim} + +The following example reads the resulting pickled data. When reading +a pickle-containing file, you should open the file in binary mode +because you can't be sure if the ASCII or binary format was used. + +\begin{verbatim} +import pprint, pickle + +pkl_file = open('data.pkl', 'rb') + +data1 = pickle.load(pkl_file) +pprint.pprint(data1) + +data2 = pickle.load(pkl_file) +pprint.pprint(data2) + +pkl_file.close() +\end{verbatim} + +Here's a larger example that shows how to modify pickling behavior for a class. The \class{TextReader} class opens a text file, and returns the line number and line contents each time its \method{readline()} method is called. If a \class{TextReader} instance is pickled, all Modified: stackless/trunk/Doc/lib/libpkgutil.tex ============================================================================== --- stackless/trunk/Doc/lib/libpkgutil.tex (original) +++ stackless/trunk/Doc/lib/libpkgutil.tex Mon Aug 14 12:38:35 2006 @@ -30,7 +30,7 @@ with \code{import}. A \file{*.pkg} file is trusted at face value: apart from checking for duplicates, all entries found in a \file{*.pkg} file are added to the path, regardless of whether they - exist the filesystem. (This is a feature.) + exist on the filesystem. (This is a feature.) If the input path is not a list (as is the case for frozen packages) it is returned unchanged. The input path is not Modified: stackless/trunk/Doc/lib/libposixpath.tex ============================================================================== --- stackless/trunk/Doc/lib/libposixpath.tex (original) +++ stackless/trunk/Doc/lib/libposixpath.tex Mon Aug 14 12:38:35 2006 @@ -42,8 +42,11 @@ \end{funcdesc} \begin{funcdesc}{exists}{path} -Return \code{True} if \var{path} refers to an existing path. -Returns \code{False} for broken symbolic links. +Return \code{True} if \var{path} refers to an existing path. Returns +\code{False} for broken symbolic links. On some platforms, this +function may return \code{False} if permission is not granted to +execute \function{os.stat()} on the requested file, even if the +\var{path} physically exists. \end{funcdesc} \begin{funcdesc}{lexists}{path} @@ -190,9 +193,8 @@ \end{funcdesc} \begin{funcdesc}{sameopenfile}{fp1, fp2} -Return \code{True} if the file objects \var{fp1} and \var{fp2} refer to the -same file. The two file objects may represent different file -descriptors. +Return \code{True} if the file descriptors \var{fp1} and \var{fp2} refer +to the same file. Availability: Macintosh, \UNIX. \end{funcdesc} Modified: stackless/trunk/Doc/lib/librandom.tex ============================================================================== --- stackless/trunk/Doc/lib/librandom.tex (original) +++ stackless/trunk/Doc/lib/librandom.tex Mon Aug 14 12:38:35 2006 @@ -236,7 +236,7 @@ \var{beta} is the shape parameter. \end{funcdesc} -Alternative Generators +Alternative Generators: \begin{classdesc}{WichmannHill}{\optional{seed}} Class that implements the Wichmann-Hill algorithm as the core generator. @@ -267,6 +267,30 @@ \versionadded{2.4} \end{classdesc} +Examples of basic usage: + +\begin{verbatim} +>>> random.random() # Random float x, 0.0 <= x < 1.0 +0.37444887175646646 +>>> random.uniform(1, 10) # Random float x, 1.0 <= x < 10.0 +1.1800146073117523 +>>> random.randint(1, 10) # Integer from 1 to 10, endpoints included +7 +>>> random.randrange(0, 101, 2) # Even integer from 0 to 100 +26 +>>> random.choice('abcdefghij') # Choose a random element +'c' + +>>> items = [1, 2, 3, 4, 5, 6, 7] +>>> random.shuffle(items) +>>> items +[7, 3, 2, 5, 6, 4, 1] + +>>> random.sample([1, 2, 3, 4, 5], 3) # Choose 3 elements +[4, 1, 5] + +\end{verbatim} + \begin{seealso} \seetext{M. Matsumoto and T. Nishimura, ``Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom Modified: stackless/trunk/Doc/lib/libre.tex ============================================================================== --- stackless/trunk/Doc/lib/libre.tex (original) +++ stackless/trunk/Doc/lib/libre.tex Mon Aug 14 12:38:35 2006 @@ -897,7 +897,7 @@ \lineii{\code{\%d}} {\regexp{[-+]?\e d+}} \lineii{\code{\%e}, \code{\%E}, \code{\%f}, \code{\%g}} - {\regexp{[-+]?(\e d+(\e.\e d*)?|\e d*\e.\e d+)([eE][-+]?\e d+)?}} + {\regexp{[-+]?(\e d+(\e.\e d*)?|\e.\e d+)([eE][-+]?\e d+)?}} \lineii{\code{\%i}} {\regexp{[-+]?(0[xX][\e dA-Fa-f]+|0[0-7]*|\e d+)}} \lineii{\code{\%o}} Modified: stackless/trunk/Doc/lib/libreadline.tex ============================================================================== --- stackless/trunk/Doc/lib/libreadline.tex (original) +++ stackless/trunk/Doc/lib/libreadline.tex Mon Aug 14 12:38:35 2006 @@ -7,10 +7,13 @@ \modulesynopsis{GNU readline support for Python.} -The \module{readline} module defines a number of functions used either -directly or from the \refmodule{rlcompleter} module to facilitate -completion and history file read and write from the Python -interpreter. +The \module{readline} module defines a number of functions to +facilitate completion and reading/writing of history files from the +Python interpreter. This module can be used directly or via the +\refmodule{rlcompleter} module. Settings made using +this module affect the behaviour of both the interpreter's interactive prompt +and the prompts offered by the \function{raw_input()} and \function{input()} +built-in functions. The \module{readline} module defines the following functions: Modified: stackless/trunk/Doc/lib/libshelve.tex ============================================================================== --- stackless/trunk/Doc/lib/libshelve.tex (original) +++ stackless/trunk/Doc/lib/libshelve.tex Mon Aug 14 12:38:35 2006 @@ -143,15 +143,17 @@ del d[key] # delete data stored at key (raises KeyError # if no such key) flag = d.has_key(key) # true if the key exists -list = d.keys() # a list of all existing keys (slow!) +klist = d.keys() # a list of all existing keys (slow!) # as d was opened WITHOUT writeback=True, beware: d['xx'] = range(4) # this works as expected, but... d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!!! + # having opened d without writeback=True, you need to code carefully: temp = d['xx'] # extracts the copy temp.append(5) # mutates the copy d['xx'] = temp # stores the copy right back, to persist it + # or, d=shelve.open(filename,writeback=True) would let you just code # d['xx'].append(5) and have it work as expected, BUT it would also # consume more memory and make the d.close() operation slower. Modified: stackless/trunk/Doc/lib/libsocket.tex ============================================================================== --- stackless/trunk/Doc/lib/libsocket.tex (original) +++ stackless/trunk/Doc/lib/libsocket.tex Mon Aug 14 12:38:35 2006 @@ -711,6 +711,17 @@ read until EOF. The return value is a string of the bytes read. \end{methoddesc} +\begin{methoddesc}{server}{} +Returns a string containing the ASN.1 distinguished name identifying the +server's certificate. (See below for an example +showing what distinguished names look like.) +\end{methoddesc} + +\begin{methoddesc}{issuer}{} +Returns a string containing the ASN.1 distinguished name identifying the +issuer of the server's certificate. +\end{methoddesc} + \subsection{Example \label{socket-example}} Here are four minimal example programs using the TCP/IP protocol:\ a @@ -833,3 +844,44 @@ s.close() print 'Received', repr(data) \end{verbatim} + +This example connects to an SSL server, prints the +server and issuer's distinguished names, sends some bytes, +and reads part of the response: + +\begin{verbatim} +import socket + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('www.verisign.com', 443)) + +ssl_sock = socket.ssl(s) + +print repr(ssl_sock.server()) +print repr(ssl_sock.issuer()) + +# Set a simple HTTP request -- use httplib in actual code. +ssl_sock.write("""GET / HTTP/1.0\r +Host: www.verisign.com\r\n\r\n""") + +# Read a chunk of data. Will not necessarily +# read all the data returned by the server. +data = ssl_sock.read() + +# Note that you need to close the underlying socket, not the SSL object. +del ssl_sock +s.close() +\end{verbatim} + +At this writing, this SSL example prints the following output (line +breaks inserted for readability): + +\begin{verbatim} +'/C=US/ST=California/L=Mountain View/ + O=VeriSign, Inc./OU=Production Services/ + OU=Terms of use at www.verisign.com/rpa (c)00/ + CN=www.verisign.com' +'/O=VeriSign Trust Network/OU=VeriSign, Inc./ + OU=VeriSign International Server CA - Class 3/ + OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign' +\end{verbatim} Modified: stackless/trunk/Doc/lib/libsocksvr.tex ============================================================================== --- stackless/trunk/Doc/lib/libsocksvr.tex (original) +++ stackless/trunk/Doc/lib/libsocksvr.tex Mon Aug 14 12:38:35 2006 @@ -74,9 +74,9 @@ \end{verbatim} Note that \class{UnixDatagramServer} derives from \class{UDPServer}, not -from \class{UnixStreamServer} -- the only difference between an IP and a -Unix stream server is the address family, which is simply repeated in both -unix server classes. +from \class{UnixStreamServer} --- the only difference between an IP and a +\UNIX{} stream server is the address family, which is simply repeated in both +\UNIX{} server classes. Forking and threading versions of each type of server can be created using the \class{ForkingMixIn} and \class{ThreadingMixIn} mix-in classes. For Modified: stackless/trunk/Doc/lib/libsqlite3.tex ============================================================================== --- stackless/trunk/Doc/lib/libsqlite3.tex (original) +++ stackless/trunk/Doc/lib/libsqlite3.tex Mon Aug 14 12:38:35 2006 @@ -512,10 +512,10 @@ \class{object} as one of its bases. \end{notice} -The \module{sqlite3} module has two default adapters for Python's builtin -\class{datetime.date} and \class{datetime.datetime} types. Now let's suppose we -want to store \class{datetime.datetime} objects not in ISO representation, but -as Unix timestamp. +The \module{sqlite3} module has two default adapters for Python's built-in +\class{datetime.date} and \class{datetime.datetime} types. Now let's suppose +we want to store \class{datetime.datetime} objects not in ISO representation, +but as a \UNIX{} timestamp. \verbatiminput{sqlite3/adapter_datetime.py} Modified: stackless/trunk/Doc/lib/libstdtypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libstdtypes.tex (original) +++ stackless/trunk/Doc/lib/libstdtypes.tex Mon Aug 14 12:38:35 2006 @@ -1,4 +1,4 @@ -\section{Built-in Types \label{types}} +\chapter{Built-in Types \label{types}} The following sections describe the standard types that are built into the interpreter. @@ -7,14 +7,14 @@ the built-in types as the basis for object-oriented inheritance. This limitation does not exist any longer.} -The principal built-in types are numerics, sequences, mappings, files +The principal built-in types are numerics, sequences, mappings, files, classes, instances and exceptions. \indexii{built-in}{types} Some operations are supported by several object types; in particular, practically all objects can be compared, tested for truth value, -and converted to a string (with the \code{`\textrm{\ldots}`} notation, -the equivalent \function{repr()} function, or the slightly different +and converted to a string (with +the \function{repr()} function or the slightly different \function{str()} function). The latter function is implicitly used when an object is written by the \keyword{print}\stindex{print} statement. @@ -24,7 +24,7 @@ \citetitle[../tut/tut.html]{Python Tutorial}.) -\subsection{Truth Value Testing\label{truth}} +\section{Truth Value Testing\label{truth}} Any object can be tested for truth value, for use in an \keyword{if} or \keyword{while} condition or as operand of the Boolean operations below. @@ -71,7 +71,7 @@ \index{False} \index{True} -\subsection{Boolean Operations --- +\section{Boolean Operations --- \keyword{and}, \keyword{or}, \keyword{not} \label{boolean}} @@ -107,7 +107,7 @@ \end{description} -\subsection{Comparisons \label{comparisons}} +\section{Comparisons \label{comparisons}} Comparison operations are supported by all objects. They all have the same priority (which is higher than that of the Boolean operations). @@ -174,7 +174,7 @@ only by sequence types (below). -\subsection{Numeric Types --- +\section{Numeric Types --- \class{int}, \class{float}, \class{long}, \class{complex} \label{typesnumeric}} @@ -307,7 +307,7 @@ \end{description} % XXXJH exceptions: overflow (when? what operations?) zerodivision -\subsubsection{Bit-string Operations on Integer Types \label{bitstring-ops}} +\subsection{Bit-string Operations on Integer Types \label{bitstring-ops}} \nodename{Bit-string Operations} Plain and long integer types support additional operations that make @@ -350,7 +350,7 @@ \end{description} -\subsection{Iterator Types \label{typeiter}} +\section{Iterator Types \label{typeiter}} \versionadded{2.2} \index{iterator protocol} @@ -414,7 +414,7 @@ supplying the \method{__iter__()} and \method{next()} methods. -\subsection{Sequence Types --- +\section{Sequence Types --- \class{str}, \class{unicode}, \class{list}, \class{tuple}, \class{buffer}, \class{xrange} \label{typesseq}} @@ -566,7 +566,7 @@ \end{description} -\subsubsection{String Methods \label{string-methods}} +\subsection{String Methods \label{string-methods}} \indexii{string}{methods} These are the string methods which both 8-bit strings and Unicode @@ -901,7 +901,7 @@ \end{methoddesc} -\subsubsection{String Formatting Operations \label{typesseq-strings}} +\subsection{String Formatting Operations \label{typesseq-strings}} \index{formatting, string (\%{})} \index{interpolation, string (\%{})} @@ -1072,7 +1072,7 @@ \refmodule{re}.\refstmodindex{re} -\subsubsection{XRange Type \label{typesseq-xrange}} +\subsection{XRange Type \label{typesseq-xrange}} The \class{xrange}\obindex{xrange} type is an immutable sequence which is commonly used for looping. The advantage of the \class{xrange} @@ -1084,7 +1084,7 @@ iteration, and the \function{len()} function. -\subsubsection{Mutable Sequence Types \label{typesseq-mutable}} +\subsection{Mutable Sequence Types \label{typesseq-mutable}} List objects support additional operations that allow in-place modification of the object. @@ -1216,7 +1216,7 @@ that the list has been mutated during a sort. \end{description} -\subsection{Set Types --- +\section{Set Types --- \class{set}, \class{frozenset} \label{types-set}} \obindex{set} @@ -1355,7 +1355,7 @@ \end{seealso} -\subsection{Mapping Types --- \class{dict} \label{typesmapping}} +\section{Mapping Types --- \class{dict} \label{typesmapping}} \obindex{mapping} \obindex{dictionary} @@ -1518,7 +1518,7 @@ \end{description} -\subsection{File Objects +\section{File Objects \label{bltin-file-objects}} File objects\obindex{file} are implemented using C's \code{stdio} @@ -1797,7 +1797,7 @@ \end{memberdesc} -\subsection{Context Manager Types \label{typecontextmanager}} +\section{Context Manager Types \label{typecontextmanager}} \versionadded{2.5} \index{context manager} @@ -1878,13 +1878,13 @@ is negligible. -\subsection{Other Built-in Types \label{typesother}} +\section{Other Built-in Types \label{typesother}} The interpreter supports several other kinds of objects. Most of these support only one or two operations. -\subsubsection{Modules \label{typesmodules}} +\subsection{Modules \label{typesmodules}} The only special operation on a module is attribute access: \code{\var{m}.\var{name}}, where \var{m} is a module and \var{name} @@ -1910,14 +1910,14 @@ '/usr/local/lib/python\shortversion/os.pyc'>}. -\subsubsection{Classes and Class Instances \label{typesobjects}} +\subsection{Classes and Class Instances \label{typesobjects}} \nodename{Classes and Instances} See chapters 3 and 7 of the \citetitle[../ref/ref.html]{Python Reference Manual} for these. -\subsubsection{Functions \label{typesfunctions}} +\subsection{Functions \label{typesfunctions}} Function objects are created by function definitions. The only operation on a function object is to call it: @@ -1931,7 +1931,7 @@ See the \citetitle[../ref/ref.html]{Python Reference Manual} for more information. -\subsubsection{Methods \label{typesmethods}} +\subsection{Methods \label{typesmethods}} \obindex{method} Methods are functions that are called using the attribute notation. @@ -1976,7 +1976,7 @@ information. -\subsubsection{Code Objects \label{bltin-code-objects}} +\subsection{Code Objects \label{bltin-code-objects}} \obindex{code} Code objects are used by the implementation to represent @@ -1999,7 +1999,7 @@ information. -\subsubsection{Type Objects \label{bltin-type-objects}} +\subsection{Type Objects \label{bltin-type-objects}} Type objects represent the various object types. An object's type is accessed by the built-in function \function{type()}. There are no special @@ -2011,7 +2011,7 @@ Types are written like this: \code{}. -\subsubsection{The Null Object \label{bltin-null-object}} +\subsection{The Null Object \label{bltin-null-object}} This object is returned by functions that don't explicitly return a value. It supports no special operations. There is exactly one null @@ -2020,7 +2020,7 @@ It is written as \code{None}. -\subsubsection{The Ellipsis Object \label{bltin-ellipsis-object}} +\subsection{The Ellipsis Object \label{bltin-ellipsis-object}} This object is used by extended slice notation (see the \citetitle[../ref/ref.html]{Python Reference Manual}). It supports no @@ -2029,7 +2029,7 @@ It is written as \code{Ellipsis}. -\subsubsection{Boolean Values} +\subsection{Boolean Values} Boolean values are the two constant objects \code{False} and \code{True}. They are used to represent truth values (although other @@ -2046,14 +2046,14 @@ \indexii{Boolean}{values} -\subsubsection{Internal Objects \label{typesinternal}} +\subsection{Internal Objects \label{typesinternal}} See the \citetitle[../ref/ref.html]{Python Reference Manual} for this information. It describes stack frame objects, traceback objects, and slice objects. -\subsection{Special Attributes \label{specialattrs}} +\section{Special Attributes \label{specialattrs}} The implementation adds a few special read-only attributes to several object types, where they are relevant. Some of these are not reported Modified: stackless/trunk/Doc/lib/libstringio.tex ============================================================================== --- stackless/trunk/Doc/lib/libstringio.tex (original) +++ stackless/trunk/Doc/lib/libstringio.tex Mon Aug 14 12:38:35 2006 @@ -37,6 +37,24 @@ Free the memory buffer. \end{methoddesc} +Example usage: + +\begin{verbatim} +import StringIO + +output = StringIO.StringIO() +output.write('First line.\n') +print >>output, 'Second line.' + +# Retrieve file contents -- this will be +# 'First line.\nSecond line.\n' +contents = output.getvalue() + +# Close object and discard memory buffer -- +# .getvalue() will now raise an exception. +output.close() +\end{verbatim} + \section{\module{cStringIO} --- Faster version of \module{StringIO}} @@ -82,3 +100,22 @@ There is a C API to the module as well; refer to the module source for more information. + +Example usage: + +\begin{verbatim} +import cStringIO + +output = cStringIO.StringIO() +output.write('First line.\n') +print >>output, 'Second line.' + +# Retrieve file contents -- this will be +# 'First line.\nSecond line.\n' +contents = output.getvalue() + +# Close object and discard memory buffer -- +# .getvalue() will now raise an exception. +output.close() +\end{verbatim} + Modified: stackless/trunk/Doc/lib/libsubprocess.tex ============================================================================== --- stackless/trunk/Doc/lib/libsubprocess.tex (original) +++ stackless/trunk/Doc/lib/libsubprocess.tex Mon Aug 14 12:38:35 2006 @@ -107,7 +107,7 @@ If \var{universal_newlines} is \constant{True}, the file objects stdout and stderr are opened as text files, but lines may be terminated by -any of \code{'\e n'}, the Unix end-of-line convention, \code{'\e r'}, +any of \code{'\e n'}, the \UNIX{} end-of-line convention, \code{'\e r'}, the Macintosh convention or \code{'\e r\e n'}, the Windows convention. All of these external representations are seen as \code{'\e n'} by the Python program. \note{This feature is only available if Python is built @@ -140,7 +140,7 @@ Run command with arguments. Wait for command to complete. If the exit code was zero then return, otherwise raise \exception{CalledProcessError.} The \exception{CalledProcessError} object will have the return code in the -\member{errno} attribute. +\member{returncode} attribute. The arguments are the same as for the Popen constructor. Example: @@ -164,9 +164,8 @@ A \exception{ValueError} will be raised if \class{Popen} is called with invalid arguments. -check_call() will raise \exception{CalledProcessError}, which is a -subclass of \exception{OSError}, if the called process returns a -non-zero return code. +check_call() will raise \exception{CalledProcessError}, if the called +process returns a non-zero return code. \subsubsection{Security} Modified: stackless/trunk/Doc/lib/libsys.tex ============================================================================== --- stackless/trunk/Doc/lib/libsys.tex (original) +++ stackless/trunk/Doc/lib/libsys.tex Mon Aug 14 12:38:35 2006 @@ -21,7 +21,7 @@ \begin{datadesc}{byteorder} An indicator of the native byte order. This will have the value - \code{'big'} on big-endian (most-signigicant byte first) platforms, + \code{'big'} on big-endian (most-significant byte first) platforms, and \code{'little'} on little-endian (least-significant byte first) platforms. \versionadded{2.0} @@ -258,14 +258,14 @@ \begin{itemize} \item On Windows 9x, the encoding is ``mbcs''. \item On Mac OS X, the encoding is ``utf-8''. -\item On Unix, the encoding is the user's preference - according to the result of nl_langinfo(CODESET), or None if - the nl_langinfo(CODESET) failed. +\item On \UNIX, the encoding is the user's preference + according to the result of nl_langinfo(CODESET), or \constant{None} + if the \code{nl_langinfo(CODESET)} failed. \item On Windows NT+, file names are Unicode natively, so no conversion - is performed. \code{getfilesystemencoding} still returns ``mbcs'', - as this is the encoding that applications should use when they - explicitly want to convert Unicode strings to byte strings that - are equivalent when used as file names. + is performed. \function{getfilesystemencoding()} still returns + \code{'mbcs'}, as this is the encoding that applications should use + when they explicitly want to convert Unicode strings to byte strings + that are equivalent when used as file names. \end{itemize} \versionadded{2.3} \end{funcdesc} Modified: stackless/trunk/Doc/lib/libtime.tex ============================================================================== --- stackless/trunk/Doc/lib/libtime.tex (original) +++ stackless/trunk/Doc/lib/libtime.tex Mon Aug 14 12:38:35 2006 @@ -226,6 +226,8 @@ \versionchanged[Allowed \var{t} to be omitted]{2.1} \versionchanged[\exception{ValueError} raised if a field in \var{t} is out of range]{2.4} +\versionchanged[0 is now a legal argument for any position in the time tuple; +if it is normally illegal the value is forced to a correct one.]{2.5} The following directives can be embedded in the \var{format} string. @@ -425,7 +427,7 @@ '16:08:12 05/08/03 AEST' \end{verbatim} -On many Unix systems (including *BSD, Linux, Solaris, and Darwin), it +On many \UNIX{} systems (including *BSD, Linux, Solaris, and Darwin), it is more convenient to use the system's zoneinfo (\manpage{tzfile}{5}) database to specify the timezone rules. To do this, set the \envvar{TZ} environment variable to the path of the required timezone Modified: stackless/trunk/Doc/lib/libturtle.tex ============================================================================== --- stackless/trunk/Doc/lib/libturtle.tex (original) +++ stackless/trunk/Doc/lib/libturtle.tex Mon Aug 14 12:38:35 2006 @@ -27,6 +27,45 @@ Set angle measurement units to radians. \end{funcdesc} +\begin{funcdesc}{setup}{**kwargs} +Sets the size and position of the main window. Keywords are: +\begin{itemize} + \item \code{width}: either a size in pixels or a fraction of the screen. + The default is 50\% of the screen. + \item \code{height}: either a size in pixels or a fraction of the screen. + The default is 50\% of the screen. + \item \code{startx}: starting position in pixels from the left edge + of the screen. \code{None} is the default value and + centers the window horizontally on screen. + \item \code{starty}: starting position in pixels from the top edge + of the screen. \code{None} is the default value and + centers the window vertically on screen. +\end{itemize} + + Examples: + +\begin{verbatim} +# Uses default geometry: 50% x 50% of screen, centered. +setup() + +# Sets window to 200x200 pixels, in upper left of screen +setup (width=200, height=200, startx=0, starty=0) + +# Sets window to 75% of screen by 50% of screen, and centers it. +setup(width=.75, height=0.5, startx=None, starty=None) +\end{verbatim} + +\end{funcdesc} + +\begin{funcdesc}{title}{title_str} +Set the window's title to \var{title}. +\end{funcdesc} + +\begin{funcdesc}{done}{} +Enters the Tk main loop. The window will continue to +be displayed until the user closes it or the process is killed. +\end{funcdesc} + \begin{funcdesc}{reset}{} Clear the screen, re-center the pen, and set variables to the default values. Modified: stackless/trunk/Doc/lib/libtypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libtypes.tex (original) +++ stackless/trunk/Doc/lib/libtypes.tex Mon Aug 14 12:38:35 2006 @@ -180,6 +180,30 @@ \function{buffer()}\bifuncindex{buffer} function. \end{datadesc} +\begin{datadesc}{DictProxyType} +The type of dict proxies, such as \code{TypeType.__dict__}. +\end{datadesc} + +\begin{datadesc}{NotImplementedType} +The type of \code{NotImplemented} +\end{datadesc} + +\begin{datadesc}{GetSetDescriptorType} +The type of objects defined in extension modules with \code{PyGetSetDef}, such +as \code{FrameType.f_locals} or \code{array.array.typecode}. This constant is +not defined in implementations of Python that do not have such extension +types, so for portable code use \code{hasattr(types, 'GetSetDescriptorType')}. +\versionadded{2.5} +\end{datadesc} + +\begin{datadesc}{MemberDescriptorType} +The type of objects defined in extension modules with \code{PyMemberDef}, such +as \code {datetime.timedelta.days}. This constant is not defined in +implementations of Python that do not have such extension types, so for +portable code use \code{hasattr(types, 'MemberDescriptorType')}. +\versionadded{2.5} +\end{datadesc} + \begin{datadesc}{StringTypes} A sequence containing \code{StringType} and \code{UnicodeType} used to facilitate easier checking for any string object. Using this is more Modified: stackless/trunk/Doc/lib/libundoc.tex ============================================================================== --- stackless/trunk/Doc/lib/libundoc.tex (original) +++ stackless/trunk/Doc/lib/libundoc.tex Mon Aug 14 12:38:35 2006 @@ -49,7 +49,7 @@ \item[\module{bsddb185}] --- Backwards compatibility module for systems which still use the Berkeley - DB 1.85 module. It is normally only available on certain BSD Unix-based + DB 1.85 module. It is normally only available on certain BSD \UNIX-based systems. It should never be used directly. \end{description} Modified: stackless/trunk/Doc/lib/libunicodedata.tex ============================================================================== --- stackless/trunk/Doc/lib/libunicodedata.tex (original) +++ stackless/trunk/Doc/lib/libunicodedata.tex Mon Aug 14 12:38:35 2006 @@ -14,11 +14,11 @@ This module provides access to the Unicode Character Database which defines character properties for all Unicode characters. The data in this database is based on the \file{UnicodeData.txt} file version -4.1.0 which is publically available from \url{ftp://ftp.unicode.org/}. +4.1.0 which is publicly available from \url{ftp://ftp.unicode.org/}. The module uses the same names and symbols as defined by the UnicodeData File Format 4.1.0 (see -\url{http://www.unicode.org/Public/4.1-Update/UnicodeData-4.1.0.html}). It +\url{http://www.unicode.org/Public/4.1.0/ucd/UCD.html}). It defines the following functions: \begin{funcdesc}{lookup}{name} @@ -108,7 +108,7 @@ Normal form C (NFC) first applies a canonical decomposition, then composes pre-combined characters again. -In addition to these two forms, there two additional normal forms +In addition to these two forms, there are two additional normal forms based on compatibility equivalence. In Unicode, certain characters are supported which normally would be unified with other characters. For example, U+2160 (ROMAN NUMERAL ONE) is really the same thing as U+0049 @@ -139,3 +139,22 @@ \versionadded{2.5} \end{datadesc} + +Examples: + +\begin{verbatim} +>>> unicodedata.lookup('LEFT CURLY BRACKET') +u'{' +>>> unicodedata.name(u'/') +'SOLIDUS' +>>> unicodedata.decimal(u'9') +9 +>>> unicodedata.decimal(u'a') +Traceback (most recent call last): + File "", line 1, in ? +ValueError: not a decimal +>>> unicodedata.category(u'A') # 'L'etter, 'u'ppercase +'Lu' +>>> unicodedata.bidirectional(u'\u0660') # 'A'rabic, 'N'umber +'AN' +\end{verbatim} Modified: stackless/trunk/Doc/lib/liburllib.tex ============================================================================== --- stackless/trunk/Doc/lib/liburllib.tex (original) +++ stackless/trunk/Doc/lib/liburllib.tex Mon Aug 14 12:38:35 2006 @@ -270,10 +270,10 @@ environmental proxy settings will be used if present, as discussed in the definition of \function{urlopen()}, above. -Additional keyword parameters, collected in \var{x509}, are used for -authentication with the \file{https:} scheme. The keywords -\var{key_file} and \var{cert_file} are supported; both are needed to -actually retrieve a resource at an \file{https:} URL. +Additional keyword parameters, collected in \var{x509}, may be used for +authentication of the client when using the \file{https:} scheme. The keywords +\var{key_file} and \var{cert_file} are supported to provide an +SSL key and certificate; both are needed to support client authentication. \class{URLopener} objects will raise an \exception{IOError} exception if the server returns an error code. Modified: stackless/trunk/Doc/lib/liburllib2.tex ============================================================================== --- stackless/trunk/Doc/lib/liburllib2.tex (original) +++ stackless/trunk/Doc/lib/liburllib2.tex Mon Aug 14 12:38:35 2006 @@ -19,7 +19,8 @@ object. \var{data} may be a string specifying additional data to send to the -server. Currently HTTP requests are the only ones that use \var{data}; +server, or \code{None} if no such data is needed. +Currently HTTP requests are the only ones that use \var{data}; the HTTP request will be a POST instead of a GET when the \var{data} parameter is provided. \var{data} should be a buffer in the standard \mimetype{application/x-www-form-urlencoded} format. The @@ -97,8 +98,17 @@ \optional{, origin_req_host}\optional{, unverifiable}} This class is an abstraction of a URL request. -\var{url} should be a string which is a valid URL. For a description -of \var{data} see the \method{add_data()} description. +\var{url} should be a string containing a valid URL. + +\var{data} may be a string specifying additional data to send to the +server, or \code{None} if no such data is needed. +Currently HTTP requests are the only ones that use \var{data}; +the HTTP request will be a POST instead of a GET when the \var{data} +parameter is provided. \var{data} should be a buffer in the standard +\mimetype{application/x-www-form-urlencoded} format. The +\function{urllib.urlencode()} function takes a mapping or sequence of +2-tuples and returns a string in this format. + \var{headers} should be a dictionary, and will be treated as if \method{add_header()} was called with each key and value as arguments. Modified: stackless/trunk/Doc/lib/libuuid.tex ============================================================================== --- stackless/trunk/Doc/lib/libuuid.tex (original) +++ stackless/trunk/Doc/lib/libuuid.tex Mon Aug 14 12:38:35 2006 @@ -32,7 +32,7 @@ Create a UUID from either a string of 32 hexadecimal digits, a string of 16 bytes as the \var{bytes} argument, a tuple of six -integers (32-bit \var{time_low}, 16-bit \var{time_mid}, +integers (32-bit \var{time_low}, 16-bit \var{time_mid}, 16-bit \var{time_hi_version}, 8-bit \var{clock_seq_hi_variant}, 8-bit \var{clock_seq_low}, 48-bit \var{node}) as the \var{fields} argument, or a single 128-bit integer as the \var{int} @@ -109,10 +109,13 @@ The \module{uuid} module defines the following functions \begin{funcdesc}{getnode}{} -Get the hardware address as a 48-bit integer. The first time this runs, -it may launch a separate program, which could be quite slow. If all +Get the hardware address as a 48-bit positive integer. The first time this +runs, it may launch a separate program, which could be quite slow. If all attempts to obtain the hardware address fail, we choose a random 48-bit -number with its eighth bit set to 1 as recommended in RFC 4122. +number with its eighth bit set to 1 as recommended in RFC 4122. "Hardware +address" means the MAC address of a network interface, and on a machine +with multiple network interfaces the MAC address of any one of them may +be returned. \end{funcdesc} \index{getnode} @@ -126,10 +129,10 @@ \index{uuid1} \begin{funcdesc}{uuid3}{namespace, name} -Generate a UUID based upon a MD5 hash of the \var{name} string value -drawn from a specified namespace. \var{namespace} +Generate a UUID based upon a MD5 hash of the \var{name} string value +drawn from a specified namespace. \var{namespace} must be one of \constant{NAMESPACE_DNS}, -\constant{NAMESPACE_URL}, \constant{NAMESPACE_OID}, +\constant{NAMESPACE_URL}, \constant{NAMESPACE_OID}, or \constant{NAMESPACE_X500}. \end{funcdesc} \index{uuid3} @@ -140,15 +143,15 @@ \index{uuid4} \begin{funcdesc}{uuid5}{namespace, name} -Generate a UUID based upon a SHA-1 hash of the \var{name} string value -drawn from a specified namespace. \var{namespace} +Generate a UUID based upon a SHA-1 hash of the \var{name} string value +drawn from a specified namespace. \var{namespace} must be one of \constant{NAMESPACE_DNS}, -\constant{NAMESPACE_URL}, \constant{NAMESPACE_OID}, +\constant{NAMESPACE_URL}, \constant{NAMESPACE_OID}, or \constant{NAMESPACE_X500}. \end{funcdesc} \index{uuid5} -The \module{uuid} module defines the following namespace constants +The \module{uuid} module defines the following namespace constants for use with \function{uuid3()} or \function{uuid5()}. \begin{datadesc}{NAMESPACE_DNS} @@ -167,7 +170,7 @@ X.500 DN namespace UUID. \end{datadesc} -The \module{uuid} module defines the following constants +The \module{uuid} module defines the following constants for the possible values of the \member{variant} attribute: \begin{datadesc}{RESERVED_NCS} Modified: stackless/trunk/Doc/lib/libweakref.tex ============================================================================== --- stackless/trunk/Doc/lib/libweakref.tex (original) +++ stackless/trunk/Doc/lib/libweakref.tex Mon Aug 14 12:38:35 2006 @@ -65,10 +65,14 @@ obj = Dict(red=1, green=2, blue=3) # this object is weak referencable \end{verbatim} -Extension types can easily be made to support weak references; see section -\ref{weakref-extension}, ``Weak References in Extension Types,'' for more -information. - +Extension types can easily be made to support weak references; see +``\ulink{Weak Reference Support}{../ext/weakref-support.html}'' in +\citetitle[../ext/ext.html]{Extending and Embedding the Python +Interpreter}. +% The referenced section used to appear in this document with the +% \label weakref-extension. It would be good to be able to generate a +% redirect for the corresponding HTML page (weakref-extension.html) +% for on-line versions of this document. \begin{classdesc}{ref}{object\optional{, callback}} Return a weak reference to \var{object}. The original object can be @@ -330,83 +334,3 @@ def id2obj(oid): return _id2obj_dict[oid] \end{verbatim} - - -\subsection{Weak References in Extension Types - \label{weakref-extension}} - -One of the goals of the implementation is to allow any type to -participate in the weak reference mechanism without incurring the -overhead on those objects which do not benefit by weak referencing -(such as numbers). - -For an object to be weakly referencable, the extension must include a -\ctype{PyObject*} field in the instance structure for the use of the -weak reference mechanism; it must be initialized to \NULL{} by the -object's constructor. It must also set the \member{tp_weaklistoffset} -field of the corresponding type object to the offset of the field. -Also, it needs to add \constant{Py_TPFLAGS_HAVE_WEAKREFS} to the -tp_flags slot. For example, the instance type is defined with the -following structure: - -\begin{verbatim} -typedef struct { - PyObject_HEAD - PyClassObject *in_class; /* The class object */ - PyObject *in_dict; /* A dictionary */ - PyObject *in_weakreflist; /* List of weak references */ -} PyInstanceObject; -\end{verbatim} - -The statically-declared type object for instances is defined this way: - -\begin{verbatim} -PyTypeObject PyInstance_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "module.instance", - - /* Lots of stuff omitted for brevity... */ - - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */ -}; -\end{verbatim} - -The type constructor is responsible for initializing the weak reference -list to \NULL: - -\begin{verbatim} -static PyObject * -instance_new() { - /* Other initialization stuff omitted for brevity */ - - self->in_weakreflist = NULL; - - return (PyObject *) self; -} -\end{verbatim} - -The only further addition is that the destructor needs to call the -weak reference manager to clear any weak references. This should be -done before any other parts of the destruction have occurred, but is -only required if the weak reference list is non-\NULL: - -\begin{verbatim} -static void -instance_dealloc(PyInstanceObject *inst) -{ - /* Allocate temporaries if needed, but do not begin - destruction just yet. - */ - - if (inst->in_weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) inst); - - /* Proceed with object destruction normally. */ -} -\end{verbatim} Modified: stackless/trunk/Doc/lib/libwebbrowser.tex ============================================================================== --- stackless/trunk/Doc/lib/libwebbrowser.tex (original) +++ stackless/trunk/Doc/lib/libwebbrowser.tex Mon Aug 14 12:38:35 2006 @@ -136,6 +136,18 @@ Only on MacOS X platform. \end{description} +Here are some simple examples: + +\begin{verbatim} +url = 'http://www.python.org' + +# Open URL in a new tab, if a browser window is already open. +webbrowser.open_new_tab(url + '/doc') + +# Open URL in new window, raising the window if possible. +webbrowser.open_new(url) +\end{verbatim} + \subsection{Browser Controller Objects \label{browser-controllers}} Modified: stackless/trunk/Doc/lib/libzipfile.tex ============================================================================== --- stackless/trunk/Doc/lib/libzipfile.tex (original) +++ stackless/trunk/Doc/lib/libzipfile.tex Mon Aug 14 12:38:35 2006 @@ -106,12 +106,12 @@ is specified but the \refmodule{zlib} module is not available, \exception{RuntimeError} is also raised. The default is \constant{ZIP_STORED}. - If \var{allowZip64} is \code{True} zipfile will create zipfiles that use - the ZIP64 extensions when the zipfile is larger than 2GBytes. If it is - false (the default) zipfile will raise an exception when the zipfile would - require ZIP64 extensions. ZIP64 extensions are disabled by default because - the default zip and unzip commands on Unix (the InfoZIP utilities) don't - support these extensions. + If \var{allowZip64} is \code{True} zipfile will create ZIP files that use + the ZIP64 extensions when the zipfile is larger than 2 GB. If it is + false (the default) \module{zipfile} will raise an exception when the + ZIP file would require ZIP64 extensions. ZIP64 extensions are disabled by + default because the default \program{zip} and \program{unzip} commands on + \UNIX{} (the InfoZIP utilities) don't support these extensions. \end{classdesc} \begin{methoddesc}{close}{} Modified: stackless/trunk/Doc/lib/sqlite3/complete_statement.py ============================================================================== --- stackless/trunk/Doc/lib/sqlite3/complete_statement.py (original) +++ stackless/trunk/Doc/lib/sqlite3/complete_statement.py Mon Aug 14 12:38:35 2006 @@ -24,7 +24,7 @@ if buffer.lstrip().upper().startswith("SELECT"): print cur.fetchall() except sqlite3.Error, e: - print "An error occured:", e.args[0] + print "An error occurred:", e.args[0] buffer = "" con.close() Modified: stackless/trunk/Doc/lib/tkinter.tex ============================================================================== --- stackless/trunk/Doc/lib/tkinter.tex (original) +++ stackless/trunk/Doc/lib/tkinter.tex Mon Aug 14 12:38:35 2006 @@ -18,10 +18,9 @@ module \module{\_tkinter} provides a threadsafe mechanism which allows Python and Tcl to interact. -Tk is not the only GUI for Python, but is however the most commonly -used one; see section~\ref{other-gui-modules}, ``Other User Interface -Modules and Packages,'' for more information on other GUI toolkits for -Python. +Tk is not the only GUI for Python; see +section~\ref{other-gui-packages}, ``Other User Interface Modules and +Packages,'' for more information on other GUI toolkits for Python. % Other sections I have in mind are % Tkinter internals @@ -103,14 +102,14 @@ \end{classdesc} \begin{funcdesc}{Tcl}{screenName=None, baseName=None, className='Tk', useTk=0} -The \function{Tcl} function is a factory function which creates an object -much like that created by the \class{Tk} class, except that it does not -initialize the Tk subsystem. This is most often useful when driving the Tcl -interpreter in an environment where one doesn't want to create extraneous -toplevel windows, or where one cannot (i.e. Unix/Linux systems without an X -server). An object created by the \function{Tcl} object can have a Toplevel -window created (and the Tk subsystem initialized) by calling its -\method{loadtk} method. +The \function{Tcl} function is a factory function which creates an +object much like that created by the \class{Tk} class, except that it +does not initialize the Tk subsystem. This is most often useful when +driving the Tcl interpreter in an environment where one doesn't want +to create extraneous toplevel windows, or where one cannot (such as +\UNIX/Linux systems without an X server). An object created by the +\function{Tcl} object can have a Toplevel window created (and the Tk +subsystem initialized) by calling its \method{loadtk} method. \versionadded{2.4} \end{funcdesc} @@ -316,10 +315,10 @@ periods. For example, \code{.myApp.controlPanel.okButton} might be the name of a widget. -\item[\var{options} ] +\item[\var{options}] configure the widget's appearance and in some cases, its behavior. The options come in the form of a list of flags and values. -Flags are proceeded by a `-', like unix shell command flags, and +Flags are proceeded by a `-', like \UNIX{} shell command flags, and values are put in quotes if they are more than one word. \end{description} @@ -1806,24 +1805,29 @@ through the Tk/Tcl layer.} \end{seealso*} - -Tk is not the only GUI for Python, but is however the -most commonly used one. +Other GUI packages are also available for Python: \begin{seealso*} -\seetitle[http://www.wxwindows.org]{wxWindows}{ -is a GUI toolkit that combines the most attractive attributes of Qt, -Tk, Motif, and GTK+ in one powerful and efficient package. It is -implemented in \Cpp. wxWindows supports two flavors of \UNIX{} -implementation: GTK+ and Motif, and under Windows, it has a standard -Microsoft Foundation Classes (MFC) appearance, because it uses Win32 -widgets. There is a Python class wrapper, independent of Tkinter. - -wxWindows is much richer in widgets than \refmodule{Tkinter}, with its -help system, sophisticated HTML and image viewers, and other -specialized widgets, extensive documentation, and printing capabilities. +\seetitle[http://www.wxpython.org]{wxPython}{ +wxPython is a cross-platform GUI toolkit for Python that is built +around the popular \ulink{wxWidgets}{http://www.wxwidgets.org/} \Cpp{} +toolkit. ?It provides a native look and feel for applications on +Windows, Mac OS X, and \UNIX{} systems by using each platform's native +widgets where ever possible, (GTK+ on \UNIX-like systems). ?In +addition to an extensive set of widgets, wxPython provides classes for +online documentation and context sensitive help, printing, HTML +viewing, low-level device context drawing, drag and drop, system +clipboard access, an XML-based resource format and more, including an +ever growing library of user-contributed modules. ?Both the wxWidgets +and wxPython projects are under active development and continuous +improvement, and have active and helpful user and developer +communities. +} +\seetitle[http://www.amazon.com/exec/obidos/ASIN/1932394621] +{wxPython in Action}{ +The wxPython book, by Noel Rappin and Robin Dunn. } -\seetitle[]{PyQt}{ +\seetitle{PyQt}{ PyQt is a \program{sip}-wrapped binding to the Qt toolkit. Qt is an extensive \Cpp{} GUI toolkit that is available for \UNIX, Windows and Mac OS X. \program{sip} is a tool for generating bindings for \Cpp{} Modified: stackless/trunk/Doc/mac/libmacfs.tex ============================================================================== --- stackless/trunk/Doc/mac/libmacfs.tex (original) +++ stackless/trunk/Doc/mac/libmacfs.tex Mon Aug 14 12:38:35 2006 @@ -22,10 +22,10 @@ argument can be one of three things:\ (1) a full or partial Macintosh pathname, (2) an \class{FSSpec} object or (3) a 3-tuple \code{(\var{wdRefNum}, \var{parID}, \var{name})} as described in -\citetitle{Inside Macintosh:\ Files}. An \class{FSSpec} can point to +\citetitle{Inside Macintosh:\ Files}. An \class{FSSpec} can point to a non-existing file, as long as the folder containing the file exists. -Under MacPython the same is true for a pathname, but not under unix-Pyton -because of the way pathnames and FSRefs works. See Apple's documentation +Under MacPython the same is true for a pathname, but not under \UNIX-Python +because of the way pathnames and FSRefs works. See Apple's documentation for details. A description of aliases and the Modified: stackless/trunk/Doc/mac/libmacos.tex ============================================================================== --- stackless/trunk/Doc/mac/libmacos.tex (original) +++ stackless/trunk/Doc/mac/libmacos.tex Mon Aug 14 12:38:35 2006 @@ -25,7 +25,7 @@ incompatible between linking models, packages could use this information to give more decent error messages. The value is one of \code{'static'} for a statically linked Python, \code{'framework'} for Python in a Mac OS X framework, -\code{'shared'} for Python in a standard unix shared library. +\code{'shared'} for Python in a standard \UNIX{} shared library. Older Pythons could also have the value \code{'cfm'} for Mac OS 9-compatible Python. \end{datadesc} Modified: stackless/trunk/Doc/mac/using.tex ============================================================================== --- stackless/trunk/Doc/mac/using.tex (original) +++ stackless/trunk/Doc/mac/using.tex Mon Aug 14 12:38:35 2006 @@ -6,7 +6,7 @@ features such as the IDE and the Package Manager that are worth pointing out. Python on Mac OS 9 or earlier can be quite different from Python on -Unix or Windows, but is beyond the scope of this manual, as that platform +\UNIX{} or Windows, but is beyond the scope of this manual, as that platform is no longer supported, starting with Python 2.4. See \url{http://www.cwi.nl/\textasciitilde jack/macpython} for installers for the latest 2.3 release for Mac OS 9 and related documentation. Modified: stackless/trunk/Doc/ref/ref3.tex ============================================================================== --- stackless/trunk/Doc/ref/ref3.tex (original) +++ stackless/trunk/Doc/ref/ref3.tex Mon Aug 14 12:38:35 2006 @@ -1886,6 +1886,9 @@ \method{__pow__()} should be defined to accept an optional third argument if the ternary version of the built-in \function{pow()}\bifuncindex{pow} function is to be supported. + +If one of those methods does not support the operation with the +supplied arguments, it should return \code{NotImplemented}. \end{methoddesc} \begin{methoddesc}[numeric object]{__div__}{self, other} @@ -1937,7 +1940,7 @@ \note{If the right operand's type is a subclass of the left operand's type and that subclass provides the reflected method for the - operation, this method will be called before the right operand's + operation, this method will be called before the left operand's non-reflected method. This behavior allows subclasses to override their ancestors' operations.} \end{methoddesc} Modified: stackless/trunk/Doc/whatsnew/whatsnew20.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew20.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew20.tex Mon Aug 14 12:38:35 2006 @@ -216,7 +216,7 @@ character properties. For example, \code{unicodedata.category(u'A')} returns the 2-character string 'Lu', the 'L' denoting it's a letter, and 'u' meaning that it's uppercase. -\code{u.bidirectional(u'\e x0660')} returns 'AN', meaning that U+0660 is +\code{unicodedata.bidirectional(u'\e u0660')} returns 'AN', meaning that U+0660 is an Arabic number. The \module{codecs} module contains functions to look up existing encodings @@ -571,7 +571,7 @@ The \keyword{print} statement can now have its output directed to a file-like object by following the \keyword{print} with -\verb|>> file|, similar to the redirection operator in Unix shells. +\verb|>> file|, similar to the redirection operator in \UNIX{} shells. Previously you'd either have to use the \method{write()} method of the file-like object, which lacks the convenience and simplicity of \keyword{print}, or you could assign a new value to @@ -894,7 +894,7 @@ name. This third argument is, respectively, a Python object, a C long, or a C string. -A wrapper API was added for Unix-style signal handlers. +A wrapper API was added for \UNIX-style signal handlers. \function{PyOS_getsig()} gets a signal handler and \function{PyOS_setsig()} will set a new handler. @@ -905,7 +905,7 @@ was no way to figure out automatically where Python is installed, or what compiler options to use for extension modules. Software authors had to go through an arduous ritual of editing Makefiles and -configuration files, which only really work on Unix and leave Windows +configuration files, which only really work on \UNIX{} and leave Windows and MacOS unsupported. Python users faced wildly differing installation instructions which varied between different extension packages, which made administering a Python installation something of @@ -1222,7 +1222,7 @@ (Contributed by Peter Bosch, with fixes by Jeremy Hylton.) \item{\module{mmap}:} An interface to memory-mapped files on both -Windows and Unix. A file's contents can be mapped directly into +Windows and \UNIX. A file's contents can be mapped directly into memory, at which point it behaves like a mutable string, so its contents can be read and modified. They can even be passed to functions that expect ordinary strings, such as the \module{re} @@ -1262,7 +1262,7 @@ \item{\module{zipfile}:} A module for reading and writing ZIP-format archives. These are archives produced by \program{PKZIP} on -DOS/Windows or \program{zip} on Unix, not to be confused with +DOS/Windows or \program{zip} on \UNIX, not to be confused with \program{gzip}-format files (which are supported by the \module{gzip} module) (Contributed by James C. Ahlstrom.) Modified: stackless/trunk/Doc/whatsnew/whatsnew21.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew21.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew21.tex Mon Aug 14 12:38:35 2006 @@ -325,7 +325,7 @@ When compiling Python, the user had to go in and edit the \file{Modules/Setup} file in order to enable various additional modules; the default set is relatively small and limited to modules -that compile on most Unix platforms. This means that on Unix +that compile on most \UNIX{} platforms. This means that on \Unix{} platforms with many more features, most notably Linux, Python installations often don't contain all useful modules they could. @@ -661,7 +661,7 @@ \item The \module{difflib} module contains a class, \class{SequenceMatcher}, which compares two sequences and computes the changes required to transform one sequence into the other. For -example, this module can be used to write a tool similar to the Unix +example, this module can be used to write a tool similar to the \UNIX{} \program{diff} program, and in fact the sample program \file{Tools/scripts/ndiff.py} demonstrates how to write such a script. Modified: stackless/trunk/Doc/whatsnew/whatsnew23.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew23.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew23.tex Mon Aug 14 12:38:35 2006 @@ -1979,7 +1979,7 @@ The \module{getopt} module provides simple parsing of command-line arguments. The new \module{optparse} module (originally named Optik) -provides more elaborate command-line parsing that follows the Unix +provides more elaborate command-line parsing that follows the \UNIX{} conventions, automatically creates the output for \longprogramopt{help}, and can perform different actions for different options. Modified: stackless/trunk/Doc/whatsnew/whatsnew24.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew24.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew24.tex Mon Aug 14 12:38:35 2006 @@ -162,7 +162,7 @@ Generator expressions always have to be written inside parentheses, as in the above example. The parentheses signalling a function call also -count, so if you want to create a iterator that will be immediately +count, so if you want to create an iterator that will be immediately passed to a function you could write: \begin{verbatim} Modified: stackless/trunk/Doc/whatsnew/whatsnew25.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew25.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew25.tex Mon Aug 14 12:38:35 2006 @@ -6,7 +6,7 @@ % Count up the patches and bugs \title{What's New in Python 2.5} -\release{0.3} +\release{0.4} \author{A.M. Kuchling} \authoraddress{\email{amk at amk.ca}} @@ -74,7 +74,7 @@ Candidates included C's \code{cond ? true_v : false_v}, \code{if cond then true_v else false_v}, and 16 other variations. -GvR eventually chose a surprising syntax: +Guido van~Rossum eventually chose a surprising syntax: \begin{verbatim} x = true_value if condition else false_value @@ -407,7 +407,7 @@ combined version was complicated and it wasn't clear what the semantics of the combined should be. -GvR spent some time working with Java, which does support the +Guido van~Rossum spent some time working with Java, which does support the equivalent of combining \keyword{except} blocks and a \keyword{finally} block, and this clarified what the statement should mean. In Python 2.5, you can now write: @@ -600,7 +600,11 @@ \seepep{342}{Coroutines via Enhanced Generators}{PEP written by Guido van~Rossum and Phillip J. Eby; implemented by Phillip J. Eby. Includes examples of -some fancier uses of generators as coroutines.} +some fancier uses of generators as coroutines. + +Earlier versions of these features were proposed in +\pep{288} by Raymond Hettinger and \pep{325} by Samuele Pedroni. +} \seeurl{http://en.wikipedia.org/wiki/Coroutine}{The Wikipedia entry for coroutines.} @@ -1152,8 +1156,8 @@ false values. \function{any()} returns \constant{True} if any value returned by the iterator is true; otherwise it will return \constant{False}. \function{all()} returns \constant{True} only if -all of the values returned by the iterator evaluate as being true. -(Suggested by GvR, and implemented by Raymond Hettinger.) +all of the values returned by the iterator evaluate as true. +(Suggested by Guido van~Rossum, and implemented by Raymond Hettinger.) \item ASCII is now the default encoding for modules. It's now a syntax error if a module contains string literals with 8-bit @@ -1206,6 +1210,11 @@ Newbies who try \code{quit()} or \code{exit()} will now exit the interpreter as they expect. (Implemented by Georg Brandl.) +The Python executable now accepts the standard long options +\longprogramopt{help} and \longprogramopt{version}; on Windows, +it also accepts the \programopt{/?} option for displaying a help message. +(Implemented by Georg Brandl.) + %====================================================================== \subsection{Optimizations\label{opts}} @@ -1254,7 +1263,8 @@ \item The code generator's peephole optimizer now performs simple constant folding in expressions. If you write something like \code{a = 2+3}, the code generator will do the arithmetic and produce -code corresponding to \code{a = 5}. +code corresponding to \code{a = 5}. (Proposed and implemented +by Raymond Hettinger.) \item Function calls are now faster because code objects now keep the most recently finished frame (a ``zombie frame'') in an internal @@ -1348,10 +1358,13 @@ 'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']} \end{verbatim} -The \class{deque} double-ended queue type supplied by the +(Contributed by Guido van~Rossum.) + +\item The \class{deque} double-ended queue type supplied by the \module{collections} module now has a \method{remove(\var{value})} method that removes the first occurrence of \var{value} in the queue, raising \exception{ValueError} if the value isn't found. +(Contributed by Raymond Hettinger.) \item New module: The \module{contextlib} module contains helper functions for use with the new '\keyword{with}' statement. See @@ -1380,6 +1393,17 @@ \member{line_num} attribute that counts the number of physical lines read from the source; records can span multiple physical lines, so \member{line_num} is not the same as the number of records read. + +The CSV parser is now stricter about multi-line quoted +fields. Previously, if a line ended within a quoted field without a +terminating newline character, a newline would be inserted into the +returned field. This behavior caused problems when reading files that +contained carriage return characters within fields, so the code was +changed to return the field without inserting newlines. As a +consequence, if newlines embedded within fields are important, the +input should be split into lines in a manner that preserves the +newline characters. + (Contributed by Skip Montanaro and Andrew McNamara.) \item The \class{datetime} class in the \module{datetime} @@ -1640,7 +1664,7 @@ \end{verbatim} You can also pack and unpack data to and from buffer objects directly -using the \method{pack_to(\var{buffer}, \var{offset}, \var{v1}, +using the \method{pack_into(\var{buffer}, \var{offset}, \var{v1}, \var{v2}, ...)} and \method{unpack_from(\var{buffer}, \var{offset})} methods. This lets you store data directly into an array or a memory-mapped file. @@ -1662,14 +1686,20 @@ \code{"trunk:45355:45356M, Apr 13 2006, 07:42:19"}. (Contributed by Barry Warsaw.) +\item Another new function, \function{sys._current_frames()}, returns +the current stack frames for all running threads as a dictionary +mapping thread identifiers to the topmost stack frame currently active +in that thread at the time the function is called. (Contributed by +Tim Peters.) + \item The \class{TarFile} class in the \module{tarfile} module now has an \method{extractall()} method that extracts all members from the archive into the current working directory. It's also possible to set a different directory as the extraction target, and to unpack only a -subset of the archive's members. +subset of the archive's members. -A tarfile's compression can be autodetected by -using the mode \code{'r|*'}. +The compression used for a tarfile opened in stream mode can now be +autodetected using the mode \code{'r|*'}. % patch 918101 (Contributed by Lars Gust\"abel.) @@ -1741,13 +1771,6 @@ Brandl.) % Patch #754022 -\item The standard library's XML-related package -has been renamed to \module{xmlcore}. The \module{xml} module will -now import either the \module{xmlcore} or PyXML version of subpackages -such as \module{xml.dom}. The renaming means it will always be -possible to import the standard library's XML support whether or not -the PyXML package is installed. - \item The \module{xmlrpclib} module now supports returning \class{datetime} objects for the XML-RPC date type. Supply \code{use_datetime=True} to the \function{loads()} function @@ -2186,6 +2209,11 @@ \begin{itemize} +\item The Python source tree was converted from CVS to Subversion, +in a complex migration procedure that was supervised and flawlessly +carried out by Martin von~L\"owis. The procedure was developed as +\pep{347}. + \item The largest change to the C API came from \pep{353}, which modifies the interpreter to use a \ctype{Py_ssize_t} type definition instead of \ctype{int}. See the earlier @@ -2263,6 +2291,13 @@ \var{dict})} can now accept a tuple of base classes as its \var{base} argument. (Contributed by Georg Brandl.) +\item The \cfunction{PyErr_Warn()} function for issuing warnings +is now deprecated in favour of \cfunction{PyErr_WarnEx(category, +message, stacklevel)} which lets you specify the number of stack +frames separating this function and the caller. A \var{stacklevel} of +1 is the function calling \cfunction{PyErr_WarnEx()}, 2 is the +function above that, and so forth. (Added by Neal Norwitz.) + \item The CPython interpreter is still written in C, but the code can now be compiled with a {\Cpp} compiler without errors. (Implemented by Anthony Baxter, Martin von~L\"owis, Skip Montanaro.) @@ -2305,7 +2340,7 @@ As usual, there were a bunch of other improvements and bugfixes scattered throughout the source tree. A search through the SVN change -logs finds there were XXX patches applied and YYY bugs fixed between +logs finds there were 334 patches applied and 443 bugs fixed between Python 2.4 and 2.5. Both figures are likely to be underestimates. Some of the more notable changes are: @@ -2366,6 +2401,10 @@ described in section~\ref{pep-342}, it's now possible for \member{gi_frame} to be \code{None}. +\item Library: the \module{csv} module is now stricter about multi-line quoted +fields. If your files contain newlines embedded within fields, the +input should be split into lines in a manner which preserves the +newline characters. \item Library: The \module{pickle} and \module{cPickle} modules no longer accept a return value of \code{None} from the @@ -2380,10 +2419,6 @@ \member{rpc_paths} to \code{None} or an empty tuple disables this path checking. -\item Library: the \module{xml} package has been renamed to \module{xmlcore}. -The PyXML package will therefore be \module{xml}, and the Python -distribution's code will always be accessible as \module{xmlcore}. - \item C API: Many functions now use \ctype{Py_ssize_t} instead of \ctype{int} to allow processing more data on 64-bit machines. Extension code may need to make the same change to avoid @@ -2406,8 +2441,10 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: Nick Coghlan, Phillip J. Eby, Ralf W. Grosse-Kunstleve, Kent -Johnson, Martin von~L\"owis, Fredrik Lundh, Gustavo Niemeyer, James -Pryor, Mike Rovner, Scott Weikart, Barry Warsaw, Thomas Wouters. +article: Nick Coghlan, Phillip J. Eby, Lars Gust\"abel, Raymond Hettinger, Ralf +W. Grosse-Kunstleve, Kent Johnson, Martin von~L\"owis, Fredrik Lundh, +Andrew McNamara, Skip Montanaro, +Gustavo Niemeyer, James Pryor, Mike Rovner, Scott Weikart, Barry +Warsaw, Thomas Wouters. \end{document} Modified: stackless/trunk/Include/patchlevel.h ============================================================================== --- stackless/trunk/Include/patchlevel.h (original) +++ stackless/trunk/Include/patchlevel.h Mon Aug 14 12:38:35 2006 @@ -23,10 +23,10 @@ #define PY_MINOR_VERSION 5 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 2 +#define PY_RELEASE_SERIAL 3 /* Version as a string */ -#define PY_VERSION "2.5b2" +#define PY_VERSION "2.5b3" /* Subversion Revision number of this file (not of the repository) */ #define PY_PATCHLEVEL_REVISION "$Revision$" Modified: stackless/trunk/Include/pyerrors.h ============================================================================== --- stackless/trunk/Include/pyerrors.h (original) +++ stackless/trunk/Include/pyerrors.h Mon Aug 14 12:38:35 2006 @@ -228,10 +228,14 @@ PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); /* Issue a warning or exception */ -PyAPI_FUNC(int) PyErr_Warn(PyObject *, char *); +PyAPI_FUNC(int) PyErr_WarnEx(PyObject *category, const char *msg, + Py_ssize_t stack_level); PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int, const char *, PyObject *); +/* PyErr_Warn is only for backwards compatability and will be removed. + Use PyErr_WarnEx instead. */ +#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) /* In sigcheck.c or signalmodule.c */ PyAPI_FUNC(int) PyErr_CheckSignals(void); Modified: stackless/trunk/Include/weakrefobject.h ============================================================================== --- stackless/trunk/Include/weakrefobject.h (original) +++ stackless/trunk/Include/weakrefobject.h Mon Aug 14 12:38:35 2006 @@ -62,7 +62,7 @@ PyObject *callback); PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); -PyAPI_FUNC(long) _PyWeakref_GetWeakrefCount(PyWeakReference *head); +PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); Modified: stackless/trunk/Lib/binhex.py ============================================================================== --- stackless/trunk/Lib/binhex.py (original) +++ stackless/trunk/Lib/binhex.py Mon Aug 14 12:38:35 2006 @@ -44,22 +44,14 @@ # # Workarounds for non-mac machines. -if os.name == 'mac': - import macfs - import MacOS - try: - openrf = MacOS.openrf - except AttributeError: - # Backward compatibility - openrf = open - - def FInfo(): - return macfs.FInfo() +try: + from Carbon.File import FSSpec, FInfo + from MacOS import openrf def getfileinfo(name): - finfo = macfs.FSSpec(name).GetFInfo() + finfo = FSSpec(name).FSpGetFInfo() dir, file = os.path.split(name) - # XXXX Get resource/data sizes + # XXX Get resource/data sizes fp = open(name, 'rb') fp.seek(0, 2) dlen = fp.tell() @@ -75,7 +67,7 @@ mode = '*' + mode[0] return openrf(name, mode) -else: +except ImportError: # # Glue code for non-macintosh usage # @@ -183,7 +175,7 @@ ofname = ofp ofp = open(ofname, 'w') if os.name == 'mac': - fss = macfs.FSSpec(ofname) + fss = FSSpec(ofname) fss.SetCreatorType('BnHq', 'TEXT') ofp.write('(This file must be converted with BinHex 4.0)\n\n:') hqxer = _Hqxcoderengine(ofp) @@ -486,7 +478,7 @@ if not out: out = ifp.FName if os.name == 'mac': - ofss = macfs.FSSpec(out) + ofss = FSSpec(out) out = ofss.as_pathname() ofp = open(out, 'wb') @@ -519,6 +511,7 @@ def _test(): if os.name == 'mac': + import macfs fss, ok = macfs.PromptGetFile('File to convert:') if not ok: sys.exit(0) Modified: stackless/trunk/Lib/bsddb/test/test_basics.py ============================================================================== --- stackless/trunk/Lib/bsddb/test/test_basics.py (original) +++ stackless/trunk/Lib/bsddb/test/test_basics.py Mon Aug 14 12:38:35 2006 @@ -562,6 +562,9 @@ num = d.truncate() assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,) + #---------------------------------------- + + #---------------------------------------------------------------------- @@ -583,18 +586,40 @@ dbopenflags = db.DB_THREAD -class BasicBTreeWithEnvTestCase(BasicTestCase): - dbtype = db.DB_BTREE +class BasicWithEnvTestCase(BasicTestCase): dbopenflags = db.DB_THREAD useEnv = 1 envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK + #---------------------------------------- + + def test07_EnvRemoveAndRename(self): + if not self.env: + return + + if verbose: + print '\n', '-=' * 30 + print "Running %s.test07_EnvRemoveAndRename..." % self.__class__.__name__ + + # can't rename or remove an open DB + self.d.close() + + newname = self.filename + '.renamed' + self.env.dbrename(self.filename, None, newname) + self.env.dbremove(newname) + + # dbremove and dbrename are in 4.1 and later + if db.version() < (4,1): + del test07_EnvRemoveAndRename + + #---------------------------------------- + +class BasicBTreeWithEnvTestCase(BasicWithEnvTestCase): + dbtype = db.DB_BTREE + -class BasicHashWithEnvTestCase(BasicTestCase): +class BasicHashWithEnvTestCase(BasicWithEnvTestCase): dbtype = db.DB_HASH - dbopenflags = db.DB_THREAD - useEnv = 1 - envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK #---------------------------------------------------------------------- Modified: stackless/trunk/Lib/compiler/future.py ============================================================================== --- stackless/trunk/Lib/compiler/future.py (original) +++ stackless/trunk/Lib/compiler/future.py Mon Aug 14 12:38:35 2006 @@ -23,14 +23,7 @@ def visitModule(self, node): stmt = node.node - found_docstring = False for s in stmt.nodes: - # Skip over docstrings - if not found_docstring and isinstance(s, ast.Discard) \ - and isinstance(s.expr, ast.Const) \ - and isinstance(s.expr.value, str): - found_docstring = True - continue if not self.check_stmt(s): break Modified: stackless/trunk/Lib/compiler/transformer.py ============================================================================== --- stackless/trunk/Lib/compiler/transformer.py (original) +++ stackless/trunk/Lib/compiler/transformer.py Mon Aug 14 12:38:35 2006 @@ -1382,6 +1382,7 @@ symbol.testlist, symbol.testlist_safe, symbol.test, + symbol.or_test, symbol.and_test, symbol.not_test, symbol.comparison, Modified: stackless/trunk/Lib/ctypes/__init__.py ============================================================================== --- stackless/trunk/Lib/ctypes/__init__.py (original) +++ stackless/trunk/Lib/ctypes/__init__.py Mon Aug 14 12:38:35 2006 @@ -5,7 +5,7 @@ import os as _os, sys as _sys -__version__ = "0.9.9.7" +__version__ = "1.0.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer @@ -22,6 +22,23 @@ if _os.name in ("nt", "ce"): from _ctypes import FormatError +DEFAULT_MODE = RTLD_LOCAL +if _os.name == "posix" and _sys.platform == "darwin": + import gestalt + + # gestalt.gestalt("sysv") returns the version number of the + # currently active system file as BCD. + # On OS X 10.4.6 -> 0x1046 + # On OS X 10.2.8 -> 0x1028 + # See also http://www.rgaros.nl/gestalt/ + # + # On OS X 10.3, we use RTLD_GLOBAL as default mode + # because RTLD_LOCAL does not work at least on some + # libraries. + + if gestalt.gestalt("sysv") < 0x1040: + DEFAULT_MODE = RTLD_GLOBAL + from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI @@ -284,7 +301,7 @@ _flags_ = _FUNCFLAG_CDECL _restype_ = c_int # default, can be overridden in instances - def __init__(self, name, mode=RTLD_LOCAL, handle=None): + def __init__(self, name, mode=DEFAULT_MODE, handle=None): self._name = name if handle is None: self._handle = _dlopen(self._name, mode) @@ -300,13 +317,14 @@ def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError, name - return self.__getitem__(name) + func = self.__getitem__(name) + setattr(self, name, func) + return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, (int, long)): func.__name__ = name_or_ordinal - setattr(self, name_or_ordinal, func) return func class PyDLL(CDLL): @@ -446,52 +464,21 @@ return _wstring_at(ptr, size) -if _os.name == "nt": # COM stuff +if _os.name in ("nt", "ce"): # COM stuff def DllGetClassObject(rclsid, riid, ppv): - # First ask ctypes.com.server than comtypes.server for the - # class object. - - # trick py2exe by doing dynamic imports - result = -2147221231 # CLASS_E_CLASSNOTAVAILABLE try: - ctcom = __import__("ctypes.com.server", globals(), locals(), ['*']) + ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: - pass + return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: - result = ctcom.DllGetClassObject(rclsid, riid, ppv) - - if result == -2147221231: # CLASS_E_CLASSNOTAVAILABLE - try: - ccom = __import__("comtypes.server", globals(), locals(), ['*']) - except ImportError: - pass - else: - result = ccom.DllGetClassObject(rclsid, riid, ppv) - - return result + return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): - # First ask ctypes.com.server than comtypes.server if we can unload or not. - # trick py2exe by doing dynamic imports - result = 0 # S_OK try: - ctcom = __import__("ctypes.com.server", globals(), locals(), ['*']) + ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: - pass - else: - result = ctcom.DllCanUnloadNow() - if result != 0: # != S_OK - return result - - try: - ccom = __import__("comtypes.server", globals(), locals(), ['*']) - except ImportError: - return result - try: - return ccom.DllCanUnloadNow() - except AttributeError: - pass - return result + return 0 # S_OK + return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure Modified: stackless/trunk/Lib/ctypes/test/test_varsize_struct.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_varsize_struct.py (original) +++ stackless/trunk/Lib/ctypes/test/test_varsize_struct.py Mon Aug 14 12:38:35 2006 @@ -46,70 +46,5 @@ self.failUnlessRaises(IndexError, array.__setitem__, -1, None) self.failUnlessRaises(IndexError, array.__getitem__, -1) - def test_varsized_array(self): - array = (c_int * 20)(20, 21, 22, 23, 24, 25, 26, 27, 28, 29) - - # no range checking is done on arrays with size == 1 - varsize_array = (c_int * 1).from_address(addressof(array)) - - # __getitem__ - self.failUnlessEqual(varsize_array[0], 20) - self.failUnlessEqual(varsize_array[1], 21) - self.failUnlessEqual(varsize_array[2], 22) - self.failUnlessEqual(varsize_array[3], 23) - self.failUnlessEqual(varsize_array[4], 24) - self.failUnlessEqual(varsize_array[5], 25) - self.failUnlessEqual(varsize_array[6], 26) - self.failUnlessEqual(varsize_array[7], 27) - self.failUnlessEqual(varsize_array[8], 28) - self.failUnlessEqual(varsize_array[9], 29) - - # still, normal sequence of length one behaviour: - self.failUnlessEqual(varsize_array[-1], 20) - self.failUnlessRaises(IndexError, lambda: varsize_array[-2]) - # except for this one, which will raise MemoryError - self.failUnlessRaises(MemoryError, lambda: varsize_array[:]) - - # __setitem__ - varsize_array[0] = 100 - varsize_array[1] = 101 - varsize_array[2] = 102 - varsize_array[3] = 103 - varsize_array[4] = 104 - varsize_array[5] = 105 - varsize_array[6] = 106 - varsize_array[7] = 107 - varsize_array[8] = 108 - varsize_array[9] = 109 - - for i in range(10): - self.failUnlessEqual(varsize_array[i], i + 100) - self.failUnlessEqual(array[i], i + 100) - - # __getslice__ - self.failUnlessEqual(varsize_array[0:10], range(100, 110)) - self.failUnlessEqual(varsize_array[1:9], range(101, 109)) - self.failUnlessEqual(varsize_array[1:-1], []) - - # __setslice__ - varsize_array[0:10] = range(1000, 1010) - self.failUnlessEqual(varsize_array[0:10], range(1000, 1010)) - - varsize_array[1:9] = range(1001, 1009) - self.failUnlessEqual(varsize_array[1:9], range(1001, 1009)) - - def test_vararray_is_sane(self): - array = (c_int * 15)(20, 21, 22, 23, 24, 25, 26, 27, 28, 29) - - varsize_array = (c_int * 1).from_address(addressof(array)) - varsize_array[:] = [1, 2, 3, 4, 5] - - self.failUnlessEqual(array[:], [1, 2, 3, 4, 5, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0]) - self.failUnlessEqual(varsize_array[0:10], [1, 2, 3, 4, 5, 25, 26, 27, 28, 29]) - - array[:5] = [10, 11, 12, 13, 14] - self.failUnlessEqual(array[:], [10, 11, 12, 13, 14, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0]) - self.failUnlessEqual(varsize_array[0:10], [10, 11, 12, 13, 14, 25, 26, 27, 28, 29]) - if __name__ == "__main__": unittest.main() Modified: stackless/trunk/Lib/ctypes/util.py ============================================================================== --- stackless/trunk/Lib/ctypes/util.py (original) +++ stackless/trunk/Lib/ctypes/util.py Mon Aug 14 12:38:35 2006 @@ -47,10 +47,13 @@ def _findLib_gcc(name): expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name + fdout, ccout = tempfile.mkstemp() + os.close(fdout) cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \ - '$CC -Wl,-t -o /dev/null 2>&1 -l' + name + '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name try: fdout, outfile = tempfile.mkstemp() + os.close(fdout) fd = os.popen(cmd) trace = fd.read() err = fd.close() @@ -60,6 +63,11 @@ except OSError, e: if e.errno != errno.ENOENT: raise + try: + os.unlink(ccout) + except OSError, e: + if e.errno != errno.ENOENT: + raise res = re.search(expr, trace) if not res: return None Modified: stackless/trunk/Lib/distutils/__init__.py ============================================================================== --- stackless/trunk/Lib/distutils/__init__.py (original) +++ stackless/trunk/Lib/distutils/__init__.py Mon Aug 14 12:38:35 2006 @@ -12,4 +12,6 @@ __revision__ = "$Id$" -__version__ = "2.4.0" +import sys +__version__ = "%d.%d.%d" % sys.version_info[:3] +del sys Modified: stackless/trunk/Lib/distutils/msvccompiler.py ============================================================================== --- stackless/trunk/Lib/distutils/msvccompiler.py (original) +++ stackless/trunk/Lib/distutils/msvccompiler.py Mon Aug 14 12:38:35 2006 @@ -131,8 +131,10 @@ self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") except KeyError, exc: # raise DistutilsPlatformError, \ - ("Visual Studio 2003 needs to be installed before " - "building extensions for Python.") + ("""Python was built with Visual Studio 2003; +extensions must be built with a compiler than can generate compatible binaries. +Visual Studio 2003 was not found on this system. If you have Cygwin installed, +you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") p = r"Software\Microsoft\NET Framework Setup\Product" for base in HKEYS: Modified: stackless/trunk/Lib/doctest.py ============================================================================== --- stackless/trunk/Lib/doctest.py (original) +++ stackless/trunk/Lib/doctest.py Mon Aug 14 12:38:35 2006 @@ -821,6 +821,11 @@ # Recursively expore `obj`, extracting DocTests. tests = [] self._find(tests, obj, name, module, source_lines, globs, {}) + # Sort the tests by alpha order of names, for consistency in + # verbose-mode output. This was a feature of doctest in Pythons + # <= 2.3 that got lost by accident in 2.4. It was repaired in + # 2.4.4 and 2.5. + tests.sort() return tests def _from_module(self, module, object): Modified: stackless/trunk/Lib/email/__init__.py ============================================================================== --- stackless/trunk/Lib/email/__init__.py (original) +++ stackless/trunk/Lib/email/__init__.py Mon Aug 14 12:38:35 2006 @@ -4,7 +4,7 @@ """A package for parsing, handling, and generating email messages.""" -__version__ = '4.0a2' +__version__ = '4.0.1' __all__ = [ # Old names Modified: stackless/trunk/Lib/email/message.py ============================================================================== --- stackless/trunk/Lib/email/message.py (original) +++ stackless/trunk/Lib/email/message.py Mon Aug 14 12:38:35 2006 @@ -747,7 +747,18 @@ if isinstance(charset, tuple): # RFC 2231 encoded, so decode it, and it better end up as ascii. pcharset = charset[0] or 'us-ascii' - charset = unicode(charset[2], pcharset).encode('us-ascii') + try: + # LookupError will be raised if the charset isn't known to + # Python. UnicodeError will be raised if the encoded text + # contains a character not in the charset. + charset = unicode(charset[2], pcharset).encode('us-ascii') + except (LookupError, UnicodeError): + charset = charset[2] + # charset character must be in us-ascii range + try: + charset = unicode(charset, 'us-ascii').encode('us-ascii') + except UnicodeError: + return failobj # RFC 2046, $4.1.2 says charsets are not case sensitive return charset.lower() Modified: stackless/trunk/Lib/email/test/test_email.py ============================================================================== --- stackless/trunk/Lib/email/test/test_email.py (original) +++ stackless/trunk/Lib/email/test/test_email.py Mon Aug 14 12:38:35 2006 @@ -3005,14 +3005,29 @@ ''' msg = email.message_from_string(m) - self.assertEqual(msg.get_param('NAME'), - (None, None, 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')) + param = msg.get_param('NAME') + self.failIf(isinstance(param, tuple)) + self.assertEqual( + param, + 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm') def test_rfc2231_no_language_or_charset_in_filename(self): m = '''\ Content-Disposition: inline; -\tfilename*0="This%20is%20even%20more%20"; -\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*0*="''This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + 'This is even more ***fun*** is it not.pdf') + + def test_rfc2231_no_language_or_charset_in_filename_encoded(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="''This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; \tfilename*2="is it not.pdf" ''' @@ -3020,11 +3035,37 @@ self.assertEqual(msg.get_filename(), 'This is even more ***fun*** is it not.pdf') + def test_rfc2231_partly_encoded(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0="''This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual( + msg.get_filename(), + 'This%20is%20even%20more%20***fun*** is it not.pdf') + + def test_rfc2231_partly_nonencoded(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0="This%20is%20even%20more%20"; +\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual( + msg.get_filename(), + 'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf') + def test_rfc2231_no_language_or_charset_in_boundary(self): m = '''\ Content-Type: multipart/alternative; -\tboundary*0="This%20is%20even%20more%20"; -\tboundary*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tboundary*0*="''This%20is%20even%20more%20"; +\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20"; \tboundary*2="is it not.pdf" ''' @@ -3036,8 +3077,8 @@ # This is a nonsensical charset value, but tests the code anyway m = '''\ Content-Type: text/plain; -\tcharset*0="This%20is%20even%20more%20"; -\tcharset*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tcharset*0*="This%20is%20even%20more%20"; +\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20"; \tcharset*2="is it not.pdf" ''' @@ -3045,15 +3086,145 @@ self.assertEqual(msg.get_content_charset(), 'this is even more ***fun*** is it not.pdf') + def test_rfc2231_bad_encoding_in_filename(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="bogus'xx'This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + 'This is even more ***fun*** is it not.pdf') + + def test_rfc2231_bad_encoding_in_charset(self): + m = """\ +Content-Type: text/plain; charset*=bogus''utf-8%E2%80%9D + +""" + msg = email.message_from_string(m) + # This should return None because non-ascii characters in the charset + # are not allowed. + self.assertEqual(msg.get_content_charset(), None) + + def test_rfc2231_bad_character_in_charset(self): + m = """\ +Content-Type: text/plain; charset*=ascii''utf-8%E2%80%9D + +""" + msg = email.message_from_string(m) + # This should return None because non-ascii characters in the charset + # are not allowed. + self.assertEqual(msg.get_content_charset(), None) + + def test_rfc2231_bad_character_in_filename(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="ascii'xx'This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2*="is it not.pdf%E2" + +''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + u'This is even more ***fun*** is it not.pdf\ufffd') + def test_rfc2231_unknown_encoding(self): m = """\ Content-Transfer-Encoding: 8bit -Content-Disposition: inline; filename*0=X-UNKNOWN''myfile.txt +Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt """ msg = email.message_from_string(m) self.assertEqual(msg.get_filename(), 'myfile.txt') + def test_rfc2231_single_tick_in_filename_extended(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0*=\"Frank's\"; name*1*=\" Document\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, None) + eq(language, None) + eq(s, "Frank's Document") + + def test_rfc2231_single_tick_in_filename(self): + m = """\ +Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\" + +""" + msg = email.message_from_string(m) + param = msg.get_param('name') + self.failIf(isinstance(param, tuple)) + self.assertEqual(param, "Frank's Document") + + def test_rfc2231_tick_attack_extended(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, 'us-ascii') + eq(language, 'en-us') + eq(s, "Frank's Document") + + def test_rfc2231_tick_attack(self): + m = """\ +Content-Type: application/x-foo; +\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\" + +""" + msg = email.message_from_string(m) + param = msg.get_param('name') + self.failIf(isinstance(param, tuple)) + self.assertEqual(param, "us-ascii'en-us'Frank's Document") + + def test_rfc2231_no_extended_values(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; name=\"Frank's Document\" + +""" + msg = email.message_from_string(m) + eq(msg.get_param('name'), "Frank's Document") + + def test_rfc2231_encoded_then_unencoded_segments(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0*=\"us-ascii'en-us'My\"; +\tname*1=\" Document\"; +\tname*2*=\" For You\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, 'us-ascii') + eq(language, 'en-us') + eq(s, 'My Document For You') + + def test_rfc2231_unencoded_then_encoded_segments(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0=\"us-ascii'en-us'My\"; +\tname*1*=\" Document\"; +\tname*2*=\" For You\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, 'us-ascii') + eq(language, 'en-us') + eq(s, 'My Document For You') + def _testclasses(): Modified: stackless/trunk/Lib/email/test/test_email_renamed.py ============================================================================== --- stackless/trunk/Lib/email/test/test_email_renamed.py (original) +++ stackless/trunk/Lib/email/test/test_email_renamed.py Mon Aug 14 12:38:35 2006 @@ -3011,14 +3011,29 @@ ''' msg = email.message_from_string(m) - self.assertEqual(msg.get_param('NAME'), - (None, None, 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')) + param = msg.get_param('NAME') + self.failIf(isinstance(param, tuple)) + self.assertEqual( + param, + 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm') def test_rfc2231_no_language_or_charset_in_filename(self): m = '''\ Content-Disposition: inline; -\tfilename*0="This%20is%20even%20more%20"; -\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*0*="''This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + 'This is even more ***fun*** is it not.pdf') + + def test_rfc2231_no_language_or_charset_in_filename_encoded(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="''This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; \tfilename*2="is it not.pdf" ''' @@ -3026,11 +3041,37 @@ self.assertEqual(msg.get_filename(), 'This is even more ***fun*** is it not.pdf') + def test_rfc2231_partly_encoded(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0="''This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual( + msg.get_filename(), + 'This%20is%20even%20more%20***fun*** is it not.pdf') + + def test_rfc2231_partly_nonencoded(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0="This%20is%20even%20more%20"; +\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual( + msg.get_filename(), + 'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf') + def test_rfc2231_no_language_or_charset_in_boundary(self): m = '''\ Content-Type: multipart/alternative; -\tboundary*0="This%20is%20even%20more%20"; -\tboundary*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tboundary*0*="''This%20is%20even%20more%20"; +\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20"; \tboundary*2="is it not.pdf" ''' @@ -3042,8 +3083,8 @@ # This is a nonsensical charset value, but tests the code anyway m = '''\ Content-Type: text/plain; -\tcharset*0="This%20is%20even%20more%20"; -\tcharset*1="%2A%2A%2Afun%2A%2A%2A%20"; +\tcharset*0*="This%20is%20even%20more%20"; +\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20"; \tcharset*2="is it not.pdf" ''' @@ -3051,15 +3092,145 @@ self.assertEqual(msg.get_content_charset(), 'this is even more ***fun*** is it not.pdf') + def test_rfc2231_bad_encoding_in_filename(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="bogus'xx'This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2="is it not.pdf" + +''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + 'This is even more ***fun*** is it not.pdf') + + def test_rfc2231_bad_encoding_in_charset(self): + m = """\ +Content-Type: text/plain; charset*=bogus''utf-8%E2%80%9D + +""" + msg = email.message_from_string(m) + # This should return None because non-ascii characters in the charset + # are not allowed. + self.assertEqual(msg.get_content_charset(), None) + + def test_rfc2231_bad_character_in_charset(self): + m = """\ +Content-Type: text/plain; charset*=ascii''utf-8%E2%80%9D + +""" + msg = email.message_from_string(m) + # This should return None because non-ascii characters in the charset + # are not allowed. + self.assertEqual(msg.get_content_charset(), None) + + def test_rfc2231_bad_character_in_filename(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="ascii'xx'This%20is%20even%20more%20"; +\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; +\tfilename*2*="is it not.pdf%E2" + +''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_filename(), + u'This is even more ***fun*** is it not.pdf\ufffd') + def test_rfc2231_unknown_encoding(self): m = """\ Content-Transfer-Encoding: 8bit -Content-Disposition: inline; filename*0=X-UNKNOWN''myfile.txt +Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt """ msg = email.message_from_string(m) self.assertEqual(msg.get_filename(), 'myfile.txt') + def test_rfc2231_single_tick_in_filename_extended(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0*=\"Frank's\"; name*1*=\" Document\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, None) + eq(language, None) + eq(s, "Frank's Document") + + def test_rfc2231_single_tick_in_filename(self): + m = """\ +Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\" + +""" + msg = email.message_from_string(m) + param = msg.get_param('name') + self.failIf(isinstance(param, tuple)) + self.assertEqual(param, "Frank's Document") + + def test_rfc2231_tick_attack_extended(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, 'us-ascii') + eq(language, 'en-us') + eq(s, "Frank's Document") + + def test_rfc2231_tick_attack(self): + m = """\ +Content-Type: application/x-foo; +\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\" + +""" + msg = email.message_from_string(m) + param = msg.get_param('name') + self.failIf(isinstance(param, tuple)) + self.assertEqual(param, "us-ascii'en-us'Frank's Document") + + def test_rfc2231_no_extended_values(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; name=\"Frank's Document\" + +""" + msg = email.message_from_string(m) + eq(msg.get_param('name'), "Frank's Document") + + def test_rfc2231_encoded_then_unencoded_segments(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0*=\"us-ascii'en-us'My\"; +\tname*1=\" Document\"; +\tname*2*=\" For You\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, 'us-ascii') + eq(language, 'en-us') + eq(s, 'My Document For You') + + def test_rfc2231_unencoded_then_encoded_segments(self): + eq = self.assertEqual + m = """\ +Content-Type: application/x-foo; +\tname*0=\"us-ascii'en-us'My\"; +\tname*1*=\" Document\"; +\tname*2*=\" For You\" + +""" + msg = email.message_from_string(m) + charset, language, s = msg.get_param('name') + eq(charset, 'us-ascii') + eq(language, 'en-us') + eq(s, 'My Document For You') + def _testclasses(): Modified: stackless/trunk/Lib/email/utils.py ============================================================================== --- stackless/trunk/Lib/email/utils.py (original) +++ stackless/trunk/Lib/email/utils.py Mon Aug 14 12:38:35 2006 @@ -25,6 +25,7 @@ import base64 import random import socket +import urllib import warnings from cStringIO import StringIO @@ -45,6 +46,7 @@ EMPTYSTRING = '' UEMPTYSTRING = u'' CRLF = '\r\n' +TICK = "'" specialsre = re.compile(r'[][\\()<>@,:;".]') escapesre = re.compile(r'[][\\()"]') @@ -230,12 +232,14 @@ # RFC2231-related functions - parameter encoding and decoding def decode_rfc2231(s): """Decode string according to RFC 2231""" - import urllib - parts = s.split("'", 2) - if len(parts) == 1: - return None, None, urllib.unquote(s) - charset, language, s = parts - return charset, language, urllib.unquote(s) + parts = s.split(TICK, 2) + if len(parts) <= 2: + return None, None, s + if len(parts) > 3: + charset, language = parts[:2] + s = TICK.join(parts[2:]) + return charset, language, s + return parts def encode_rfc2231(s, charset=None, language=None): @@ -259,37 +263,54 @@ def decode_params(params): """Decode parameters list according to RFC 2231. - params is a sequence of 2-tuples containing (content type, string value). + params is a sequence of 2-tuples containing (param name, string value). """ + # Copy params so we don't mess with the original + params = params[:] new_params = [] - # maps parameter's name to a list of continuations + # Map parameter's name to a list of continuations. The values are a + # 3-tuple of the continuation number, the string value, and a flag + # specifying whether a particular segment is %-encoded. rfc2231_params = {} - # params is a sequence of 2-tuples containing (content_type, string value) - name, value = params[0] + name, value = params.pop(0) new_params.append((name, value)) - # Cycle through each of the rest of the parameters. - for name, value in params[1:]: + while params: + name, value = params.pop(0) + if name.endswith('*'): + encoded = True + else: + encoded = False value = unquote(value) mo = rfc2231_continuation.match(name) if mo: name, num = mo.group('name', 'num') if num is not None: num = int(num) - rfc2231_param1 = rfc2231_params.setdefault(name, []) - rfc2231_param1.append((num, value)) + rfc2231_params.setdefault(name, []).append((num, value, encoded)) else: new_params.append((name, '"%s"' % quote(value))) if rfc2231_params: for name, continuations in rfc2231_params.items(): value = [] + extended = False # Sort by number continuations.sort() - # And now append all values in num order - for num, continuation in continuations: - value.append(continuation) - charset, language, value = decode_rfc2231(EMPTYSTRING.join(value)) - new_params.append( - (name, (charset, language, '"%s"' % quote(value)))) + # And now append all values in numerical order, converting + # %-encodings for the encoded segments. If any of the + # continuation names ends in a *, then the entire string, after + # decoding segments and concatenating, must have the charset and + # language specifiers at the beginning of the string. + for num, s, encoded in continuations: + if encoded: + s = urllib.unquote(s) + extended = True + value.append(s) + value = quote(EMPTYSTRING.join(value)) + if extended: + charset, language, value = decode_rfc2231(value) + new_params.append((name, (charset, language, '"%s"' % value))) + else: + new_params.append((name, '"%s"' % value)) return new_params def collapse_rfc2231_value(value, errors='replace', Modified: stackless/trunk/Lib/encodings/mbcs.py ============================================================================== --- stackless/trunk/Lib/encodings/mbcs.py (original) +++ stackless/trunk/Lib/encodings/mbcs.py Mon Aug 14 12:38:35 2006 @@ -15,39 +15,31 @@ ### Codec APIs -class Codec(codecs.Codec): +encode = mbcs_encode - # Note: Binding these as C functions will result in the class not - # converting them to methods. This is intended. - encode = mbcs_encode - decode = mbcs_decode +def decode(input, errors='strict'): + return mbcs_decode(input, errors, True) class IncrementalEncoder(codecs.IncrementalEncoder): def encode(self, input, final=False): - return mbcs_encode(input,self.errors)[0] + return mbcs_encode(input, self.errors)[0] class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, input, errors, final): - return mbcs_decode(input,self.errors,final) - -class StreamWriter(Codec,codecs.StreamWriter): - pass + _buffer_decode = mbcs_decode -class StreamReader(Codec,codecs.StreamReader): - pass - -class StreamConverter(StreamWriter,StreamReader): +class StreamWriter(codecs.StreamWriter): + encode = mbcs_encode - encode = codecs.mbcs_decode - decode = codecs.mbcs_encode +class StreamReader(codecs.StreamReader): + decode = mbcs_decode ### encodings module API def getregentry(): return codecs.CodecInfo( name='mbcs', - encode=Codec.encode, - decode=Codec.decode, + encode=encode, + decode=decode, incrementalencoder=IncrementalEncoder, incrementaldecoder=IncrementalDecoder, streamreader=StreamReader, Modified: stackless/trunk/Lib/gzip.py ============================================================================== --- stackless/trunk/Lib/gzip.py (original) +++ stackless/trunk/Lib/gzip.py Mon Aug 14 12:38:35 2006 @@ -315,7 +315,13 @@ def close(self): if self.mode == WRITE: self.fileobj.write(self.compress.flush()) - write32(self.fileobj, self.crc) + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + write32u(self.fileobj, LOWU32(self.crc)) # self.size may exceed 2GB, or even 4GB write32u(self.fileobj, LOWU32(self.size)) self.fileobj = None Modified: stackless/trunk/Lib/httplib.py ============================================================================== --- stackless/trunk/Lib/httplib.py (original) +++ stackless/trunk/Lib/httplib.py Mon Aug 14 12:38:35 2006 @@ -3,7 +3,7 @@ -HTTPConnection go through a number of "states", which defines when a client +HTTPConnection goes through a number of "states", which define when a client may legally make another request or fetch the response for a particular request. This diagram details these state transitions: @@ -926,15 +926,15 @@ self.__state = _CS_IDLE if response.will_close: - # this effectively passes the connection to the response - self.close() + # Pass the socket to the response + self.sock = None else: # remember this, so we can tell when it is complete self.__response = response return response -# The next several classes are used to define FakeSocket,a socket-like +# The next several classes are used to define FakeSocket, a socket-like # interface to an SSL connection. # The primary complexity comes from faking a makefile() method. The Modified: stackless/trunk/Lib/idlelib/CREDITS.txt ============================================================================== --- stackless/trunk/Lib/idlelib/CREDITS.txt (original) +++ stackless/trunk/Lib/idlelib/CREDITS.txt Mon Aug 14 12:38:35 2006 @@ -19,17 +19,18 @@ subprocess, and made a number of usability enhancements. Other contributors include Raymond Hettinger, Tony Lownds (Mac integration), -Neal Norwitz (code check and clean-up), and Chui Tey (RPC integration, debugger -integration and persistent breakpoints). - -Scott David Daniels, Hernan Foffani, Christos Georgiou, Martin v. L?wis, -Jason Orendorff, Noam Raphael, Josh Robb, Nigel Rowe, Bruce Sherwood, and -Jeff Shute have submitted useful patches. Thanks, guys! +Neal Norwitz (code check and clean-up), Noam Raphael (Code Context, Call Tips, +many other patches), and Chui Tey (RPC integration, debugger integration and +persistent breakpoints). + +Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, +Martin v. L?wis, Jason Orendorff, Josh Robb, Nigel Rowe, Bruce Sherwood, +and Jeff Shute have submitted useful patches. Thanks, guys! For additional details refer to NEWS.txt and Changelog. -Please contact the IDLE maintainer to have yourself included here if you -are one of those we missed! +Please contact the IDLE maintainer (kbk at shore.net) to have yourself included +here if you are one of those we missed! Modified: stackless/trunk/Lib/idlelib/CallTipWindow.py ============================================================================== --- stackless/trunk/Lib/idlelib/CallTipWindow.py (original) +++ stackless/trunk/Lib/idlelib/CallTipWindow.py Mon Aug 14 12:38:35 2006 @@ -49,7 +49,11 @@ """ # truncate overly long calltip if len(text) >= 79: - text = text[:75] + ' ...' + textlines = text.splitlines() + for i, line in enumerate(textlines): + if len(line) > 79: + textlines[i] = line[:75] + ' ...' + text = '\n'.join(textlines) self.text = text if self.tipwindow or not self.text: return Modified: stackless/trunk/Lib/idlelib/CallTips.py ============================================================================== --- stackless/trunk/Lib/idlelib/CallTips.py (original) +++ stackless/trunk/Lib/idlelib/CallTips.py Mon Aug 14 12:38:35 2006 @@ -127,7 +127,7 @@ argText = "" if ob is not None: argOffset = 0 - if type(ob)==types.ClassType: + if type(ob) in (types.ClassType, types.TypeType): # Look for the highest __init__ in the class chain. fob = _find_constructor(ob) if fob is None: Modified: stackless/trunk/Lib/idlelib/CodeContext.py ============================================================================== --- stackless/trunk/Lib/idlelib/CodeContext.py (original) +++ stackless/trunk/Lib/idlelib/CodeContext.py Mon Aug 14 12:38:35 2006 @@ -11,11 +11,10 @@ """ import Tkinter from configHandler import idleConf -from sets import Set import re from sys import maxint as INFINITY -BLOCKOPENERS = Set(["class", "def", "elif", "else", "except", "finally", "for", +BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for", "if", "try", "while"]) UPDATEINTERVAL = 100 # millisec FONTUPDATEINTERVAL = 1000 # millisec Modified: stackless/trunk/Lib/idlelib/ColorDelegator.py ============================================================================== --- stackless/trunk/Lib/idlelib/ColorDelegator.py (original) +++ stackless/trunk/Lib/idlelib/ColorDelegator.py Mon Aug 14 12:38:35 2006 @@ -8,28 +8,29 @@ DEBUG = False -def any(name, list): - return "(?P<%s>" % name + "|".join(list) + ")" +def any(name, alternates): + "Return a named group pattern matching list of alternates." + return "(?P<%s>" % name + "|".join(alternates) + ")" def make_pat(): kw = r"\b" + any("KEYWORD", keyword.kwlist) + r"\b" builtinlist = [str(name) for name in dir(__builtin__) if not name.startswith('_')] # self.file = file("file") : - # 1st 'file' colorized normal, 2nd as builtin, 3rd as comment - builtin = r"([^.'\"\\]\b|^)" + any("BUILTIN", builtinlist) + r"\b" + # 1st 'file' colorized normal, 2nd as builtin, 3rd as string + builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b" comment = any("COMMENT", [r"#[^\n]*"]) - sqstring = r"(\b[rR])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" - dqstring = r'(\b[rR])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' - sq3string = r"(\b[rR])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" - dq3string = r'(\b[rR])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' + sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" + dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' + sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" + dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' string = any("STRING", [sq3string, dq3string, sqstring, dqstring]) return kw + "|" + builtin + "|" + comment + "|" + string +\ "|" + any("SYNC", [r"\n"]) prog = re.compile(make_pat(), re.S) idprog = re.compile(r"\s+(\w+)", re.S) -asprog = re.compile(r".*?\b(as)\b", re.S) +asprog = re.compile(r".*?\b(as)\b") class ColorDelegator(Delegator): @@ -208,10 +209,15 @@ head + "+%dc" % a, head + "+%dc" % b) elif value == "import": - # color all the "as" words on same line; - # cheap approximation to the truth + # color all the "as" words on same line, except + # if in a comment; cheap approximation to the + # truth + if '#' in chars: + endpos = chars.index('#') + else: + endpos = len(chars) while True: - m1 = self.asprog.match(chars, b) + m1 = self.asprog.match(chars, b, endpos) if not m1: break a, b = m1.span(1) Modified: stackless/trunk/Lib/idlelib/EditorWindow.py ============================================================================== --- stackless/trunk/Lib/idlelib/EditorWindow.py (original) +++ stackless/trunk/Lib/idlelib/EditorWindow.py Mon Aug 14 12:38:35 2006 @@ -85,17 +85,22 @@ self.flist = flist root = root or flist.root self.root = root + try: + sys.ps1 + except AttributeError: + sys.ps1 = '>>> ' self.menubar = Menu(root) self.top = top = WindowList.ListedToplevel(root, menu=self.menubar) if flist: self.tkinter_vars = flist.vars #self.top.instance_dict makes flist.inversedict avalable to #configDialog.py so it can access all EditorWindow instaces - self.top.instance_dict=flist.inversedict + self.top.instance_dict = flist.inversedict else: self.tkinter_vars = {} # keys: Tkinter event names # values: Tkinter variable instances - self.recent_files_path=os.path.join(idleConf.GetUserCfgDir(), + self.top.instance_dict = {} + self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(), 'recent-files.lst') self.vbar = vbar = Scrollbar(top, name='vbar') self.text_frame = text_frame = Frame(top) @@ -121,6 +126,9 @@ self.top.protocol("WM_DELETE_WINDOW", self.close) self.top.bind("<>", self.close_event) + if macosxSupport.runningAsOSXApp(): + # Command-W on editorwindows doesn't work without this. + text.bind('<>', self.close_event) text.bind("<>", self.cut) text.bind("<>", self.copy) text.bind("<>", self.paste) Modified: stackless/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- stackless/trunk/Lib/idlelib/NEWS.txt (original) +++ stackless/trunk/Lib/idlelib/NEWS.txt Mon Aug 14 12:38:35 2006 @@ -1,3 +1,24 @@ +What's New in IDLE 1.2b3? +========================= + +*Release date: 03-AUG-2006* + +- EditorWindow.test() was failing. Bug 1417598 + +- EditorWindow failed when used stand-alone if sys.ps1 not set. + Bug 1010370 Dave Florek + +- Tooltips failed on new-syle class __init__ args. Bug 1027566 Loren Guthrie + +- Avoid occasional failure to detect closing paren properly. + Patch 1407280 Tal Einat + +- Rebinding Tab key was inserting 'tab' instead of 'Tab'. Bug 1179168. + +- Colorizer now handles # correctly, also unicode strings and + 'as' keyword in comment directly following import command. Closes 1325071. + Patch 1479219 Tal Einat + What's New in IDLE 1.2b2? ========================= Modified: stackless/trunk/Lib/idlelib/ParenMatch.py ============================================================================== --- stackless/trunk/Lib/idlelib/ParenMatch.py (original) +++ stackless/trunk/Lib/idlelib/ParenMatch.py Mon Aug 14 12:38:35 2006 @@ -8,7 +8,7 @@ from HyperParser import HyperParser from configHandler import idleConf -keysym_opener = {"parenright":'(', "bracketright":'[', "braceright":'{'} +_openers = {')':'(',']':'[','}':'{'} CHECK_DELAY = 100 # miliseconds class ParenMatch: @@ -100,12 +100,13 @@ def paren_closed_event(self, event): # If it was a shortcut and not really a closing paren, quit. - if self.text.get("insert-1c") not in (')',']','}'): + closer = self.text.get("insert-1c") + if closer not in _openers: return hp = HyperParser(self.editwin, "insert-1c") if not hp.is_in_code(): return - indices = hp.get_surrounding_brackets(keysym_opener[event.keysym], True) + indices = hp.get_surrounding_brackets(_openers[closer], True) if indices is None: self.warn_mismatched() return Modified: stackless/trunk/Lib/idlelib/PyShell.py ============================================================================== --- stackless/trunk/Lib/idlelib/PyShell.py (original) +++ stackless/trunk/Lib/idlelib/PyShell.py Mon Aug 14 12:38:35 2006 @@ -1306,10 +1306,6 @@ script = None startup = False try: - sys.ps1 - except AttributeError: - sys.ps1 = '>>> ' - try: opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") except getopt.error, msg: sys.stderr.write("Error: %s\n" % str(msg)) Modified: stackless/trunk/Lib/idlelib/ScriptBinding.py ============================================================================== --- stackless/trunk/Lib/idlelib/ScriptBinding.py (original) +++ stackless/trunk/Lib/idlelib/ScriptBinding.py Mon Aug 14 12:38:35 2006 @@ -51,7 +51,7 @@ # Provide instance variables referenced by Debugger # XXX This should be done differently self.flist = self.editwin.flist - self.root = self.flist.root + self.root = self.editwin.root def check_module_event(self, event): filename = self.getfilename() Modified: stackless/trunk/Lib/idlelib/config-keys.def ============================================================================== --- stackless/trunk/Lib/idlelib/config-keys.def (original) +++ stackless/trunk/Lib/idlelib/config-keys.def Mon Aug 14 12:38:35 2006 @@ -159,3 +159,56 @@ change-indentwidth= del-word-left= del-word-right= + +[IDLE Classic OSX] +toggle-tabs = +interrupt-execution = +untabify-region = +remove-selection = +print-window = +replace = +goto-line = +plain-newline-and-indent = +history-previous = +beginning-of-line = +end-of-line = +comment-region = +redo = +close-window = +restart-shell = +save-window-as-file = +close-all-windows = +view-restart = +tabify-region = +find-again = +find = +toggle-auto-coloring = +select-all = +smart-backspace = +change-indentwidth = +do-nothing = +smart-indent = +center-insert = +history-next = +del-word-right = +undo = +save-window = +uncomment-region = +cut = +find-in-files = +dedent-region = +copy = +paste = +indent-region = +del-word-left = +newline-and-indent = +end-of-file = +open-class-browser = +open-new-window = +open-module = +find-selection = +python-context-help = +save-copy-of-window-as-file = +open-window-from-file = +python-docs = + Modified: stackless/trunk/Lib/idlelib/idlever.py ============================================================================== --- stackless/trunk/Lib/idlelib/idlever.py (original) +++ stackless/trunk/Lib/idlelib/idlever.py Mon Aug 14 12:38:35 2006 @@ -1 +1 @@ -IDLE_VERSION = "1.2b2" +IDLE_VERSION = "1.2b3" Modified: stackless/trunk/Lib/idlelib/keybindingDialog.py ============================================================================== --- stackless/trunk/Lib/idlelib/keybindingDialog.py (original) +++ stackless/trunk/Lib/idlelib/keybindingDialog.py Mon Aug 14 12:38:35 2006 @@ -202,7 +202,7 @@ ':':'colon',',':'comma','.':'period','<':'less','>':'greater', '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next', 'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up', - 'Down Arrow': 'Down', 'Tab':'tab'} + 'Down Arrow': 'Down', 'Tab':'Tab'} if key in translateDict.keys(): key = translateDict[key] if 'Shift' in modifiers and key in string.ascii_lowercase: Modified: stackless/trunk/Lib/idlelib/macosxSupport.py ============================================================================== --- stackless/trunk/Lib/idlelib/macosxSupport.py (original) +++ stackless/trunk/Lib/idlelib/macosxSupport.py Mon Aug 14 12:38:35 2006 @@ -25,6 +25,81 @@ def hideTkConsole(root): root.tk.call('console', 'hide') +def overrideRootMenu(root, flist): + """ + Replace the Tk root menu by something that's more appropriate for + IDLE. + """ + # The menu that is attached to the Tk root (".") is also used by AquaTk for + # all windows that don't specify a menu of their own. The default menubar + # contains a number of menus, none of which are appropriate for IDLE. The + # Most annoying of those is an 'About Tck/Tk...' menu in the application + # menu. + # + # This function replaces the default menubar by a mostly empty one, it + # should only contain the correct application menu and the window menu. + # + # Due to a (mis-)feature of TkAqua the user will also see an empty Help + # menu. + from Tkinter import Menu, Text, Text + from EditorWindow import prepstr, get_accelerator + import Bindings + import WindowList + from MultiCall import MultiCallCreator + + menubar = Menu(root) + root.configure(menu=menubar) + menudict = {} + + menudict['windows'] = menu = Menu(menubar, name='windows') + menubar.add_cascade(label='Window', menu=menu, underline=0) + + def postwindowsmenu(menu=menu): + end = menu.index('end') + if end is None: + end = -1 + + if end > 0: + menu.delete(0, end) + WindowList.add_windows_to_menu(menu) + WindowList.register_callback(postwindowsmenu) + + menudict['application'] = menu = Menu(menubar, name='apple') + menubar.add_cascade(label='IDLE', menu=menu) + + def about_dialog(event=None): + import aboutDialog + aboutDialog.AboutDialog(root, 'About IDLE') + + def config_dialog(event=None): + import configDialog + configDialog.ConfigDialog(root, 'Settings') + + root.bind('<>', about_dialog) + root.bind('<>', config_dialog) + if flist: + root.bind('<>', flist.close_all_callback) + + for mname, entrylist in Bindings.menudefs: + menu = menudict.get(mname) + if not menu: + continue + for entry in entrylist: + if not entry: + menu.add_separator() + else: + label, eventname = entry + underline, label = prepstr(label) + accelerator = get_accelerator(Bindings.default_keydefs, + eventname) + def command(text=root, eventname=eventname): + text.event_generate(eventname) + menu.add_command(label=label, underline=underline, + command=command, accelerator=accelerator) + + + + def setupApp(root, flist): """ @@ -33,4 +108,5 @@ if not runningAsOSXApp(): return hideTkConsole(root) + overrideRootMenu(root, flist) addOpenEventSupport(root, flist) Modified: stackless/trunk/Lib/inspect.py ============================================================================== --- stackless/trunk/Lib/inspect.py (original) +++ stackless/trunk/Lib/inspect.py Mon Aug 14 12:38:35 2006 @@ -89,6 +89,40 @@ is not guaranteed.""" return (hasattr(object, "__set__") and hasattr(object, "__get__")) +if hasattr(types, 'MemberDescriptorType'): + # CPython and equivalent + def ismemberdescriptor(object): + """Return true if the object is a member descriptor. + + Member descriptors are specialized descriptors defined in extension + modules.""" + return isinstance(object, types.MemberDescriptorType) +else: + # Other implementations + def ismemberdescriptor(object): + """Return true if the object is a member descriptor. + + Member descriptors are specialized descriptors defined in extension + modules.""" + return False + +if hasattr(types, 'GetSetDescriptorType'): + # CPython and equivalent + def isgetsetdescriptor(object): + """Return true if the object is a getset descriptor. + + getset descriptors are specialized descriptors defined in extension + modules.""" + return isinstance(object, types.GetSetDescriptorType) +else: + # Other implementations + def isgetsetdescriptor(object): + """Return true if the object is a getset descriptor. + + getset descriptors are specialized descriptors defined in extension + modules.""" + return False + def isfunction(object): """Return true if the object is a user-defined function. @@ -364,8 +398,9 @@ The idea is for each object to have a unique origin, so this routine normalizes the result as much as possible.""" - return os.path.normcase( - os.path.abspath(_filename or getsourcefile(object) or getfile(object))) + if _filename is None: + _filename = getsourcefile(object) or getfile(object) + return os.path.normcase(os.path.abspath(_filename)) modulesbyfile = {} Modified: stackless/trunk/Lib/lib-tk/Tkinter.py ============================================================================== --- stackless/trunk/Lib/lib-tk/Tkinter.py (original) +++ stackless/trunk/Lib/lib-tk/Tkinter.py Mon Aug 14 12:38:35 2006 @@ -186,7 +186,7 @@ if name: self._name = name else: - self._name = 'PY_VAR' + `_varnum` + self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value != None: self.set(value) Modified: stackless/trunk/Lib/lib-tk/turtle.py ============================================================================== --- stackless/trunk/Lib/lib-tk/turtle.py (original) +++ stackless/trunk/Lib/lib-tk/turtle.py Mon Aug 14 12:38:35 2006 @@ -713,7 +713,7 @@ def setup(**geometry): """ Sets the size and position of the main window. - Keywords are width, height, startx and starty + Keywords are width, height, startx and starty: width: either a size in pixels or a fraction of the screen. Default is 50% of screen. @@ -788,7 +788,7 @@ _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty)) def title(title): - """ set the window title. + """Set the window title. By default this is set to 'Turtle Graphics' Modified: stackless/trunk/Lib/logging/handlers.py ============================================================================== --- stackless/trunk/Lib/logging/handlers.py (original) +++ stackless/trunk/Lib/logging/handlers.py Mon Aug 14 12:38:35 2006 @@ -562,6 +562,18 @@ "local7": LOG_LOCAL7, } + #The map below appears to be trivially lowercasing the key. However, + #there's more to it than meets the eye - in some locales, lowercasing + #gives unexpected results. See SF #1524081: in the Turkish locale, + #"INFO".lower() != "info" + priority_map = { + "DEBUG" : "debug", + "INFO" : "info", + "WARNING" : "warning", + "ERROR" : "error", + "CRITICAL" : "critical" + } + def __init__(self, address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER): """ Initialize a handler. @@ -598,7 +610,7 @@ # necessary. log_format_string = '<%d>%s\000' - def encodePriority (self, facility, priority): + def encodePriority(self, facility, priority): """ Encode the facility and priority. You can pass in strings or integers - if strings are passed, the facility_names and @@ -619,6 +631,16 @@ self.socket.close() logging.Handler.close(self) + def mapPriority(self, levelName): + """ + Map a logging level name to a key in the priority_names map. + This is useful in two scenarios: when custom levels are being + used, and in the case where you can't do a straightforward + mapping by lowercasing the logging level name because of locale- + specific issues (see SF #1524081). + """ + return self.priority_map.get(levelName, "warning") + def emit(self, record): """ Emit a record. @@ -633,8 +655,8 @@ """ msg = self.log_format_string % ( self.encodePriority(self.facility, - string.lower(record.levelname)), - msg) + self.mapPriority(record.levelname)), + msg) try: if self.unixsocket: try: Modified: stackless/trunk/Lib/mailbox.py ============================================================================== --- stackless/trunk/Lib/mailbox.py (original) +++ stackless/trunk/Lib/mailbox.py Mon Aug 14 12:38:35 2006 @@ -15,6 +15,9 @@ import rfc822 import StringIO try: + if sys.platform == 'os2emx': + # OS/2 EMX fcntl() not adequate + raise ImportError import fcntl except ImportError: fcntl = None @@ -565,7 +568,8 @@ try: os.rename(new_file.name, self._path) except OSError, e: - if e.errno == errno.EEXIST: + if e.errno == errno.EEXIST or \ + (os.name == 'os2' and e.errno == errno.EACCES): os.remove(self._path) os.rename(new_file.name, self._path) else: @@ -1030,6 +1034,9 @@ if hasattr(os, 'link'): os.link(os.path.join(self._path, str(key)), os.path.join(self._path, str(prev + 1))) + if sys.platform == 'os2emx': + # cannot unlink an open file on OS/2 + f.close() os.unlink(os.path.join(self._path, str(key))) else: f.close() @@ -1828,7 +1835,8 @@ os.rename(pre_lock.name, f.name + '.lock') dotlock_done = True except OSError, e: - if e.errno == errno.EEXIST: + if e.errno == errno.EEXIST or \ + (os.name == 'os2' and e.errno == errno.EACCES): os.remove(pre_lock.name) raise ExternalClashError('dot lock unavailable: %s' % f.name) Modified: stackless/trunk/Lib/optparse.py ============================================================================== --- stackless/trunk/Lib/optparse.py (original) +++ stackless/trunk/Lib/optparse.py Mon Aug 14 12:38:35 2006 @@ -16,7 +16,7 @@ # Python developers: please do not make changes to this file, since # it is automatically generated from the Optik source code. -__version__ = "1.5.1+" +__version__ = "1.5.3" __all__ = ['Option', 'SUPPRESS_HELP', @@ -75,9 +75,9 @@ # This file was generated from: -# Id: option_parser.py 522 2006-06-11 16:22:03Z gward +# Id: option_parser.py 527 2006-07-23 15:21:30Z greg # Id: option.py 522 2006-06-11 16:22:03Z gward -# Id: help.py 509 2006-04-20 00:58:24Z gward +# Id: help.py 527 2006-07-23 15:21:30Z greg # Id: errors.py 509 2006-04-20 00:58:24Z gward try: @@ -1631,7 +1631,10 @@ # used by test suite def _get_encoding(self, file): - return getattr(file, "encoding", sys.getdefaultencoding()) + encoding = getattr(file, "encoding", None) + if not encoding: + encoding = sys.getdefaultencoding() + return encoding def print_help(self, file=None): """print_help(file : file = stdout) Modified: stackless/trunk/Lib/os.py ============================================================================== --- stackless/trunk/Lib/os.py (original) +++ stackless/trunk/Lib/os.py Mon Aug 14 12:38:35 2006 @@ -723,7 +723,7 @@ """ try: _urandomfd = open("/dev/urandom", O_RDONLY) - except: + except (OSError, IOError): raise NotImplementedError("/dev/urandom (or equivalent) not found") bytes = "" while len(bytes) < n: Modified: stackless/trunk/Lib/pdb.py ============================================================================== --- stackless/trunk/Lib/pdb.py (original) +++ stackless/trunk/Lib/pdb.py Mon Aug 14 12:38:35 2006 @@ -230,7 +230,8 @@ """Interpret the argument as though it had been typed in response to the prompt. - Checks wether this line is typed in the normal prompt or in a breakpoint command list definition + Checks whether this line is typed at the normal prompt or in + a breakpoint command list definition. """ if not self.commands_defining: return cmd.Cmd.onecmd(self, line) Modified: stackless/trunk/Lib/pkgutil.py ============================================================================== --- stackless/trunk/Lib/pkgutil.py (original) +++ stackless/trunk/Lib/pkgutil.py Mon Aug 14 12:38:35 2006 @@ -69,7 +69,33 @@ def walk_packages(path=None, prefix='', onerror=None): - """Yield submodule names+loaders recursively, for path or sys.path""" + """Yields (module_loader, name, ispkg) for all modules recursively + on path, or, if path is None, all accessible modules. + + 'path' should be either None or a list of paths to look for + modules in. + + 'prefix' is a string to output on the front of every module name + on output. + + Note that this function must import all *packages* (NOT all + modules!) on the given path, in order to access the __path__ + attribute to find submodules. + + 'onerror' is a function which gets called with one argument (the + name of the package which was being imported) if any exception + occurs while trying to import a package. If no onerror function is + supplied, ImportErrors are caught and ignored, while all other + exceptions are propagated, terminating the search. + + Examples: + + # list all modules python can access + walk_packages() + + # list all submodules of ctypes + walk_packages(ctypes.__path__, ctypes.__name__+'.') + """ def seen(p, m={}): if p in m: @@ -84,19 +110,33 @@ __import__(name) except ImportError: if onerror is not None: - onerror() + onerror(name) + except Exception: + if onerror is not None: + onerror(name) + else: + raise else: path = getattr(sys.modules[name], '__path__', None) or [] # don't traverse path items we've seen before path = [p for p in path if not seen(p)] - for item in walk_packages(path, name+'.'): + for item in walk_packages(path, name+'.', onerror): yield item def iter_modules(path=None, prefix=''): - """Yield submodule names+loaders for path or sys.path""" + """Yields (module_loader, name, ispkg) for all submodules on path, + or, if path is None, all top-level modules on sys.path. + + 'path' should be either None or a list of paths to look for + modules in. + + 'prefix' is a string to output on the front of every module name + on output. + """ + if path is None: importers = iter_importers() else: @@ -341,9 +381,7 @@ importer = None sys.path_importer_cache.setdefault(path_item, importer) - # The boolean values are used for caching valid and invalid - # file paths for the built-in import machinery - if importer in (None, True, False): + if importer is None: try: importer = ImpImporter(path_item) except ImportError: Modified: stackless/trunk/Lib/popen2.py ============================================================================== --- stackless/trunk/Lib/popen2.py (original) +++ stackless/trunk/Lib/popen2.py Mon Aug 14 12:38:35 2006 @@ -72,7 +72,7 @@ # In case the child hasn't been waited on, check if it's done. self.poll(_deadstate=sys.maxint) if self.sts < 0: - if _active: + if _active is not None: # Child is still running, keep us alive until we can wait on it. _active.append(self) Modified: stackless/trunk/Lib/pydoc.py ============================================================================== --- stackless/trunk/Lib/pydoc.py (original) +++ stackless/trunk/Lib/pydoc.py Mon Aug 14 12:38:35 2006 @@ -318,6 +318,8 @@ # identifies something in a way that pydoc itself has issues handling; # think 'super' and how it is a descriptor (which raises the exception # by lacking a __name__ attribute) and an instance. + if inspect.isgetsetdescriptor(object): return self.docdata(*args) + if inspect.ismemberdescriptor(object): return self.docdata(*args) try: if inspect.ismodule(object): return self.docmodule(*args) if inspect.isclass(object): return self.docclass(*args) @@ -333,7 +335,7 @@ name and ' ' + repr(name), type(object).__name__) raise TypeError, message - docmodule = docclass = docroutine = docother = fail + docmodule = docclass = docroutine = docother = docproperty = docdata = fail def getdocloc(self, object): """Return the location of module docs or None""" @@ -915,6 +917,10 @@ lhs = name and '%s = ' % name or '' return lhs + self.repr(object) + def docdata(self, object, name=None, mod=None, cl=None): + """Produce html documentation for a data descriptor.""" + return self._docdescriptor(name, object, mod) + def index(self, dir, shadowed=None): """Generate an HTML index for a directory of modules.""" modpkgs = [] @@ -1268,6 +1274,10 @@ """Produce text documentation for a property.""" return self._docdescriptor(name, object, mod) + def docdata(self, object, name=None, mod=None, cl=None): + """Produce text documentation for a data descriptor.""" + return self._docdescriptor(name, object, mod) + def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None): """Produce text documentation for a data object.""" repr = self.repr(object) @@ -1397,6 +1407,14 @@ return 'module ' + thing.__name__ if inspect.isbuiltin(thing): return 'built-in function ' + thing.__name__ + if inspect.isgetsetdescriptor(thing): + return 'getset descriptor %s.%s.%s' % ( + thing.__objclass__.__module__, thing.__objclass__.__name__, + thing.__name__) + if inspect.ismemberdescriptor(thing): + return 'member descriptor %s.%s.%s' % ( + thing.__objclass__.__module__, thing.__objclass__.__name__, + thing.__name__) if inspect.isclass(thing): return 'class ' + thing.__name__ if inspect.isfunction(thing): @@ -1453,6 +1471,8 @@ if not (inspect.ismodule(object) or inspect.isclass(object) or inspect.isroutine(object) or + inspect.isgetsetdescriptor(object) or + inspect.ismemberdescriptor(object) or isinstance(object, property)): # If the passed object is a piece of data or an instance, # document its available methods instead of its value. Modified: stackless/trunk/Lib/shutil.py ============================================================================== --- stackless/trunk/Lib/shutil.py (original) +++ stackless/trunk/Lib/shutil.py Mon Aug 14 12:38:35 2006 @@ -127,7 +127,13 @@ # continue with other files except Error, err: errors.extend(err.args[0]) - copystat(src, dst) + try: + copystat(src, dst) + except WindowsError: + # can't copy file access times on Windows + pass + except OSError, why: + errors.extend((src, dst, str(why))) if errors: raise Error, errors Modified: stackless/trunk/Lib/socket.py ============================================================================== --- stackless/trunk/Lib/socket.py (original) +++ stackless/trunk/Lib/socket.py Mon Aug 14 12:38:35 2006 @@ -139,6 +139,8 @@ __slots__ = [] def _dummy(*args): raise error(EBADF, 'Bad file descriptor') + def close(self): + pass # All _delegate_methods must also be initialized here. send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy __getattr__ = _dummy @@ -157,6 +159,7 @@ setattr(self, method, getattr(_sock, method)) def close(self): + self._sock.close() self._sock = _closedsocket() dummy = self._sock._dummy for method in _delegate_methods: Modified: stackless/trunk/Lib/struct.py ============================================================================== --- stackless/trunk/Lib/struct.py (original) +++ stackless/trunk/Lib/struct.py Mon Aug 14 12:38:35 2006 @@ -64,7 +64,7 @@ def pack_into(fmt, buf, offset, *args): """ - Pack the values v2, v2, ... according to fmt, write + Pack the values v1, v2, ... according to fmt, write the packed bytes into the writable buffer buf starting at offset. See struct.__doc__ for more on format strings. """ Modified: stackless/trunk/Lib/subprocess.py ============================================================================== --- stackless/trunk/Lib/subprocess.py (original) +++ stackless/trunk/Lib/subprocess.py Mon Aug 14 12:38:35 2006 @@ -121,7 +121,7 @@ Run command with arguments. Wait for command to complete. If the exit code was zero then return, otherwise raise CalledProcessError. The CalledProcessError object will have the - return code in the errno attribute. + return code in the returncode attribute. The arguments are the same as for the Popen constructor. Example: @@ -141,8 +141,8 @@ A ValueError will be raised if Popen is called with invalid arguments. -check_call() will raise CalledProcessError, which is a subclass of -OSError, if the called process returns a non-zero return code. +check_call() will raise CalledProcessError, if the called process +returns a non-zero return code. Security @@ -360,11 +360,16 @@ import traceback # Exception classes used by this module. -class CalledProcessError(OSError): +class CalledProcessError(Exception): """This exception is raised when a process run by check_call() returns a non-zero exit status. The exit status will be stored in the - errno attribute. This exception is a subclass of - OSError.""" + returncode attribute.""" + def __init__(self, returncode, cmd): + self.returncode = returncode + self.cmd = cmd + def __str__(self): + return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) + if mswindows: import threading @@ -442,7 +447,7 @@ """Run command with arguments. Wait for command to complete. If the exit code was zero then return, otherwise raise CalledProcessError. The CalledProcessError object will have the - return code in the errno attribute. + return code in the returncode attribute. The arguments are the same as for the Popen constructor. Example: @@ -453,7 +458,7 @@ if cmd is None: cmd = popenargs[0] if retcode: - raise CalledProcessError(retcode, "Command %s returned non-zero exit status" % cmd) + raise CalledProcessError(retcode, cmd) return retcode @@ -613,7 +618,7 @@ return # In case the child hasn't been waited on, check if it's done. self.poll(_deadstate=sys.maxint) - if self.returncode is None: + if self.returncode is None and _active is not None: # Child is still running, keep us alive until we can wait on it. _active.append(self) Modified: stackless/trunk/Lib/tarfile.py ============================================================================== --- stackless/trunk/Lib/tarfile.py (original) +++ stackless/trunk/Lib/tarfile.py Mon Aug 14 12:38:35 2006 @@ -417,7 +417,13 @@ self.fileobj.write(self.buf) self.buf = "" if self.comptype == "gz": - self.fileobj.write(struct.pack("', 'exec') + self.assert_('__doc__' in c.co_names) + c = compiler.compile('def f():\n "doc"', '', 'exec') + g = {} + exec c in g + self.assertEquals(g['f'].__doc__, "doc") + def testLineNo(self): # Test that all nodes except Module have a correct lineno attribute. filename = __file__ Modified: stackless/trunk/Lib/test/test_defaultdict.py ============================================================================== --- stackless/trunk/Lib/test/test_defaultdict.py (original) +++ stackless/trunk/Lib/test/test_defaultdict.py Mon Aug 14 12:38:35 2006 @@ -4,6 +4,7 @@ import copy import tempfile import unittest +from test import test_support from collections import defaultdict @@ -131,5 +132,8 @@ self.assertEqual(d2, d1) +def test_main(): + test_support.run_unittest(TestDefaultDict) + if __name__ == "__main__": - unittest.main() + test_main() Modified: stackless/trunk/Lib/test/test_dis.py ============================================================================== --- stackless/trunk/Lib/test/test_dis.py (original) +++ stackless/trunk/Lib/test/test_dis.py Mon Aug 14 12:38:35 2006 @@ -81,6 +81,13 @@ bug1333982.func_code.co_firstlineno + 2, bug1333982.func_code.co_firstlineno + 3) +_BIG_LINENO_FORMAT = """\ +%3d 0 LOAD_GLOBAL 0 (spam) + 3 POP_TOP + 4 LOAD_CONST 0 (None) + 7 RETURN_VALUE +""" + class DisTests(unittest.TestCase): def do_disassembly_test(self, func, expected): s = StringIO.StringIO() @@ -124,6 +131,23 @@ if __debug__: self.do_disassembly_test(bug1333982, dis_bug1333982) + def test_big_linenos(self): + def func(count): + namespace = {} + func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"]) + exec func in namespace + return namespace['foo'] + + # Test all small ranges + for i in xrange(1, 300): + expected = _BIG_LINENO_FORMAT % (i + 2) + self.do_disassembly_test(func(i), expected) + + # Test some larger ranges too + for i in xrange(300, 5000, 10): + expected = _BIG_LINENO_FORMAT % (i + 2) + self.do_disassembly_test(func(i), expected) + def test_main(): run_unittest(DisTests) Modified: stackless/trunk/Lib/test/test_doctest.py ============================================================================== --- stackless/trunk/Lib/test/test_doctest.py (original) +++ stackless/trunk/Lib/test/test_doctest.py Mon Aug 14 12:38:35 2006 @@ -419,7 +419,6 @@ >>> finder = doctest.DocTestFinder() >>> tests = finder.find(SampleClass) - >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 3 SampleClass @@ -435,7 +434,6 @@ New-style classes are also supported: >>> tests = finder.find(SampleNewStyleClass) - >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 1 SampleNewStyleClass @@ -475,7 +473,6 @@ >>> # ignoring the objects since they weren't defined in m. >>> import test.test_doctest >>> tests = finder.find(m, module=test.test_doctest) - >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 1 some_module @@ -499,7 +496,6 @@ >>> from test import doctest_aliases >>> tests = excl_empty_finder.find(doctest_aliases) - >>> tests.sort() >>> print len(tests) 2 >>> print tests[0].name @@ -517,7 +513,6 @@ By default, an object with no doctests doesn't create any tests: >>> tests = doctest.DocTestFinder().find(SampleClass) - >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 3 SampleClass @@ -536,7 +531,6 @@ displays. >>> tests = doctest.DocTestFinder(exclude_empty=False).find(SampleClass) - >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 3 SampleClass @@ -557,7 +551,6 @@ using the `recurse` flag: >>> tests = doctest.DocTestFinder(recurse=False).find(SampleClass) - >>> tests.sort() >>> for t in tests: ... print '%2s %s' % (len(t.examples), t.name) 3 SampleClass Modified: stackless/trunk/Lib/test/test_email_codecs.py ============================================================================== --- stackless/trunk/Lib/test/test_email_codecs.py (original) +++ stackless/trunk/Lib/test/test_email_codecs.py Mon Aug 14 12:38:35 2006 @@ -1,11 +1,15 @@ # Copyright (C) 2002 Python Software Foundation # email package unit tests for (optional) Asian codecs -import unittest # The specific tests now live in Lib/email/test -from email.test.test_email_codecs import suite +from email.test import test_email_codecs +from email.test import test_email_codecs_renamed +from test import test_support +def test_main(): + suite = test_email_codecs.suite() + suite.addTest(test_email_codecs_renamed.suite()) + test_support.run_suite(suite) - if __name__ == '__main__': - unittest.main(defaultTest='suite') + test_main() Modified: stackless/trunk/Lib/test/test_filecmp.py ============================================================================== --- stackless/trunk/Lib/test/test_filecmp.py (original) +++ stackless/trunk/Lib/test/test_filecmp.py Mon Aug 14 12:38:35 2006 @@ -1,5 +1,5 @@ -import os, filecmp, shutil, tempfile +import os, filecmp, shutil, tempfile, shutil import unittest from test import test_support @@ -49,6 +49,7 @@ self.caseinsensitive = os.path.normcase('A') == os.path.normcase('a') data = 'Contents of file go here.\n' for dir in [self.dir, self.dir_same, self.dir_diff]: + shutil.rmtree(dir, True) os.mkdir(dir) if self.caseinsensitive and dir is self.dir_same: fn = 'FiLe' # Verify case-insensitive comparison Modified: stackless/trunk/Lib/test/test_generators.py ============================================================================== --- stackless/trunk/Lib/test/test_generators.py (original) +++ stackless/trunk/Lib/test/test_generators.py Mon Aug 14 12:38:35 2006 @@ -1497,22 +1497,55 @@ +A yield expression with augmented assignment. + +>>> def coroutine(seq): +... count = 0 +... while count < 200: +... count += yield +... seq.append(count) +>>> seq = [] +>>> c = coroutine(seq) +>>> c.next() +>>> print seq +[] +>>> c.send(10) +>>> print seq +[10] +>>> c.send(10) +>>> print seq +[10, 20] +>>> c.send(10) +>>> print seq +[10, 20, 30] + + Check some syntax errors for yield expressions: >>> f=lambda: (yield 1),(yield 2) Traceback (most recent call last): ... -SyntaxError: 'yield' outside function (, line 1) +SyntaxError: 'yield' outside function (, line 1) >>> def f(): return lambda x=(yield): 1 Traceback (most recent call last): ... -SyntaxError: 'return' with argument inside generator (, line 1) +SyntaxError: 'return' with argument inside generator (, line 1) >>> def f(): x = yield = y Traceback (most recent call last): ... -SyntaxError: assignment to yield expression not possible (, line 1) +SyntaxError: assignment to yield expression not possible (, line 1) + +>>> def f(): (yield bar) = y +Traceback (most recent call last): + ... +SyntaxError: can't assign to yield expression (, line 1) + +>>> def f(): (yield bar) += y +Traceback (most recent call last): + ... +SyntaxError: augmented assignment to yield expression not possible (, line 1) Now check some throw() conditions: Modified: stackless/trunk/Lib/test/test_getargs2.py ============================================================================== --- stackless/trunk/Lib/test/test_getargs2.py (original) +++ stackless/trunk/Lib/test/test_getargs2.py Mon Aug 14 12:38:35 2006 @@ -233,8 +233,25 @@ self.failUnlessEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE)) + +class Tuple_TestCase(unittest.TestCase): + def test_tuple(self): + from _testcapi import getargs_tuple + + ret = getargs_tuple(1, (2, 3)) + self.assertEquals(ret, (1,2,3)) + + # make sure invalid tuple arguments are handled correctly + class seq: + def __len__(self): + return 2 + def __getitem__(self, n): + raise ValueError + self.assertRaises(TypeError, getargs_tuple, 1, seq()) + + def test_main(): - tests = [Signed_TestCase, Unsigned_TestCase] + tests = [Signed_TestCase, Unsigned_TestCase, Tuple_TestCase] try: from _testcapi import getargs_L, getargs_K except ImportError: Modified: stackless/trunk/Lib/test/test_grammar.py ============================================================================== --- stackless/trunk/Lib/test/test_grammar.py (original) +++ stackless/trunk/Lib/test/test_grammar.py Mon Aug 14 12:38:35 2006 @@ -531,6 +531,11 @@ for x in Squares(10): n = n+x if n != 285: raise TestFailed, 'for over growing sequence' +result = [] +for x, in [(1,), (2,), (3,)]: + result.append(x) +vereq(result, [1, 2, 3]) + print 'try_stmt' ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ### | 'try' ':' suite 'finally' ':' suite Modified: stackless/trunk/Lib/test/test_inspect.py ============================================================================== --- stackless/trunk/Lib/test/test_inspect.py (original) +++ stackless/trunk/Lib/test/test_inspect.py Mon Aug 14 12:38:35 2006 @@ -1,6 +1,8 @@ import sys +import types import unittest import inspect +import datetime from test.test_support import TESTFN, run_unittest @@ -40,10 +42,12 @@ self.failIf(other(obj), 'not %s(%s)' % (other.__name__, exp)) class TestPredicates(IsTestBase): - def test_eleven(self): - # Doc/lib/libinspect.tex claims there are 11 such functions + def test_thirteen(self): count = len(filter(lambda x:x.startswith('is'), dir(inspect))) - self.assertEqual(count, 11, "There are %d (not 11) is* functions" % count) + # Doc/lib/libinspect.tex claims there are 13 such functions + expected = 13 + err_msg = "There are %d (not %d) is* functions" % (count, expected) + self.assertEqual(count, expected, err_msg) def test_excluding_predicates(self): self.istest(inspect.isbuiltin, 'sys.exit') @@ -58,6 +62,15 @@ self.istest(inspect.istraceback, 'tb') self.istest(inspect.isdatadescriptor, '__builtin__.file.closed') self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace') + if hasattr(types, 'GetSetDescriptorType'): + self.istest(inspect.isgetsetdescriptor, + 'type(tb.tb_frame).f_locals') + else: + self.failIf(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals)) + if hasattr(types, 'MemberDescriptorType'): + self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') + else: + self.failIf(inspect.ismemberdescriptor(datetime.timedelta.days)) def test_isroutine(self): self.assert_(inspect.isroutine(mod.spam)) @@ -187,6 +200,7 @@ exec "def x(): pass" in m.__dict__ self.assertEqual(inspect.getsourcefile(m.x.func_code), '') del sys.modules[name] + inspect.getmodule(compile('a=10','','single')) class TestDecorators(GetSourceBase): fodderFile = mod2 Modified: stackless/trunk/Lib/test/test_iterlen.py ============================================================================== --- stackless/trunk/Lib/test/test_iterlen.py (original) +++ stackless/trunk/Lib/test/test_iterlen.py Mon Aug 14 12:38:35 2006 @@ -235,9 +235,7 @@ self.assertEqual(len(it), 0) - -if __name__ == "__main__": - +def test_main(): unittests = [ TestRepeat, TestXrange, @@ -255,3 +253,6 @@ TestSeqIterReversed, ] test_support.run_unittest(*unittests) + +if __name__ == "__main__": + test_main() Modified: stackless/trunk/Lib/test/test_mailbox.py ============================================================================== --- stackless/trunk/Lib/test/test_mailbox.py (original) +++ stackless/trunk/Lib/test/test_mailbox.py Mon Aug 14 12:38:35 2006 @@ -461,7 +461,7 @@ def setUp(self): TestMailbox.setUp(self) - if os.name == 'nt': + if os.name in ('nt', 'os2'): self._box.colon = '!' def test_add_MM(self): @@ -520,7 +520,7 @@ # Initialize an existing mailbox self.tearDown() for subdir in '', 'tmp', 'new', 'cur': - os.mkdir(os.path.join(self._path, subdir)) + os.mkdir(os.path.normpath(os.path.join(self._path, subdir))) self._box = mailbox.Maildir(self._path) self._check_basics(factory=rfc822.Message) self._box = mailbox.Maildir(self._path, factory=None) Modified: stackless/trunk/Lib/test/test_mimetools.py ============================================================================== --- stackless/trunk/Lib/test/test_mimetools.py (original) +++ stackless/trunk/Lib/test/test_mimetools.py Mon Aug 14 12:38:35 2006 @@ -1,7 +1,7 @@ import unittest from test import test_support -import string, StringIO, mimetools, sets +import string, StringIO, mimetools msgtext1 = mimetools.Message(StringIO.StringIO( """Content-Type: text/plain; charset=iso-8859-1; format=flowed @@ -25,7 +25,7 @@ self.assertEqual(o.getvalue(), start) def test_boundary(self): - s = sets.Set([""]) + s = set([""]) for i in xrange(100): nb = mimetools.choose_boundary() self.assert_(nb not in s) Modified: stackless/trunk/Lib/test/test_mimetypes.py ============================================================================== --- stackless/trunk/Lib/test/test_mimetypes.py (original) +++ stackless/trunk/Lib/test/test_mimetypes.py Mon Aug 14 12:38:35 2006 @@ -1,7 +1,6 @@ import mimetypes import StringIO import unittest -from sets import Set from test import test_support @@ -52,8 +51,8 @@ # First try strict. Use a set here for testing the results because if # test_urllib2 is run before test_mimetypes, global state is modified # such that the 'all' set will have more items in it. - all = Set(self.db.guess_all_extensions('text/plain', strict=True)) - unless(all >= Set(['.bat', '.c', '.h', '.ksh', '.pl', '.txt'])) + all = set(self.db.guess_all_extensions('text/plain', strict=True)) + unless(all >= set(['.bat', '.c', '.h', '.ksh', '.pl', '.txt'])) # And now non-strict all = self.db.guess_all_extensions('image/jpg', strict=False) all.sort() Modified: stackless/trunk/Lib/test/test_minidom.py ============================================================================== --- stackless/trunk/Lib/test/test_minidom.py (original) +++ stackless/trunk/Lib/test/test_minidom.py Mon Aug 14 12:38:35 2006 @@ -1,4 +1,4 @@ -# test for xmlcore.dom.minidom +# test for xml.dom.minidom import os import sys @@ -7,12 +7,12 @@ from StringIO import StringIO from test.test_support import verbose -import xmlcore.dom -import xmlcore.dom.minidom -import xmlcore.parsers.expat +import xml.dom +import xml.dom.minidom +import xml.parsers.expat -from xmlcore.dom.minidom import parse, Node, Document, parseString -from xmlcore.dom.minidom import getDOMImplementation +from xml.dom.minidom import parse, Node, Document, parseString +from xml.dom.minidom import getDOMImplementation if __name__ == "__main__": @@ -138,29 +138,29 @@ text = dom.createTextNode('text') try: dom.appendChild(text) - except xmlcore.dom.HierarchyRequestErr: pass + except xml.dom.HierarchyRequestErr: pass else: print "dom.appendChild didn't raise HierarchyRequestErr" dom.appendChild(elem) try: dom.insertBefore(text, elem) - except xmlcore.dom.HierarchyRequestErr: pass + except xml.dom.HierarchyRequestErr: pass else: print "dom.appendChild didn't raise HierarchyRequestErr" try: dom.replaceChild(text, elem) - except xmlcore.dom.HierarchyRequestErr: pass + except xml.dom.HierarchyRequestErr: pass else: print "dom.appendChild didn't raise HierarchyRequestErr" nodemap = elem.attributes try: nodemap.setNamedItem(text) - except xmlcore.dom.HierarchyRequestErr: pass + except xml.dom.HierarchyRequestErr: pass else: print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr" try: nodemap.setNamedItemNS(text) - except xmlcore.dom.HierarchyRequestErr: pass + except xml.dom.HierarchyRequestErr: pass else: print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr" @@ -439,7 +439,7 @@ and pi.firstChild is None and pi.lastChild is None and pi.localName is None - and pi.namespaceURI == xmlcore.dom.EMPTY_NAMESPACE) + and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE) def testProcessingInstructionRepr(): pass @@ -454,7 +454,7 @@ elem = doc.createElement("extra") try: doc.appendChild(elem) - except xmlcore.dom.HierarchyRequestErr: + except xml.dom.HierarchyRequestErr: pass else: print "Failed to catch expected exception when" \ @@ -491,7 +491,7 @@ confirm(a1.isSameNode(a2)) try: attrs.removeNamedItem("a") - except xmlcore.dom.NotFoundErr: + except xml.dom.NotFoundErr: pass def testRemoveNamedItemNS(): @@ -503,7 +503,7 @@ confirm(a1.isSameNode(a2)) try: attrs.removeNamedItemNS("http://xml.python.org/", "b") - except xmlcore.dom.NotFoundErr: + except xml.dom.NotFoundErr: pass def testAttrListValues(): pass @@ -682,7 +682,7 @@ doc2 = parseString("") try: doc1.importNode(doc2, deep) - except xmlcore.dom.NotSupportedErr: + except xml.dom.NotSupportedErr: pass else: raise Exception(testName + @@ -705,14 +705,12 @@ doctype = getDOMImplementation().createDocumentType("doc", None, None) doctype.entities._seq = [] doctype.notations._seq = [] - notation = xmlcore.dom.minidom.Notation( - "my-notation", None, - "http://xml.python.org/notations/my") + notation = xml.dom.minidom.Notation("my-notation", None, + "http://xml.python.org/notations/my") doctype.notations._seq.append(notation) - entity = xmlcore.dom.minidom.Entity( - "my-entity", None, - "http://xml.python.org/entities/my", - "my-notation") + entity = xml.dom.minidom.Entity("my-entity", None, + "http://xml.python.org/entities/my", + "my-notation") entity.version = "1.0" entity.encoding = "utf-8" entity.actualEncoding = "us-ascii" @@ -731,7 +729,7 @@ target = create_doc_without_doctype() try: imported = target.importNode(src.doctype, 0) - except xmlcore.dom.NotSupportedErr: + except xml.dom.NotSupportedErr: pass else: raise Exception( @@ -742,7 +740,7 @@ target = create_doc_without_doctype() try: imported = target.importNode(src.doctype, 1) - except xmlcore.dom.NotSupportedErr: + except xml.dom.NotSupportedErr: pass else: raise Exception( @@ -850,7 +848,7 @@ doc.unlink() def testSAX2DOM(): - from xmlcore.dom import pulldom + from xml.dom import pulldom sax2dom = pulldom.SAX2DOM() sax2dom.startDocument() @@ -940,11 +938,11 @@ attr = elem.attributes['a'] # Simple renaming - attr = doc.renameNode(attr, xmlcore.dom.EMPTY_NAMESPACE, "b") + attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b") confirm(attr.name == "b" and attr.nodeName == "b" and attr.localName is None - and attr.namespaceURI == xmlcore.dom.EMPTY_NAMESPACE + and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE and attr.prefix is None and attr.value == "v" and elem.getAttributeNode("a") is None @@ -989,11 +987,11 @@ and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr)) # Rename back to a simple non-NS node - attr = doc.renameNode(attr, xmlcore.dom.EMPTY_NAMESPACE, "e") + attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e") confirm(attr.name == "e" and attr.nodeName == "e" and attr.localName is None - and attr.namespaceURI == xmlcore.dom.EMPTY_NAMESPACE + and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE and attr.prefix is None and attr.value == "v" and elem.getAttributeNode("a") is None @@ -1007,7 +1005,7 @@ try: doc.renameNode(attr, "http://xml.python.org/ns", "xmlns") - except xmlcore.dom.NamespaceErr: + except xml.dom.NamespaceErr: pass else: print "expected NamespaceErr" @@ -1020,11 +1018,11 @@ elem = doc.documentElement # Simple renaming - elem = doc.renameNode(elem, xmlcore.dom.EMPTY_NAMESPACE, "a") + elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a") confirm(elem.tagName == "a" and elem.nodeName == "a" and elem.localName is None - and elem.namespaceURI == xmlcore.dom.EMPTY_NAMESPACE + and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE and elem.prefix is None and elem.ownerDocument.isSameNode(doc)) @@ -1047,11 +1045,11 @@ and elem.ownerDocument.isSameNode(doc)) # Rename back to a simple non-NS node - elem = doc.renameNode(elem, xmlcore.dom.EMPTY_NAMESPACE, "d") + elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d") confirm(elem.tagName == "d" and elem.nodeName == "d" and elem.localName is None - and elem.namespaceURI == xmlcore.dom.EMPTY_NAMESPACE + and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE and elem.prefix is None and elem.ownerDocument.isSameNode(doc)) @@ -1062,15 +1060,15 @@ # Make sure illegal NS usage is detected: try: doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo") - except xmlcore.dom.NamespaceErr: + except xml.dom.NamespaceErr: pass else: print "expected NamespaceErr" doc2 = parseString("") try: - doc2.renameNode(node, xmlcore.dom.EMPTY_NAMESPACE, "foo") - except xmlcore.dom.WrongDocumentErr: + doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo") + except xml.dom.WrongDocumentErr: pass else: print "expected WrongDocumentErr" @@ -1078,12 +1076,12 @@ def testRenameOther(): # We have to create a comment node explicitly since not all DOM # builders used with minidom add comments to the DOM. - doc = xmlcore.dom.minidom.getDOMImplementation().createDocument( - xmlcore.dom.EMPTY_NAMESPACE, "e", None) + doc = xml.dom.minidom.getDOMImplementation().createDocument( + xml.dom.EMPTY_NAMESPACE, "e", None) node = doc.createComment("comment") try: - doc.renameNode(node, xmlcore.dom.EMPTY_NAMESPACE, "foo") - except xmlcore.dom.NotSupportedErr: + doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo") + except xml.dom.NotSupportedErr: pass else: print "expected NotSupportedErr when renaming comment node" @@ -1194,13 +1192,13 @@ # since each supports a different level of DTD information. t = elem.schemaType confirm(t.name is None - and t.namespace == xmlcore.dom.EMPTY_NAMESPACE) + and t.namespace == xml.dom.EMPTY_NAMESPACE) names = "id notid text enum ref refs ent ents nm nms".split() for name in names: a = elem.getAttributeNode(name) t = a.schemaType confirm(hasattr(t, "name") - and t.namespace == xmlcore.dom.EMPTY_NAMESPACE) + and t.namespace == xml.dom.EMPTY_NAMESPACE) def testSetIdAttribute(): doc = parseString("") @@ -1229,7 +1227,7 @@ and a2.isId and not a3.isId) # renaming an attribute should not affect its ID-ness: - doc.renameNode(a2, xmlcore.dom.EMPTY_NAMESPACE, "an") + doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) @@ -1265,7 +1263,7 @@ confirm(not a3.isId) confirm(doc.getElementById("v") is None) # renaming an attribute should not affect its ID-ness: - doc.renameNode(a2, xmlcore.dom.EMPTY_NAMESPACE, "an") + doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) @@ -1301,7 +1299,7 @@ confirm(not a3.isId) confirm(doc.getElementById("v") is None) # renaming an attribute should not affect its ID-ness: - doc.renameNode(a2, xmlcore.dom.EMPTY_NAMESPACE, "an") + doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) Modified: stackless/trunk/Lib/test/test_optparse.py ============================================================================== --- stackless/trunk/Lib/test/test_optparse.py (original) +++ stackless/trunk/Lib/test/test_optparse.py Mon Aug 14 12:38:35 2006 @@ -1460,10 +1460,11 @@ make_option("--foo", action="append", type="string", dest='foo', help="store FOO in the foo list for later fooing"), ] - # The parser constructor looks at the COLUMNS envar. We need to - # restore the original value after the parser is constructed, else - # that's a permanent change possibly affecting other tests, and - # definitely affecting these tests when they're run multiple times. + + # We need to set COLUMNS for the OptionParser constructor, but + # we must restore its original value -- otherwise, this test + # screws things up for other tests when it's part of the Python + # test suite. orig_columns = os.environ.get('COLUMNS') os.environ['COLUMNS'] = str(columns) try: Modified: stackless/trunk/Lib/test/test_ossaudiodev.py ============================================================================== --- stackless/trunk/Lib/test/test_ossaudiodev.py (original) +++ stackless/trunk/Lib/test/test_ossaudiodev.py Mon Aug 14 12:38:35 2006 @@ -40,6 +40,10 @@ data = audioop.ulaw2lin(data, 2) return (data, rate, 16, nchannels) +# version of assert that still works with -O +def _assert(expr, message=None): + if not expr: + raise AssertionError(message or "assertion failed") def play_sound_file(data, rate, ssize, nchannels): try: @@ -57,9 +61,9 @@ dsp.fileno() # Make sure the read-only attributes work. - assert dsp.closed is False, "dsp.closed is not False" - assert dsp.name == "/dev/dsp" - assert dsp.mode == 'w', "bad dsp.mode: %r" % dsp.mode + _assert(dsp.closed is False, "dsp.closed is not False") + _assert(dsp.name == "/dev/dsp") + _assert(dsp.mode == 'w', "bad dsp.mode: %r" % dsp.mode) # And make sure they're really read-only. for attr in ('closed', 'name', 'mode'): @@ -69,14 +73,23 @@ except TypeError: pass + # Compute expected running time of sound sample (in seconds). + expected_time = float(len(data)) / (ssize/8) / nchannels / rate + # set parameters based on .au file headers dsp.setparameters(AFMT_S16_NE, nchannels, rate) + print ("playing test sound file (expected running time: %.2f sec)" + % expected_time) t1 = time.time() - print "playing test sound file..." dsp.write(data) dsp.close() t2 = time.time() - print "elapsed time: %.1f sec" % (t2-t1) + elapsed_time = t2 - t1 + + percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100 + _assert(percent_diff <= 10.0, \ + ("elapsed time (%.2f sec) > 10%% off of expected time (%.2f sec)" + % (elapsed_time, expected_time))) def test_setparameters(dsp): # Two configurations for testing: @@ -101,11 +114,11 @@ # setparameters() should be able to set this configuration in # either strict or non-strict mode. result = dsp.setparameters(fmt, channels, rate, False) - assert result == (fmt, channels, rate), \ - "setparameters%r: returned %r" % (config + result) + _assert(result == (fmt, channels, rate), + "setparameters%r: returned %r" % (config, result)) result = dsp.setparameters(fmt, channels, rate, True) - assert result == (fmt, channels, rate), \ - "setparameters%r: returned %r" % (config + result) + _assert(result == (fmt, channels, rate), + "setparameters%r: returned %r" % (config, result)) def test_bad_setparameters(dsp): @@ -123,8 +136,8 @@ ]: (fmt, channels, rate) = config result = dsp.setparameters(fmt, channels, rate, False) - assert result != config, \ - "setparameters: unexpectedly got requested configuration" + _assert(result != config, + "setparameters: unexpectedly got requested configuration") try: result = dsp.setparameters(fmt, channels, rate, True) @@ -145,6 +158,6 @@ #test_bad_setparameters(dsp) finally: dsp.close() - assert dsp.closed is True, "dsp.closed is not True" + _assert(dsp.closed is True, "dsp.closed is not True") test() Modified: stackless/trunk/Lib/test/test_sax.py ============================================================================== --- stackless/trunk/Lib/test/test_sax.py (original) +++ stackless/trunk/Lib/test/test_sax.py Mon Aug 14 12:38:35 2006 @@ -1,17 +1,17 @@ # regression test for SAX 2.0 -*- coding: iso-8859-1 -*- # $Id$ -from xmlcore.sax import make_parser, ContentHandler, \ - SAXException, SAXReaderNotAvailable, SAXParseException +from xml.sax import make_parser, ContentHandler, \ + SAXException, SAXReaderNotAvailable, SAXParseException try: make_parser() except SAXReaderNotAvailable: # don't try to test this module if we cannot create a parser raise ImportError("no XML parsers available") -from xmlcore.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ - XMLFilterBase -from xmlcore.sax.expatreader import create_parser -from xmlcore.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl +from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ + XMLFilterBase +from xml.sax.expatreader import create_parser +from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl from cStringIO import StringIO from test.test_support import verify, verbose, TestFailed, findfile import os @@ -36,17 +36,17 @@ # Creating parsers several times in a row should succeed. # Testing this because there have been failures of this kind # before. - from xmlcore.sax import make_parser + from xml.sax import make_parser p = make_parser() - from xmlcore.sax import make_parser + from xml.sax import make_parser p = make_parser() - from xmlcore.sax import make_parser + from xml.sax import make_parser p = make_parser() - from xmlcore.sax import make_parser + from xml.sax import make_parser p = make_parser() - from xmlcore.sax import make_parser + from xml.sax import make_parser p = make_parser() - from xmlcore.sax import make_parser + from xml.sax import make_parser p = make_parser() except: return 0 @@ -108,7 +108,7 @@ try: # Creating a parser should succeed - it should fall back # to the expatreader - p = make_parser(['xmlcore.parsers.no_such_parser']) + p = make_parser(['xml.parsers.no_such_parser']) except: return 0 else: @@ -671,6 +671,55 @@ attrs.getQNameByName((ns_uri, "attr")) == "ns:attr" +# During the development of Python 2.5, an attempt to move the "xml" +# package implementation to a new package ("xmlcore") proved painful. +# The goal of this change was to allow applications to be able to +# obtain and rely on behavior in the standard library implementation +# of the XML support without needing to be concerned about the +# availability of the PyXML implementation. +# +# While the existing import hackery in Lib/xml/__init__.py can cause +# PyXML's _xmlpus package to supplant the "xml" package, that only +# works because either implementation uses the "xml" package name for +# imports. +# +# The move resulted in a number of problems related to the fact that +# the import machinery's "package context" is based on the name that's +# being imported rather than the __name__ of the actual package +# containment; it wasn't possible for the "xml" package to be replaced +# by a simple module that indirected imports to the "xmlcore" package. +# +# The following two tests exercised bugs that were introduced in that +# attempt. Keeping these tests around will help detect problems with +# other attempts to provide reliable access to the standard library's +# implementation of the XML support. + +def test_sf_1511497(): + # Bug report: http://www.python.org/sf/1511497 + import sys + old_modules = sys.modules.copy() + for modname in sys.modules.keys(): + if modname.startswith("xml."): + del sys.modules[modname] + try: + import xml.sax.expatreader + module = xml.sax.expatreader + return module.__name__ == "xml.sax.expatreader" + finally: + sys.modules.update(old_modules) + +def test_sf_1513611(): + # Bug report: http://www.python.org/sf/1513611 + sio = StringIO("invalid") + parser = make_parser() + from xml.sax import SAXParseException + try: + parser.parse(sio) + except SAXParseException: + return True + else: + return False + # ===== Main program def make_test_output(): Modified: stackless/trunk/Lib/test/test_shutil.py ============================================================================== --- stackless/trunk/Lib/test/test_shutil.py (original) +++ stackless/trunk/Lib/test/test_shutil.py Mon Aug 14 12:38:35 2006 @@ -74,6 +74,33 @@ except: pass + + def test_copytree_simple(self): + src_dir = tempfile.mkdtemp() + dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') + open(os.path.join(src_dir, 'test.txt'), 'w').write('123') + os.mkdir(os.path.join(src_dir, 'test_dir')) + open(os.path.join(src_dir, 'test_dir', 'test.txt'), 'w').write('456') + # + try: + shutil.copytree(src_dir, dst_dir) + self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt'))) + self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir'))) + self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir', 'test.txt'))) + self.assertEqual(open(os.path.join(dst_dir, 'test.txt')).read(), '123') + self.assertEqual(open(os.path.join(dst_dir, 'test_dir', 'test.txt')).read(), '456') + finally: + try: + os.remove(os.path.join(src_dir, 'test.txt')) + os.remove(os.path.join(dst_dir, 'test.txt')) + os.remove(os.path.join(src_dir, 'test_dir', 'test.txt')) + os.remove(os.path.join(dst_dir, 'test_dir', 'test.txt')) + os.removedirs(src_dir) + os.removedirs(dst_dir) + except: + pass + + if hasattr(os, "symlink"): def test_dont_copy_file_onto_link_to_itself(self): # bug 851123. Modified: stackless/trunk/Lib/test/test_signal.py ============================================================================== --- stackless/trunk/Lib/test/test_signal.py (original) +++ stackless/trunk/Lib/test/test_signal.py Mon Aug 14 12:38:35 2006 @@ -25,7 +25,11 @@ ) & """ % vars() +a_called = b_called = False + def handlerA(*args): + global a_called + a_called = True if verbose: print "handlerA", args @@ -33,11 +37,14 @@ pass def handlerB(*args): + global b_called + b_called = True if verbose: print "handlerB", args raise HandlerBCalled, args -signal.alarm(20) # Entire test lasts at most 20 sec. +MAX_DURATION = 20 +signal.alarm(MAX_DURATION) # Entire test should last at most 20 sec. hup = signal.signal(signal.SIGHUP, handlerA) usr1 = signal.signal(signal.SIGUSR1, handlerB) usr2 = signal.signal(signal.SIGUSR2, signal.SIG_IGN) @@ -65,9 +72,35 @@ except TypeError: pass +# Set up a child to send an alarm signal to us (the parent) after waiting +# long enough to receive the alarm. It seems we miss the alarm for some +# reason. This will hopefully stop the hangs on Tru64/Alpha. +def force_test_exit(): + # Sigh, both imports seem necessary to avoid errors. + import os + fork_pid = os.fork() + if fork_pid == 0: + # In child + import os, time + try: + # Wait 5 seconds longer than the expected alarm to give enough + # time for the normal sequence of events to occur. This is + # just a stop-gap to prevent the test from hanging. + time.sleep(MAX_DURATION + 5) + print >> sys.__stdout__, ' child should not have to kill parent' + for i in range(3): + os.kill(pid, signal.SIGALARM) + finally: + os._exit(0) + # In parent (or error) + return fork_pid + try: os.system(script) + # Try to ensure this test exits even if there is some problem with alarm. + # Tru64/Alpha sometimes hangs and is ultimately killed by the buildbot. + fork_pid = force_test_exit() print "starting pause() loop..." try: @@ -88,6 +121,22 @@ if verbose: print "KeyboardInterrupt (assume the alarm() went off)" + # Forcibly kill the child we created to ping us if there was a test error. + try: + # Make sure we don't kill ourself if there was a fork error. + if fork_pid > 0: + os.kill(fork_pid, signal.SIGKILL) + except: + # If the child killed us, it has probably exited. Killing a + # non-existant process will raise an error which we don't care about. + pass + + if not a_called: + print 'HandlerA not called' + + if not b_called: + print 'HandlerB not called' + finally: signal.signal(signal.SIGHUP, hup) signal.signal(signal.SIGUSR1, usr1) Modified: stackless/trunk/Lib/test/test_socket.py ============================================================================== --- stackless/trunk/Lib/test/test_socket.py (original) +++ stackless/trunk/Lib/test/test_socket.py Mon Aug 14 12:38:35 2006 @@ -11,6 +11,7 @@ import sys import array from weakref import proxy +import signal PORT = 50007 HOST = 'localhost' @@ -817,6 +818,37 @@ if not ok: self.fail("accept() returned success when we did not expect it") + def testInterruptedTimeout(self): + # XXX I don't know how to do this test on MSWindows or any other + # plaform that doesn't support signal.alarm() or os.kill(), though + # the bug should have existed on all platforms. + if not hasattr(signal, "alarm"): + return # can only test on *nix + self.serv.settimeout(5.0) # must be longer than alarm + class Alarm(Exception): + pass + def alarm_handler(signal, frame): + raise Alarm + old_alarm = signal.signal(signal.SIGALRM, alarm_handler) + try: + signal.alarm(2) # POSIX allows alarm to be up to 1 second early + try: + foo = self.serv.accept() + except socket.timeout: + self.fail("caught timeout instead of Alarm") + except Alarm: + pass + except: + self.fail("caught other exception instead of Alarm") + else: + self.fail("nothing caught") + signal.alarm(0) # shut off alarm + except Alarm: + self.fail("got Alarm in wrong place") + finally: + # no alarm can be pending. Safe to restore old handler. + signal.signal(signal.SIGALRM, old_alarm) + class UDPTimeoutTest(SocketTCPTest): def testUDPTimeout(self): Modified: stackless/trunk/Lib/test/test_subprocess.py ============================================================================== --- stackless/trunk/Lib/test/test_subprocess.py (original) +++ stackless/trunk/Lib/test/test_subprocess.py Mon Aug 14 12:38:35 2006 @@ -68,7 +68,7 @@ subprocess.check_call([sys.executable, "-c", "import sys; sys.exit(47)"]) except subprocess.CalledProcessError, e: - self.assertEqual(e.errno, 47) + self.assertEqual(e.returncode, 47) else: self.fail("Expected CalledProcessError") @@ -476,10 +476,36 @@ else: self.fail("Expected OSError") + def _suppress_core_files(self): + """Try to prevent core files from being created. + Returns previous ulimit if successful, else None. + """ + try: + import resource + old_limit = resource.getrlimit(resource.RLIMIT_CORE) + resource.setrlimit(resource.RLIMIT_CORE, (0,0)) + return old_limit + except (ImportError, ValueError, resource.error): + return None + + def _unsuppress_core_files(self, old_limit): + """Return core file behavior to default.""" + if old_limit is None: + return + try: + import resource + resource.setrlimit(resource.RLIMIT_CORE, old_limit) + except (ImportError, ValueError, resource.error): + return + def test_run_abort(self): # returncode handles signal termination - p = subprocess.Popen([sys.executable, - "-c", "import os; os.abort()"]) + old_limit = self._suppress_core_files() + try: + p = subprocess.Popen([sys.executable, + "-c", "import os; os.abort()"]) + finally: + self._unsuppress_core_files(old_limit) p.wait() self.assertEqual(-p.returncode, signal.SIGABRT) Modified: stackless/trunk/Lib/test/test_sys.py ============================================================================== --- stackless/trunk/Lib/test/test_sys.py (original) +++ stackless/trunk/Lib/test/test_sys.py Mon Aug 14 12:38:35 2006 @@ -239,6 +239,19 @@ # sys._current_frames() is a CPython-only gimmick. def test_current_frames(self): + have_threads = True + try: + import thread + except ImportError: + have_threads = False + + if have_threads: + self.current_frames_with_threads() + else: + self.current_frames_without_threads() + + # Test sys._current_frames() in a WITH_THREADS build. + def current_frames_with_threads(self): import threading, thread import traceback @@ -261,8 +274,9 @@ t.start() entered_g.wait() - # At this point, t has finished its entered_g.set(), and is blocked - # in its leave_g.wait(). + # At this point, t has finished its entered_g.set(), although it's + # impossible to guess whether it's still on that line or has moved on + # to its leave_g.wait(). self.assertEqual(len(thread_info), 1) thread_id = thread_info[0] @@ -292,12 +306,21 @@ # And the next record must be for g456(). filename, lineno, funcname, sourceline = stack[i+1] self.assertEqual(funcname, "g456") - self.assertEqual(sourceline, "leave_g.wait()") + self.assert_(sourceline in ["leave_g.wait()", "entered_g.set()"]) # Reap the spawned thread. leave_g.set() t.join() + # Test sys._current_frames() when thread support doesn't exist. + def current_frames_without_threads(self): + # Not much happens here: there is only one thread, with artificial + # "thread id" 0. + d = sys._current_frames() + self.assertEqual(len(d), 1) + self.assert_(0 in d) + self.assert_(d[0] is sys._getframe()) + def test_attributes(self): self.assert_(isinstance(sys.api_version, int)) self.assert_(isinstance(sys.argv, list)) Modified: stackless/trunk/Lib/test/test_time.py ============================================================================== --- stackless/trunk/Lib/test/test_time.py (original) +++ stackless/trunk/Lib/test/test_time.py Mon Aug 14 12:38:35 2006 @@ -39,9 +39,9 @@ def test_strftime_bounds_checking(self): # Make sure that strftime() checks the bounds of the various parts - #of the time tuple. + #of the time tuple (0 is valid for *all* values). - # Check year + # Check year [1900, max(int)] self.assertRaises(ValueError, time.strftime, '', (1899, 1, 1, 0, 0, 0, 0, 1, -1)) if time.accept2dyear: @@ -49,27 +49,27 @@ (-1, 1, 1, 0, 0, 0, 0, 1, -1)) self.assertRaises(ValueError, time.strftime, '', (100, 1, 1, 0, 0, 0, 0, 1, -1)) - # Check month + # Check month [1, 12] + zero support self.assertRaises(ValueError, time.strftime, '', - (1900, 0, 1, 0, 0, 0, 0, 1, -1)) + (1900, -1, 1, 0, 0, 0, 0, 1, -1)) self.assertRaises(ValueError, time.strftime, '', (1900, 13, 1, 0, 0, 0, 0, 1, -1)) - # Check day of month + # Check day of month [1, 31] + zero support self.assertRaises(ValueError, time.strftime, '', - (1900, 1, 0, 0, 0, 0, 0, 1, -1)) + (1900, 1, -1, 0, 0, 0, 0, 1, -1)) self.assertRaises(ValueError, time.strftime, '', (1900, 1, 32, 0, 0, 0, 0, 1, -1)) - # Check hour + # Check hour [0, 23] self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, -1, 0, 0, 0, 1, -1)) self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 24, 0, 0, 0, 1, -1)) - # Check minute + # Check minute [0, 59] self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, -1, 0, 0, 1, -1)) self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, 60, 0, 0, 1, -1)) - # Check second + # Check second [0, 61] self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, 0, -1, 0, 1, -1)) # C99 only requires allowing for one leap second, but Python's docs say @@ -82,17 +82,25 @@ # modulo. self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, 0, 0, -2, 1, -1)) - # Check day of the year + # Check day of the year [1, 366] + zero support self.assertRaises(ValueError, time.strftime, '', - (1900, 1, 1, 0, 0, 0, 0, 0, -1)) + (1900, 1, 1, 0, 0, 0, 0, -1, -1)) self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 367, -1)) - # Check daylight savings flag + # Check daylight savings flag [-1, 1] self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, -2)) self.assertRaises(ValueError, time.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, 2)) + def test_default_values_for_zero(self): + # Make sure that using all zeros uses the proper default values. + # No test for daylight savings since strftime() does not change output + # based on its value. + expected = "2000 01 01 00 00 00 1 001" + result = time.strftime("%Y %m %d %H %M %S %w %j", (0,)*9) + self.assertEquals(expected, result) + def test_strptime(self): tt = time.gmtime(self.t) for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I', Modified: stackless/trunk/Lib/test/test_traceback.py ============================================================================== --- stackless/trunk/Lib/test/test_traceback.py (original) +++ stackless/trunk/Lib/test/test_traceback.py Mon Aug 14 12:38:35 2006 @@ -31,8 +31,9 @@ err = self.get_exception_format(self.syntax_error_with_caret, SyntaxError) self.assert_(len(err) == 4) - self.assert_("^" in err[2]) # third line has caret self.assert_(err[1].strip() == "return x!") + self.assert_("^" in err[2]) # third line has caret + self.assert_(err[1].find("!") == err[2].find("^")) # in the right place def test_nocaret(self): if is_jython: @@ -47,8 +48,9 @@ err = self.get_exception_format(self.syntax_error_bad_indentation, IndentationError) self.assert_(len(err) == 4) - self.assert_("^" in err[2]) self.assert_(err[1].strip() == "print 2") + self.assert_("^" in err[2]) + self.assert_(err[1].find("2") == err[2].find("^")) def test_bug737473(self): import sys, os, tempfile, time @@ -109,6 +111,36 @@ lst = traceback.format_exception_only(e.__class__, e) self.assertEqual(lst, ['KeyboardInterrupt\n']) + # String exceptions are deprecated, but legal. The quirky form with + # separate "type" and "value" tends to break things, because + # not isinstance(value, type) + # and a string cannot be the first argument to issubclass. + # + # Note that sys.last_type and sys.last_value do not get set if an + # exception is caught, so we sort of cheat and just emulate them. + # + # test_string_exception1 is equivalent to + # + # >>> raise "String Exception" + # + # test_string_exception2 is equivalent to + # + # >>> raise "String Exception", "String Value" + # + def test_string_exception1(self): + str_type = "String Exception" + err = traceback.format_exception_only(str_type, None) + self.assert_(len(err) == 1) + self.assert_(err[0] == str_type + '\n') + + def test_string_exception2(self): + str_type = "String Exception" + str_value = "String Value" + err = traceback.format_exception_only(str_type, str_value) + self.assert_(len(err) == 1) + self.assert_(err[0] == str_type + ': ' + str_value + '\n') + + def test_main(): run_unittest(TracebackCases) Modified: stackless/trunk/Lib/test/test_urllib2.py ============================================================================== --- stackless/trunk/Lib/test/test_urllib2.py (original) +++ stackless/trunk/Lib/test/test_urllib2.py Mon Aug 14 12:38:35 2006 @@ -676,11 +676,11 @@ r = MockResponse(200, "OK", {}, "") newreq = h.do_request_(req) if data is None: # GET - self.assert_("Content-length" not in req.unredirected_hdrs) - self.assert_("Content-type" not in req.unredirected_hdrs) + self.assert_("Content-Length" not in req.unredirected_hdrs) + self.assert_("Content-Type" not in req.unredirected_hdrs) else: # POST - self.assertEqual(req.unredirected_hdrs["Content-length"], "0") - self.assertEqual(req.unredirected_hdrs["Content-type"], + self.assertEqual(req.unredirected_hdrs["Content-Length"], "0") + self.assertEqual(req.unredirected_hdrs["Content-Type"], "application/x-www-form-urlencoded") # XXX the details of Host could be better tested self.assertEqual(req.unredirected_hdrs["Host"], "example.com") @@ -692,8 +692,8 @@ req.add_unredirected_header("Host", "baz") req.add_unredirected_header("Spam", "foo") newreq = h.do_request_(req) - self.assertEqual(req.unredirected_hdrs["Content-length"], "foo") - self.assertEqual(req.unredirected_hdrs["Content-type"], "bar") + self.assertEqual(req.unredirected_hdrs["Content-Length"], "foo") + self.assertEqual(req.unredirected_hdrs["Content-Type"], "bar") self.assertEqual(req.unredirected_hdrs["Host"], "baz") self.assertEqual(req.unredirected_hdrs["Spam"], "foo") @@ -847,7 +847,7 @@ 407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm) opener.add_handler(auth_handler) opener.add_handler(http_handler) - self._test_basic_auth(opener, auth_handler, "Proxy-authorization", + self._test_basic_auth(opener, auth_handler, "Proxy-Authorization", realm, http_handler, password_manager, "http://acme.example.com:3128/protected", "proxy.example.com:3128", Modified: stackless/trunk/Lib/test/test_uuid.py ============================================================================== --- stackless/trunk/Lib/test/test_uuid.py (original) +++ stackless/trunk/Lib/test/test_uuid.py Mon Aug 14 12:38:35 2006 @@ -1,4 +1,5 @@ -from unittest import TestCase, main +from unittest import TestCase +from test import test_support import uuid def importable(name): @@ -10,6 +11,7 @@ class TestUUID(TestCase): last_node = None + source2node = {} def test_UUID(self): equal = self.assertEqual @@ -265,7 +267,7 @@ badtype(lambda: setattr(u, 'fields', f)) badtype(lambda: setattr(u, 'int', i)) - def check_node(self, node, source=''): + def check_node(self, node, source): individual_group_bit = (node >> 40L) & 1 universal_local_bit = (node >> 40L) & 2 message = "%012x doesn't look like a real MAC address" % node @@ -274,25 +276,41 @@ self.assertNotEqual(node, 0, message) self.assertNotEqual(node, 0xffffffffffffL, message) self.assert_(0 <= node, message) - self.assert_(node < 1<<48L, message) + self.assert_(node < (1L << 48), message) - import sys - if source: - sys.stderr.write('(%s: %012x)' % (source, node)) + TestUUID.source2node[source] = node if TestUUID.last_node: - self.assertEqual(TestUUID.last_node, node, 'inconsistent node IDs') + if TestUUID.last_node != node: + msg = "different sources disagree on node:\n" + for s, n in TestUUID.source2node.iteritems(): + msg += " from source %r, node was %012x\n" % (s, n) + # There's actually no reason to expect the MAC addresses + # to agree across various methods -- e.g., a box may have + # multiple network interfaces, and different ways of getting + # a MAC address may favor different HW. + ##self.fail(msg) else: TestUUID.last_node = node def test_ifconfig_getnode(self): + import sys + print >>sys.__stdout__, \ +""" WARNING: uuid._ifconfig_getnode is unreliable on many platforms. + It is disabled until the code and/or test can be fixed properly.""" + return + import os if os.name == 'posix': - self.check_node(uuid._ifconfig_getnode(), 'ifconfig') + node = uuid._ifconfig_getnode() + if node is not None: + self.check_node(node, 'ifconfig') def test_ipconfig_getnode(self): import os if os.name == 'nt': - self.check_node(uuid._ipconfig_getnode(), 'ipconfig') + node = uuid._ipconfig_getnode() + if node is not None: + self.check_node(node, 'ipconfig') def test_netbios_getnode(self): if importable('win32wnet') and importable('netbios'): @@ -301,9 +319,15 @@ def test_random_getnode(self): node = uuid._random_getnode() self.assert_(0 <= node) - self.assert_(node < 1<<48L) + self.assert_(node < (1L <<48)) def test_unixdll_getnode(self): + import sys + print >>sys.__stdout__, \ +""" WARNING: uuid._unixdll_getnode is unreliable on many platforms. + It is disabled until the code and/or test can be fixed properly.""" + return + import os if importable('ctypes') and os.name == 'posix': self.check_node(uuid._unixdll_getnode(), 'unixdll') @@ -314,10 +338,20 @@ self.check_node(uuid._windll_getnode(), 'windll') def test_getnode(self): - self.check_node(uuid.getnode()) + import sys + print >>sys.__stdout__, \ +""" WARNING: uuid.getnode is unreliable on many platforms. + It is disabled until the code and/or test can be fixed properly.""" + return + + node1 = uuid.getnode() + self.check_node(node1, "getnode1") # Test it again to ensure consistency. - self.check_node(uuid.getnode()) + node2 = uuid.getnode() + self.check_node(node2, "getnode2") + + self.assertEqual(node1, node2) def test_uuid1(self): equal = self.assertEqual @@ -392,5 +426,9 @@ equal(u, uuid.UUID(v)) equal(str(u), v) + +def test_main(): + test_support.run_unittest(TestUUID) + if __name__ == '__main__': - main() + test_main() Modified: stackless/trunk/Lib/test/test_winreg.py ============================================================================== --- stackless/trunk/Lib/test/test_winreg.py (original) +++ stackless/trunk/Lib/test/test_winreg.py Mon Aug 14 12:38:35 2006 @@ -151,3 +151,6 @@ else: print "Remote registry calls can be tested using", print "'test_winreg.py --remote \\\\machine_name'" + # perform minimal ConnectRegistry test which just invokes it + h = ConnectRegistry(None, HKEY_LOCAL_MACHINE) + h.Close() Modified: stackless/trunk/Lib/test/test_xml_etree.py ============================================================================== --- stackless/trunk/Lib/test/test_xml_etree.py (original) +++ stackless/trunk/Lib/test/test_xml_etree.py Mon Aug 14 12:38:35 2006 @@ -1,4 +1,4 @@ -# xmlcore.etree test. This file contains enough tests to make sure that +# xml.etree test. This file contains enough tests to make sure that # all included components work as they should. For a more extensive # test suite, see the selftest script in the ElementTree distribution. @@ -6,8 +6,6 @@ from test import test_support -from xmlcore.etree import ElementTree as ET - SAMPLE_XML = """ text @@ -32,9 +30,9 @@ """ Import sanity. - >>> from xmlcore.etree import ElementTree - >>> from xmlcore.etree import ElementInclude - >>> from xmlcore.etree import ElementPath + >>> from xml.etree import ElementTree + >>> from xml.etree import ElementInclude + >>> from xml.etree import ElementPath """ def check_method(method): @@ -61,6 +59,8 @@ """ Test element tree interface. + >>> from xml.etree import ElementTree as ET + >>> element = ET.Element("tag", key="value") >>> tree = ET.ElementTree(element) @@ -108,6 +108,8 @@ """ Test find methods (including xpath syntax). + >>> from xml.etree import ElementTree as ET + >>> elem = ET.XML(SAMPLE_XML) >>> elem.find("tag").tag 'tag' @@ -174,6 +176,8 @@ def parseliteral(): r""" + >>> from xml.etree import ElementTree as ET + >>> element = ET.XML("text") >>> ET.ElementTree(element).write(sys.stdout) text @@ -195,18 +199,20 @@ 'body' """ -def check_encoding(encoding): + +def check_encoding(ET, encoding): """ - >>> check_encoding("ascii") - >>> check_encoding("us-ascii") - >>> check_encoding("iso-8859-1") - >>> check_encoding("iso-8859-15") - >>> check_encoding("cp437") - >>> check_encoding("mac-roman") + >>> from xml.etree import ElementTree as ET + + >>> check_encoding(ET, "ascii") + >>> check_encoding(ET, "us-ascii") + >>> check_encoding(ET, "iso-8859-1") + >>> check_encoding(ET, "iso-8859-15") + >>> check_encoding(ET, "cp437") + >>> check_encoding(ET, "mac-roman") """ - ET.XML( - "" % encoding - ) + ET.XML("" % encoding) + # # xinclude tests (samples from appendix C of the xinclude specification) @@ -282,14 +288,16 @@ except KeyError: raise IOError("resource not found") if parse == "xml": - return ET.XML(data) + from xml.etree.ElementTree import XML + return XML(data) return data def xinclude(): r""" Basic inclusion example (XInclude C.1) - >>> from xmlcore.etree import ElementInclude + >>> from xml.etree import ElementTree as ET + >>> from xml.etree import ElementInclude >>> document = xinclude_loader("C1.xml") >>> ElementInclude.include(document, xinclude_loader) Modified: stackless/trunk/Lib/test/test_xml_etree_c.py ============================================================================== --- stackless/trunk/Lib/test/test_xml_etree_c.py (original) +++ stackless/trunk/Lib/test/test_xml_etree_c.py Mon Aug 14 12:38:35 2006 @@ -1,10 +1,10 @@ -# xmlcore.etree test for cElementTree +# xml.etree test for cElementTree import doctest, sys from test import test_support -from xmlcore.etree import cElementTree as ET +from xml.etree import cElementTree as ET SAMPLE_XML = """ @@ -30,7 +30,7 @@ """ Import sanity. - >>> from xmlcore.etree import cElementTree + >>> from xml.etree import cElementTree """ def check_method(method): Modified: stackless/trunk/Lib/traceback.py ============================================================================== --- stackless/trunk/Lib/traceback.py (original) +++ stackless/trunk/Lib/traceback.py Mon Aug 14 12:38:35 2006 @@ -150,50 +150,63 @@ The arguments are the exception type and value such as given by sys.last_type and sys.last_value. The return value is a list of - strings, each ending in a newline. Normally, the list contains a - single string; however, for SyntaxError exceptions, it contains - several lines that (when printed) display detailed information - about where the syntax error occurred. The message indicating - which exception occurred is the always last string in the list. + strings, each ending in a newline. + + Normally, the list contains a single string; however, for + SyntaxError exceptions, it contains several lines that (when + printed) display detailed information about where the syntax + error occurred. + + The message indicating which exception occurred is always the last + string in the list. + """ - list = [] - if (type(etype) == types.ClassType - or (isinstance(etype, type) and issubclass(etype, BaseException))): - stype = etype.__name__ + + # An instance should not have a meaningful value parameter, but + # sometimes does, particularly for string exceptions, such as + # >>> raise string1, string2 # deprecated + # + # Clear these out first because issubtype(string1, SyntaxError) + # would throw another exception and mask the original problem. + if (isinstance(etype, BaseException) or + isinstance(etype, types.InstanceType) or + type(etype) is str): + return [_format_final_exc_line(etype, value)] + + stype = etype.__name__ + + if not issubclass(etype, SyntaxError): + return [_format_final_exc_line(stype, value)] + + # It was a syntax error; show exactly where the problem was found. + lines = [] + try: + msg, (filename, lineno, offset, badline) = value + except Exception: + pass else: - stype = etype - if value is None: - list.append(str(stype) + '\n') + filename = filename or "" + lines.append(' File "%s", line %d\n' % (filename, lineno)) + if badline is not None: + lines.append(' %s\n' % badline.strip()) + if offset is not None: + caretspace = badline[:offset].lstrip() + # non-space whitespace (likes tabs) must be kept for alignment + caretspace = ((c.isspace() and c or ' ') for c in caretspace) + # only three spaces to account for offset1 == pos 0 + lines.append(' %s^\n' % ''.join(caretspace)) + value = msg + + lines.append(_format_final_exc_line(stype, value)) + return lines + +def _format_final_exc_line(etype, value): + """Return a list of a single line -- normal case for format_exception_only""" + if value is None or not str(value): + line = "%s\n" % etype else: - if issubclass(etype, SyntaxError): - try: - msg, (filename, lineno, offset, line) = value - except: - pass - else: - if not filename: filename = "" - list.append(' File "%s", line %d\n' % - (filename, lineno)) - if line is not None: - i = 0 - while i < len(line) and line[i].isspace(): - i = i+1 - list.append(' %s\n' % line.strip()) - if offset is not None: - s = ' ' - for c in line[i:offset-1]: - if c.isspace(): - s = s + c - else: - s = s + ' ' - list.append('%s^\n' % s) - value = msg - s = _some_str(value) - if s: - list.append('%s: %s\n' % (str(stype), s)) - else: - list.append('%s\n' % str(stype)) - return list + line = "%s: %s\n" % (etype, _some_str(value)) + return line def _some_str(value): try: Modified: stackless/trunk/Lib/types.py ============================================================================== --- stackless/trunk/Lib/types.py (original) +++ stackless/trunk/Lib/types.py Mon Aug 14 12:38:35 2006 @@ -86,4 +86,16 @@ DictProxyType = type(TypeType.__dict__) NotImplementedType = type(NotImplemented) -del sys, _f, _g, _C, _x # Not for export +# Extension types defined in a C helper module. XXX There may be no +# equivalent in implementations other than CPython, so it seems better to +# leave them undefined then to set them to e.g. None. +try: + import _types +except ImportError: + pass +else: + GetSetDescriptorType = type(_types.Helper.getter) + MemberDescriptorType = type(_types.Helper.member) + del _types + +del sys, _f, _g, _C, _x # Not for export Modified: stackless/trunk/Lib/urllib.py ============================================================================== --- stackless/trunk/Lib/urllib.py (original) +++ stackless/trunk/Lib/urllib.py Mon Aug 14 12:38:35 2006 @@ -118,7 +118,7 @@ self.proxies = proxies self.key_file = x509.get('key_file') self.cert_file = x509.get('cert_file') - self.addheaders = [('User-agent', self.version)] + self.addheaders = [('User-Agent', self.version)] self.__tempfiles = [] self.__unlink = os.unlink # See cleanup() self.tempcache = None @@ -314,8 +314,8 @@ h = httplib.HTTP(host) if data is not None: h.putrequest('POST', selector) - h.putheader('Content-type', 'application/x-www-form-urlencoded') - h.putheader('Content-length', '%d' % len(data)) + h.putheader('Content-Type', 'application/x-www-form-urlencoded') + h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) @@ -400,9 +400,9 @@ cert_file=self.cert_file) if data is not None: h.putrequest('POST', selector) - h.putheader('Content-type', + h.putheader('Content-Type', 'application/x-www-form-urlencoded') - h.putheader('Content-length', '%d' % len(data)) + h.putheader('Content-Length', '%d' % len(data)) else: h.putrequest('GET', selector) if proxy_auth: h.putheader('Proxy-Authorization: Basic %s' % proxy_auth) @@ -584,7 +584,7 @@ data = base64.decodestring(data) else: data = unquote(data) - msg.append('Content-length: %d' % len(data)) + msg.append('Content-Length: %d' % len(data)) msg.append('') msg.append(data) msg = '\n'.join(msg) Modified: stackless/trunk/Lib/urllib2.py ============================================================================== --- stackless/trunk/Lib/urllib2.py (original) +++ stackless/trunk/Lib/urllib2.py Mon Aug 14 12:38:35 2006 @@ -263,11 +263,11 @@ def add_header(self, key, val): # useful for something like authentication - self.headers[key.capitalize()] = val + self.headers[key.title()] = val def add_unredirected_header(self, key, val): # will not be added to a redirected request - self.unredirected_hdrs[key.capitalize()] = val + self.unredirected_hdrs[key.title()] = val def has_header(self, header_name): return (header_name in self.headers or @@ -286,7 +286,7 @@ class OpenerDirector: def __init__(self): client_version = "Python-urllib/%s" % __version__ - self.addheaders = [('User-agent', client_version)] + self.addheaders = [('User-Agent', client_version)] # manage the individual handlers self.handlers = [] self.handle_open = {} @@ -675,7 +675,7 @@ if user and password: user_pass = '%s:%s' % (unquote(user), unquote(password)) creds = base64.encodestring(user_pass).strip() - req.add_header('Proxy-authorization', 'Basic ' + creds) + req.add_header('Proxy-Authorization', 'Basic ' + creds) hostport = unquote(hostport) req.set_proxy(hostport, proxy_type) if orig_type == proxy_type: @@ -819,7 +819,7 @@ class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): - auth_header = 'Proxy-authorization' + auth_header = 'Proxy-Authorization' def http_error_407(self, req, fp, code, msg, headers): # http_error_auth_reqed requires that there is no userinfo component in @@ -1022,20 +1022,20 @@ if request.has_data(): # POST data = request.get_data() - if not request.has_header('Content-type'): + if not request.has_header('Content-Type'): request.add_unredirected_header( - 'Content-type', + 'Content-Type', 'application/x-www-form-urlencoded') - if not request.has_header('Content-length'): + if not request.has_header('Content-Length'): request.add_unredirected_header( - 'Content-length', '%d' % len(data)) + 'Content-Length', '%d' % len(data)) scheme, sel = splittype(request.get_selector()) sel_host, sel_path = splithost(sel) if not request.has_header('Host'): request.add_unredirected_header('Host', sel_host or host) for name, value in self.parent.addheaders: - name = name.capitalize() + name = name.title() if not request.has_header(name): request.add_unredirected_header(name, value) @@ -1217,7 +1217,7 @@ modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(file)[0] headers = mimetools.Message(StringIO( - 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % + 'Content-Type: %s\nContent-Length: %d\nLast-Modified: %s\n' % (mtype or 'text/plain', size, modified))) if host: host, port = splitport(host) @@ -1272,9 +1272,9 @@ headers = "" mtype = mimetypes.guess_type(req.get_full_url())[0] if mtype: - headers += "Content-type: %s\n" % mtype + headers += "Content-Type: %s\n" % mtype if retrlen is not None and retrlen >= 0: - headers += "Content-length: %d\n" % retrlen + headers += "Content-Length: %d\n" % retrlen sf = StringIO(headers) headers = mimetools.Message(sf) return addinfourl(fp, headers, req.get_full_url()) Modified: stackless/trunk/Lib/uuid.py ============================================================================== --- stackless/trunk/Lib/uuid.py (original) +++ stackless/trunk/Lib/uuid.py Mon Aug 14 12:38:35 2006 @@ -271,19 +271,51 @@ version = property(get_version) -def _ifconfig_getnode(): - """Get the hardware address on Unix by running ifconfig.""" +def _find_mac(command, args, hw_identifiers, get_index): import os for dir in ['', '/sbin/', '/usr/sbin']: + executable = os.path.join(dir, command) + if not os.path.exists(executable): + continue + try: - pipe = os.popen(os.path.join(dir, 'ifconfig')) + # LC_ALL to get English output, 2>/dev/null to + # prevent output on stderr + cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args) + pipe = os.popen(cmd) except IOError: continue + for line in pipe: words = line.lower().split() for i in range(len(words)): - if words[i] in ['hwaddr', 'ether']: - return int(words[i + 1].replace(':', ''), 16) + if words[i] in hw_identifiers: + return int(words[get_index(i)].replace(':', ''), 16) + return None + +def _ifconfig_getnode(): + """Get the hardware address on Unix by running ifconfig.""" + + # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes. + for args in ('', '-a', '-av'): + mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1) + if mac: + return mac + + import socket + ip_addr = socket.gethostbyname(socket.gethostname()) + + # Try getting the MAC addr from arp based on our IP address (Solaris). + mac = _find_mac('arp', '-an', [ip_addr], lambda i: -1) + if mac: + return mac + + # This might work on HP-UX. + mac = _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0) + if mac: + return mac + + return None def _ipconfig_getnode(): """Get the hardware address on Windows by running ipconfig.exe.""" @@ -359,6 +391,10 @@ # hardware address. On Windows 2000 and later, UuidCreate makes a # random UUID and UuidCreateSequential gives a UUID containing the # hardware address. These routines are provided by the RPC runtime. + # NOTE: at least on Tim's WinXP Pro SP2 desktop box, while the last + # 6 bytes returned by UuidCreateSequential are fixed, they don't appear + # to bear any relationship to the MAC address of any network device + # on the box. try: lib = ctypes.windll.rpcrt4 except: @@ -386,10 +422,13 @@ _node = None def getnode(): - """Get the hardware address as a 48-bit integer. The first time this - runs, it may launch a separate program, which could be quite slow. If - all attempts to obtain the hardware address fail, we choose a random - 48-bit number with its eighth bit set to 1 as recommended in RFC 4122.""" + """Get the hardware address as a 48-bit positive integer. + + The first time this runs, it may launch a separate program, which could + be quite slow. If all attempts to obtain the hardware address fail, we + choose a random 48-bit number with its eighth bit set to 1 as recommended + in RFC 4122. + """ global _node if _node is not None: Deleted: /stackless/trunk/Lib/xml.py ============================================================================== --- /stackless/trunk/Lib/xml.py Mon Aug 14 12:38:35 2006 +++ (empty file) @@ -1,47 +0,0 @@ -"""Core XML support for Python. - -This package contains four sub-packages: - -dom -- The W3C Document Object Model. This supports DOM Level 1 + - Namespaces. - -parsers -- Python wrappers for XML parsers (currently only supports Expat). - -sax -- The Simple API for XML, developed by XML-Dev, led by David - Megginson and ported to Python by Lars Marius Garshol. This - supports the SAX 2 API. - -etree -- The ElementTree XML library. This is a subset of the full - ElementTree XML release. - -""" - -import sys -import xmlcore - -__all__ = ["dom", "parsers", "sax", "etree"] - -# When being checked-out without options, this has the form -# "Revision: x.y " -# When exported using -kv, it is "x.y". -__version__ = "$Revision$".split()[-2:][0] - - -_MINIMUM_XMLPLUS_VERSION = (0, 8, 4) - -try: - import _xmlplus -except ImportError: - sys.modules[__name__] = xmlcore -else: - try: - v = _xmlplus.version_info - except AttributeError: - # _xmlplus is too old; ignore it - pass - else: - if v >= _MINIMUM_XMLPLUS_VERSION: - _xmlplus.__path__.extend(xmlcore.__path__) - sys.modules[__name__] = _xmlplus - else: - del v Modified: stackless/trunk/Lib/zipfile.py ============================================================================== --- stackless/trunk/Lib/zipfile.py (original) +++ stackless/trunk/Lib/zipfile.py Mon Aug 14 12:38:35 2006 @@ -664,7 +664,7 @@ if zinfo.header_offset > ZIP64_LIMIT: extra.append(zinfo.header_offset) - header_offset = 0xffffffff #-1 + header_offset = -1 # struct "l" format: 32 one bits else: header_offset = zinfo.header_offset @@ -708,9 +708,10 @@ stringEndArchive64Locator, 0, pos2, 1) self.fp.write(zip64locrec) + # XXX Why is `pos3` computed next? It's never referenced. pos3 = self.fp.tell() endrec = struct.pack(structEndArchive, stringEndArchive, - 0, 0, count, count, pos2 - pos1, 0xffffffff, 0) # -1, 0) + 0, 0, count, count, pos2 - pos1, -1, 0) self.fp.write(endrec) else: Modified: stackless/trunk/Mac/BuildScript/README.txt ============================================================================== --- stackless/trunk/Mac/BuildScript/README.txt (original) +++ stackless/trunk/Mac/BuildScript/README.txt Mon Aug 14 12:38:35 2006 @@ -8,15 +8,47 @@ an Installer package from the installation plus other files in ``resources`` and ``scripts`` and placed that on a ``.dmg`` disk image. -Here are the steps you ned to follow to build a MacPython installer: +Prerequisites +------------- -- Run ``./build-installer.py``. Optionally you can pass a number of arguments - to specify locations of various files. Please see the top of +* A MacOS X 10.4 (or later) + +* XCode 2.2 (or later), with the universal SDK + +* No Fink (in ``/sw``) or DarwinPorts (in ``/opt/local``), those could + interfere with the build. + +* The documentation for the release must be available on python.org + because it is included in the installer. + + +The Recipe +---------- + +Here are the steps you need to follow to build a MacPython installer: + +* Run ``./build-installer.py``. Optionally you can pass a number of arguments + to specify locations of various files. Please see the top of ``build-installer.py`` for its usage. -- When done the script will tell you where the DMG image is. -The script needs to be run on Mac OS X 10.4 with Xcode 2.2 or later and -the 10.4u SDK. + Running this script takes some time, I will not only build Python itself + but also some 3th-party libraries that are needed for extensions. + +* When done the script will tell you where the DMG image is (by default + somewhere in ``/tmp/_py``). + +Testing +------- + +The resulting binaries should work on MacOSX 10.3.9 or later. I usually run +the installer on a 10.3.9, a 10.4.x PPC and a 10.4.x Intel system and then +run the testsuite to make sure. + + +Announcements +------------- + +(This is mostly of historic interest) When all is done, announcements can be posted to at least the following places: Modified: stackless/trunk/Mac/BuildScript/scripts/postflight.patch-profile ============================================================================== --- stackless/trunk/Mac/BuildScript/scripts/postflight.patch-profile (original) +++ stackless/trunk/Mac/BuildScript/scripts/postflight.patch-profile Mon Aug 14 12:38:35 2006 @@ -5,14 +5,27 @@ echo "These changes will be effective only in shell windows that you open" echo "after running this script." -PYVER=@PYVER@ +PYVER=2.5 PYTHON_ROOT="/Library/Frameworks/Python.framework/Versions/Current" +if [ `id -ur` = 0 ]; then + # Run from the installer, do some trickery to fetch the information + # we need. + theShell="`finger $USER | grep Shell: | head -1 | awk '{ print $NF }'`" + +else + theShell="${SHELL}" +fi + # Make sure the directory ${PYTHON_ROOT}/bin is on the users PATH. -BSH="`basename "${SHELL}"`" +BSH="`basename "${theShell}"`" case "${BSH}" in bash|ksh|sh|*csh) - P="`${SHELL} -c 'echo $PATH'`" + if [ `id -ur` = 0 ]; then + P=`su - ${USER} -c 'echo A-X-4-X@@$PATH@@X-4-X-A' | grep 'A-X-4-X@@.*@@X-4-X-A' | sed -e 's/^A-X-4-X@@//g' -e 's/@@X-4-X-A$//g'` + else + P="`(exec -l ${theShell} -c 'echo $PATH')`" + fi ;; *) echo "Sorry, I don't know how to patch $BSH shells" @@ -42,10 +55,15 @@ echo "# Setting PATH for MacPython ${PYVER}" >> "${HOME}/.cshrc" echo "# The orginal version is saved in .cshrc.pysave" >> "${HOME}/.cshrc" echo "set path=(${PYTHON_ROOT}/bin "'$path'")" >> "${HOME}/.cshrc" + if [ `id -ur` = 0 ]; then + chown "${USER}" "${HOME}/.cshrc" + fi exit 0 ;; bash) - if [ -e "${HOME}/.profile" ]; then + if [ -e "${HOME}/.bash_profile" ]; then + PR="${HOME}/.bash_profile" + elif [ -e "${HOME}/.profile" ]; then PR="${HOME}/.profile" else PR="${HOME}/.bash_profile" @@ -66,6 +84,6 @@ echo 'PATH="'"${PYTHON_ROOT}/bin"':${PATH}"' >> "${PR}" echo 'export PATH' >> "${PR}" if [ `id -ur` = 0 ]; then - chown "${LOGNAME}" "${PR}" + chown "${USER}" "${PR}" fi exit 0 Modified: stackless/trunk/Mac/IDLE/config-main.def ============================================================================== --- stackless/trunk/Mac/IDLE/config-main.def (original) +++ stackless/trunk/Mac/IDLE/config-main.def Mon Aug 14 12:38:35 2006 @@ -71,7 +71,7 @@ [Keys] default= 1 -name= IDLE Classic Mac +name= IDLE Classic OSX [History] cyclic=1 Deleted: /stackless/trunk/Mac/Modules/macosmodule.c ============================================================================== --- /stackless/trunk/Mac/Modules/macosmodule.c Mon Aug 14 12:38:35 2006 +++ (empty file) @@ -1,643 +0,0 @@ -/*********************************************************** -Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam, -The Netherlands. - - 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 names of Stichting Mathematisch -Centrum or CWI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior permission. - -STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO -THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM 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. - -******************************************************************/ - -/* Macintosh OS-specific interface */ - -#include "Python.h" -#include "pymactoolbox.h" - -#include -#include - -static PyObject *MacOS_Error; /* Exception MacOS.Error */ - -#define PATHNAMELEN 1024 - -/* ----------------------------------------------------- */ - -/* Declarations for objects of type Resource fork */ - -typedef struct { - PyObject_HEAD - short fRefNum; - int isclosed; -} rfobject; - -static PyTypeObject Rftype; - - - -/* ---------------------------------------------------------------- */ - -static void -do_close(rfobject *self) -{ - if (self->isclosed ) return; - (void)FSClose(self->fRefNum); - self->isclosed = 1; -} - -static char rf_read__doc__[] = -"Read data from resource fork" -; - -static PyObject * -rf_read(rfobject *self, PyObject *args) -{ - long n; - PyObject *v; - OSErr err; - - if (self->isclosed) { - PyErr_SetString(PyExc_ValueError, "Operation on closed file"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "l", &n)) - return NULL; - - v = PyString_FromStringAndSize((char *)NULL, n); - if (v == NULL) - return NULL; - - err = FSRead(self->fRefNum, &n, PyString_AsString(v)); - if (err && err != eofErr) { - PyMac_Error(err); - Py_DECREF(v); - return NULL; - } - _PyString_Resize(&v, n); - return v; -} - - -static char rf_write__doc__[] = -"Write to resource fork" -; - -static PyObject * -rf_write(rfobject *self, PyObject *args) -{ - char *buffer; - long size; - OSErr err; - - if (self->isclosed) { - PyErr_SetString(PyExc_ValueError, "Operation on closed file"); - return NULL; - } - if (!PyArg_ParseTuple(args, "s#", &buffer, &size)) - return NULL; - err = FSWrite(self->fRefNum, &size, buffer); - if (err) { - PyMac_Error(err); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; -} - - -static char rf_seek__doc__[] = -"Set file position" -; - -static PyObject * -rf_seek(rfobject *self, PyObject *args) -{ - long amount, pos; - int whence = SEEK_SET; - long eof; - OSErr err; - - if (self->isclosed) { - PyErr_SetString(PyExc_ValueError, "Operation on closed file"); - return NULL; - } - if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) - return NULL; - - if ((err = GetEOF(self->fRefNum, &eof))) - goto ioerr; - - switch (whence) { - case SEEK_CUR: - if ((err = GetFPos(self->fRefNum, &pos))) - goto ioerr; - break; - case SEEK_END: - pos = eof; - break; - case SEEK_SET: - pos = 0; - break; - default: - PyErr_BadArgument(); - return NULL; - } - - pos += amount; - - /* Don't bother implementing seek past EOF */ - if (pos > eof || pos < 0) { - PyErr_BadArgument(); - return NULL; - } - - if ((err = SetFPos(self->fRefNum, fsFromStart, pos)) ) { -ioerr: - PyMac_Error(err); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; -} - - -static char rf_tell__doc__[] = -"Get file position" -; - -static PyObject * -rf_tell(rfobject *self, PyObject *args) -{ - long where; - OSErr err; - - if (self->isclosed) { - PyErr_SetString(PyExc_ValueError, "Operation on closed file"); - return NULL; - } - if (!PyArg_ParseTuple(args, "")) - return NULL; - if ((err = GetFPos(self->fRefNum, &where)) ) { - PyMac_Error(err); - return NULL; - } - return PyInt_FromLong(where); -} - -static char rf_close__doc__[] = -"Close resource fork" -; - -static PyObject * -rf_close(rfobject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - do_close(self); - Py_INCREF(Py_None); - return Py_None; -} - - -static struct PyMethodDef rf_methods[] = { - {"read", (PyCFunction)rf_read, 1, rf_read__doc__}, - {"write", (PyCFunction)rf_write, 1, rf_write__doc__}, - {"seek", (PyCFunction)rf_seek, 1, rf_seek__doc__}, - {"tell", (PyCFunction)rf_tell, 1, rf_tell__doc__}, - {"close", (PyCFunction)rf_close, 1, rf_close__doc__}, - - {NULL, NULL} /* sentinel */ -}; - -/* ---------- */ - - -static rfobject * -newrfobject(void) -{ - rfobject *self; - - self = PyObject_NEW(rfobject, &Rftype); - if (self == NULL) - return NULL; - self->isclosed = 1; - return self; -} - - -static void -rf_dealloc(rfobject *self) -{ - do_close(self); - PyObject_DEL(self); -} - -static PyObject * -rf_getattr(rfobject *self, char *name) -{ - return Py_FindMethod(rf_methods, (PyObject *)self, name); -} - -static char Rftype__doc__[] = -"Resource fork file object" -; - -static PyTypeObject Rftype = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "MacOS.ResourceFork", /*tp_name*/ - sizeof(rfobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)rf_dealloc, /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ - (getattrfunc)rf_getattr, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - (cmpfunc)0, /*tp_compare*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - - /* Space for future expansion */ - 0L,0L,0L,0L, - Rftype__doc__ /* Documentation string */ -}; - -/* End of code for Resource fork objects */ -/* -------------------------------------------------------- */ - -/*----------------------------------------------------------------------*/ -/* Miscellaneous File System Operations */ - -static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file"; - -static PyObject * -MacOS_GetCreatorAndType(PyObject *self, PyObject *args) -{ - FSSpec fss; - FInfo info; - PyObject *creator, *type, *res; - OSErr err; - - if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss)) - return NULL; - if ((err = FSpGetFInfo(&fss, &info)) != noErr) - return PyErr_Mac(MacOS_Error, err); - creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4); - type = PyString_FromStringAndSize((char *)&info.fdType, 4); - res = Py_BuildValue("OO", creator, type); - Py_DECREF(creator); - Py_DECREF(type); - return res; -} - -static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file"; - -static PyObject * -MacOS_SetCreatorAndType(PyObject *self, PyObject *args) -{ - FSSpec fss; - ResType creator, type; - FInfo info; - OSErr err; - - if (!PyArg_ParseTuple(args, "O&O&O&", - PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) - return NULL; - if ((err = FSpGetFInfo(&fss, &info)) != noErr) - return PyErr_Mac(MacOS_Error, err); - info.fdCreator = creator; - info.fdType = type; - if ((err = FSpSetFInfo(&fss, &info)) != noErr) - return PyErr_Mac(MacOS_Error, err); - Py_INCREF(Py_None); - return Py_None; -} - - -static char geterr_doc[] = "Convert OSErr number to string"; - -static PyObject * -MacOS_GetErrorString(PyObject *self, PyObject *args) -{ - int err; - char buf[256]; - Handle h; - char *str; - static int errors_loaded; - - if (!PyArg_ParseTuple(args, "i", &err)) - return NULL; - - h = GetResource('Estr', err); - if (!h && !errors_loaded) { - /* - ** Attempt to open the resource file containing the - ** Estr resources. We ignore all errors. We also try - ** this only once. - */ - PyObject *m, *rv; - errors_loaded = 1; - - m = PyImport_ImportModule("macresource"); - if (!m) { - if (Py_VerboseFlag) - PyErr_Print(); - PyErr_Clear(); - } - else { - rv = PyObject_CallMethod(m, "open_error_resource", ""); - if (!rv) { - if (Py_VerboseFlag) - PyErr_Print(); - PyErr_Clear(); - } - else { - Py_DECREF(rv); - /* And try again... */ - h = GetResource('Estr', err); - } - } - } - /* - ** Whether the code above succeeded or not, we won't try - ** again. - */ - errors_loaded = 1; - - if (h) { - HLock(h); - str = (char *)*h; - memcpy(buf, str+1, (unsigned char)str[0]); - buf[(unsigned char)str[0]] = '\0'; - HUnlock(h); - ReleaseResource(h); - } - else { - PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err); - } - - return Py_BuildValue("s", buf); -} - -static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)"; - -static PyObject * -MacOS_splash(PyObject *self, PyObject *args) -{ - int resid = -1; - static DialogPtr curdialog = NULL; - DialogPtr olddialog; - WindowRef theWindow; - CGrafPtr thePort; -#if 0 - short xpos, ypos, width, height, swidth, sheight; -#endif - - if (!PyArg_ParseTuple(args, "|i", &resid)) - return NULL; - olddialog = curdialog; - curdialog = NULL; - - if ( resid != -1 ) { - curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1); - if ( curdialog ) { - theWindow = GetDialogWindow(curdialog); - thePort = GetWindowPort(theWindow); -#if 0 - width = thePort->portRect.right - thePort->portRect.left; - height = thePort->portRect.bottom - thePort->portRect.top; - swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left; - sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight(); - xpos = (swidth-width)/2; - ypos = (sheight-height)/5 + LMGetMBarHeight(); - MoveWindow(theWindow, xpos, ypos, 0); - ShowWindow(theWindow); -#endif - DrawDialog(curdialog); - } - } - if (olddialog) - DisposeDialog(olddialog); - Py_INCREF(Py_None); - return Py_None; -} - -static char DebugStr_doc[] = "Switch to low-level debugger with a message"; - -static PyObject * -MacOS_DebugStr(PyObject *self, PyObject *args) -{ - Str255 message; - PyObject *object = 0; - - if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object)) - return NULL; - DebugStr(message); - Py_INCREF(Py_None); - return Py_None; -} - -static char SysBeep_doc[] = "BEEEEEP!!!"; - -static PyObject * -MacOS_SysBeep(PyObject *self, PyObject *args) -{ - int duration = 6; - - if (!PyArg_ParseTuple(args, "|i", &duration)) - return NULL; - SysBeep(duration); - Py_INCREF(Py_None); - return Py_None; -} - -static char WMAvailable_doc[] = - "True if this process can interact with the display." - "Will foreground the application on the first call as a side-effect." - ; - -static PyObject * -MacOS_WMAvailable(PyObject *self, PyObject *args) -{ - static PyObject *rv = NULL; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - if (!rv) { - ProcessSerialNumber psn; - - /* - ** This is a fairly innocuous call to make if we don't have a window - ** manager, or if we have no permission to talk to it. It will print - ** a message on stderr, but at least it won't abort the process. - ** It appears the function caches the result itself, and it's cheap, so - ** no need for us to cache. - */ -#ifdef kCGNullDirectDisplay - /* On 10.1 CGMainDisplayID() isn't available, and - ** kCGNullDirectDisplay isn't defined. - */ - if (CGMainDisplayID() == 0) { - rv = Py_False; - } else { -#else - { -#endif - if (GetCurrentProcess(&psn) < 0 || - SetFrontProcess(&psn) < 0) { - rv = Py_False; - } else { - rv = Py_True; - } - } - } - Py_INCREF(rv); - return rv; -} - -static char GetTicks_doc[] = "Return number of ticks since bootup"; - -static PyObject * -MacOS_GetTicks(PyObject *self, PyObject *args) -{ - return Py_BuildValue("i", (int)TickCount()); -} - -static char openrf_doc[] = "Open resource fork of a file"; - -static PyObject * -MacOS_openrf(PyObject *self, PyObject *args) -{ - OSErr err; - char *mode = "r"; - FSSpec fss; - SignedByte permission = 1; - rfobject *fp; - - if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode)) - return NULL; - while (*mode) { - switch (*mode++) { - case '*': break; - case 'r': permission = 1; break; - case 'w': permission = 2; break; - case 'b': break; - default: - PyErr_BadArgument(); - return NULL; - } - } - - if ( (fp = newrfobject()) == NULL ) - return NULL; - - err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum); - - if ( err == fnfErr ) { - /* In stead of doing complicated things here to get creator/type - ** correct we let the standard i/o library handle it - */ - FILE *tfp; - char pathname[PATHNAMELEN]; - - if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) { - PyMac_Error(err); - Py_DECREF(fp); - return NULL; - } - - if ( (tfp = fopen(pathname, "w")) == NULL ) { - PyMac_Error(fnfErr); /* What else... */ - Py_DECREF(fp); - return NULL; - } - fclose(tfp); - err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum); - } - if ( err ) { - Py_DECREF(fp); - PyMac_Error(err); - return NULL; - } - fp->isclosed = 0; - return (PyObject *)fp; -} - - -static PyMethodDef MacOS_Methods[] = { - {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc}, - {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc}, - {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc}, - {"openrf", MacOS_openrf, 1, openrf_doc}, - {"splash", MacOS_splash, 1, splash_doc}, - {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc}, - {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc}, - {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc}, - {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc}, - {NULL, NULL} /* Sentinel */ -}; - - -void -initMacOS(void) -{ - PyObject *m, *d; - - m = Py_InitModule("MacOS", MacOS_Methods); - d = PyModule_GetDict(m); - - /* Initialize MacOS.Error exception */ - MacOS_Error = PyMac_GetOSErrException(); - if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0) - return; - Rftype.ob_type = &PyType_Type; - Py_INCREF(&Rftype); - if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0) - return; - /* - ** This is a hack: the following constant added to the id() of a string - ** object gives you the address of the data. Unfortunately, it is needed for - ** some of the image and sound processing interfaces on the mac:-( - */ - { - PyStringObject *p = 0; - long off = (long)&(p->ob_sval[0]); - - if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0) - return; - } -#define PY_RUNTIMEMODEL "macho" - if (PyDict_SetItemString(d, "runtimemodel", - Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0) - return; -#if defined(WITH_NEXT_FRAMEWORK) -#define PY_LINKMODEL "framework" -#elif defined(Py_ENABLE_SHARED) -#define PY_LINKMODEL "shared" -#else -#define PY_LINKMODEL "static" -#endif - if (PyDict_SetItemString(d, "linkmodel", - Py_BuildValue("s", PY_LINKMODEL)) != 0) - return; - -} Modified: stackless/trunk/Mac/PythonLauncher/FileSettings.m ============================================================================== --- stackless/trunk/Mac/PythonLauncher/FileSettings.m (original) +++ stackless/trunk/Mac/PythonLauncher/FileSettings.m Mon Aug 14 12:38:35 2006 @@ -245,12 +245,26 @@ if (value) with_terminal = [value boolValue]; } +- (NSString*)_replaceSingleQuotes: (NSString*)string +{ + /* Replace all single-quotes by '"'"', that way shellquoting will + * be correct when the result value is delimited using single quotes. + */ + NSArray* components = [string componentsSeparatedByString:@"'"]; + + return [components componentsJoinedByString:@"'\"'\"'"]; +} + - (NSString *)commandLineForScript: (NSString *)script { NSString *cur_interp = NULL; + NSString* script_dir = NULL; char hashbangbuf[1024]; FILE *fp; char *p; + + script_dir = [script substringToIndex: + [script length]-[[script lastPathComponent] length]]; if (honourhashbang && (fp=fopen([script cString], "r")) && @@ -266,8 +280,9 @@ cur_interp = interpreter; return [NSString stringWithFormat: - @"\"%@\"%s%s%s%s%s%s %@ \"%@\" %@ %s", - cur_interp, + @"cd '%@' && '%@'%s%s%s%s%s%s %@ '%@' %@ %s", + [self _replaceSingleQuotes:script_dir], + [self _replaceSingleQuotes:cur_interp], debug?" -d":"", verbose?" -v":"", inspect?" -i":"", @@ -275,7 +290,7 @@ nosite?" -S":"", tabs?" -t":"", others, - script, + [self _replaceSingleQuotes:script], scriptargs, with_terminal? "&& echo Exit status: $? && exit 1" : " &"]; } Modified: stackless/trunk/Makefile.pre.in ============================================================================== --- stackless/trunk/Makefile.pre.in (original) +++ stackless/trunk/Makefile.pre.in Mon Aug 14 12:38:35 2006 @@ -334,6 +334,7 @@ ########################################################################## # objects that get linked into the Python library LIBRARY_OBJS= \ + Modules/_typesmodule.o \ Modules/getbuildinfo.o \ $(PARSER_OBJS) \ $(OBJECT_OBJS) \ @@ -370,6 +371,7 @@ $(LIBRARY): $(LIBRARY_OBJS) -rm -f $@ $(AR) cr $@ Modules/getbuildinfo.o + $(AR) cr $@ Modules/_typesmodule.o $(AR) cr $@ $(PARSER_OBJS) $(AR) cr $@ $(OBJECT_OBJS) $(AR) cr $@ $(PYTHON_OBJS) @@ -502,7 +504,7 @@ $(AST_C): $(AST_ASDL) $(ASDLGEN_FILES) $(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL) - + Python/compile.o Python/symtable.o: $(GRAMMAR_H) $(AST_H) Python/getplatform.o: $(srcdir)/Python/getplatform.c @@ -687,6 +689,7 @@ else true; \ fi (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)) + (cd $(DESTDIR)$(BINDIR); $(LN) -sf python$(VERSION)-config python-config) # Install the interpreter with $(VERSION) affixed # This goes into $(exec_prefix) @@ -730,7 +733,7 @@ EXTRAPLATDIR= @EXTRAPLATDIR@ EXTRAMACHDEPPATH=@EXTRAMACHDEPPATH@ MACHDEPS= $(PLATDIR) $(EXTRAPLATDIR) -XMLLIBSUBDIRS= xmlcore xmlcore/dom xmlcore/etree xmlcore/parsers xmlcore/sax +XMLLIBSUBDIRS= xml xml/dom xml/etree xml/parsers xml/sax PLATMACDIRS= plat-mac plat-mac/Carbon plat-mac/lib-scriptpackages \ plat-mac/lib-scriptpackages/_builtinSuites \ plat-mac/lib-scriptpackages/CodeWarrior \ @@ -900,8 +903,8 @@ $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh # Substitution happens here, as the completely-expanded BINDIR # is not available in configure - sed -e "s, at BINDIR@,$(BINDIR)," < $(srcdir)/Misc/python-config.in >python-config - $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python-config + sed -e "s, at EXENAME@,$(BINDIR)/python$(VERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config + $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(VERSION)-config rm python-config @if [ -s Modules/python.exp -a \ "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ @@ -985,7 +988,7 @@ # Install a number of symlinks to keep software that expects a normal unix # install (which includes python-config) happy. frameworkinstallmaclib: - ln -s "../../../Python" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" + ln -fs "../../../Python" "$(DESTDIR)$(prefix)/lib/python$(VERSION)/config/libpython$(VERSION).a" cd Mac && $(MAKE) installmacsubtree DESTDIR="$(DESTDIR)" # This installs the IDE, the Launcher and other apps into /Applications Modified: stackless/trunk/Misc/ACKS ============================================================================== --- stackless/trunk/Misc/ACKS (original) +++ stackless/trunk/Misc/ACKS Mon Aug 14 12:38:35 2006 @@ -203,6 +203,7 @@ Russell Finn Nils Fischbeck Frederik Fix +Matt Fleming Hern?n Mart?nez Foffani Doug Fort John Fouhy @@ -434,6 +435,7 @@ Takahiro Nakayama Travers Naran Fredrik Nehr +Tony Nelson Chad Netzer Max Neunh?ffer George Neville-Neil @@ -623,6 +625,7 @@ John Tromp Jason Trowbridge Anthony Tuininga +Christopher Tur Lesniewski-Laas Stephen Turner Bill Tutt Doobee R. Tzeck Modified: stackless/trunk/Misc/NEWS ============================================================================== --- stackless/trunk/Misc/NEWS (original) +++ stackless/trunk/Misc/NEWS Mon Aug 14 12:38:35 2006 @@ -4,6 +4,209 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 2.5 beta 3? +================================ + +*Release date: 03-AUG-2006* + +Core and builtins +----------------- + +- _PyWeakref_GetWeakrefCount() now returns a Py_ssize_t, it previously + returned a long (see PEP 353). + +- Bug #1515471: string.replace() accepts character buffers again. + +- Add PyErr_WarnEx() so C code can pass the stacklevel to warnings.warn(). + This provides the proper warning for struct.pack(). + PyErr_Warn() is now deprecated in favor of PyErr_WarnEx(). + +- Patch #1531113: Fix augmented assignment with yield expressions. + Also fix a SystemError when trying to assign to yield expressions. + +- Bug #1529871: The speed enhancement patch #921466 broke Python's compliance + with PEP 302. This was fixed by adding an ``imp.NullImporter`` type that is + used in ``sys.path_importer_cache`` to cache non-directory paths and avoid + excessive filesystem operations during imports. + +- Bug #1521947: When checking for overflow, ``PyOS_strtol()`` used some + operations on signed longs that are formally undefined by C. + Unfortunately, at least one compiler now cares about that, so complicated + the code to make that compiler happy again. + +- Bug #1524310: Properly report errors from FindNextFile in os.listdir. + +- Patch #1232023: Stop including current directory in search + path on Windows. + +- Fix some potential crashes found with failmalloc. + +- Fix warnings reported by Klocwork's static analysis tool. + +- Bug #1512814, Fix incorrect lineno's when code within a function + had more than 255 blank lines. + +- Patch #1521179: Python now accepts the standard options ``--help`` and + ``--version`` as well as ``/?`` on Windows. + +- Bug #1520864: unpacking singleton tuples in a 'for' loop (for x, in) works + again. Fixing this problem required changing the .pyc magic number. + This means that .pyc files generated before 2.5c1 will be regenerated. + +- Bug #1524317: Compiling Python ``--without-threads`` failed. + The Python core compiles again then, and, in a build without threads, the + new ``sys._current_frames()`` returns a dictionary with one entry, + mapping the faux "thread id" 0 to the current frame. + +- Bug #1525447: build on MacOS X on a case-sensitive filesystem. + + +Library +------- + +- Correction of patch #1455898: In the mbcs decoder, set final=False + for stream decoder, but final=True for the decode function. + +- os.urandom no longer masks unrelated exceptions like SystemExit or + KeyboardInterrupt. + +- Bug #1525866: Don't copy directory stat times in + shutil.copytree on Windows + +- Bug #1002398: The documentation for os.path.sameopenfile now correctly + refers to file descriptors, not file objects. + +- Rename of the xml package to xmlcore, and the import hackery done to + make it appear at both names, has been removed. Bug #1511497, + #1513611, and probably others. + +- Bug #1441397: The compiler module now recognizes module and function + docstrings correctly as it did in Python 2.4. + +- Bug #1529297: The rewrite of doctest for Python 2.4 unintentionally + lost that tests are sorted by name before being run. This rarely + matters for well-written tests, but can create baffling symptoms if + side effects from one test to the next affect outcomes. ``DocTestFinder`` + has been changed to sort the list of tests it returns. + +- The distutils version has been changed to 2.5.0, and are now kept + in sync with sys.version_info[:3]. + +- Bug #978833: Really close underlying socket in _socketobject.close. + +- Bug #1459963: urllib and urllib2 now normalize HTTP header names correctly + with title(). + +- Patch #1525766: In pkgutil.walk_packages, correctly pass the onerror callback + to recursive calls and call it with the failing package name. + +- Bug #1525817: Don't truncate short lines in IDLE's tool tips. + +- Patch #1515343: Fix printing of deprecated string exceptions with a + value in the traceback module. + +- Resync optparse with Optik 1.5.3: minor tweaks for/to tests. + +- Patch #1524429: Use repr() instead of backticks in Tkinter again. + +- Bug #1520914: Change time.strftime() to accept a zero for any position in its + argument tuple. For arguments where zero is illegal, the value is forced to + the minimum value that is correct. This is to support an undocumented but + common way people used to fill in inconsequential information in the time + tuple pre-2.4. + +- Patch #1220874: Update the binhex module for Mach-O. + +- The email package has improved RFC 2231 support, specifically for + recognizing the difference between encoded (name*0*=) and non-encoded + (name*0=) parameter continuations. This may change the types of + values returned from email.message.Message.get_param() and friends. + Specifically in some cases where non-encoded continuations were used, + get_param() used to return a 3-tuple of (None, None, string) whereas now it + will just return the string (since non-encoded continuations don't have + charset and language parts). + + Also, whereas % values were decoded in all parameter continuations, they are + now only decoded in encoded parameter parts. + +- Bug #1517990: IDLE keybindings on MacOS X now work correctly + +- Bug #1517996: IDLE now longer shows the default Tk menu when a + path browser, class browser or debugger is the frontmost window on MacOS X + +- Patch #1520294: Support for getset and member descriptors in types.py, + inspect.py, and pydoc.py. Specifically, this allows for querying the type + of an object against these built-in types and more importantly, for getting + their docstrings printed in the interactive interpreter's help() function. + + +Extension Modules +----------------- + +- Patch #1519025 and bug #926423: If a KeyboardInterrupt occurs during + a socket operation on a socket with a timeout, the exception will be + caught correctly. Previously, the exception was not caught. + +- Patch #1529514: The _ctypes extension is now compiled on more + openbsd target platforms. + +- The ``__reduce__()`` method of the new ``collections.defaultdict`` had + a memory leak, affecting pickles and deep copies. + +- Bug #1471938: Fix curses module build problem on Solaris 8; patch by + Paul Eggert. + +- Patch #1448199: Release interpreter lock in _winreg.ConnectRegistry. + +- Patch #1521817: Index range checking on ctypes arrays containing + exactly one element enabled again. This allows iterating over these + arrays, without the need to check the array size before. + +- Bug #1521375: When the code in ctypes.util.find_library was + run with root privileges, it could overwrite or delete + /dev/null in certain cases; this is now fixed. + +- Bug #1467450: On Mac OS X 10.3, RTLD_GLOBAL is now used as the + default mode for loading shared libraries in ctypes. + +- Because of a misspelled preprocessor symbol, ctypes was always + compiled without thread support; this is now fixed. + +- pybsddb Bug #1527939: bsddb module DBEnv dbremove and dbrename + methods now allow their database parameter to be None as the + sleepycat API allows. + +- Bug #1526460: Fix socketmodule compile on NetBSD as it has a different + bluetooth API compared with Linux and FreeBSD. + +Tests +----- + +- Bug #1501330: Change test_ossaudiodev to be much more tolerant in terms of + how long the test file should take to play. Now accepts taking 2.93 secs + (exact time) +/- 10% instead of the hard-coded 3.1 sec. + +- Patch #1529686: The standard tests ``test_defaultdict``, ``test_iterlen``, + ``test_uuid`` and ``test_email_codecs`` didn't actually run any tests when + run via ``regrtest.py``. Now they do. + +Build +----- + +- Bug #1439538: Drop usage of test -e in configure as it is not portable. + +Mac +--- + +- PythonLauncher now works correctly when the path to the script contains + characters that are treated specially by the shell (such as quotes). + +- Bug #1527397: PythonLauncher now launches scripts with the working directory + set to the directory that contains the script instead of the user home + directory. That latter was an implementation accident and not what users + expect. + + What's New in Python 2.5 beta 2? ================================ @@ -46,6 +249,9 @@ Library ------- +- Bug #1257728: Mention Cygwin in distutils error message about a missing + VS 2003. + - Patch #1519566: Update turtle demo, make begin_fill idempotent. - Bug #1508010: msvccompiler now requires the DISTUTILS_USE_SDK @@ -105,9 +311,9 @@ Extension Modules ----------------- -- #1494314: Fix a regression with high-numbered sockets in 2.4.3. This - means that select() on sockets > FD_SETSIZE (typically 1024) work again. - The patch makes sockets use poll() internally where available. +- #1494314: Fix a regression with high-numbered sockets in 2.4.3. This + means that select() on sockets > FD_SETSIZE (typically 1024) work again. + The patch makes sockets use poll() internally where available. - Assigning None to pointer type fields in ctypes structures possible overwrote the wrong fields, this is fixed now. @@ -139,6 +345,8 @@ Build ----- +- Automate Windows build process for the Win64 SSL module. + - 'configure' now detects the zlib library the same way as distutils. Previously, the slight difference could cause compilation errors of the 'zlib' module on systems with more than one version of zlib. @@ -543,6 +751,10 @@ Library ------- +- Bug #1223937: subprocess.CalledProcessError reports the exit status + of the process using the returncode attribute, instead of + abusing errno. + - Patch #1475231: ``doctest`` has a new ``SKIP`` option, which causes a doctest to be skipped (the code is not run, and the expected output or exception is ignored). @@ -1161,6 +1373,10 @@ Library ------- +- Patch #1388073: Numerous __-prefixed attributes of unittest.TestCase have + been renamed to have only a single underscore prefix. This was done to + make subclassing easier. + - PEP 338: new module runpy defines a run_module function to support executing modules which provide access to source code or a code object via the PEP 302 import mechanisms. @@ -1476,8 +1692,8 @@ - Bug #792570: SimpleXMLRPCServer had problems if the request grew too large. Fixed by reading the HTTP body in chunks instead of one big socket.read(). -- Patches #893642, #1039083: add allow_none, encoding arguments to constructors of - SimpleXMLRPCServer and CGIXMLRPCRequestHandler. +- Patches #893642, #1039083: add allow_none, encoding arguments to + constructors of SimpleXMLRPCServer and CGIXMLRPCRequestHandler. - Bug #1110478: Revert os.environ.update to do putenv again. Modified: stackless/trunk/Misc/RPM/python-2.5.spec ============================================================================== --- stackless/trunk/Misc/RPM/python-2.5.spec (original) +++ stackless/trunk/Misc/RPM/python-2.5.spec Mon Aug 14 12:38:35 2006 @@ -33,7 +33,7 @@ ################################# %define name python -%define version 2.5b2 +%define version 2.5b3 %define libvers 2.5 %define release 1pydotorg %define __prefix /usr Modified: stackless/trunk/Misc/build.sh ============================================================================== --- stackless/trunk/Misc/build.sh (original) +++ stackless/trunk/Misc/build.sh Mon Aug 14 12:38:35 2006 @@ -161,6 +161,10 @@ make install >& build/$F update_status "Installing" "$F" $start + if [ ! -x $PYTHON ]; then + ln -s ${PYTHON}2.* $PYTHON + fi + ## make and run basic tests F=make-test.out start=`current_time` Modified: stackless/trunk/Misc/python-config.in ============================================================================== --- stackless/trunk/Misc/python-config.in (original) +++ stackless/trunk/Misc/python-config.in Mon Aug 14 12:38:35 2006 @@ -1,4 +1,4 @@ -#!@BINDIR@/python +#!@EXENAME@ import sys import os @@ -36,13 +36,14 @@ print sysconfig.EXEC_PREFIX elif opt in ('--includes', '--cflags'): - flags = ['-I'+dir for dir in getvar('INCLDIRSTOMAKE').split()] + flags = ['-I' + sysconfig.get_python_inc(), + '-I' + sysconfig.get_python_inc(plat_specific=True)] if opt == '--cflags': flags.extend(getvar('CFLAGS').split()) print ' '.join(flags) elif opt in ('--libs', '--ldflags'): - libs = sysconfig.get_config_var('LIBS').split() + libs = getvar('LIBS').split() + getvar('SYSLIBS').split() libs.append('-lpython'+pyver) if opt == '--ldflags': libs.insert(0, '-L' + getvar('LIBPL')) Modified: stackless/trunk/Modules/_bsddb.c ============================================================================== --- stackless/trunk/Modules/_bsddb.c (original) +++ stackless/trunk/Modules/_bsddb.c Mon Aug 14 12:38:35 2006 @@ -98,7 +98,7 @@ #error "eek! DBVER can't handle minor versions > 9" #endif -#define PY_BSDDB_VERSION "4.4.4" +#define PY_BSDDB_VERSION "4.4.5" static char *rcs_id = "$Id$"; @@ -528,6 +528,7 @@ PyObject *errObj = NULL; PyObject *errTuple = NULL; int exceptionRaised = 0; + unsigned int bytes_left; switch (err) { case 0: /* successful, no error */ break; @@ -535,12 +536,15 @@ #if (DBVER < 41) case DB_INCOMPLETE: #if INCOMPLETE_IS_WARNING - our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt)); - if (_db_errmsg[0]) { + bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt)); + /* Ensure that bytes_left never goes negative */ + if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) { + bytes_left = sizeof(errTxt) - bytes_left - 4 - 1; + assert(bytes_left >= 0); strcat(errTxt, " -- "); - strcat(errTxt, _db_errmsg); - _db_errmsg[0] = 0; + strncat(errTxt, _db_errmsg, bytes_left); } + _db_errmsg[0] = 0; #ifdef HAVE_WARNINGS exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt); #else @@ -588,12 +592,15 @@ } if (errObj != NULL) { - our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt)); - if (_db_errmsg[0]) { + bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt)); + /* Ensure that bytes_left never goes negative */ + if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) { + bytes_left = sizeof(errTxt) - bytes_left - 4 - 1; + assert(bytes_left >= 0); strcat(errTxt, " -- "); - strcat(errTxt, _db_errmsg); - _db_errmsg[0] = 0; + strncat(errTxt, _db_errmsg, bytes_left); } + _db_errmsg[0] = 0; errTuple = Py_BuildValue("(is)", err, errTxt); PyErr_SetObject(errObj, errTuple); @@ -798,10 +805,12 @@ MYDB_BEGIN_ALLOW_THREADS; err = db_create(&self->db, db_env, flags); - self->db->set_errcall(self->db, _db_errorCallback); + if (self->db != NULL) { + self->db->set_errcall(self->db, _db_errorCallback); #if (DBVER >= 33) - self->db->app_private = (void*)self; + self->db->app_private = (void*)self; #endif + } MYDB_END_ALLOW_THREADS; /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs * list so that a DBEnv can refuse to close without aborting any open @@ -3867,7 +3876,7 @@ static char* kwnames[] = { "file", "database", "txn", "flags", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|Oi:dbremove", kwnames, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames, &file, &database, &txnobj, &flags)) { return NULL; } @@ -3895,7 +3904,7 @@ static char* kwnames[] = { "file", "database", "newname", "txn", "flags", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sss|Oi:dbrename", kwnames, + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames, &file, &database, &newname, &txnobj, &flags)) { return NULL; } Modified: stackless/trunk/Modules/_codecsmodule.c ============================================================================== --- stackless/trunk/Modules/_codecsmodule.c (original) +++ stackless/trunk/Modules/_codecsmodule.c Mon Aug 14 12:38:35 2006 @@ -481,7 +481,7 @@ const char *data; Py_ssize_t size, consumed; const char *errors = NULL; - int final = 1; + int final = 0; PyObject *decoded; if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode", Modified: stackless/trunk/Modules/_ctypes/_ctypes.c ============================================================================== --- stackless/trunk/Modules/_ctypes/_ctypes.c (original) +++ stackless/trunk/Modules/_ctypes/_ctypes.c Mon Aug 14 12:38:35 2006 @@ -3573,7 +3573,8 @@ int offset, size; StgDictObject *stgdict; - if (self->b_length == 0 || index < 0 || (self->b_length > 1 && index >= self->b_length)) { + + if (index < 0 || index >= self->b_length) { PyErr_SetString(PyExc_IndexError, "invalid index"); return NULL; @@ -3602,11 +3603,11 @@ if (ilow < 0) ilow = 0; - else if (ilow > self->b_length && self->b_length != 1) + else if (ilow > self->b_length) ilow = self->b_length; if (ihigh < ilow) ihigh = ilow; - else if (ihigh > self->b_length && self->b_length != 1) + else if (ihigh > self->b_length) ihigh = self->b_length; len = ihigh - ilow; @@ -3649,8 +3650,7 @@ } stgdict = PyObject_stgdict((PyObject *)self); - if (self->b_length == 0 || index < 0 - || (self->b_length > 1 && index >= self->b_length)) { + if (index < 0 || index >= stgdict->length) { PyErr_SetString(PyExc_IndexError, "invalid index"); return -1; @@ -3677,19 +3677,17 @@ if (ilow < 0) ilow = 0; - else if (ilow > self->b_length && self->b_length != 1) + else if (ilow > self->b_length) ilow = self->b_length; - if (ihigh < 0) ihigh = 0; - if (ihigh < ilow) ihigh = ilow; - else if (ihigh > self->b_length && self->b_length != 1) + else if (ihigh > self->b_length) ihigh = self->b_length; len = PySequence_Length(value); - if (self->b_length != 1 && len != ihigh - ilow) { + if (len != ihigh - ilow) { PyErr_SetString(PyExc_ValueError, "Can only assign sequence of same size"); return -1; @@ -4523,23 +4521,30 @@ if (obj->b_objects == Py_None) { Py_DECREF(Py_None); obj->b_objects = PyDict_New(); + if (obj->b_objects == NULL) + goto failed; } - Py_INCREF(obj->b_objects); result->b_objects = obj->b_objects; if (result->b_objects) { - PyObject *index = PyLong_FromVoidPtr((void *)src); + PyObject *index; int rc; + Py_INCREF(obj->b_objects); + index = PyLong_FromVoidPtr((void *)src); if (index == NULL) - return NULL; + goto failed; rc = PyDict_SetItem(result->b_objects, index, src); Py_DECREF(index); if (rc == -1) - return NULL; + goto failed; } } /* Should we assert that result is a pointer type? */ memcpy(result->b_ptr, &ptr, sizeof(void *)); return (PyObject *)result; + + failed: + Py_DECREF(result); + return NULL; } #ifdef CTYPES_UNICODE @@ -4561,7 +4566,7 @@ ob_type is the metatype (the 'type'), defaults to PyType_Type, tp_base is the base type, defaults to 'object' aka PyBaseObject_Type. */ -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyEval_InitThreads(); #endif m = Py_InitModule3("_ctypes", module_methods, module_docs); @@ -4673,7 +4678,7 @@ #endif PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); - PyModule_AddStringConstant(m, "__version__", "0.9.9.7"); + PyModule_AddStringConstant(m, "__version__", "1.0.0"); PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); @@ -4711,13 +4716,14 @@ } /***************************************************************** - * replacements for broken Python api functions + * replacements for broken Python api functions (in Python 2.3). + * See #1047269 Buffer overwrite in PyUnicode_AsWideChar */ #ifdef HAVE_WCHAR_H PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w, - int size) + Py_ssize_t size) { PyUnicodeObject *unicode; @@ -4749,7 +4755,7 @@ int My_PyUnicode_AsWideChar(PyUnicodeObject *unicode, register wchar_t *w, - int size) + Py_ssize_t size) { if (unicode == NULL) { PyErr_BadInternalCall(); Modified: stackless/trunk/Modules/_ctypes/callbacks.c ============================================================================== --- stackless/trunk/Modules/_ctypes/callbacks.c (original) +++ stackless/trunk/Modules/_ctypes/callbacks.c Mon Aug 14 12:38:35 2006 @@ -127,7 +127,7 @@ PyObject *result; PyObject *arglist = NULL; int nArgs; -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyGILState_STATE state = PyGILState_Ensure(); #endif @@ -237,7 +237,7 @@ Py_XDECREF(result); Done: Py_XDECREF(arglist); -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyGILState_Release(state); #endif } @@ -348,7 +348,9 @@ static void LoadPython(void) { if (!Py_IsInitialized()) { +#ifdef WITH_THREAD PyEval_InitThreads(); +#endif Py_Initialize(); } } @@ -400,16 +402,16 @@ LPVOID *ppv) { long result; -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyGILState_STATE state; #endif LoadPython(); -#ifdef WITH_THREADS +#ifdef WITH_THREAD state = PyGILState_Ensure(); #endif result = Call_GetClassObject(rclsid, riid, ppv); -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyGILState_Release(state); #endif return result; @@ -463,11 +465,11 @@ STDAPI DllCanUnloadNow(void) { long result; -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyGILState_STATE state = PyGILState_Ensure(); #endif result = Call_CanUnloadNow(); -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyGILState_Release(state); #endif return result; Modified: stackless/trunk/Modules/_ctypes/callproc.c ============================================================================== --- stackless/trunk/Modules/_ctypes/callproc.c (original) +++ stackless/trunk/Modules/_ctypes/callproc.c Mon Aug 14 12:38:35 2006 @@ -617,7 +617,7 @@ void *resmem, int argcount) { -#ifdef WITH_THREADS +#ifdef WITH_THREAD PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */ #endif ffi_cif cif; @@ -651,7 +651,7 @@ return -1; } -#ifdef WITH_THREADS +#ifdef WITH_THREAD if ((flags & FUNCFLAG_PYTHONAPI) == 0) Py_UNBLOCK_THREADS #endif @@ -671,7 +671,7 @@ } #endif #endif -#ifdef WITH_THREADS +#ifdef WITH_THREAD if ((flags & FUNCFLAG_PYTHONAPI) == 0) Py_BLOCK_THREADS #endif @@ -818,7 +818,9 @@ /* We absolutely have to release the GIL during COM method calls, otherwise we may get a deadlock! */ +#ifdef WITH_THREAD Py_BEGIN_ALLOW_THREADS +#endif hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei); if (FAILED(hr)) @@ -842,22 +844,24 @@ pei->lpVtbl->Release(pei); failed: +#ifdef WITH_THREAD Py_END_ALLOW_THREADS +#endif progid = NULL; ProgIDFromCLSID(&guid, &progid); -/* XXX Is COMError derived from WindowsError or not? */ text = FormatError(errcode); + obj = Py_BuildValue( #ifdef _UNICODE - obj = Py_BuildValue("iu(uuuiu)", + "iu(uuuiu)", #else - obj = Py_BuildValue("is(uuuiu)", + "is(uuuiu)", #endif - errcode, - text, - descr, source, helpfile, helpcontext, - progid); + errcode, + text, + descr, source, helpfile, helpcontext, + progid); if (obj) { PyErr_SetObject(ComError, obj); Py_DECREF(obj); @@ -1156,7 +1160,7 @@ } static char copy_com_pointer_doc[] = -"CopyComPointer(a, b) -> integer\n"; +"CopyComPointer(src, dst) -> HRESULT value\n"; static PyObject * copy_com_pointer(PyObject *self, PyObject *args) Modified: stackless/trunk/Modules/_ctypes/cfield.c ============================================================================== --- stackless/trunk/Modules/_ctypes/cfield.c (original) +++ stackless/trunk/Modules/_ctypes/cfield.c Mon Aug 14 12:38:35 2006 @@ -124,7 +124,7 @@ self->getfunc = getfunc; self->index = index; - Py_XINCREF(proto); + Py_INCREF(proto); self->proto = proto; switch (fieldtype) { Modified: stackless/trunk/Modules/_ctypes/ctypes.h ============================================================================== --- stackless/trunk/Modules/_ctypes/ctypes.h (original) +++ stackless/trunk/Modules/_ctypes/ctypes.h Mon Aug 14 12:38:35 2006 @@ -377,8 +377,8 @@ # undef PyUnicode_AsWideChar # define PyUnicode_AsWideChar My_PyUnicode_AsWideChar -extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, int); -extern int My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, int); +extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, Py_ssize_t); +extern int My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, Py_ssize_t); #endif Modified: stackless/trunk/Modules/_ctypes/libffi/configure ============================================================================== --- stackless/trunk/Modules/_ctypes/libffi/configure (original) +++ stackless/trunk/Modules/_ctypes/libffi/configure Mon Aug 14 12:38:35 2006 @@ -934,7 +934,7 @@ else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi - cd $ac_popdir + cd "$ac_popdir" done fi @@ -1973,8 +1973,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2032,8 +2031,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2149,8 +2147,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2204,8 +2201,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2250,8 +2246,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2295,8 +2290,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2623,8 +2617,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2794,8 +2787,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -2862,8 +2854,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3047,8 +3038,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3111,8 +3101,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3290,8 +3279,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3408,8 +3396,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3483,6 +3470,12 @@ TARGETDIR="unknown" case "$host" in +mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;; +sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; +sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; +alpha*-*-openbsd*) TARGET=ALPHA; TARGETDIR=alpha;; +m68k-*-openbsd*) TARGET=M68K; TARGETDIR=m68k;; +powerpc-*-openbsd*) TARGET=POWERPC; TARGETDIR=powerpc;; i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;; i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; @@ -3575,8 +3568,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3777,8 +3769,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3841,8 +3832,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -3923,8 +3913,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4065,8 +4054,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4202,8 +4190,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4265,8 +4252,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4306,8 +4292,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4363,8 +4348,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4404,8 +4388,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4469,8 +4452,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4501,10 +4483,8 @@ esac else if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} + { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 +echo "$as_me: error: internal error: not reached in cross-compile" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF @@ -4616,8 +4596,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4679,8 +4658,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4720,8 +4698,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4777,8 +4754,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4818,8 +4794,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4883,8 +4858,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -4915,10 +4889,8 @@ esac else if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} + { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5 +echo "$as_me: error: internal error: not reached in cross-compile" >&2;} { (exit 1); exit 1; }; } else cat >conftest.$ac_ext <<_ACEOF @@ -5048,8 +5020,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5091,8 +5062,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5149,8 +5119,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5282,8 +5251,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5349,8 +5317,7 @@ cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -6309,11 +6276,6 @@ - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ @@ -6352,6 +6314,12 @@ fi;; esac done` || { (exit 1); exit 1; } + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub Modified: stackless/trunk/Modules/_ctypes/libffi/configure.ac ============================================================================== --- stackless/trunk/Modules/_ctypes/libffi/configure.ac (original) +++ stackless/trunk/Modules/_ctypes/libffi/configure.ac Mon Aug 14 12:38:35 2006 @@ -21,6 +21,12 @@ TARGETDIR="unknown" case "$host" in +mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;; +sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; +sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; +alpha*-*-openbsd*) TARGET=ALPHA; TARGETDIR=alpha;; +m68k-*-openbsd*) TARGET=M68K; TARGETDIR=m68k;; +powerpc-*-openbsd*) TARGET=POWERPC; TARGETDIR=powerpc;; i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;; i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; Modified: stackless/trunk/Modules/_ctypes/stgdict.c ============================================================================== --- stackless/trunk/Modules/_ctypes/stgdict.c (original) +++ stackless/trunk/Modules/_ctypes/stgdict.c Mon Aug 14 12:38:35 2006 @@ -134,16 +134,25 @@ type = (PyTypeObject *)obj; if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS)) return NULL; - if (!type->tp_dict || !StgDict_Check(type->tp_dict)) + if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } /* May return NULL, but does not set an exception! */ +/* + This function should be as fast as possible, so we don't call PyType_stgdict + above but inline the code, and avoid the PyType_Check(). +*/ StgDictObject * PyObject_stgdict(PyObject *self) { - return PyType_stgdict((PyObject *)self->ob_type); + PyTypeObject *type = self->ob_type; + if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS)) + return NULL; + if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict)) + return NULL; + return (StgDictObject *)type->tp_dict; } /* descr is the descriptor for a field marked as anonymous. Get all the Modified: stackless/trunk/Modules/_cursesmodule.c ============================================================================== --- stackless/trunk/Modules/_cursesmodule.c (original) +++ stackless/trunk/Modules/_cursesmodule.c Mon Aug 14 12:38:35 2006 @@ -43,7 +43,7 @@ del_curterm delscreen dupwin inchnstr inchstr innstr keyok mcprint mvaddchnstr mvaddchstr mvchgat mvcur mvinchnstr mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr mvwchgat - mvwgetnstr mvwinchnstr mvwinchstr mvwinnstr newterm + mvwinchnstr mvwinchstr mvwinnstr newterm restartterm ripoffline scr_dump scr_init scr_restore scr_set scrl set_curterm set_term setterm tgetent tgetflag tgetnum tgetstr tgoto timeout tputs @@ -819,14 +819,17 @@ if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x)) return NULL; Py_BEGIN_ALLOW_THREADS +#ifdef STRICT_SYSV_CURSES + rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023); +#else rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023); +#endif Py_END_ALLOW_THREADS break; case 3: if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n)) return NULL; #ifdef STRICT_SYSV_CURSES - /* Untested */ Py_BEGIN_ALLOW_THREADS rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, MIN(n, 1023)); @@ -838,7 +841,7 @@ #endif break; default: - PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 2 arguments"); + PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments"); return NULL; } if (rtn2 == ERR) Modified: stackless/trunk/Modules/_sqlite/cursor.c ============================================================================== --- stackless/trunk/Modules/_sqlite/cursor.c (original) +++ stackless/trunk/Modules/_sqlite/cursor.c Mon Aug 14 12:38:35 2006 @@ -621,7 +621,7 @@ } } else { if (PyErr_Occurred()) { - /* there was an error that occured in a user-defined callback */ + /* there was an error that occurred in a user-defined callback */ if (_enable_callback_tracebacks) { PyErr_Print(); } else { Modified: stackless/trunk/Modules/_sqlite/util.c ============================================================================== --- stackless/trunk/Modules/_sqlite/util.c (original) +++ stackless/trunk/Modules/_sqlite/util.c Mon Aug 14 12:38:35 2006 @@ -38,7 +38,7 @@ /** * Checks the SQLite error code and sets the appropriate DB-API exception. - * Returns the error code (0 means no error occured). + * Returns the error code (0 means no error occurred). */ int _seterror(sqlite3* db) { Modified: stackless/trunk/Modules/_sqlite/util.h ============================================================================== --- stackless/trunk/Modules/_sqlite/util.h (original) +++ stackless/trunk/Modules/_sqlite/util.h Mon Aug 14 12:38:35 2006 @@ -32,7 +32,7 @@ /** * Checks the SQLite error code and sets the appropriate DB-API exception. - * Returns the error code (0 means no error occured). + * Returns the error code (0 means no error occurred). */ int _seterror(sqlite3* db); #endif Modified: stackless/trunk/Modules/_struct.c ============================================================================== --- stackless/trunk/Modules/_struct.c (original) +++ stackless/trunk/Modules/_struct.c Mon Aug 14 12:38:35 2006 @@ -214,6 +214,8 @@ /* Helper routine to get a Python integer and raise the appropriate error if it isn't one */ +#define INT_OVERFLOW "struct integer overflow masking is deprecated" + static int get_wrapped_long(PyObject *v, long *p) { @@ -223,7 +225,7 @@ PyObject *wrapped; long x; PyErr_Clear(); - if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) + if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) return -1; wrapped = PyNumber_And(v, pylong_ulong_mask); if (wrapped == NULL) @@ -250,7 +252,7 @@ wrapped = PyNumber_And(v, pylong_ulong_mask); if (wrapped == NULL) return -1; - if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) { Py_DECREF(wrapped); return -1; } @@ -345,8 +347,8 @@ Py_XDECREF(ptraceback); if (msg == NULL) return -1; - rval = PyErr_Warn(PyExc_DeprecationWarning, - PyString_AS_STRING(msg)); + rval = PyErr_WarnEx(PyExc_DeprecationWarning, + PyString_AS_STRING(msg), 2); Py_DECREF(msg); if (rval == 0) return 0; Modified: stackless/trunk/Modules/_testcapimodule.c ============================================================================== --- stackless/trunk/Modules/_testcapimodule.c (original) +++ stackless/trunk/Modules/_testcapimodule.c Mon Aug 14 12:38:35 2006 @@ -294,6 +294,16 @@ #endif /* ifdef HAVE_LONG_LONG */ +/* Test tuple argument processing */ +static PyObject * +getargs_tuple(PyObject *self, PyObject *args) +{ + int a, b, c; + if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c)) + return NULL; + return Py_BuildValue("iii", a, b, c); +} + /* Functions to call PyArg_ParseTuple with integer format codes, and return the result. */ @@ -707,6 +717,7 @@ {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, + {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_b", getargs_b, METH_VARARGS}, {"getargs_B", getargs_B, METH_VARARGS}, {"getargs_H", getargs_H, METH_VARARGS}, Modified: stackless/trunk/Modules/_tkinter.c ============================================================================== --- stackless/trunk/Modules/_tkinter.c (original) +++ stackless/trunk/Modules/_tkinter.c Mon Aug 14 12:38:35 2006 @@ -2104,8 +2104,8 @@ data = PyMem_NEW(PythonCmd_ClientData, 1); if (!data) return PyErr_NoMemory(); - Py_XINCREF(self); - Py_XINCREF(func); + Py_INCREF(self); + Py_INCREF(func); data->self = selfptr; data->func = func; Modified: stackless/trunk/Modules/_weakref.c ============================================================================== --- stackless/trunk/Modules/_weakref.c (original) +++ stackless/trunk/Modules/_weakref.c Mon Aug 14 12:38:35 2006 @@ -17,7 +17,7 @@ if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); - result = PyInt_FromLong(_PyWeakref_GetWeakrefCount(*list)); + result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list)); } else result = PyInt_FromLong(0); @@ -37,12 +37,12 @@ if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); - long count = _PyWeakref_GetWeakrefCount(*list); + Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); result = PyList_New(count); if (result != NULL) { PyWeakReference *current = *list; - long i; + Py_ssize_t i; for (i = 0; i < count; ++i) { PyList_SET_ITEM(result, i, (PyObject *) current); Py_INCREF(current); Modified: stackless/trunk/Modules/bz2module.c ============================================================================== --- stackless/trunk/Modules/bz2module.c (original) +++ stackless/trunk/Modules/bz2module.c Mon Aug 14 12:38:35 2006 @@ -1348,8 +1348,10 @@ #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); - if (!self->lock) + if (!self->lock) { + PyErr_SetString(PyExc_MemoryError, "unable to allocate lock"); goto error; + } #endif if (mode_char == 'r') @@ -1371,10 +1373,12 @@ return 0; error: - Py_DECREF(self->file); + Py_CLEAR(self->file); #ifdef WITH_THREAD - if (self->lock) + if (self->lock) { PyThread_free_lock(self->lock); + self->lock = NULL; + } #endif return -1; } @@ -1682,8 +1686,10 @@ #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); - if (!self->lock) + if (!self->lock) { + PyErr_SetString(PyExc_MemoryError, "unable to allocate lock"); goto error; + } #endif memset(&self->bzs, 0, sizeof(bz_stream)); @@ -1698,8 +1704,10 @@ return 0; error: #ifdef WITH_THREAD - if (self->lock) + if (self->lock) { PyThread_free_lock(self->lock); + self->lock = NULL; + } #endif return -1; } @@ -1894,8 +1902,10 @@ #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); - if (!self->lock) + if (!self->lock) { + PyErr_SetString(PyExc_MemoryError, "unable to allocate lock"); goto error; + } #endif self->unused_data = PyString_FromString(""); @@ -1915,10 +1925,12 @@ error: #ifdef WITH_THREAD - if (self->lock) + if (self->lock) { PyThread_free_lock(self->lock); + self->lock = NULL; + } #endif - Py_XDECREF(self->unused_data); + Py_CLEAR(self->unused_data); return -1; } Modified: stackless/trunk/Modules/cPickle.c ============================================================================== --- stackless/trunk/Modules/cPickle.c (original) +++ stackless/trunk/Modules/cPickle.c Mon Aug 14 12:38:35 2006 @@ -198,7 +198,7 @@ for (i = self->length, p = self->data + clearto; --i >= clearto; p++) { - Py_DECREF(*p); + Py_CLEAR(*p); } self->length = clearto; @@ -210,6 +210,7 @@ { int bigger; size_t nbytes; + PyObject **tmp; bigger = self->size << 1; if (bigger <= 0) /* was 0, or new value overflows */ @@ -219,14 +220,14 @@ nbytes = (size_t)bigger * sizeof(PyObject *); if (nbytes / sizeof(PyObject *) != (size_t)bigger) goto nomemory; - self->data = realloc(self->data, nbytes); - if (self->data == NULL) + tmp = realloc(self->data, nbytes); + if (tmp == NULL) goto nomemory; + self->data = tmp; self->size = bigger; return 0; nomemory: - self->size = 0; PyErr_NoMemory(); return -1; } @@ -2663,7 +2664,7 @@ if (ik >= lm || ik == 0) { PyErr_SetString(PicklingError, "Invalid get data"); - return NULL; + goto err; } if (have_get[ik]) /* with matching get */ rsize += ik < 256 ? 2 : 5; @@ -2675,7 +2676,7 @@ ) { PyErr_SetString(PicklingError, "Unexpected data in internal list"); - return NULL; + goto err; } else { /* put */ @@ -3472,11 +3473,11 @@ /********************************************/ str = PyString_DecodeEscape(p, len, NULL, 0, NULL); + free(s); if (str) { PDATA_PUSH(self->stack, str, -1); res = 0; } - free(s); return res; insecure: @@ -4235,6 +4236,7 @@ int list_len; slice=Pdata_popList(self->stack, x); + if (! slice) return -1; list_len = PyList_GET_SIZE(list); i=PyList_SetSlice(list, list_len, list_len, slice); Py_DECREF(slice); @@ -5239,6 +5241,9 @@ if (!( self->memo = PyDict_New())) goto err; + if (!self->stack) + goto err; + Py_INCREF(f); self->file = f; Modified: stackless/trunk/Modules/collectionsmodule.c ============================================================================== --- stackless/trunk/Modules/collectionsmodule.c (original) +++ stackless/trunk/Modules/collectionsmodule.c Mon Aug 14 12:38:35 2006 @@ -10,7 +10,7 @@ /* The block length may be set to any number over 1. Larger numbers * reduce the number of calls to the memory allocator but take more * memory. Ideally, BLOCKLEN should be set with an eye to the - * length of a cache line. + * length of a cache line. */ #define BLOCKLEN 62 @@ -22,9 +22,9 @@ * element is at d.leftblock[leftindex] and its last element is at * d.rightblock[rightindex]; note that, unlike as for Python slice * indices, these indices are inclusive on both ends. By being inclusive - * on both ends, algorithms for left and right operations become + * on both ends, algorithms for left and right operations become * symmetrical which simplifies the design. - * + * * The list of blocks is never empty, so d.leftblock and d.rightblock * are never equal to NULL. * @@ -37,11 +37,11 @@ * d.leftindex == CENTER+1; and d.rightindex == CENTER. * Checking for d.len == 0 is the intended way to see whether d is empty. * - * Whenever d.leftblock == d.rightblock, + * Whenever d.leftblock == d.rightblock, * d.leftindex + d.len - 1 == d.rightindex. - * + * * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex - * become indices into distinct blocks and either may be larger than the + * become indices into distinct blocks and either may be larger than the * other. */ @@ -381,7 +381,7 @@ int cmp = PyObject_RichCompareBool(item, value, Py_EQ); if (deque->len != n) { - PyErr_SetString(PyExc_IndexError, + PyErr_SetString(PyExc_IndexError, "deque mutated during remove()."); return NULL; } @@ -920,7 +920,7 @@ "deque mutated during iteration"); return NULL; } - assert (!(it->b == it->deque->rightblock && + assert (!(it->b == it->deque->rightblock && it->index > it->deque->rightindex)); item = it->b->data[it->index]; @@ -1016,7 +1016,7 @@ "deque mutated during iteration"); return NULL; } - assert (!(it->b == it->deque->leftblock && + assert (!(it->b == it->deque->leftblock && it->index < it->deque->leftindex)); item = it->b->data[it->index]; @@ -1117,7 +1117,7 @@ static PyObject * defdict_reduce(defdictobject *dd) { - /* __reduce__ must returns a 5-tuple as follows: + /* __reduce__ must return a 5-tuple as follows: - factory function - tuple of args for the factory function @@ -1155,6 +1155,7 @@ } result = PyTuple_Pack(5, dd->dict.ob_type, args, Py_None, Py_None, items); + Py_DECREF(items); Py_DECREF(args); return result; } Modified: stackless/trunk/Modules/config.c.in ============================================================================== --- stackless/trunk/Modules/config.c.in (original) +++ stackless/trunk/Modules/config.c.in Mon Aug 14 12:38:35 2006 @@ -28,6 +28,7 @@ extern void initimp(void); extern void initgc(void); extern void init_ast(void); +extern void init_types(void); struct _inittab _PyImport_Inittab[] = { @@ -42,6 +43,9 @@ /* This lives in Python/Python-ast.c */ {"_ast", init_ast}, + /* This lives in Python/_types.c */ + {"_types", init_types}, + /* These entries are here for sys.builtin_module_names */ {"__main__", NULL}, {"__builtin__", NULL}, Modified: stackless/trunk/Modules/fcntlmodule.c ============================================================================== --- stackless/trunk/Modules/fcntlmodule.c (original) +++ stackless/trunk/Modules/fcntlmodule.c Mon Aug 14 12:38:35 2006 @@ -290,7 +290,7 @@ "flock(fd, operation)\n\ \n\ Perform the lock operation op on file descriptor fd. See the Unix \n\ -manual flock(3) for details. (On some systems, this function is\n\ +manual page for flock(3) for details. (On some systems, this function is\n\ emulated using fcntl().)"); @@ -327,7 +327,7 @@ l.l_type = F_WRLCK; else { PyErr_SetString(PyExc_ValueError, - "unrecognized flock argument"); + "unrecognized lockf argument"); return NULL; } l.l_start = l.l_len = 0; Modified: stackless/trunk/Modules/itertoolsmodule.c ============================================================================== --- stackless/trunk/Modules/itertoolsmodule.c (original) +++ stackless/trunk/Modules/itertoolsmodule.c Mon Aug 14 12:38:35 2006 @@ -357,7 +357,7 @@ { if (tdo->nextlink == NULL) tdo->nextlink = teedataobject_new(tdo->it); - Py_INCREF(tdo->nextlink); + Py_XINCREF(tdo->nextlink); return tdo->nextlink; } @@ -468,7 +468,7 @@ if (to->index >= LINKCELLS) { link = teedataobject_jumplink(to->dataobj); - Py_XDECREF(to->dataobj); + Py_DECREF(to->dataobj); to->dataobj = (teedataobject *)link; to->index = 0; } @@ -522,6 +522,12 @@ if (to == NULL) goto done; to->dataobj = (teedataobject *)teedataobject_new(it); + if (!to->dataobj) { + PyObject_GC_Del(to); + to = NULL; + goto done; + } + to->index = 0; to->weakreflist = NULL; PyObject_GC_Track(to); Modified: stackless/trunk/Modules/main.c ============================================================================== --- stackless/trunk/Modules/main.c (original) +++ stackless/trunk/Modules/main.c Mon Aug 14 12:38:35 2006 @@ -40,7 +40,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX" +#define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX?" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS @@ -62,7 +62,7 @@ -c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser (also PYTHONDEBUG=x)\n\ -E : ignore environment variables (such as PYTHONPATH)\n\ --h : print this help message and exit\n\ +-h : print this help message and exit (also --help)\n\ -i : inspect interactively after running script, (also PYTHONINSPECT=x)\n\ and force prompts, even if stdin does not appear to be a terminal\n\ "; @@ -78,7 +78,7 @@ static char *usage_3 = "\ see man page for details on internal buffering relating to '-u'\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ --V : print the Python version number and exit\n\ +-V : print the Python version number and exit (also --version)\n\ -W arg : warning control (arg is action:message:category:module:lineno)\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ file : program read from script file\n\ @@ -313,6 +313,7 @@ Py_UnicodeFlag++; break; case 'h': + case '?': help++; break; case 'V': Modified: stackless/trunk/Modules/posixmodule.c ============================================================================== --- stackless/trunk/Modules/posixmodule.c (original) +++ stackless/trunk/Modules/posixmodule.c Mon Aug 14 12:38:35 2006 @@ -1862,6 +1862,15 @@ Py_BEGIN_ALLOW_THREADS result = FindNextFileW(hFindFile, &wFileData); Py_END_ALLOW_THREADS + /* FindNextFile sets error to ERROR_NO_MORE_FILES if + it got to the end of the directory. */ + if (!result && GetLastError() != ERROR_NO_MORE_FILES) { + Py_DECREF(d); + win32_error_unicode("FindNextFileW", wnamebuf); + FindClose(hFindFile); + free(wnamebuf); + return NULL; + } } while (result == TRUE); if (FindClose(hFindFile) == FALSE) { @@ -1921,6 +1930,14 @@ Py_BEGIN_ALLOW_THREADS result = FindNextFile(hFindFile, &FileData); Py_END_ALLOW_THREADS + /* FindNextFile sets error to ERROR_NO_MORE_FILES if + it got to the end of the directory. */ + if (!result && GetLastError() != ERROR_NO_MORE_FILES) { + Py_DECREF(d); + win32_error("FindNextFile", namebuf); + FindClose(hFindFile); + return NULL; + } } while (result == TRUE); if (FindClose(hFindFile) == FALSE) { Modified: stackless/trunk/Modules/readline.c ============================================================================== --- stackless/trunk/Modules/readline.c (original) +++ stackless/trunk/Modules/readline.c Mon Aug 14 12:38:35 2006 @@ -20,6 +20,12 @@ #include #endif +#ifdef SAVE_LOCALE +# define RESTORE_LOCALE(sl) { setlocale(LC_CTYPE, sl); free(sl); } +#else +# define RESTORE_LOCALE(sl) +#endif + /* GNU readline definitions */ #undef HAVE_CONFIG_H /* Else readline/chardefs.h includes strings.h */ #include @@ -723,10 +729,7 @@ */ rl_initialize(); -#ifdef SAVE_LOCALE - setlocale(LC_CTYPE, saved_locale); /* Restore locale */ - free(saved_locale); -#endif + RESTORE_LOCALE(saved_locale) } /* Wrapper around GNU readline that handles signals differently. */ @@ -864,7 +867,8 @@ p = readline_until_enter_or_signal(prompt, &signal); /* we got an interrupt signal */ - if(signal) { + if (signal) { + RESTORE_LOCALE(saved_locale) return NULL; } @@ -873,6 +877,7 @@ p = PyMem_Malloc(1); if (p != NULL) *p = '\0'; + RESTORE_LOCALE(saved_locale) return p; } @@ -905,10 +910,7 @@ p[n+1] = '\0'; } free(q); -#ifdef SAVE_LOCALE - setlocale(LC_CTYPE, saved_locale); /* Restore locale */ - free(saved_locale); -#endif + RESTORE_LOCALE(saved_locale) return p; } Modified: stackless/trunk/Modules/socketmodule.c ============================================================================== --- stackless/trunk/Modules/socketmodule.c (original) +++ stackless/trunk/Modules/socketmodule.c Mon Aug 14 12:38:35 2006 @@ -367,6 +367,14 @@ #define _BT_SOCKADDR_MEMB(s, proto) &((s)->sock_addr) #define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb) +#elif defined(__NetBSD__) +#define sockaddr_l2 sockaddr_bt +#define sockaddr_rc sockaddr_bt +#define sockaddr_sco sockaddr_bt +#define _BT_SOCKADDR_MEMB(s, proto) &((s)->sock_addr) +#define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb) +#define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb) +#define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb) #else #define _BT_SOCKADDR_MEMB(s, proto) (&((s)->sock_addr).bt_##proto) #define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb) @@ -700,7 +708,7 @@ The argument writing indicates the direction. This does not raise an exception; we'll let our caller do that after they've reacquired the interpreter lock. - Returns 1 on timeout, 0 otherwise. */ + Returns 1 on timeout, -1 on error, 0 otherwise. */ static int internal_select(PySocketSockObject *s, int writing) { @@ -745,6 +753,9 @@ n = select(s->sock_fd+1, &fds, NULL, NULL, &tv); } #endif + + if (n < 0) + return -1; if (n == 0) return 1; return 0; @@ -1544,7 +1555,7 @@ &addrlen); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -1915,9 +1926,15 @@ if (s->sock_timeout > 0.0) { if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { timeout = internal_select(s, 1); - res = connect(s->sock_fd, addr, addrlen); - if (res < 0 && errno == EISCONN) - res = 0; + if (timeout == 0) { + res = connect(s->sock_fd, addr, addrlen); + if (res < 0 && errno == EISCONN) + res = 0; + } + else if (timeout == -1) + res = errno; /* had error */ + else + res = EWOULDBLOCK; /* timed out */ } } @@ -1947,7 +1964,7 @@ res = internal_connect(s, addr, addrlen, &timeout); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -1981,6 +1998,13 @@ res = internal_connect(s, addr, addrlen, &timeout); Py_END_ALLOW_THREADS + /* Signals are not errors (though they may raise exceptions). Adapted + from PyErr_SetFromErrnoWithFilenameObject(). */ +#ifdef EINTR + if (res == EINTR && PyErr_CheckSignals()) + return NULL; +#endif + return PyInt_FromLong((long) res); } @@ -2201,10 +2225,10 @@ static ssize_t sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags) { - ssize_t outlen = 0; + ssize_t outlen = -1; int timeout; #ifdef __VMS - int remaining, nread; + int remaining; char *read_buf; #endif @@ -2220,7 +2244,7 @@ outlen = recv(s->sock_fd, cbuf, len, flags); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return -1; } @@ -2235,6 +2259,7 @@ remaining = len; while (remaining != 0) { unsigned int segment; + int nread = -1; segment = remaining /SEGMENT_SIZE; if (segment != 0) { @@ -2250,7 +2275,7 @@ nread = recv(s->sock_fd, read_buf, segment, flags); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return -1; } @@ -2299,7 +2324,7 @@ /* Call the guts */ outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags); if (outlen < 0) { - /* An error occured, release the string and return an + /* An error occurred, release the string and return an error. */ Py_DECREF(buf); return NULL; @@ -2398,7 +2423,7 @@ { sock_addr_t addrbuf; int timeout; - ssize_t n = 0; + ssize_t n = -1; socklen_t addrlen; *addr = NULL; @@ -2430,7 +2455,7 @@ } Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return -1; } @@ -2545,7 +2570,7 @@ sock_send(PySocketSockObject *s, PyObject *args) { char *buf; - int len, n = 0, flags = 0, timeout; + int len, n = -1, flags = 0, timeout; if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags)) return NULL; @@ -2563,7 +2588,7 @@ #endif Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -2586,7 +2611,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args) { char *buf; - int len, n = 0, flags = 0, timeout; + int len, n = -1, flags = 0, timeout; if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags)) return NULL; @@ -2597,6 +2622,7 @@ Py_BEGIN_ALLOW_THREADS do { timeout = internal_select(s, 1); + n = -1; if (timeout) break; #ifdef __VMS @@ -2611,7 +2637,7 @@ } while (len > 0); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } @@ -2639,7 +2665,7 @@ PyObject *addro; char *buf; struct sockaddr *addr; - int addrlen, len, n = 0, flags, timeout; + int addrlen, len, n = -1, flags, timeout; flags = 0; if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) { @@ -2661,7 +2687,7 @@ n = sendto(s->sock_fd, buf, len, flags, addr, addrlen); Py_END_ALLOW_THREADS - if (timeout) { + if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } Modified: stackless/trunk/Modules/spwdmodule.c ============================================================================== --- stackless/trunk/Modules/spwdmodule.c (original) +++ stackless/trunk/Modules/spwdmodule.c Mon Aug 14 12:38:35 2006 @@ -91,7 +91,7 @@ #undef SETI if (PyErr_Occurred()) { - Py_XDECREF(v); + Py_DECREF(v); return NULL; } Modified: stackless/trunk/Modules/timemodule.c ============================================================================== --- stackless/trunk/Modules/timemodule.c (original) +++ stackless/trunk/Modules/timemodule.c Mon Aug 14 12:38:35 2006 @@ -406,13 +406,35 @@ indexing blindly into some array for a textual representation by some bad index (fixes bug #897625). - No check for year since handled in gettmarg(). + Also support values of zero from Python code for arguments in which + that is out of range by forcing that value to the lowest value that + is valid (fixed bug #1520914). + + Valid ranges based on what is allowed in struct tm: + + - tm_year: [0, max(int)] (1) + - tm_mon: [0, 11] (2) + - tm_mday: [1, 31] + - tm_hour: [0, 23] + - tm_min: [0, 59] + - tm_sec: [0, 60] + - tm_wday: [0, 6] (1) + - tm_yday: [0, 365] (2) + - tm_isdst: [-max(int), max(int)] + + (1) gettmarg() handles bounds-checking. + (2) Python's acceptable range is one greater than the range in C, + thus need to check against automatic decrement by gettmarg(). */ - if (buf.tm_mon < 0 || buf.tm_mon > 11) { + if (buf.tm_mon == -1) + buf.tm_mon = 0; + else if (buf.tm_mon < 0 || buf.tm_mon > 11) { PyErr_SetString(PyExc_ValueError, "month out of range"); return NULL; } - if (buf.tm_mday < 1 || buf.tm_mday > 31) { + if (buf.tm_mday == 0) + buf.tm_mday = 1; + else if (buf.tm_mday < 0 || buf.tm_mday > 31) { PyErr_SetString(PyExc_ValueError, "day of month out of range"); return NULL; } @@ -434,7 +456,9 @@ PyErr_SetString(PyExc_ValueError, "day of week out of range"); return NULL; } - if (buf.tm_yday < 0 || buf.tm_yday > 365) { + if (buf.tm_yday == -1) + buf.tm_yday = 0; + else if (buf.tm_yday < 0 || buf.tm_yday > 365) { PyErr_SetString(PyExc_ValueError, "day of year out of range"); return NULL; } Modified: stackless/trunk/Modules/unicodedata.c ============================================================================== --- stackless/trunk/Modules/unicodedata.c (original) +++ stackless/trunk/Modules/unicodedata.c Mon Aug 14 12:38:35 2006 @@ -395,6 +395,7 @@ PyUnicodeObject *v; char decomp[256]; int code, index, count, i; + unsigned int prefix_index; if (!PyArg_ParseTuple(args, "O!:decomposition", &PyUnicode_Type, &v)) @@ -428,9 +429,15 @@ /* XXX: could allocate the PyString up front instead (strlen(prefix) + 5 * count + 1 bytes) */ + /* Based on how index is calculated above and decomp_data is generated + from Tools/unicode/makeunicodedata.py, it should not be possible + to overflow decomp_prefix. */ + prefix_index = decomp_data[index] & 255; + assert(prefix_index < (sizeof(decomp_prefix)/sizeof(*decomp_prefix))); + /* copy prefix */ - i = strlen(decomp_prefix[decomp_data[index] & 255]); - memcpy(decomp, decomp_prefix[decomp_data[index] & 255], i); + i = strlen(decomp_prefix[prefix_index]); + memcpy(decomp, decomp_prefix[prefix_index], i); while (count-- > 0) { if (i) Modified: stackless/trunk/Objects/codeobject.c ============================================================================== --- stackless/trunk/Objects/codeobject.c (original) +++ stackless/trunk/Objects/codeobject.c Mon Aug 14 12:38:35 2006 @@ -556,6 +556,7 @@ the line increments here, treating them as byte increments gets confusing, to say the least. */ + bounds->ap_lower = 0; while (size > 0) { if (addr + *p > lasti) break; Modified: stackless/trunk/Objects/complexobject.c ============================================================================== --- stackless/trunk/Objects/complexobject.c (original) +++ stackless/trunk/Objects/complexobject.c Mon Aug 14 12:38:35 2006 @@ -274,16 +274,16 @@ { char format[32]; if (v->cval.real == 0.) { - PyOS_snprintf(format, 32, "%%.%ig", precision); - PyOS_ascii_formatd(buf, bufsz, format, v->cval.imag); - strncat(buf, "j", bufsz); + PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); + PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag); + strncat(buf, "j", 1); } else { char re[64], im[64]; /* Format imaginary part with sign, real part without */ - PyOS_snprintf(format, 32, "%%.%ig", precision); - PyOS_ascii_formatd(re, 64, format, v->cval.real); - PyOS_snprintf(format, 32, "%%+.%ig", precision); - PyOS_ascii_formatd(im, 64, format, v->cval.imag); + PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); + PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real); + PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision); + PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag); PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im); } } Modified: stackless/trunk/Objects/dictobject.c ============================================================================== --- stackless/trunk/Objects/dictobject.c (original) +++ stackless/trunk/Objects/dictobject.c Mon Aug 14 12:38:35 2006 @@ -599,6 +599,8 @@ PyErr_BadInternalCall(); return -1; } + assert(key); + assert(value); mp = (dictobject *)op; if (PyString_CheckExact(key)) { hash = ((PyStringObject *)key)->ob_shash; @@ -647,6 +649,7 @@ PyErr_BadInternalCall(); return -1; } + assert(key); if (!PyString_CheckExact(key) || (hash = ((PyStringObject *) key)->ob_shash) == -1) { hash = PyObject_Hash(key); Modified: stackless/trunk/Objects/fileobject.c ============================================================================== --- stackless/trunk/Objects/fileobject.c (original) +++ stackless/trunk/Objects/fileobject.c Mon Aug 14 12:38:35 2006 @@ -103,6 +103,7 @@ fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode, int (*close)(FILE *)) { + assert(name != NULL); assert(f != NULL); assert(PyFile_Check(f)); assert(f->f_fp == NULL); @@ -111,7 +112,7 @@ Py_DECREF(f->f_mode); Py_DECREF(f->f_encoding); - Py_INCREF (name); + Py_INCREF(name); f->f_name = name; f->f_mode = PyString_FromString(mode); @@ -126,7 +127,7 @@ Py_INCREF(Py_None); f->f_encoding = Py_None; - if (f->f_name == NULL || f->f_mode == NULL) + if (f->f_mode == NULL) return NULL; f->f_fp = fp; f = dircheck(f); @@ -278,7 +279,9 @@ PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type, NULL, NULL); if (f != NULL) { - PyObject *o_name = PyString_FromString(name); + PyObject *o_name = PyString_FromString(name); + if (o_name == NULL) + return NULL; if (fill_file_fields(f, fp, o_name, mode, close) == NULL) { Py_DECREF(f); f = NULL; @@ -411,11 +414,11 @@ if (PyUnicode_Check(f->f_name)) { #ifdef Py_USING_UNICODE PyObject *ret = NULL; - PyObject *name; - name = PyUnicode_AsUnicodeEscapeString(f->f_name); + PyObject *name = PyUnicode_AsUnicodeEscapeString(f->f_name); + const char *name_str = name ? PyString_AsString(name) : "?"; ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>", f->f_fp == NULL ? "closed" : "open", - PyString_AsString(name), + name_str, PyString_AsString(f->f_mode), f); Py_XDECREF(name); Modified: stackless/trunk/Objects/frameobject.c ============================================================================== --- stackless/trunk/Objects/frameobject.c (original) +++ stackless/trunk/Objects/frameobject.c Mon Aug 14 12:38:35 2006 @@ -666,6 +666,7 @@ f->f_trace = NULL; f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL; } + f->f_stacktop = f->f_valuestack; f->f_builtins = builtins; Py_XINCREF(back); f->f_back = back; @@ -696,7 +697,6 @@ f->f_lineno = code->co_firstlineno; f->f_iblock = 0; - f->f_stacktop = f->f_valuestack; #ifdef STACKLESS f->f_execute = NULL; #endif Modified: stackless/trunk/Objects/funcobject.c ============================================================================== --- stackless/trunk/Objects/funcobject.c (original) +++ stackless/trunk/Objects/funcobject.c Mon Aug 14 12:38:35 2006 @@ -110,8 +110,8 @@ } if (defaults == Py_None) defaults = NULL; - else if (PyTuple_Check(defaults)) { - Py_XINCREF(defaults); + else if (defaults && PyTuple_Check(defaults)) { + Py_INCREF(defaults); } else { PyErr_SetString(PyExc_SystemError, "non-tuple default args"); @@ -142,7 +142,7 @@ if (closure == Py_None) closure = NULL; else if (PyTuple_Check(closure)) { - Py_XINCREF(closure); + Py_INCREF(closure); } else { PyErr_Format(PyExc_SystemError, Modified: stackless/trunk/Objects/listsort.txt ============================================================================== --- stackless/trunk/Objects/listsort.txt (original) +++ stackless/trunk/Objects/listsort.txt Mon Aug 14 12:38:35 2006 @@ -494,7 +494,7 @@ 467-474, Austin, Texas, 25-27 January 1993. and it probably dates back to an earlier paper by Bentley and Yao. The -McIlory paper in particular has good analysis of a mergesort that's +McIlroy paper in particular has good analysis of a mergesort that's probably strongly related to this one in its galloping strategy. Modified: stackless/trunk/Objects/longobject.c ============================================================================== --- stackless/trunk/Objects/longobject.c (original) +++ stackless/trunk/Objects/longobject.c Mon Aug 14 12:38:35 2006 @@ -1203,7 +1203,7 @@ register PyLongObject *a = (PyLongObject *)aa; PyStringObject *str; Py_ssize_t i; - const Py_ssize_t size_a = ABS(a->ob_size); + Py_ssize_t size_a; char *p; int bits; char sign = '\0'; @@ -1213,6 +1213,7 @@ return NULL; } assert(base >= 2 && base <= 36); + size_a = ABS(a->ob_size); /* Compute a rough upper bound for the length of the string */ i = base; @@ -3149,9 +3150,8 @@ : MAX(size_a, size_b); z = _PyLong_New(size_z); if (z == NULL) { - Py_XDECREF(a); - Py_XDECREF(b); - Py_XDECREF(z); + Py_DECREF(a); + Py_DECREF(b); return NULL; } Modified: stackless/trunk/Objects/setobject.c ============================================================================== --- stackless/trunk/Objects/setobject.c (original) +++ stackless/trunk/Objects/setobject.c Mon Aug 14 12:38:35 2006 @@ -1384,12 +1384,12 @@ while (set_next(otherset, &pos, &entry)) { int rv = set_discard_entry(so, entry); if (rv == -1) { - Py_XDECREF(otherset); + Py_DECREF(otherset); return NULL; } if (rv == DISCARD_NOTFOUND) { if (set_add_entry(so, entry) == -1) { - Py_XDECREF(otherset); + Py_DECREF(otherset); return NULL; } } @@ -1801,7 +1801,7 @@ PyDoc_STRVAR(set_doc, "set(iterable) --> set object\n\ \n\ -Build an unordered collection."); +Build an unordered collection of unique elements."); PyTypeObject PySet_Type = { PyObject_HEAD_INIT(&PyType_Type) @@ -1896,7 +1896,7 @@ PyDoc_STRVAR(frozenset_doc, "frozenset(iterable) --> frozenset object\n\ \n\ -Build an immutable unordered collection."); +Build an immutable unordered collection of unique elements."); PyTypeObject PyFrozenSet_Type = { PyObject_HEAD_INIT(&PyType_Type) Modified: stackless/trunk/Objects/stringobject.c ============================================================================== --- stackless/trunk/Objects/stringobject.c (original) +++ stackless/trunk/Objects/stringobject.c Mon Aug 14 12:38:35 2006 @@ -1492,7 +1492,6 @@ j = i+pos; SPLIT_ADD(s, i, j); i = j + n; - } #else i = j = 0; @@ -1588,7 +1587,7 @@ return NULL; i = j = len-1; - + while (maxsplit-- > 0) { RSKIP_SPACE(s, i); if (i<0) break; @@ -2464,11 +2463,11 @@ } Py_LOCAL_INLINE(Py_ssize_t) -countchar(char *target, int target_len, char c, Py_ssize_t maxcount) +countchar(const char *target, int target_len, char c, Py_ssize_t maxcount) { Py_ssize_t count=0; - char *start=target; - char *end=target+target_len; + const char *start=target; + const char *end=target+target_len; while ( (start=findchar(start, end-start, c)) != NULL ) { count++; @@ -2480,8 +2479,8 @@ } Py_LOCAL(Py_ssize_t) -findstring(char *target, Py_ssize_t target_len, - char *pattern, Py_ssize_t pattern_len, +findstring(const char *target, Py_ssize_t target_len, + const char *pattern, Py_ssize_t pattern_len, Py_ssize_t start, Py_ssize_t end, int direction) @@ -2518,8 +2517,8 @@ } Py_LOCAL_INLINE(Py_ssize_t) -countstring(char *target, Py_ssize_t target_len, - char *pattern, Py_ssize_t pattern_len, +countstring(const char *target, Py_ssize_t target_len, + const char *pattern, Py_ssize_t pattern_len, Py_ssize_t start, Py_ssize_t end, int direction, Py_ssize_t maxcount) @@ -2572,22 +2571,21 @@ /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */ Py_LOCAL(PyStringObject *) replace_interleave(PyStringObject *self, - PyStringObject *to, + const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { - char *self_s, *to_s, *result_s; - Py_ssize_t self_len, to_len, result_len; + char *self_s, *result_s; + Py_ssize_t self_len, result_len; Py_ssize_t count, i, product; PyStringObject *result; self_len = PyString_GET_SIZE(self); - to_len = PyString_GET_SIZE(to); - + /* 1 at the end plus 1 after every character */ count = self_len+1; if (maxcount < count) count = maxcount; - + /* Check for overflow */ /* result_len = count * to_len + self_len; */ product = count * to_len; @@ -2608,8 +2606,6 @@ return NULL; self_s = PyString_AS_STRING(self); - to_s = PyString_AS_STRING(to); - to_len = PyString_GET_SIZE(to); result_s = PyString_AS_STRING(result); /* TODO: special case single character, which doesn't need memcpy */ @@ -2670,25 +2666,24 @@ start = next+1; } Py_MEMCPY(result_s, start, end-start); - + return result; } /* len(self)>=1, len(from)>=2, to="", maxcount>=1 */ Py_LOCAL(PyStringObject *) -replace_delete_substring(PyStringObject *self, PyStringObject *from, +replace_delete_substring(PyStringObject *self, + const char *from_s, Py_ssize_t from_len, Py_ssize_t maxcount) { - char *self_s, *from_s, *result_s; + char *self_s, *result_s; char *start, *next, *end; - Py_ssize_t self_len, from_len, result_len; + Py_ssize_t self_len, result_len; Py_ssize_t count, offset; PyStringObject *result; self_len = PyString_GET_SIZE(self); self_s = PyString_AS_STRING(self); - from_len = PyString_GET_SIZE(from); - from_s = PyString_AS_STRING(from); count = countstring(self_s, self_len, from_s, from_len, @@ -2702,13 +2697,13 @@ result_len = self_len - (count * from_len); assert (result_len>=0); - + if ( (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) == NULL ) return NULL; - + result_s = PyString_AS_STRING(result); - + start = self_s; end = self_s + self_len; while (count-- > 0) { @@ -2718,9 +2713,9 @@ if (offset == -1) break; next = start + offset; - + Py_MEMCPY(result_s, start, next-start); - + result_s += (next-start); start = next+from_len; } @@ -2737,31 +2732,31 @@ char *self_s, *result_s, *start, *end, *next; Py_ssize_t self_len; PyStringObject *result; - + /* The result string will be the same size */ self_s = PyString_AS_STRING(self); self_len = PyString_GET_SIZE(self); - + next = findchar(self_s, self_len, from_c); - + if (next == NULL) { /* No matches; return the original string */ return return_self(self); } - + /* Need to make a new string */ result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len); if (result == NULL) return NULL; result_s = PyString_AS_STRING(result); Py_MEMCPY(result_s, self_s, self_len); - + /* change everything in-place, starting with this one */ start = result_s + (next-self_s); *start = to_c; start++; end = result_s + self_len; - + while (--maxcount > 0) { next = findchar(start, end-start, from_c); if (next == NULL) @@ -2769,40 +2764,35 @@ *next = to_c; start = next+1; } - + return result; } /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */ Py_LOCAL(PyStringObject *) replace_substring_in_place(PyStringObject *self, - PyStringObject *from, - PyStringObject *to, + const char *from_s, Py_ssize_t from_len, + const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { char *result_s, *start, *end; - char *self_s, *from_s, *to_s; - Py_ssize_t self_len, from_len, offset; + char *self_s; + Py_ssize_t self_len, offset; PyStringObject *result; - + /* The result string will be the same size */ - + self_s = PyString_AS_STRING(self); self_len = PyString_GET_SIZE(self); - - from_s = PyString_AS_STRING(from); - from_len = PyString_GET_SIZE(from); - to_s = PyString_AS_STRING(to); - + offset = findstring(self_s, self_len, from_s, from_len, 0, self_len, FORWARD); - if (offset == -1) { /* No matches; return the original string */ return return_self(self); } - + /* Need to make a new string */ result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len); if (result == NULL) @@ -2810,13 +2800,12 @@ result_s = PyString_AS_STRING(result); Py_MEMCPY(result_s, self_s, self_len); - /* change everything in-place, starting with this one */ start = result_s + offset; Py_MEMCPY(start, to_s, from_len); start += from_len; end = result_s + self_len; - + while ( --maxcount > 0) { offset = findstring(start, end-start, from_s, from_len, @@ -2826,7 +2815,7 @@ Py_MEMCPY(start+offset, to_s, from_len); start += offset+from_len; } - + return result; } @@ -2834,28 +2823,24 @@ Py_LOCAL(PyStringObject *) replace_single_character(PyStringObject *self, char from_c, - PyStringObject *to, + const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { - char *self_s, *to_s, *result_s; + char *self_s, *result_s; char *start, *next, *end; - Py_ssize_t self_len, to_len, result_len; + Py_ssize_t self_len, result_len; Py_ssize_t count, product; PyStringObject *result; - + self_s = PyString_AS_STRING(self); self_len = PyString_GET_SIZE(self); - + count = countchar(self_s, self_len, from_c, maxcount); - if (count == 0) { /* no matches, return unchanged */ return return_self(self); } - - to_s = PyString_AS_STRING(to); - to_len = PyString_GET_SIZE(to); - + /* use the difference between current and new, hence the "-1" */ /* result_len = self_len + count * (to_len-1) */ product = count * (to_len-1); @@ -2868,19 +2853,19 @@ PyErr_SetString(PyExc_OverflowError, "replace string is too long"); return NULL; } - + if ( (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) == NULL) return NULL; result_s = PyString_AS_STRING(result); - + start = self_s; end = self_s + self_len; while (count-- > 0) { next = findchar(start, end-start, from_c); if (next == NULL) break; - + if (next == start) { /* replace with the 'to' */ Py_MEMCPY(result_s, to_s, to_len); @@ -2897,27 +2882,25 @@ } /* Copy the remainder of the remaining string */ Py_MEMCPY(result_s, start, end-start); - + return result; } /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */ Py_LOCAL(PyStringObject *) replace_substring(PyStringObject *self, - PyStringObject *from, - PyStringObject *to, + const char *from_s, Py_ssize_t from_len, + const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { - char *self_s, *from_s, *to_s, *result_s; + char *self_s, *result_s; char *start, *next, *end; - Py_ssize_t self_len, from_len, to_len, result_len; + Py_ssize_t self_len, result_len; Py_ssize_t count, offset, product; PyStringObject *result; - + self_s = PyString_AS_STRING(self); self_len = PyString_GET_SIZE(self); - from_s = PyString_AS_STRING(from); - from_len = PyString_GET_SIZE(from); - + count = countstring(self_s, self_len, from_s, from_len, 0, self_len, FORWARD, maxcount); @@ -2925,10 +2908,7 @@ /* no matches, return unchanged */ return return_self(self); } - - to_s = PyString_AS_STRING(to); - to_len = PyString_GET_SIZE(to); - + /* Check for overflow */ /* result_len = self_len + count * (to_len-from_len) */ product = count * (to_len-from_len); @@ -2941,12 +2921,12 @@ PyErr_SetString(PyExc_OverflowError, "replace string is too long"); return NULL; } - + if ( (result = (PyStringObject *) PyString_FromStringAndSize(NULL, result_len)) == NULL) return NULL; result_s = PyString_AS_STRING(result); - + start = self_s; end = self_s + self_len; while (count-- > 0) { @@ -2972,29 +2952,24 @@ } /* Copy the remainder of the remaining string */ Py_MEMCPY(result_s, start, end-start); - + return result; } Py_LOCAL(PyStringObject *) replace(PyStringObject *self, - PyStringObject *from, - PyStringObject *to, + const char *from_s, Py_ssize_t from_len, + const char *to_s, Py_ssize_t to_len, Py_ssize_t maxcount) { - Py_ssize_t from_len, to_len; - if (maxcount < 0) { maxcount = PY_SSIZE_T_MAX; } else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) { /* nothing to do; return the original string */ return return_self(self); } - - from_len = PyString_GET_SIZE(from); - to_len = PyString_GET_SIZE(to); - + if (maxcount == 0 || (from_len == 0 && to_len == 0)) { /* nothing to do; return the original string */ @@ -3002,12 +2977,12 @@ } /* Handle zero-length special cases */ - + if (from_len == 0) { /* insert the 'to' string everywhere. */ /* >>> "Python".replace("", ".") */ /* '.P.y.t.h.o.n.' */ - return replace_interleave(self, to, maxcount); + return replace_interleave(self, to_s, to_len, maxcount); } /* Except for "".replace("", "A") == "A" there is no way beyond this */ @@ -3021,9 +2996,9 @@ /* delete all occurances of 'from' string */ if (from_len == 1) { return replace_delete_single_character( - self, PyString_AS_STRING(from)[0], maxcount); + self, from_s[0], maxcount); } else { - return replace_delete_substring(self, from, maxcount); + return replace_delete_substring(self, from_s, from_len, maxcount); } } @@ -3033,22 +3008,22 @@ if (from_len == 1) { return replace_single_character_in_place( self, - PyString_AS_STRING(from)[0], - PyString_AS_STRING(to)[0], + from_s[0], + to_s[0], maxcount); } else { return replace_substring_in_place( - self, from, to, maxcount); + self, from_s, from_len, to_s, to_len, maxcount); } } /* Otherwise use the more generic algorithms */ if (from_len == 1) { - return replace_single_character(self, PyString_AS_STRING(from)[0], - to, maxcount); + return replace_single_character(self, from_s[0], + to_s, to_len, maxcount); } else { /* len('from')>=2, len('to')>=1 */ - return replace_substring(self, from, to, maxcount); + return replace_substring(self, from_s, from_len, to_s, to_len, maxcount); } } @@ -3064,37 +3039,39 @@ { Py_ssize_t count = -1; PyObject *from, *to; - const char *tmp_s; - Py_ssize_t tmp_len; + const char *from_s, *to_s; + Py_ssize_t from_len, to_len; if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) return NULL; if (PyString_Check(from)) { - /* Can this be made a '!check' after the Unicode check? */ + from_s = PyString_AS_STRING(from); + from_len = PyString_GET_SIZE(from); } #ifdef Py_USING_UNICODE if (PyUnicode_Check(from)) return PyUnicode_Replace((PyObject *)self, from, to, count); #endif - else if (PyObject_AsCharBuffer(from, &tmp_s, &tmp_len)) + else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) return NULL; if (PyString_Check(to)) { - /* Can this be made a '!check' after the Unicode check? */ + to_s = PyString_AS_STRING(to); + to_len = PyString_GET_SIZE(to); } #ifdef Py_USING_UNICODE else if (PyUnicode_Check(to)) return PyUnicode_Replace((PyObject *)self, from, to, count); #endif - else if (PyObject_AsCharBuffer(to, &tmp_s, &tmp_len)) + else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) return NULL; return (PyObject *)replace((PyStringObject *) self, - (PyStringObject *) from, - (PyStringObject *) to, count); + from_s, from_len, + to_s, to_len, count); } /** End DALKE **/ Modified: stackless/trunk/Objects/typeobject.c ============================================================================== --- stackless/trunk/Objects/typeobject.c (original) +++ stackless/trunk/Objects/typeobject.c Mon Aug 14 12:38:35 2006 @@ -3324,6 +3324,8 @@ if (PyDict_GetItemString(type->tp_dict, "__doc__") == NULL) { if (type->tp_doc != NULL) { PyObject *doc = PyString_FromString(type->tp_doc); + if (doc == NULL) + goto error; PyDict_SetItemString(type->tp_dict, "__doc__", doc); Py_DECREF(doc); } else { Modified: stackless/trunk/Objects/unicodeobject.c ============================================================================== --- stackless/trunk/Objects/unicodeobject.c (original) +++ stackless/trunk/Objects/unicodeobject.c Mon Aug 14 12:38:35 2006 @@ -7918,6 +7918,9 @@ unicode_freelist = NULL; unicode_freelist_size = 0; unicode_empty = _PyUnicode_New(0); + if (!unicode_empty) + return; + strcpy(unicode_default_encoding, "ascii"); for (i = 0; i < 256; i++) unicode_latin1[i] = NULL; Modified: stackless/trunk/Objects/weakrefobject.c ============================================================================== --- stackless/trunk/Objects/weakrefobject.c (original) +++ stackless/trunk/Objects/weakrefobject.c Mon Aug 14 12:38:35 2006 @@ -6,10 +6,10 @@ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) -long +Py_ssize_t _PyWeakref_GetWeakrefCount(PyWeakReference *head) { - long count = 0; + Py_ssize_t count = 0; while (head != NULL) { ++count; Modified: stackless/trunk/PC/_winreg.c ============================================================================== --- stackless/trunk/PC/_winreg.c (original) +++ stackless/trunk/PC/_winreg.c Mon Aug 14 12:38:35 2006 @@ -960,7 +960,9 @@ return NULL; if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) return NULL; + Py_BEGIN_ALLOW_THREADS rc = RegConnectRegistry(szCompName, hKey, &retKey); + Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "ConnectRegistry"); Modified: stackless/trunk/PC/config.c ============================================================================== --- stackless/trunk/PC/config.c (original) +++ stackless/trunk/PC/config.c Mon Aug 14 12:38:35 2006 @@ -70,6 +70,7 @@ extern void init_subprocess(void); extern void init_lsprof(void); extern void init_ast(void); +extern void init_types(void); /* tools/freeze/makeconfig.py marker for additional "extern" */ /* -- ADDMODULE MARKER 1 -- */ @@ -164,6 +165,8 @@ {"__builtin__", NULL}, {"sys", NULL}, {"exceptions", NULL}, + + {"_types", init_types}, /* Sentinel */ {0, 0} Modified: stackless/trunk/PC/getpathp.c ============================================================================== --- stackless/trunk/PC/getpathp.c (original) +++ stackless/trunk/PC/getpathp.c Mon Aug 14 12:38:35 2006 @@ -297,6 +297,10 @@ } RegCloseKey(subKey); } + + /* return null if no path to return */ + if (dataSize == 0) goto done; + /* original datasize from RegQueryInfo doesn't include the \0 */ dataBuf = malloc((dataSize+1) * sizeof(TCHAR)); if (dataBuf) { Modified: stackless/trunk/PC/os2emx/Makefile ============================================================================== --- stackless/trunk/PC/os2emx/Makefile (original) +++ stackless/trunk/PC/os2emx/Makefile Mon Aug 14 12:38:35 2006 @@ -2,15 +2,15 @@ # # Top-Level Makefile for Building Python 2.4 for OS/2 using GCC/EMX # Originally written by Andrew Zabolotny, for Python 1.5.2 -# Modified by Andrew MacIntyre, for Python 2.4 +# Modified by Andrew MacIntyre, for Python 2.5 # # This makefile was developed for use with [P]GCC/EMX compiler any # version and GNU Make. # -# The output of the build is a largish Python24.DLL containing the +# The output of the build is a largish Python25.DLL containing the # essential modules of Python and a small Python.exe program to start # the interpreter. When embedding Python within another program, only -# Python24.DLL is needed. We also build python_s.a static library (which +# Python25.DLL is needed. We also build python_s.a static library (which # can be converted into OMF (.lib) format using emxomf tool) and both # python.a and python.lib import libraries. Then the optional # extension modules, which are OS/2 DLLs renamed with a PYD file extension. @@ -64,7 +64,7 @@ # === install locations === # default value of PYTHONHOME -LIB_DIR=C:/Python24 +LIB_DIR=C:/Python25 # default is to have everything in or under PYTHONHOME EXE_DIR=$(LIB_DIR) DLL_DIR=$(EXE_DIR) @@ -236,8 +236,8 @@ @echo STACKSIZE 2097152 >>$@ # Output file names -PYTHON_VER= 2.4 -PYTHON_LIB= python24 +PYTHON_VER= 2.5 +PYTHON_LIB= python25 PYTHON.LIB= $(PYTHON_LIB)_s$A PYTHON.IMPLIB= $(PYTHON_LIB)$A ifeq ($(EXEOMF),yes) @@ -295,20 +295,23 @@ Modules/dlmodule.c \ Modules/errnomodule.c \ Modules/fcntlmodule.c \ + Modules/_functoolsmodule.c \ Modules/_heapqmodule.c \ Modules/imageop.c \ Modules/itertoolsmodule.c \ Modules/_localemodule.c \ Modules/mathmodule.c \ - Modules/md5c.c \ + Modules/md5.c \ Modules/md5module.c \ Modules/operator.c \ Modules/_randommodule.c \ Modules/rgbimgmodule.c \ Modules/shamodule.c \ + Modules/sha256module.c \ + Modules/sha512module.c \ Modules/_sre.c \ Modules/stropmodule.c \ - Modules/structmodule.c \ + Modules/_struct.c \ Modules/symtablemodule.c \ Modules/termios.c \ Modules/timemodule.c \ @@ -331,6 +334,9 @@ SRC.PARSER= $(SRC.PARSE1) \ $(SRC.PARSE2) SRC.PYTHON= $(addprefix $(TOP), \ + Python/Python-ast.c \ + Python/asdl.c \ + Python/ast.c \ Python/bltinmodule.c \ Python/exceptions.c \ Python/ceval.c \ @@ -353,6 +359,7 @@ Python/modsupport.c \ Python/mysnprintf.c \ Python/mystrtoul.c \ + Python/pyarena.c \ Python/pyfpe.c \ Python/pystate.c \ Python/pystrtod.c \ @@ -371,6 +378,7 @@ Objects/cellobject.c \ Objects/classobject.c \ Objects/cobject.c \ + Objects/codeobject.c \ Objects/complexobject.c \ Objects/descrobject.c \ Objects/dictobject.c \ Modified: stackless/trunk/PC/os2emx/README.os2emx ============================================================================== --- stackless/trunk/PC/os2emx/README.os2emx (original) +++ stackless/trunk/PC/os2emx/README.os2emx Mon Aug 14 12:38:35 2006 @@ -612,22 +612,11 @@ test_posixpath should skip these tests on EMX. -24. I have had a report that attempting to use the Bittorrent package -(http://bitconjurer.org/BitTorrent/) with this port causes traps not -long after starting the download; this using the "headless" download -script on eCS v1.1. I have not been able to duplicate this myself, -but the indications I have suggest a failure in the 32 bit TCP/IP -stack (v4.3.2? on eCS v1.1) - on my v4.0 FP12 system with MPTS fixpack -WR8425 applied (16 bit TCP/IP stack v4.02), BitTorrent appears to work -normally in testing on a 100Mbit LAN. With the curses.panel fix (see -item 13 above), the BitTorrent curses downloader works too. I'd -appreciate any success or failure reports with BitTorrent, though -I've regretfully recommended that the person who reported the failure -take this up with eCS support. Since this report, I have received a -followup which suggests that the problem may be addressed by TCP/IP -fixes (IC35005+PJ29457, contained in NEWSTACK.ZIP in the Hobbes -archive). I think it suffices to say that BitTorrent is a fair stress -test of a system's networking capability. +24. I have reports of BitTorrent not working. It appears that the +EMX select() emulation, possibly in concert with bugs in the TCP/IP +stack, runs into problems under the stress imposed by this application. +I think it suffices to say that BitTorrent is a fair stress test of a +system's networking capability. 25. In the absence of an EMX implementation of the link() function, I've implemented a crude Python emulation, in the file @@ -659,14 +648,16 @@ 29. The default stack size for threads has been 64k. This is proving insufficient for some codebases, such as Zope. The thread stack size -still defaults to 64k, but this can now be increased by defining +still defaults to 64k, but this can now be increased via the stack_size() +function exposed by the threading & thread modules as well as by defining THREAD_STACK_SIZE to an appropriate value in the Makefile (which contains a commented out definition for 128kB thread stacks). I have seen references to heavy Zope/Plone usage requiring 1MB thread stacks on FreeBSD and Linux, but doubt that for most likely usage on OS/2 that more than 256kB is necessary. The size of the required stacks (main and thread) can vary significantly depending on which version of gcc -is used along with the compiler optimisations selected. +is used along with the compiler optimisations selected. Note that the +main thread stack size is set during linking and is currently 2MB. ... probably other issues that I've not encountered, or don't remember :-( @@ -707,4 +698,4 @@ E-mail: andymac at bullseye.apana.org.au, or andymac at pcug.org.au Web: http://www.andymac.org/ -17 February, 2005. +23 July, 2006. Modified: stackless/trunk/PC/os2emx/config.c ============================================================================== --- stackless/trunk/PC/os2emx/config.c (original) +++ stackless/trunk/PC/os2emx/config.c Mon Aug 14 12:38:35 2006 @@ -58,16 +58,19 @@ extern void initdl(); extern void initerrno(); extern void initfcntl(); +extern void init_functools(); extern void init_heapq(); extern void initimageop(); extern void inititertools(); extern void initmath(); -extern void initmd5(); +extern void init_md5(); extern void initoperator(); extern void initrgbimg(); -extern void initsha(); +extern void init_sha(); +extern void init_sha256(); +extern void init_sha512(); extern void initstrop(); -extern void initstruct(); +extern void init_struct(); extern void inittermios(); extern void inittime(); extern void inittiming(); @@ -121,16 +124,19 @@ {"dl", initdl}, {"errno", initerrno}, {"fcntl", initfcntl}, + {"_functools", init_functools}, {"_heapq", init_heapq}, {"imageop", initimageop}, {"itertools", inititertools}, {"math", initmath}, - {"md5", initmd5}, + {"_md5", init_md5}, {"operator", initoperator}, {"rgbimg", initrgbimg}, - {"sha", initsha}, + {"_sha", init_sha}, + {"_sha256", init_sha256}, + {"_sha512", init_sha512}, {"strop", initstrop}, - {"struct", initstruct}, + {"_struct", init_struct}, {"termios", inittermios}, {"time", inittime}, {"timing", inittiming}, Modified: stackless/trunk/PC/os2emx/pyconfig.h ============================================================================== --- stackless/trunk/PC/os2emx/pyconfig.h (original) +++ stackless/trunk/PC/os2emx/pyconfig.h Mon Aug 14 12:38:35 2006 @@ -46,6 +46,7 @@ #define TCPIPV4 1 #define USE_SOCKET 1 #define socklen_t int +#define FD_SETSIZE 1024 /* enable the Python object allocator */ #define WITH_PYMALLOC 1 @@ -61,6 +62,9 @@ #define PY_UNICODE_TYPE wchar_t #define Py_UNICODE_SIZE SIZEOF_SHORT +/* EMX defines ssize_t */ +#define HAVE_SSIZE_T 1 + /* system capabilities */ #define HAVE_TTYNAME 1 #define HAVE_WAIT 1 @@ -137,6 +141,9 @@ /* The number of bytes in a void *. */ #define SIZEOF_VOID_P 4 +/* The number of bytes in a size_t. */ +#define SIZEOF_SIZE_T 4 + /* Define if you have the alarm function. */ #define HAVE_ALARM 1 Deleted: /stackless/trunk/PC/os2emx/python24.def ============================================================================== --- /stackless/trunk/PC/os2emx/python24.def Mon Aug 14 12:38:35 2006 +++ (empty file) @@ -1,1173 +0,0 @@ -LIBRARY python24 INITINSTANCE TERMINSTANCE -DESCRIPTION "Python 2.4 Core DLL" -PROTMODE -DATA MULTIPLE NONSHARED -EXPORTS - -; From python24_s.lib(config) - "_PyImport_Inittab" - -; From python24_s.lib(dlfcn) -; "dlopen" -; "dlsym" -; "dlclose" -; "dlerror" - -; From python24_s.lib(getpathp) - "Py_GetProgramFullPath" - "Py_GetPrefix" - "Py_GetExecPrefix" - "Py_GetPath" - -; From python24_s.lib(getbuildinfo) - "Py_GetBuildInfo" - -; From python24_s.lib(main) - "Py_Main" - "Py_GetArgcArgv" - -; From python24_s.lib(acceler) - "PyGrammar_AddAccelerators" - "PyGrammar_RemoveAccelerators" - -; From python24_s.lib(grammar1) - "PyGrammar_FindDFA" - "PyGrammar_LabelRepr" - -; From python24_s.lib(listnode) - "PyNode_ListTree" - -; From python24_s.lib(node) - "PyNode_AddChild" - "PyNode_New" - "PyNode_Free" - -; From python24_s.lib(parser) - "PyParser_AddToken" - "PyParser_New" - "PyParser_Delete" - -; From python24_s.lib(parsetok) - "Py_TabcheckFlag" - "PyParser_ParseString" - "PyParser_ParseStringFlags" - "PyParser_ParseFile" - "PyParser_ParseFileFlags" - "PyParser_ParseStringFlagsFilename" - -; From python24_s.lib(bitset) - "_Py_newbitset" - "_Py_delbitset" - "_Py_addbit" - "_Py_samebitset" - "_Py_mergebitset" - -; From python24_s.lib(metagrammar) - "_Py_meta_grammar" - "Py_meta_grammar" - -; From python24_s.lib(tokenizer) - "PyToken_OneChar" - "PyToken_TwoChars" - "PyToken_ThreeChars" - "PyTokenizer_FromString" - "PyTokenizer_FromFile" - "PyTokenizer_Free" - "PyTokenizer_Get" - "_PyParser_TokenNames" - -; From python24_s.lib(myreadline) - "_PyOS_ReadlineTState" - "PyOS_ReadlineFunctionPointer" - "PyOS_StdioReadline" - "PyOS_Readline" - "PyOS_InputHook" - -; From python24_s.lib(abstract) - "PyObject_GetItem" - "PySequence_GetItem" - "PyObject_SetItem" - "PySequence_SetItem" - "PyObject_DelItem" - "PySequence_DelItem" - "PyNumber_Multiply" - "PyNumber_InPlaceAdd" - "PyNumber_InPlaceMultiply" - "PyNumber_Int" - "PyNumber_Long" - "PyNumber_Float" - "PySequence_GetSlice" - "PySequence_SetSlice" - "PySequence_Tuple" - "PyObject_GetIter" - "PyMapping_Size" - "PyIter_Next" - "_PySequence_IterSearch" - "PyObject_CallFunction" - "PyObject_CallMethod" - "PyObject_CallMethodObjArgs" - "PyObject_CallFunctionObjArgs" - "PyObject_Cmp" - "PyObject_Call" - "PyObject_CallObject" - "PyObject_Type" - "PyObject_Size" - "PyObject_Length" - "PyObject_DelItemString" - "PyObject_AsCharBuffer" - "PyObject_CheckReadBuffer" - "PyObject_AsReadBuffer" - "PyObject_AsWriteBuffer" - "PyNumber_Check" - "PyNumber_Add" - "PyNumber_Subtract" - "PyNumber_Divide" - "PyNumber_FloorDivide" - "PyNumber_TrueDivide" - "PyNumber_Remainder" - "PyNumber_Divmod" - "PyNumber_Power" - "PyNumber_Negative" - "PyNumber_Positive" - "PyNumber_Absolute" - "PyNumber_Invert" - "PyNumber_Lshift" - "PyNumber_Rshift" - "PyNumber_And" - "PyNumber_Xor" - "PyNumber_Or" - "PyNumber_InPlaceSubtract" - "PyNumber_InPlaceDivide" - "PyNumber_InPlaceFloorDivide" - "PyNumber_InPlaceTrueDivide" - "PyNumber_InPlaceRemainder" - "PyNumber_InPlacePower" - "PyNumber_InPlaceLshift" - "PyNumber_InPlaceRshift" - "PyNumber_InPlaceAnd" - "PyNumber_InPlaceXor" - "PyNumber_InPlaceOr" - "PySequence_Check" - "PySequence_Size" - "PySequence_Length" - "PySequence_Concat" - "PySequence_Repeat" - "PySequence_DelSlice" - "PySequence_List" - "PySequence_Fast" - "PySequence_Count" - "PySequence_Contains" - "PySequence_In" - "PySequence_Index" - "PySequence_InPlaceConcat" - "PySequence_InPlaceRepeat" - "PyMapping_Check" - "PyMapping_Length" - "PyMapping_HasKeyString" - "PyMapping_HasKey" - "PyMapping_GetItemString" - "PyMapping_SetItemString" - "PyObject_IsInstance" - "PyObject_IsSubclass" - -; From python24_s.lib(boolobject) - "PyBool_FromLong" - "PyBool_Type" - "_Py_ZeroStruct" - "_Py_TrueStruct" - -; From python24_s.lib(bufferobject) - "PyBuffer_FromObject" - "PyBuffer_FromReadWriteObject" - "PyBuffer_FromMemory" - "PyBuffer_FromReadWriteMemory" - "PyBuffer_New" - "PyBuffer_Type" - -; From python24_s.lib(cellobject) - "PyCell_New" - "PyCell_Get" - "PyCell_Set" - "PyCell_Type" - -; From python24_s.lib(classobject) - "PyClass_New" - "PyClass_IsSubclass" - "PyInstance_New" - "PyInstance_NewRaw" - "PyMethod_New" - "PyMethod_Function" - "PyMethod_Self" - "PyMethod_Class" - "_PyInstance_Lookup" - "PyMethod_Fini" - "PyClass_Type" - "PyInstance_Type" - "PyMethod_Type" - -; From python24_s.lib(cobject) - "PyCObject_FromVoidPtr" - "PyCObject_FromVoidPtrAndDesc" - "PyCObject_AsVoidPtr" - "PyCObject_GetDesc" - "PyCObject_Import" - "PyCObject_SetVoidPtr" - "PyCObject_Type" - -; From python24_s.lib(complexobject) - "_Py_c_pow" - "_Py_c_sum" - "_Py_c_diff" - "_Py_c_neg" - "_Py_c_prod" - "_Py_c_quot" - "PyComplex_FromCComplex" - "PyComplex_FromDoubles" - "PyComplex_RealAsDouble" - "PyComplex_ImagAsDouble" - "PyComplex_AsCComplex" - "PyComplex_Type" - -; From python24_s.lib(descrobject) - "PyWrapper_New" - "PyDescr_NewMethod" - "PyDescr_NewClassMethod" - "PyDescr_NewMember" - "PyDescr_NewGetSet" - "PyDescr_NewWrapper" - "PyDictProxy_New" - "PyWrapperDescr_Type" - "PyProperty_Type" - -; From python24_s.lib(dictobject) - "PyDict_New" - "PyDict_SetItem" - "PyDict_DelItem" - "PyDict_Clear" - "PyDict_MergeFromSeq2" - "PyDict_Merge" - "PyDict_Keys" - "PyDict_Values" - "PyDict_Contains" - "PyDict_GetItem" - "PyDict_Next" - "PyDict_Items" - "PyDict_Size" - "PyDict_Copy" - "PyDict_Update" - "PyDict_GetItemString" - "PyDict_SetItemString" - "PyDict_DelItemString" - "PyDict_Type" - "PyDictIterKey_Type" - "PyDictIterValue_Type" - "PyDictIterItem_Type" - -; From python24_s.lib(enumobject) - "PyEnum_Type" - "PyReversed_Type" - -; From python24_s.lib(fileobject) - "Py_UniversalNewlineFread" - "PyFile_GetLine" - "PyFile_SoftSpace" - "PyFile_WriteObject" - "PyFile_WriteString" - "PyObject_AsFileDescriptor" - "Py_UniversalNewlineFgets" - "PyFile_FromString" - "PyFile_SetBufSize" - "PyFile_SetEncoding" - "PyFile_FromFile" - "PyFile_AsFile" - "PyFile_Name" - "PyFile_Type" - -; From python24_s.lib(floatobject) - "PyFloat_FromString" - "PyFloat_AsDouble" - "PyFloat_Fini" - "_PyFloat_Pack4" - "_PyFloat_Pack8" - "PyFloat_FromDouble" - "PyFloat_AsReprString" - "PyFloat_AsString" - "_PyFloat_Unpack4" - "_PyFloat_Unpack8" - "PyFloat_AsStringEx" - "PyFloat_Type" - -; From python24_s.lib(frameobject) - "PyFrame_New" - "PyFrame_FastToLocals" - "PyFrame_LocalsToFast" - "_PyFrame_Init" - "PyFrame_Fini" - "PyFrame_BlockSetup" - "PyFrame_BlockPop" - "PyFrame_Type" - -; From python24_s.lib(funcobject) - "PyFunction_New" - "PyFunction_GetCode" - "PyFunction_GetGlobals" - "PyFunction_GetModule" - "PyFunction_GetDefaults" - "PyFunction_SetDefaults" - "PyFunction_GetClosure" - "PyFunction_SetClosure" - "PyClassMethod_New" - "PyStaticMethod_New" - "PyFunction_Type" - "PyClassMethod_Type" - "PyStaticMethod_Type" - -; From python24_s.lib(genobject) - "PyGen_New" - "PyGen_Type" - -; From python24_s.lib(intobject) - "PyInt_AsLong" - "PyInt_AsUnsignedLongMask" - "PyInt_AsUnsignedLongLongMask" - "PyInt_FromString" - "PyInt_Fini" - "PyInt_FromUnicode" - "PyInt_FromLong" - "PyInt_GetMax" - "_PyInt_Init" - "PyInt_Type" - -; From python24_s.lib(iterobject) - "PySeqIter_New" - "PyCallIter_New" - "PySeqIter_Type" - "PyCallIter_Type" - -; From python24_s.lib(listobject) - "PyList_New" - "PyList_Append" - "PyList_Size" - "PyList_GetItem" - "PyList_SetItem" - "PyList_Insert" - "PyList_GetSlice" - "PyList_SetSlice" - "PyList_Sort" - "PyList_Reverse" - "PyList_AsTuple" - "_PyList_Extend" - "PyList_Type" - "PyListIter_Type" - "PyListRevIter_Type" - -; From python24_s.lib(longobject) - "PyLong_FromDouble" - "PyLong_AsLong" - "PyLong_AsUnsignedLong" - "_PyLong_FromByteArray" - "_PyLong_AsByteArray" - "PyLong_AsDouble" - "PyLong_FromString" - "PyLong_FromLong" - "PyLong_FromUnsignedLong" - "PyLong_AsUnsignedLongMask" - "_PyLong_AsScaledDouble" - "PyLong_FromVoidPtr" - "PyLong_AsVoidPtr" - "PyLong_FromLongLong" - "PyLong_FromUnsignedLongLong" - "PyLong_AsLongLong" - "PyLong_AsUnsignedLongLong" - "PyLong_AsUnsignedLongLongMask" - "PyLong_FromUnicode" - "_PyLong_Sign" - "_PyLong_NumBits" - "_PyLong_New" - "_PyLong_Copy" - "PyLong_Type" - -; From python24_s.lib(methodobject) - "PyCFunction_Call" - "Py_FindMethodInChain" - "PyCFunction_GetFunction" - "PyCFunction_GetSelf" - "PyCFunction_GetFlags" - "Py_FindMethod" - "PyCFunction_NewEx" - "PyCFunction_Fini" - "PyCFunction_New" - "PyCFunction_Type" - -; From python24_s.lib(moduleobject) - "PyModule_New" - "_PyModule_Clear" - "PyModule_GetDict" - "PyModule_GetName" - "PyModule_GetFilename" - "PyModule_Type" - -; From python24_s.lib(object) - "Py_DivisionWarningFlag" - "PyObject_Str" - "PyObject_Repr" - "PyObject_Unicode" - "PyObject_GetAttr" - "PyObject_IsTrue" - "PyNumber_CoerceEx" - "PyObject_Compare" - "PyObject_RichCompare" - "_Py_HashDouble" - "PyObject_Hash" - "PyObject_SetAttr" - "PyObject_GenericGetAttr" - "PyObject_GenericSetAttr" - "PyCallable_Check" - "PyObject_Dir" - "PyMem_Malloc" - "PyMem_Realloc" - "PyMem_Free" - "PyObject_Print" - "_PyObject_Dump" - "PyObject_RichCompareBool" - "PyObject_GetAttrString" - "PyObject_SetAttrString" - "PyObject_HasAttrString" - "PyObject_HasAttr" - "_PyObject_GetDictPtr" - "PyObject_SelfIter" - "PyObject_Not" - "PyNumber_Coerce" - "Py_ReprEnter" - "Py_ReprLeave" - "_Py_HashPointer" - "Py_IncRef" - "Py_DecRef" - "_PyTrash_deposit_object" - "_PyTrash_destroy_chain" - "PyObject_Init" - "PyObject_InitVar" - "_PyObject_New" - "_PyObject_NewVar" - "_PyObject_Del" - "_Py_ReadyTypes" - "_Py_SwappedOp" - "_Py_NotImplementedStruct" - "_Py_NoneStruct" - "_Py_cobject_hack" - "_Py_abstract_hack" - "_PyTrash_delete_nesting" - "_PyTrash_delete_later" - -; From python24_s.lib(obmalloc) - "PyObject_Malloc" - "PyObject_Realloc" - "PyObject_Free" - -; From python24_s.lib(rangeobject) - "PyRange_New" - "PyRange_Type" - -; From python24_s.lib(setobject) - "PySet_Type" - "PyFrozenSet_Type" - -; From python24_s.lib(sliceobject) - "PySlice_GetIndices" - "PySlice_GetIndicesEx" - "PySlice_New" - "_Py_EllipsisObject" - "PySlice_Type" - -; From python24_s.lib(stringobject) - "PyString_FromStringAndSize" - "PyString_InternInPlace" - "PyString_FromString" - "PyString_FromFormatV" - "PyString_AsString" - "_PyString_Resize" - "PyString_FromFormat" - "PyString_AsDecodedString" - "PyString_AsEncodedString" - "PyString_DecodeEscape" - "PyString_Size" - "PyString_Repr" - "PyString_AsStringAndSize" - "_PyString_FormatLong" - "PyString_Format" - "_Py_ReleaseInternedStrings" - "PyString_Concat" - "PyString_ConcatAndDel" - "_PyString_Eq" - "PyString_InternImmortal" - "PyString_InternFromString" - "_PyString_Join" - "PyString_Decode" - "PyString_Encode" - "PyString_AsEncodedObject" - "PyString_AsDecodedObject" - "PyString_Fini" - "PyString_Type" - "PyBaseString_Type" - -; From python24_s.lib(structseq) - "PyStructSequence_InitType" - "PyStructSequence_New" - "PyStructSequence_UnnamedField" - -; From python24_s.lib(tupleobject) - "PyTuple_New" - "PyTuple_Pack" - "_PyTuple_Resize" - "PyTuple_Size" - "PyTuple_GetItem" - "PyTuple_SetItem" - "PyTuple_GetSlice" - "PyTuple_Fini" - "PyTuple_Type" - "PyTupleIter_Type" - -; From python24_s.lib(typeobject) - "PyType_IsSubtype" - "_PyType_Lookup" - "PyType_Ready" - "PyType_GenericAlloc" - "_PyObject_SlotCompare" - "PyType_GenericNew" - "PyType_Type" - "PyBaseObject_Type" - "PySuper_Type" - -; From python24_s.lib(unicodeobject) - "PyUnicodeUCS2_Resize" - "PyUnicodeUCS2_FromOrdinal" - "PyUnicodeUCS2_FromObject" - "PyUnicodeUCS2_FromEncodedObject" - "PyUnicodeUCS2_Decode" - "PyUnicodeUCS2_GetDefaultEncoding" - "PyUnicodeUCS2_DecodeUTF8" - "PyUnicodeUCS2_DecodeLatin1" - "PyUnicodeUCS2_DecodeASCII" - "PyUnicodeUCS2_AsEncodedString" - "PyUnicodeUCS2_AsUTF8String" - "PyUnicodeUCS2_AsLatin1String" - "PyUnicodeUCS2_AsASCIIString" - "PyUnicode_DecodeUTF7" - "PyUnicode_EncodeUTF7" - "PyUnicodeUCS2_DecodeUTF8Stateful" - "PyUnicodeUCS2_EncodeUTF8" - "PyUnicodeUCS2_DecodeUTF16Stateful" - "PyUnicodeUCS2_AsUTF16String" - "PyUnicodeUCS2_DecodeUnicodeEscape" - "PyUnicodeUCS2_DecodeRawUnicodeEscape" - "PyUnicodeUCS2_EncodeRawUnicodeEscape" - "PyUnicodeUCS2_DecodeCharmap" - "PyUnicodeUCS2_EncodeCharmap" - "PyUnicodeUCS2_TranslateCharmap" - "PyUnicodeUCS2_EncodeDecimal" - "PyUnicodeUCS2_Count" - "PyUnicodeUCS2_Find" - "PyUnicodeUCS2_Tailmatch" - "PyUnicodeUCS2_Join" - "PyUnicodeUCS2_Splitlines" - "PyUnicodeUCS2_Compare" - "PyUnicodeUCS2_Contains" - "PyUnicodeUCS2_Concat" - "_PyUnicode_XStrip" - "PyUnicodeUCS2_Replace" - "PyUnicodeUCS2_Split" - "PyUnicodeUCS2_RSplit" - "PyUnicodeUCS2_Format" - "_PyUnicodeUCS2_Fini" - "PyUnicodeUCS2_FromUnicode" - "PyUnicodeUCS2_AsUnicode" - "PyUnicodeUCS2_GetSize" - "PyUnicodeUCS2_GetMax" - "_PyUnicodeUCS2_AsDefaultEncodedString" - "PyUnicodeUCS2_SetDefaultEncoding" - "PyUnicodeUCS2_Encode" - "PyUnicodeUCS2_AsEncodedObject" - "PyUnicodeUCS2_DecodeUTF16" - "PyUnicodeUCS2_EncodeUTF16" - "PyUnicodeUCS2_AsUnicodeEscapeString" - "PyUnicodeUCS2_EncodeUnicodeEscape" - "PyUnicodeUCS2_AsRawUnicodeEscapeString" - "PyUnicodeUCS2_EncodeLatin1" - "PyUnicodeUCS2_EncodeASCII" - "PyUnicodeUCS2_AsCharmapString" - "PyUnicodeUCS2_Translate" - "PyUnicode_AsDecodedObject" - "_PyUnicodeUCS2_Init" - "PyUnicode_Type" - -; From python24_s.lib(unicodectype) - "_PyUnicode_TypeRecords" - "_PyUnicodeUCS2_ToNumeric" - "_PyUnicodeUCS2_IsLowercase" - "_PyUnicodeUCS2_IsUppercase" - "_PyUnicodeUCS2_IsTitlecase" - "_PyUnicodeUCS2_IsWhitespace" - "_PyUnicodeUCS2_IsLinebreak" - "_PyUnicodeUCS2_ToLowercase" - "_PyUnicodeUCS2_ToUppercase" - "_PyUnicodeUCS2_ToTitlecase" - "_PyUnicodeUCS2_ToDecimalDigit" - "_PyUnicodeUCS2_ToDigit" - "_PyUnicodeUCS2_IsDecimalDigit" - "_PyUnicodeUCS2_IsDigit" - "_PyUnicodeUCS2_IsNumeric" - "_PyUnicodeUCS2_IsAlpha" - -; From python24_s.lib(weakrefobject) - "PyWeakref_NewRef" - "PyWeakref_NewProxy" - "PyObject_ClearWeakRefs" - "PyWeakref_GetObject" - "_PyWeakref_GetWeakrefCount" - "_PyWeakref_ClearRef" - "_PyWeakref_RefType" - "_PyWeakref_ProxyType" - "_PyWeakref_CallableProxyType" - -; From python24_s.lib(bltinmodule) - "_PyBuiltin_Init" - "Py_FileSystemDefaultEncoding" - -; From python24_s.lib(exceptions) - "PyExc_Exception" - "PyExc_TypeError" - "PyExc_StopIteration" - "PyExc_StandardError" - "PyExc_SystemExit" - "PyExc_KeyboardInterrupt" - "PyExc_ImportError" - "PyExc_EnvironmentError" - "PyExc_IOError" - "PyExc_OSError" - "PyExc_EOFError" - "PyExc_RuntimeError" - "PyExc_NotImplementedError" - "PyExc_NameError" - "PyExc_UnboundLocalError" - "PyExc_AttributeError" - "PyExc_SyntaxError" - "PyExc_IndentationError" - "PyExc_TabError" - "PyExc_AssertionError" - "PyExc_LookupError" - "PyExc_IndexError" - "PyExc_KeyError" - "PyExc_ArithmeticError" - "PyExc_OverflowError" - "PyExc_ZeroDivisionError" - "PyExc_FloatingPointError" - "PyExc_ValueError" - "PyExc_UnicodeError" - "PyExc_UnicodeEncodeError" - "PyExc_UnicodeDecodeError" - "PyExc_UnicodeTranslateError" - "PyExc_ReferenceError" - "PyExc_SystemError" - "PyExc_MemoryError" - "PyExc_Warning" - "PyExc_UserWarning" - "PyExc_DeprecationWarning" - "PyExc_PendingDeprecationWarning" - "PyExc_SyntaxWarning" - "PyExc_OverflowWarning" - "PyExc_RuntimeWarning" - "PyExc_FutureWarning" - "PyExc_MemoryErrorInst" - "PyUnicodeEncodeError_GetStart" - "PyUnicodeDecodeError_GetStart" - "PyUnicodeEncodeError_GetEnd" - "PyUnicodeDecodeError_GetEnd" - "_PyExc_Init" - "_PyExc_Fini" - "PyUnicodeDecodeError_Create" - "PyUnicodeEncodeError_Create" - "PyUnicodeTranslateError_Create" - "PyUnicodeEncodeError_GetEncoding" - "PyUnicodeDecodeError_GetEncoding" - "PyUnicodeEncodeError_GetObject" - "PyUnicodeDecodeError_GetObject" - "PyUnicodeTranslateError_GetObject" - "PyUnicodeTranslateError_GetStart" - "PyUnicodeEncodeError_SetStart" - "PyUnicodeDecodeError_SetStart" - "PyUnicodeTranslateError_SetStart" - "PyUnicodeTranslateError_GetEnd" - "PyUnicodeEncodeError_SetEnd" - "PyUnicodeDecodeError_SetEnd" - "PyUnicodeTranslateError_SetEnd" - "PyUnicodeEncodeError_GetReason" - "PyUnicodeDecodeError_GetReason" - "PyUnicodeTranslateError_GetReason" - "PyUnicodeEncodeError_SetReason" - "PyUnicodeDecodeError_SetReason" - "PyUnicodeTranslateError_SetReason" - -; From python24_s.lib(ceval) - "PyEval_EvalFrame" - "PyEval_CallObjectWithKeywords" - "PyEval_EvalCodeEx" - "_PyEval_SliceIndex" - "PyEval_GetFrame" - "PyEval_CallObject" - "PyEval_SetProfile" - "PyEval_SetTrace" - "PyEval_GetBuiltins" - "PyEval_GetGlobals" - "PyEval_GetLocals" - "PyEval_GetRestricted" - "PyEval_MergeCompilerFlags" - "Py_FlushLine" - "Py_AddPendingCall" - "Py_MakePendingCalls" - "Py_SetRecursionLimit" - "Py_GetRecursionLimit" - "_Py_CheckRecursiveCall" - "PyEval_GetFuncName" - "PyEval_GetFuncDesc" - "PyEval_GetCallStats" - "PyEval_SaveThread" - "PyEval_RestoreThread" - "PyEval_InitThreads" - "PyEval_AcquireLock" - "PyEval_ReleaseLock" - "PyEval_AcquireThread" - "PyEval_ReleaseThread" - "PyEval_ReInitThreads" - "PyEval_EvalCode" - "_PyEval_CallTracing" - "_Py_CheckRecursionLimit" - "_Py_CheckInterval" - "_Py_Ticker" - -; From python24_s.lib(compile) - "PyCode_New" - "PySymtable_Free" - "PyNode_Compile" - "PyNode_CompileFlags" - "PyCode_Addr2Line" - "_Py_Mangle" - "PyNode_CompileSymtable" - "Py_OptimizeFlag" - "PyCode_Type" - -; From python24_s.lib(codecs) - "_PyCodec_Lookup" - "PyCodec_StreamReader" - "PyCodec_StreamWriter" - "PyCodec_Encode" - "PyCodec_Decode" - "PyCodec_IgnoreErrors" - "PyCodec_ReplaceErrors" - "PyCodec_XMLCharRefReplaceErrors" - "PyCodec_BackslashReplaceErrors" - "PyCodec_Register" - "PyCodec_Encoder" - "PyCodec_Decoder" - "PyCodec_RegisterError" - "PyCodec_LookupError" - "PyCodec_StrictErrors" - -; From python24_s.lib(errors) - "PyErr_SetNone" - "PyErr_SetString" - "PyErr_ExceptionMatches" - "PyErr_GivenExceptionMatches" - "PyErr_NormalizeException" - "PyErr_Fetch" - "PyErr_Clear" - "PyErr_NoMemory" - "PyErr_SetFromErrnoWithFilenameObject" - "PyErr_Format" - "PyErr_NewException" - "PyErr_WriteUnraisable" - "PyErr_SyntaxLocation" - "PyErr_ProgramText" - "PyErr_SetObject" - "PyErr_Occurred" - "PyErr_Restore" - "PyErr_BadArgument" - "PyErr_SetFromErrno" - "PyErr_SetFromErrnoWithFilename" - "PyErr_BadInternalCall" - "_PyErr_BadInternalCall" - "PyErr_Warn" - "PyErr_WarnExplicit" - -; From python24_s.lib(frozen) - "PyImport_FrozenModules" - -; From python24_s.lib(frozenmain) - "Py_FrozenMain" - -; From python24_s.lib(future) - "PyNode_Future" - -; From python24_s.lib(getargs) - "PyArg_Parse" - "PyArg_ParseTuple" - "PyArg_ParseTupleAndKeywords" - "PyArg_UnpackTuple" - "PyArg_VaParse" - "PyArg_VaParseTupleAndKeywords" - -; From python24_s.lib(getcompiler) - "Py_GetCompiler" - -; From python24_s.lib(getcopyright) - "Py_GetCopyright" - -; From python24_s.lib(getmtime) - "PyOS_GetLastModificationTime" - -; From python24_s.lib(getplatform) - "Py_GetPlatform" - -; From python24_s.lib(getversion) - "Py_GetVersion" - -; From python24_s.lib(graminit) - "_PyParser_Grammar" - -; From python24_s.lib(import) - "_PyImport_Init" - "_PyImportHooks_Init" - "PyImport_ImportModule" - "PyImport_Cleanup" - "_PyImport_FixupExtension" - "PyImport_AddModule" - "PyImport_ExecCodeModuleEx" - "PyImport_ImportFrozenModule" - "PyImport_ImportModuleEx" - "PyImport_ReloadModule" - "PyImport_Import" -; "initimp" - "_PyImport_Fini" - "PyImport_GetMagicNumber" - "PyImport_ExecCodeModule" - "PyImport_GetModuleDict" - "_PyImport_FindExtension" - "PyImport_AppendInittab" - "PyImport_ExtendInittab" - "PyImport_Inittab" - "_PyImport_Filetab" - -; From python24_s.lib(importdl) - "_PyImport_LoadDynamicModule" - -; From python24_s.lib(marshal) - "PyMarshal_ReadLongFromFile" - "PyMarshal_WriteObjectToString" - "PyMarshal_WriteLongToFile" - "PyMarshal_WriteObjectToFile" - "PyMarshal_ReadShortFromFile" - "PyMarshal_ReadObjectFromFile" - "PyMarshal_ReadLastObjectFromFile" - "PyMarshal_ReadObjectFromString" - "PyMarshal_Init" - -; From python24_s.lib(modsupport) - "Py_InitModule4" - "Py_BuildValue" - "Py_VaBuildValue" - "PyEval_CallFunction" - "PyEval_CallMethod" - "PyModule_AddObject" - "PyModule_AddIntConstant" - "PyModule_AddStringConstant" - "_Py_PackageContext" - -; From python24_s.lib(mysnprintf) - "PyOS_snprintf" - "PyOS_vsnprintf" - -; From python24_s.lib(mystrtoul) - "PyOS_strtoul" - "PyOS_strtol" - -; From python24_s.lib(pyfpe) - "PyFPE_dummy" - -; From python24_s.lib(pystate) - "PyInterpreterState_Clear" - "PyThreadState_Clear" - "PyGILState_Ensure" - "PyGILState_Release" - "PyInterpreterState_New" - "PyInterpreterState_Delete" - "PyThreadState_Delete" - "PyThreadState_New" - "PyThreadState_DeleteCurrent" - "PyThreadState_Get" - "PyThreadState_Swap" - "PyThreadState_GetDict" - "PyThreadState_SetAsyncExc" - "PyGILState_GetThisThreadState" - "PyInterpreterState_Head" - "PyInterpreterState_Next" - "PyInterpreterState_ThreadHead" - "PyThreadState_Next" - "_PyGILState_Init" - "_PyGILState_Fini" - "_PyThreadState_Current" - "_PyThreadState_GetFrame" - -; From python24_s.lib(pystrtod) - "PyOS_ascii_strtod" - "PyOS_ascii_formatd" - "PyOS_ascii_atof" - -; From python24_s.lib(pythonrun) - "Py_IgnoreEnvironmentFlag" - "Py_DebugFlag" - "Py_VerboseFlag" - "Py_NoSiteFlag" - "Py_InteractiveFlag" - "Py_FrozenFlag" - "Py_InitializeEx" - "Py_FatalError" - "Py_NewInterpreter" - "PyErr_Print" - "PyRun_InteractiveOneFlags" - "PyRun_SimpleFileExFlags" - "PyRun_FileExFlags" - "Py_Exit" - "PyErr_PrintEx" - "PyErr_Display" - "Py_SetProgramName" - "Py_GetProgramName" - "Py_SetPythonHome" - "Py_GetPythonHome" - "Py_Initialize" - "Py_Finalize" - "Py_IsInitialized" - "Py_EndInterpreter" - "PyRun_AnyFile" - "PyRun_AnyFileExFlags" - "PyRun_AnyFileEx" - "PyRun_AnyFileFlags" - "Py_FdIsInteractive" - "PyRun_InteractiveLoopFlags" - "PyRun_SimpleString" - "PyRun_SimpleStringFlags" - "PyRun_StringFlags" - "PyRun_SimpleFile" - "PyRun_SimpleFileEx" - "PyRun_InteractiveOne" - "PyRun_InteractiveLoop" - "PyParser_SimpleParseString" - "PyParser_SimpleParseFile" - "PyParser_SimpleParseStringFlags" - "PyParser_SimpleParseStringFlagsFilename" - "PyParser_SimpleParseFileFlags" - "PyRun_String" - "PyRun_File" - "PyRun_FileEx" - "PyRun_FileFlags" - "Py_CompileString" - "Py_CompileStringFlags" - "Py_SymtableString" - "Py_AtExit" - "PyOS_getsig" - "PyOS_setsig" - "PyParser_SetError" - "PyModule_GetWarningsModule" - "PyParser_SimpleParseStringFilename" - "Py_UseClassExceptionsFlag" - "Py_UnicodeFlag" - "_Py_QnewFlag" - -; From python24_s.lib(structmember) - "PyMember_Get" - "PyMember_GetOne" - "PyMember_SetOne" - "PyMember_Set" - -; From python24_s.lib(symtable) - "PySymtableEntry_New" - "PySymtableEntry_Type" - -; From python24_s.lib(sysmodule) - "_PySys_Init" - "PySys_SetPath" - "PySys_SetArgv" - "PySys_WriteStdout" - "PySys_WriteStderr" - "PySys_GetObject" - "PySys_SetObject" - "PySys_GetFile" - "PySys_ResetWarnOptions" - "PySys_AddWarnOption" - -; From python24_s.lib(traceback) - "PyTraceBack_Here" - "PyTraceBack_Print" - "PyTraceBack_Type" - -; From python24_s.lib(getopt) - "_PyOS_GetOpt" - "_PyOS_opterr" - "_PyOS_optind" - "_PyOS_optarg" - -; From python24_s.lib(dynload_shlib) - "_PyImport_DynLoadFiletab" - "_PyImport_GetDynLoadFunc" - -; From python24_s.lib(thread) - "PyThread_delete_key_value" - "PyThread_init_thread" - "PyThread_start_new_thread" - "PyThread_exit_thread" - "PyThread_get_thread_ident" - "PyThread_allocate_lock" - "PyThread_free_lock" - "PyThread_acquire_lock" - "PyThread_release_lock" - "PyThread_create_key" - "PyThread_delete_key" - "PyThread_set_key_value" - "PyThread_get_key_value" - "PyThread__exit_thread" - -; From python24_s.lib(gcmodule) -; "initgc" - "_PyObject_GC_New" - "_PyObject_GC_NewVar" - "PyGC_Collect" - "_PyObject_GC_Resize" - "_PyObject_GC_Malloc" - "PyObject_GC_Track" - "PyObject_GC_UnTrack" - "PyObject_GC_Del" - "_PyGC_Dump" - "_PyObject_GC_Track" - "_PyObject_GC_UnTrack" - "_PyObject_GC_Del" - "_PyGC_generation0" - -; From python24_s.lib(signalmodule) -; "initsignal" - "PyErr_CheckSignals" - "PyErr_SetInterrupt" - "PyOS_FiniInterrupts" - "PyOS_InterruptOccurred" - "PyOS_InitInterrupts" - "PyOS_AfterFork" - -; From python24_s.lib(posixmodule) -; "initos2" - -; From python24_s.lib(threadmodule) -; "initthread" - -; From python24_s.lib(arraymodule) -; "initarray" -; "array_methods" - -; From python24_s.lib(binascii) -; "initbinascii" - -; From python24_s.lib(cmathmodule) -; "initcmath" - -; From python24_s.lib(_codecsmodule) -; "init_codecs" - -; From python24_s.lib(collectionsmodule) -; "initcollections" - "dequeiter_type" - "dequereviter_type" - -; From python24_s.lib(cPickle) -; "initcPickle" -; "fast_save_leave" - -; From python24_s.lib(cStringIO) -; "initcStringIO" - -; From python24_s.lib(_csv) -; "init_csv" - -; From python24_s.lib(datetimemodule) -; "initdatetime" - -; From python24_s.lib(dlmodule) -; "initdl" - -; From python24_s.lib(errnomodule) -; "initerrno" - -; From python24_s.lib(fcntlmodule) -; "initfcntl" - -; From python24_s.lib(_heapqmodule) -; "init_heapq" - -; From python24_s.lib(imageop) -; "initimageop" - -; From python24_s.lib(itertoolsmodule) -; "inititertools" - -; From python24_s.lib(_localemodule) -; "init_locale" - -; From python24_s.lib(mathmodule) -; "initmath" - -; From python24_s.lib(md5c) -; "_Py_MD5Final" -; "_Py_MD5Init" -; "_Py_MD5Update" - -; From python24_s.lib(md5module) -; "initmd5" - -; From python24_s.lib(operator) -; "initoperator" - -; From python24_s.lib(_randommodule) -; "init_random" - -; From python24_s.lib(rgbimgmodule) -; "initrgbimg" - -; From python24_s.lib(shamodule) -; "initsha" - -; From python24_s.lib(_sre) -; "init_sre" - -; From python24_s.lib(stropmodule) -; "initstrop" - -; From python24_s.lib(structmodule) -; "initstruct" - -; From python24_s.lib(symtablemodule) -; "init_symtable" - -; From python24_s.lib(termios) -; "inittermios" - -; From python24_s.lib(timemodule) -; "inittime" - "_PyTime_DoubleToTimet" -; "inittimezone" - -; From python24_s.lib(timingmodule) -; "inittiming" - -; From python24_s.lib(_weakref) -; "init_weakref" - -; From python24_s.lib(xxsubtype) -; "initxxsubtype" - -; From python24_s.lib(zipimport) -; "initzipimport" Modified: stackless/trunk/PC/winsound.c ============================================================================== --- stackless/trunk/PC/winsound.c (original) +++ stackless/trunk/PC/winsound.c Mon Aug 14 12:38:35 2006 @@ -37,10 +37,10 @@ #include #include +#include #ifdef HAVE_CONIO_H #include /* port functions on Win9x */ #endif -#include PyDoc_STRVAR(sound_playsound_doc, "PlaySound(sound, flags) - a wrapper around the Windows PlaySound API\n" @@ -147,7 +147,7 @@ return NULL; } } -#ifdef _M_IX86 +#if defined(_M_IX86) && defined(HAVE_CONIO_H) else if (whichOS == Win9X) { int speaker_state; /* Force timer into oscillator mode via timer control port. */ @@ -172,7 +172,7 @@ /* Restore speaker control to original state. */ _outp(0x61, speaker_state); } -#endif /* _M_IX86 */ +#endif /* _M_IX86 && HAVE_CONIO_H */ else { assert(!"winsound's whichOS has insane value"); } Modified: stackless/trunk/PCbuild/_ssl.vcproj ============================================================================== --- stackless/trunk/PCbuild/_ssl.vcproj (original) +++ stackless/trunk/PCbuild/_ssl.vcproj Mon Aug 14 12:38:35 2006 @@ -21,8 +21,8 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> @@ -35,8 +35,8 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> @@ -49,8 +49,9 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> Modified: stackless/trunk/PCbuild/build_ssl.py ============================================================================== --- stackless/trunk/PCbuild/build_ssl.py (original) +++ stackless/trunk/PCbuild/build_ssl.py Mon Aug 14 12:38:35 2006 @@ -84,9 +84,59 @@ print "Could not find an SSL directory in '%s'" % (sources,) return best_name +def run_32all_py(): + # ms\32all.bat will reconfigure OpenSSL and then try to build + # all outputs (debug/nondebug/dll/lib). So we filter the file + # to exclude any "nmake" commands and then execute. + tempname = "ms\\32all_py.bat" + + in_bat = open("ms\\32all.bat") + temp_bat = open(tempname,"w") + while 1: + cmd = in_bat.readline() + print 'cmd', repr(cmd) + if not cmd: break + if cmd.strip()[:5].lower() == "nmake": + continue + temp_bat.write(cmd) + in_bat.close() + temp_bat.close() + os.system(tempname) + try: + os.remove(tempname) + except: + pass + +def run_configure(configure, do_script): + os.system("perl Configure "+configure) + os.system(do_script) + def main(): - debug = "-d" in sys.argv build_all = "-a" in sys.argv + if sys.argv[1] == "Release": + arch = "x86" + debug = False + configure = "VC-WIN32" + makefile = "32.mak" + elif sys.argv[1] == "Debug": + arch = "x86" + debug = True + configure = "VC-WIN32" + makefile="d32.mak" + elif sys.argv[1] == "ReleaseItanium": + arch = "ia64" + debug = False + configure = "VC-WIN64I" + do_script = "ms\\do_win64i" + makefile = "ms\\nt.mak" + os.environ["VSEXTCOMP_USECL"] = "MS_ITANIUM" + elif sys.argv[1] == "ReleaseAMD64": + arch="amd64" + debug=False + configure = "VC-WIN64A" + do_script = "ms\\do_win64a" + makefile = "ms\\nt.mak" + os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON" make_flags = "" if build_all: make_flags = "-a" @@ -107,49 +157,24 @@ try: os.chdir(ssl_dir) # If the ssl makefiles do not exist, we invoke Perl to generate them. - if not os.path.isfile(os.path.join(ssl_dir, "32.mak")) or \ - not os.path.isfile(os.path.join(ssl_dir, "d32.mak")): + if not os.path.isfile(makefile): print "Creating the makefiles..." # Put our working Perl at the front of our path os.environ["PATH"] = os.path.split(perl)[0] + \ os.pathsep + \ os.environ["PATH"] - # ms\32all.bat will reconfigure OpenSSL and then try to build - # all outputs (debug/nondebug/dll/lib). So we filter the file - # to exclude any "nmake" commands and then execute. - tempname = "ms\\32all_py.bat" - - in_bat = open("ms\\32all.bat") - temp_bat = open(tempname,"w") - while 1: - cmd = in_bat.readline() - print 'cmd', repr(cmd) - if not cmd: break - if cmd.strip()[:5].lower() == "nmake": - continue - temp_bat.write(cmd) - in_bat.close() - temp_bat.close() - os.system(tempname) - try: - os.remove(tempname) - except: - pass + if arch=="x86": + run_32all_py() + else: + run_configure(configure, do_script) # Now run make. print "Executing nmake over the ssl makefiles..." - if debug: - rc = os.system("nmake /nologo -f d32.mak") - if rc: - print "Executing d32.mak failed" - print rc - sys.exit(rc) - else: - rc = os.system("nmake /nologo -f 32.mak") - if rc: - print "Executing 32.mak failed" - print rc - sys.exit(rc) + rc = os.system("nmake /nologo -f "+makefile) + if rc: + print "Executing d32.mak failed" + print rc + sys.exit(rc) finally: os.chdir(old_cd) # And finally, we can build the _ssl module itself for Python. Modified: stackless/trunk/PCbuild/pythoncore.vcproj ============================================================================== --- stackless/trunk/PCbuild/pythoncore.vcproj (original) +++ stackless/trunk/PCbuild/pythoncore.vcproj Mon Aug 14 12:38:35 2006 @@ -460,9 +460,6 @@ RelativePath="..\Modules\_bisectmodule.c"> - - + + + + + + - - c_arena) : NULL); if (!args && n_args) - return NULL; /* Don't need to go to NULL; nothing allocated */ + return NULL; /* Don't need to goto error; no objects allocated */ defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL); if (!defaults && n_defaults) - goto error; + return NULL; /* Don't need to goto error; no objects allocated */ /* fpdef: NAME | '(' fplist ')' fplist: fpdef (',' fpdef)* [','] @@ -638,8 +641,11 @@ anything other than EQUAL or a comma? */ /* XXX Should NCH(n) check be made a separate check? */ if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) { - asdl_seq_SET(defaults, j++, - ast_for_expr(c, CHILD(n, i + 2))); + expr_ty expression = ast_for_expr(c, CHILD(n, i + 2)); + if (!expression) + goto error; + assert(defaults != NULL); + asdl_seq_SET(defaults, j++, expression); i += 2; found_default = 1; } @@ -1926,12 +1932,7 @@ operator_ty newoperator; node *ch = CHILD(n, 0); - if (TYPE(ch) == testlist) - expr1 = ast_for_testlist(c, ch); - else - expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch), n->n_col_offset, - c->c_arena); - + expr1 = ast_for_testlist(c, ch); if (!expr1) return NULL; /* TODO(nas): Remove duplicated error checks (set_context does it) */ @@ -1940,6 +1941,10 @@ ast_error(ch, "augmented assignment to generator " "expression not possible"); return NULL; + case Yield_kind: + ast_error(ch, "augmented assignment to yield " + "expression not possible"); + return NULL; case Name_kind: { const char *var_name = PyString_AS_STRING(expr1->v.Name.id); if (var_name[0] == 'N' && !strcmp(var_name, "None")) { @@ -1962,7 +1967,7 @@ if (TYPE(ch) == testlist) expr2 = ast_for_testlist(c, ch); else - expr2 = Yield(ast_for_expr(c, ch), LINENO(ch), ch->n_col_offset, c->c_arena); + expr2 = ast_for_expr(c, ch); if (!expr2) return NULL; @@ -2666,6 +2671,7 @@ asdl_seq *_target, *seq = NULL, *suite_seq; expr_ty expression; expr_ty target; + const node *node_target; /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */ REQ(n, for_stmt); @@ -2675,10 +2681,13 @@ return NULL; } - _target = ast_for_exprlist(c, CHILD(n, 1), Store); + node_target = CHILD(n, 1); + _target = ast_for_exprlist(c, node_target, Store); if (!_target) return NULL; - if (asdl_seq_LEN(_target) == 1) + /* Check the # of children rather than the length of _target, since + for x, in ... has 1 element in _target, but still requires a Tuple. */ + if (NCH(node_target) == 1) target = (expr_ty)asdl_seq_GET(_target, 0); else target = Tuple(_target, Store, LINENO(n), n->n_col_offset, c->c_arena); Modified: stackless/trunk/Python/compile.c ============================================================================== --- stackless/trunk/Python/compile.c (original) +++ stackless/trunk/Python/compile.c Mon Aug 14 12:38:35 2006 @@ -300,8 +300,11 @@ PyNode_Compile(struct _node *n, const char *filename) { PyCodeObject *co = NULL; + mod_ty mod; PyArena *arena = PyArena_New(); - mod_ty mod = PyAST_FromNode(n, NULL, filename, arena); + if (!arena) + return NULL; + mod = PyAST_FromNode(n, NULL, filename, arena); if (mod) co = PyAST_Compile(mod, filename, NULL, arena); PyArena_Free(arena); @@ -615,8 +618,10 @@ unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int)); int i,j, opcode, blockcnt = 0; - if (blocks == NULL) + if (blocks == NULL) { + PyErr_NoMemory(); return NULL; + } memset(blocks, 0, len*sizeof(int)); /* Mark labels in the first pass */ @@ -1071,14 +1076,14 @@ PyObject_Free((void *)b); b = next; } - Py_XDECREF(u->u_ste); - Py_XDECREF(u->u_name); - Py_XDECREF(u->u_consts); - Py_XDECREF(u->u_names); - Py_XDECREF(u->u_varnames); - Py_XDECREF(u->u_freevars); - Py_XDECREF(u->u_cellvars); - Py_XDECREF(u->u_private); + Py_CLEAR(u->u_ste); + Py_CLEAR(u->u_name); + Py_CLEAR(u->u_consts); + Py_CLEAR(u->u_names); + Py_CLEAR(u->u_varnames); + Py_CLEAR(u->u_freevars); + Py_CLEAR(u->u_cellvars); + Py_CLEAR(u->u_private); PyObject_Free(u); } @@ -1105,8 +1110,17 @@ u->u_name = name; u->u_varnames = list2dict(u->u_ste->ste_varnames); u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); + if (!u->u_varnames || !u->u_cellvars) { + compiler_unit_free(u); + return 0; + } + u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, PyDict_Size(u->u_cellvars)); + if (!u->u_freevars) { + compiler_unit_free(u); + return 0; + } u->u_blocks = NULL; u->u_tmpname = 0; @@ -1130,7 +1144,8 @@ /* Push the old compiler_unit on the stack. */ if (c->u) { PyObject *wrapper = PyCObject_FromVoidPtr(c->u, NULL); - if (PyList_Append(c->c_stack, wrapper) < 0) { + if (!wrapper || PyList_Append(c->c_stack, wrapper) < 0) { + Py_XDECREF(wrapper); compiler_unit_free(u); return 0; } @@ -1256,6 +1271,7 @@ sizeof(struct instr) * DEFAULT_BLOCK_SIZE); } else if (b->b_iused == b->b_ialloc) { + struct instr *tmp; size_t oldsize, newsize; oldsize = b->b_ialloc * sizeof(struct instr); newsize = oldsize << 1; @@ -1264,10 +1280,13 @@ return -1; } b->b_ialloc <<= 1; - b->b_instr = (struct instr *)PyObject_Realloc( + tmp = (struct instr *)PyObject_Realloc( (void *)b->b_instr, newsize); - if (b->b_instr == NULL) + if (tmp == NULL) { + PyErr_NoMemory(); return -1; + } + b->b_instr = tmp; memset((char *)b->b_instr + oldsize, 0, newsize - oldsize); } return b->b_iused++; @@ -3012,6 +3031,7 @@ return 0; s = e->v.BoolOp.values; n = asdl_seq_LEN(s) - 1; + assert(n >= 0); for (i = 0; i < n; ++i) { VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); ADDOP_JREL(c, jumpi, end); @@ -4003,6 +4023,8 @@ b->b_startdepth = INT_MIN; entryblock = b; } + if (!entryblock) + return 0; return stackdepth_walk(c, entryblock, 0, 0); } @@ -4098,9 +4120,10 @@ In order for this to work, when the addr field increments by more than 255, the line # increment in each pair generated must be 0 until the remaining addr -increment is < 256. So, in the example above, com_set_lineno should not (as -was actually done until 2.2) expand 300, 300 to 255, 255, 45, 45, but to -255, 0, 45, 255, 0, 45. +increment is < 256. So, in the example above, assemble_lnotab (it used +to be called com_set_lineno) should not (as was actually done until 2.2) +expand 300, 300 to 255, 255, 45, 45, + but to 255, 0, 45, 255, 0, 45. */ static int @@ -4155,12 +4178,12 @@ } lnotab = (unsigned char *) PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off; - *lnotab++ = 255; *lnotab++ = d_bytecode; + *lnotab++ = 255; d_bytecode = 0; for (j = 1; j < ncodes; j++) { - *lnotab++ = 255; *lnotab++ = 0; + *lnotab++ = 255; } d_lineno -= ncodes * 255; a->a_lnotab_off += ncodes * 2; Modified: stackless/trunk/Python/errors.c ============================================================================== --- stackless/trunk/Python/errors.c (original) +++ stackless/trunk/Python/errors.c Mon Aug 14 12:38:35 2006 @@ -632,7 +632,7 @@ /* Function to issue a warning message; may raise an exception. */ int -PyErr_Warn(PyObject *category, char *message) +PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level) { PyObject *dict, *func = NULL; PyObject *warnings_module = PyModule_GetWarningsModule(); @@ -650,7 +650,8 @@ if (category == NULL) category = PyExc_RuntimeWarning; - res = PyObject_CallFunction(func, "sO", message, category); + res = PyObject_CallFunction(func, "sOn", + message, category, stack_level); if (res == NULL) return -1; Py_DECREF(res); @@ -658,6 +659,16 @@ } } +/* PyErr_Warn is only for backwards compatability and will be removed. + Use PyErr_WarnEx instead. */ + +#undef PyErr_Warn + +int +PyErr_Warn(PyObject *category, char *message) +{ + return PyErr_WarnEx(category, message, 1); +} /* Warning with explicit origin */ int Modified: stackless/trunk/Python/future.c ============================================================================== --- stackless/trunk/Python/future.c (original) +++ stackless/trunk/Python/future.c Mon Aug 14 12:38:35 2006 @@ -121,8 +121,10 @@ PyFutureFeatures *ff; ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); - if (ff == NULL) + if (ff == NULL) { + PyErr_NoMemory(); return NULL; + } ff->ff_features = 0; ff->ff_lineno = -1; Modified: stackless/trunk/Python/getargs.c ============================================================================== --- stackless/trunk/Python/getargs.c (original) +++ stackless/trunk/Python/getargs.c Mon Aug 14 12:38:35 2006 @@ -351,8 +351,8 @@ "argument %d", iarg); i = 0; p += strlen(p); - while (levels[i] > 0 && (int)(p-buf) < 220) { - PyOS_snprintf(p, sizeof(buf) - (buf - p), + while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) { + PyOS_snprintf(p, sizeof(buf) - (p - buf), ", item %d", levels[i]-1); p += strlen(p); i++; @@ -439,6 +439,13 @@ char *msg; PyObject *item; item = PySequence_GetItem(arg, i); + if (item == NULL) { + PyErr_Clear(); + levels[0] = i+1; + levels[1] = 0; + strncpy(msgbuf, "is not retrievable", bufsize); + return msgbuf; + } msg = convertitem(item, &format, p_va, flags, levels+1, msgbuf, bufsize, freelist); /* PySequence_GetItem calls tp->sq_item, which INCREFs */ @@ -1509,6 +1516,7 @@ else { msg = skipitem(&format, p_va, flags); if (msg) { + levels[0] = 0; seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } Modified: stackless/trunk/Python/getopt.c ============================================================================== --- stackless/trunk/Python/getopt.c (original) +++ stackless/trunk/Python/getopt.c Mon Aug 14 12:38:35 2006 @@ -24,6 +24,9 @@ * davegottner at delphi.com. *---------------------------------------------------------------------------*/ +/* Modified to support --help and --version, as well as /? on Windows + * by Georg Brandl. */ + #include #include @@ -43,8 +46,17 @@ if (*opt_ptr == '\0') { - if (_PyOS_optind >= argc || argv[_PyOS_optind][0] != '-' || - argv[_PyOS_optind][1] == '\0' /* lone dash */ ) + if (_PyOS_optind >= argc) + return -1; +#ifdef MS_WINDOWS + else if (strcmp(argv[_PyOS_optind], "/?") == 0) { + ++_PyOS_optind; + return 'h'; + } +#endif + + else if (argv[_PyOS_optind][0] != '-' || + argv[_PyOS_optind][1] == '\0' /* lone dash */ ) return -1; else if (strcmp(argv[_PyOS_optind], "--") == 0) { @@ -52,6 +64,17 @@ return -1; } + else if (strcmp(argv[_PyOS_optind], "--help") == 0) { + ++_PyOS_optind; + return 'h'; + } + + else if (strcmp(argv[_PyOS_optind], "--version") == 0) { + ++_PyOS_optind; + return 'V'; + } + + opt_ptr = &argv[_PyOS_optind++][1]; } @@ -62,7 +85,7 @@ if (_PyOS_opterr) fprintf(stderr, "Unknown option: -%c\n", option); - return '?'; + return '_'; } if (*(ptr + 1) == ':') { @@ -76,7 +99,7 @@ if (_PyOS_opterr) fprintf(stderr, "Argument expected for the -%c option\n", option); - return '?'; + return '_'; } _PyOS_optarg = argv[_PyOS_optind++]; Modified: stackless/trunk/Python/import.c ============================================================================== --- stackless/trunk/Python/import.c (original) +++ stackless/trunk/Python/import.c Mon Aug 14 12:38:35 2006 @@ -60,9 +60,11 @@ Python 2.5a0: 62081 (ast-branch) Python 2.5a0: 62091 (with) Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) + Python 2.5b3: 62101 (fix wrong code: for x, in ...) + Python 2.5b3: 62111 (fix wrong code: x += yield) . */ -#define MAGIC (62092 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62111 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the @@ -97,6 +99,8 @@ }; #endif +static PyTypeObject NullImporterType; /* Forward reference */ + /* Initialize things */ void @@ -115,6 +119,8 @@ for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan) ++countS; filetab = PyMem_NEW(struct filedescr, countD + countS + 1); + if (filetab == NULL) + Py_FatalError("Can't initialize import file table."); memcpy(filetab, _PyImport_DynLoadFiletab, countD * sizeof(struct filedescr)); memcpy(filetab + countD, _PyImport_StandardFiletab, @@ -152,6 +158,8 @@ /* adding sys.path_hooks and sys.path_importer_cache, setting up zipimport */ + if (PyType_Ready(&NullImporterType) < 0) + goto error; if (Py_VerboseFlag) PySys_WriteStderr("# installing zipimport hook\n"); @@ -177,9 +185,11 @@ if (err) { error: PyErr_Print(); - Py_FatalError("initializing sys.meta_path, sys.path_hooks or " - "path_importer_cache failed"); + Py_FatalError("initializing sys.meta_path, sys.path_hooks, " + "path_importer_cache, or NullImporter failed" + ); } + zimpimport = PyImport_ImportModule("zipimport"); if (zimpimport == NULL) { PyErr_Clear(); /* No zip import module -- okay */ @@ -238,8 +248,11 @@ long me = PyThread_get_thread_ident(); if (me == -1) return; /* Too bad */ - if (import_lock == NULL) + if (import_lock == NULL) { import_lock = PyThread_allocate_lock(); + if (import_lock == NULL) + return; /* Nothing much we can do. */ + } if (import_lock_thread == me) { import_lock_level++; return; @@ -258,7 +271,7 @@ unlock_import(void) { long me = PyThread_get_thread_ident(); - if (me == -1) + if (me == -1 || import_lock == NULL) return 0; /* Too bad */ if (import_lock_thread != me) return -1; @@ -1052,9 +1065,18 @@ } PyErr_Clear(); } - if (importer == NULL) - importer = Py_None; - else if (importer != Py_None) { + if (importer == NULL) { + importer = PyObject_CallFunctionObjArgs( + (PyObject *)&NullImporterType, p, NULL + ); + if (importer == NULL) { + if (PyErr_ExceptionMatches(PyExc_ImportError)) { + PyErr_Clear(); + return Py_None; + } + } + } + if (importer != NULL) { int err = PyDict_SetItem(path_importer_cache, p, importer); Py_DECREF(importer); if (err != 0) @@ -1242,35 +1264,7 @@ return NULL; } /* Note: importer is a borrowed reference */ - if (importer == Py_False) { - /* Cached as not being a valid dir. */ - Py_XDECREF(copy); - continue; - } - else if (importer == Py_True) { - /* Cached as being a valid dir, so just - * continue below. */ - } - else if (importer == Py_None) { - /* No importer was found, so it has to be a file. - * Check if the directory is valid. - * Note that the empty string is a valid path, but - * not stat'able, hence the check for len. */ -#ifdef HAVE_STAT - if (len && stat(buf, &statbuf) != 0) { - /* Directory does not exist. */ - PyDict_SetItem(path_importer_cache, - v, Py_False); - Py_XDECREF(copy); - continue; - } else { - PyDict_SetItem(path_importer_cache, - v, Py_True); - } -#endif - } - else { - /* A real import hook importer was found. */ + if (importer != Py_None) { PyObject *loader; loader = PyObject_CallMethod(importer, "find_module", @@ -1905,11 +1899,10 @@ if (co == NULL) return -1; if (!PyCode_Check(co)) { - Py_DECREF(co); PyErr_Format(PyExc_TypeError, "frozen object %.200s is not a code object", name); - return -1; + goto err_return; } if (ispackage) { /* Set __path__ to the package name */ @@ -1917,22 +1910,25 @@ int err; m = PyImport_AddModule(name); if (m == NULL) - return -1; + goto err_return; d = PyModule_GetDict(m); s = PyString_InternFromString(name); if (s == NULL) - return -1; + goto err_return; err = PyDict_SetItemString(d, "__path__", s); Py_DECREF(s); if (err != 0) - return err; + goto err_return; } m = PyImport_ExecCodeModuleEx(name, co, ""); - Py_DECREF(co); if (m == NULL) - return -1; + goto err_return; + Py_DECREF(co); Py_DECREF(m); return 1; +err_return: + Py_DECREF(co); + return -1; } @@ -2927,11 +2923,120 @@ return err; } +typedef struct { + PyObject_HEAD +} NullImporter; + +static int +NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) +{ + char *path; + + if (!_PyArg_NoKeywords("NullImporter()", kwds)) + return -1; + + if (!PyArg_ParseTuple(args, "s:NullImporter", + &path)) + return -1; + + if (strlen(path) == 0) { + PyErr_SetString(PyExc_ImportError, "empty pathname"); + return -1; + } else { +#ifndef RISCOS + struct stat statbuf; + int rv; + + rv = stat(path, &statbuf); + if (rv == 0) { + /* it exists */ + if (S_ISDIR(statbuf.st_mode)) { + /* it's a directory */ + PyErr_SetString(PyExc_ImportError, + "existing directory"); + return -1; + } + } +#else + if (object_exists(path)) { + /* it exists */ + if (isdir(path)) { + /* it's a directory */ + PyErr_SetString(PyExc_ImportError, + "existing directory"); + return -1; + } + } +#endif + } + return 0; +} + +static PyObject * +NullImporter_find_module(NullImporter *self, PyObject *args) +{ + Py_RETURN_NONE; +} + +static PyMethodDef NullImporter_methods[] = { + {"find_module", (PyCFunction)NullImporter_find_module, METH_VARARGS, + "Always return None" + }, + {NULL} /* Sentinel */ +}; + + +static PyTypeObject NullImporterType = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "imp.NullImporter", /*tp_name*/ + sizeof(NullImporter), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "Null importer object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + NullImporter_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)NullImporter_init, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew /* tp_new */ +}; + + PyMODINIT_FUNC initimp(void) { PyObject *m, *d; + if (PyType_Ready(&NullImporterType) < 0) + goto failure; + m = Py_InitModule4("imp", imp_methods, doc_imp, NULL, PYTHON_API_VERSION); if (m == NULL) @@ -2949,6 +3054,8 @@ if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure; if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure; + Py_INCREF(&NullImporterType); + PyModule_AddObject(m, "NullImporter", (PyObject *)&NullImporterType); failure: ; } Modified: stackless/trunk/Python/mactoolboxglue.c ============================================================================== --- stackless/trunk/Python/mactoolboxglue.c (original) +++ stackless/trunk/Python/mactoolboxglue.c Mon Aug 14 12:38:35 2006 @@ -60,8 +60,9 @@ strncpy(buf, input, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; } + Py_DECREF(rv); } - + Py_XDECREF(m); return buf; } Modified: stackless/trunk/Python/mystrtoul.c ============================================================================== --- stackless/trunk/Python/mystrtoul.c (original) +++ stackless/trunk/Python/mystrtoul.c Mon Aug 14 12:38:35 2006 @@ -195,10 +195,19 @@ return (unsigned long)-1; } +/* Checking for overflow in PyOS_strtol is a PITA since C doesn't define + * anything about what happens when a signed integer operation overflows, + * and some compilers think they're doing you a favor by being "clever" + * then. Python assumes a 2's-complement representation, so that the bit + * pattern for the largest postive signed long is LONG_MAX, and for + * the smallest negative signed long is LONG_MAX + 1. + */ + long PyOS_strtol(char *str, char **ptr, int base) { long result; + unsigned long uresult; char sign; while (*str && isspace(Py_CHARMASK(*str))) @@ -208,17 +217,20 @@ if (sign == '+' || sign == '-') str++; - result = (long) PyOS_strtoul(str, ptr, base); + uresult = PyOS_strtoul(str, ptr, base); - /* Signal overflow if the result appears negative, - except for the largest negative integer */ - if (result < 0 && !(sign == '-' && result == -result)) { + if (uresult <= (unsigned long)LONG_MAX) { + result = (long)uresult; + if (sign == '-') + result = -result; + } + else if (sign == '-' && uresult == (unsigned long)LONG_MAX + 1) { + assert(LONG_MIN == -LONG_MAX-1); + result = LONG_MIN; + } + else { errno = ERANGE; - result = 0x7fffffff; + result = LONG_MAX; } - - if (sign == '-') - result = -result; - return result; } Modified: stackless/trunk/Python/pyarena.c ============================================================================== --- stackless/trunk/Python/pyarena.c (original) +++ stackless/trunk/Python/pyarena.c Mon Aug 14 12:38:35 2006 @@ -132,19 +132,19 @@ { PyArena* arena = (PyArena *)malloc(sizeof(PyArena)); if (!arena) - return NULL; + return (PyArena*)PyErr_NoMemory(); arena->a_head = block_new(DEFAULT_BLOCK_SIZE); arena->a_cur = arena->a_head; if (!arena->a_head) { free((void *)arena); - return NULL; + return (PyArena*)PyErr_NoMemory(); } arena->a_objects = PyList_New(0); if (!arena->a_objects) { block_free(arena->a_head); free((void *)arena); - return NULL; + return (PyArena*)PyErr_NoMemory(); } #if defined(Py_DEBUG) arena->total_allocs = 0; @@ -191,7 +191,7 @@ { void *p = block_alloc(arena->a_cur, size); if (!p) - return NULL; + return PyErr_NoMemory(); #if defined(Py_DEBUG) arena->total_allocs++; arena->total_size += size; Modified: stackless/trunk/Python/pystate.c ============================================================================== --- stackless/trunk/Python/pystate.c (original) +++ stackless/trunk/Python/pystate.c Mon Aug 14 12:38:35 2006 @@ -68,6 +68,10 @@ if (interp != NULL) { HEAD_INIT(); +#ifdef WITH_THREAD + if (head_mutex == NULL) + Py_FatalError("Can't initialize threads for interpreter"); +#endif interp->modules = NULL; interp->sysdict = NULL; interp->builtins = NULL; @@ -406,6 +410,53 @@ return tstate->next; } +/* The implementation of sys._current_frames(). This is intended to be + called with the GIL held, as it will be when called via + sys._current_frames(). It's possible it would work fine even without + the GIL held, but haven't thought enough about that. +*/ +PyObject * +_PyThread_CurrentFrames(void) +{ + PyObject *result; + PyInterpreterState *i; + + result = PyDict_New(); + if (result == NULL) + return NULL; + + /* for i in all interpreters: + * for t in all of i's thread states: + * if t's frame isn't NULL, map t's id to its frame + * Because these lists can mutute even when the GIL is held, we + * need to grab head_mutex for the duration. + */ + HEAD_LOCK(); + for (i = interp_head; i != NULL; i = i->next) { + PyThreadState *t; + for (t = i->tstate_head; t != NULL; t = t->next) { + PyObject *id; + int stat; + struct _frame *frame = t->frame; + if (frame == NULL) + continue; + id = PyInt_FromLong(t->thread_id); + if (id == NULL) + goto Fail; + stat = PyDict_SetItem(result, id, (PyObject *)frame); + Py_DECREF(id); + if (stat < 0) + goto Fail; + } + } + HEAD_UNLOCK(); + return result; + + Fail: + HEAD_UNLOCK(); + Py_DECREF(result); + return NULL; +} /* Python "auto thread state" API. */ #ifdef WITH_THREAD @@ -569,54 +620,6 @@ PyEval_SaveThread(); } -/* The implementation of sys._current_frames(). This is intended to be - called with the GIL held, as it will be when called via - sys._current_frames(). It's possible it would work fine even without - the GIL held, but haven't thought enough about that. -*/ -PyObject * -_PyThread_CurrentFrames(void) -{ - PyObject *result; - PyInterpreterState *i; - - result = PyDict_New(); - if (result == NULL) - return NULL; - - /* for i in all interpreters: - * for t in all of i's thread states: - * if t's frame isn't NULL, map t's id to its frame - * Because these lists can mutute even when the GIL is held, we - * need to grab head_mutex for the duration. - */ - HEAD_LOCK(); - for (i = interp_head; i != NULL; i = i->next) { - PyThreadState *t; - for (t = i->tstate_head; t != NULL; t = t->next) { - PyObject *id; - int stat; - struct _frame *frame = t->frame; - if (frame == NULL) - continue; - id = PyInt_FromLong(t->thread_id); - if (id == NULL) - goto Fail; - stat = PyDict_SetItem(result, id, (PyObject *)frame); - Py_DECREF(id); - if (stat < 0) - goto Fail; - } - } - HEAD_UNLOCK(); - return result; - - Fail: - HEAD_UNLOCK(); - Py_DECREF(result); - return NULL; -} - #ifdef __cplusplus } #endif Modified: stackless/trunk/Python/pythonrun.c ============================================================================== --- stackless/trunk/Python/pythonrun.c (original) +++ stackless/trunk/Python/pythonrun.c Mon Aug 14 12:38:35 2006 @@ -763,6 +763,11 @@ ps2 = PyString_AsString(w); } arena = PyArena_New(); + if (arena == NULL) { + Py_XDECREF(v); + Py_XDECREF(w); + return -1; + } mod = PyParser_ASTFromFile(fp, filename, Py_single_input, ps1, ps2, flags, &errcode, arena); @@ -1088,6 +1093,17 @@ } PyErr_Fetch(&exception2, &v2, &tb2); PyErr_NormalizeException(&exception2, &v2, &tb2); + /* It should not be possible for exception2 or v2 + to be NULL. However PyErr_Display() can't + tolerate NULLs, so just be safe. */ + if (exception2 == NULL) { + exception2 = Py_None; + Py_INCREF(exception2); + } + if (v2 == NULL) { + v2 = Py_None; + Py_INCREF(v2); + } if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); @@ -1095,8 +1111,8 @@ PyErr_Display(exception2, v2, tb2); PySys_WriteStderr("\nOriginal exception was:\n"); PyErr_Display(exception, v, tb); - Py_XDECREF(exception2); - Py_XDECREF(v2); + Py_DECREF(exception2); + Py_DECREF(v2); Py_XDECREF(tb2); } Py_XDECREF(result); @@ -1217,9 +1233,12 @@ { STACKLESS_GETARG(); PyObject *ret = NULL; + mod_ty mod; PyArena *arena = PyArena_New(); - mod_ty mod = PyParser_ASTFromString(str, "", start, flags, - arena); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromString(str, "", start, flags, arena); if (mod != NULL) { STACKLESS_PROMOTE_ALL(); ret = run_mod(mod, "", globals, locals, flags, arena); @@ -1234,9 +1253,13 @@ { STACKLESS_GETARG(); PyObject *ret; + mod_ty mod; PyArena *arena = PyArena_New(); - mod_ty mod = PyParser_ASTFromFile(fp, filename, start, 0, 0, - flags, NULL, arena); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromFile(fp, filename, start, 0, 0, + flags, NULL, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; @@ -1303,8 +1326,12 @@ PyCompilerFlags *flags) { PyCodeObject *co; + mod_ty mod; PyArena *arena = PyArena_New(); - mod_ty mod = PyParser_ASTFromString(str, filename, start, flags, arena); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromString(str, filename, start, flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; @@ -1323,8 +1350,12 @@ Py_SymtableString(const char *str, const char *filename, int start) { struct symtable *st; + mod_ty mod; PyArena *arena = PyArena_New(); - mod_ty mod = PyParser_ASTFromString(str, filename, start, NULL, arena); + if (arena == NULL) + return NULL; + + mod = PyParser_ASTFromString(str, filename, start, NULL, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; Modified: stackless/trunk/Python/symtable.c ============================================================================== --- stackless/trunk/Python/symtable.c (original) +++ stackless/trunk/Python/symtable.c Mon Aug 14 12:38:35 2006 @@ -221,8 +221,12 @@ return st; st->st_filename = filename; st->st_future = future; - symtable_enter_block(st, GET_IDENTIFIER(top), ModuleBlock, - (void *)mod, 0); + if (!symtable_enter_block(st, GET_IDENTIFIER(top), ModuleBlock, + (void *)mod, 0)) { + PySymtable_Free(st); + return NULL; + } + st->st_top = st->st_cur; st->st_cur->ste_unoptimized = OPT_TOPLEVEL; /* Any other top-level initialization? */ @@ -525,6 +529,8 @@ i = PyInt_AS_LONG(w); flags |= (i << SCOPE_OFF); u = PyInt_FromLong(flags); + if (!u) + return 0; if (PyDict_SetItem(symbols, name, u) < 0) { Py_DECREF(u); return 0; @@ -723,11 +729,13 @@ { Py_ssize_t end; - Py_DECREF(st->st_cur); + Py_CLEAR(st->st_cur); end = PyList_GET_SIZE(st->st_stack) - 1; if (end >= 0) { st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, end); + if (st->st_cur == NULL) + return 0; Py_INCREF(st->st_cur); if (PySequence_DelItem(st->st_stack, end) < 0) return 0; @@ -749,6 +757,8 @@ Py_DECREF(st->st_cur); } st->st_cur = PySTEntry_New(st, name, block, ast, lineno); + if (st->st_cur == NULL) + return 0; if (name == GET_IDENTIFIER(top)) st->st_global = st->st_cur->ste_symbols; if (prev) { Modified: stackless/trunk/Python/sysmodule.c ============================================================================== --- stackless/trunk/Python/sysmodule.c (original) +++ stackless/trunk/Python/sysmodule.c Mon Aug 14 12:38:35 2006 @@ -1145,41 +1145,38 @@ #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL s = "final"; #endif - PyDict_SetItemString(sysdict, "version_info", - v = Py_BuildValue("iiisi", PY_MAJOR_VERSION, + +#define SET_SYS_FROM_STRING(key, value) \ + v = value; \ + if (v != NULL) \ + PyDict_SetItemString(sysdict, key, v); \ + Py_XDECREF(v) + + SET_SYS_FROM_STRING("version_info", + Py_BuildValue("iiisi", PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, s, PY_RELEASE_SERIAL)); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "api_version", - v = PyInt_FromLong(PYTHON_API_VERSION)); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "copyright", - v = PyString_FromString(Py_GetCopyright())); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "platform", - v = PyString_FromString(Py_GetPlatform())); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "executable", - v = PyString_FromString(Py_GetProgramFullPath())); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "prefix", - v = PyString_FromString(Py_GetPrefix())); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "exec_prefix", - v = PyString_FromString(Py_GetExecPrefix())); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "maxint", - v = PyInt_FromLong(PyInt_GetMax())); - Py_XDECREF(v); + SET_SYS_FROM_STRING("api_version", + PyInt_FromLong(PYTHON_API_VERSION)); + SET_SYS_FROM_STRING("copyright", + PyString_FromString(Py_GetCopyright())); + SET_SYS_FROM_STRING("platform", + PyString_FromString(Py_GetPlatform())); + SET_SYS_FROM_STRING("executable", + PyString_FromString(Py_GetProgramFullPath())); + SET_SYS_FROM_STRING("prefix", + PyString_FromString(Py_GetPrefix())); + SET_SYS_FROM_STRING("exec_prefix", + PyString_FromString(Py_GetExecPrefix())); + SET_SYS_FROM_STRING("maxint", + PyInt_FromLong(PyInt_GetMax())); #ifdef Py_USING_UNICODE - PyDict_SetItemString(sysdict, "maxunicode", - v = PyInt_FromLong(PyUnicode_GetMax())); - Py_XDECREF(v); + SET_SYS_FROM_STRING("maxunicode", + PyInt_FromLong(PyUnicode_GetMax())); #endif - PyDict_SetItemString(sysdict, "builtin_module_names", - v = list_builtin_module_names()); - Py_XDECREF(v); + SET_SYS_FROM_STRING("builtin_module_names", + list_builtin_module_names()); { /* Assumes that longs are at least 2 bytes long. Should be safe! */ @@ -1191,18 +1188,16 @@ value = "big"; else value = "little"; - PyDict_SetItemString(sysdict, "byteorder", - v = PyString_FromString(value)); - Py_XDECREF(v); + SET_SYS_FROM_STRING("byteorder", + PyString_FromString(value)); } #ifdef MS_COREDLL - PyDict_SetItemString(sysdict, "dllhandle", - v = PyLong_FromVoidPtr(PyWin_DLLhModule)); - Py_XDECREF(v); - PyDict_SetItemString(sysdict, "winver", - v = PyString_FromString(PyWin_DLLVersionString)); - Py_XDECREF(v); + SET_SYS_FROM_STRING("dllhandle", + PyLong_FromVoidPtr(PyWin_DLLhModule)); + SET_SYS_FROM_STRING("winver", + PyString_FromString(PyWin_DLLVersionString)); #endif +#undef SET_SYS_FROM_STRING if (warnoptions == NULL) { warnoptions = PyList_New(0); } Modified: stackless/trunk/Python/thread.c ============================================================================== --- stackless/trunk/Python/thread.c (original) +++ stackless/trunk/Python/thread.c Mon Aug 14 12:38:35 2006 @@ -267,6 +267,8 @@ struct key *p; long id = PyThread_get_thread_ident(); + if (!keymutex) + return NULL; PyThread_acquire_lock(keymutex, 1); for (p = keyhead; p != NULL; p = p->next) { if (p->id == id && p->key == key) Modified: stackless/trunk/Python/thread_os2.h ============================================================================== --- stackless/trunk/Python/thread_os2.h (original) +++ stackless/trunk/Python/thread_os2.h Mon Aug 14 12:38:35 2006 @@ -35,21 +35,18 @@ long PyThread_start_new_thread(void (*func)(void *), void *arg) { - int aThread; - int success = 0; + int thread_id; - aThread = _beginthread(func, + thread_id = _beginthread(func, NULL, OS2_STACKSIZE(_pythread_stacksize), arg); - if (aThread == -1) { - success = -1; - fprintf(stderr, "aThread failed == %d", aThread); + if (thread_id == -1) { dprintf(("_beginthread failed. return %ld\n", errno)); } - return success; + return thread_id; } long Modified: stackless/trunk/README ============================================================================== --- stackless/trunk/README (original) +++ stackless/trunk/README Mon Aug 14 12:38:35 2006 @@ -1,5 +1,5 @@ -This is Python version 2.5 beta 2 -================================== +This is Python version 2.5 beta 3 +================================= Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. All rights reserved. @@ -226,13 +226,13 @@ Unsupported systems ------------------- -XXX This section is out of date! - -A number of features are not supported in Python 2.3 anymore. Some -support code is still present, but will be removed in Python 2.4. +A number of features are not supported in Python 2.5 anymore. Some +support code is still present, but will be removed in Python 2.6. If you still need to use current Python versions on these systems, please send a message to python-dev at python.org indicating that you -volunteer to support this system. +volunteer to support this system. For a more detailed discussion +regarding no-longer-supported and resupporting platforms, as well +as a list of platforms that became or will be unsupported, see PEP 11. More specifically, the following systems are not supported any longer: @@ -240,6 +240,7 @@ - DYNIX - dgux - Minix +- NeXT - Irix 4 and --with-sgi-dl - Linux 1 - Systems defining __d6_pthread_create (configure.in) @@ -247,6 +248,25 @@ or PY_PTHREAD_D7 in thread_pthread.h - Systems using --with-dl-dld - Systems using --without-universal-newlines +- MacOS 9 + +The following systems are still supported in Python 2.5, but +support will be dropped in 2.6: +- Systems using --with-wctype-functions +- Win9x, WinME + +Warning on install in Windows 98 and Windows Me +----------------------------------------------- + +Following Microsoft's closing of Extended Support for +Windows 98/ME (July 11, 2006), Python 2.6 will stop +supporting these platforms. Python development and +maintainability becomes easier (and more reliable) when +platform specific code targeting OSes with few users +and no dedicated expert developers is taken out. The +vendor also warns that the OS versions listed above +"can expose customers to security risks" and recommends +upgrade. Platform specific notes ----------------------- @@ -426,14 +446,6 @@ thread may interrupt system calls in others). Therefore, test_math and tests involving threads will fail until those problems are fixed. -SunOS 4.x: When using the SunPro C compiler, you may want to use the - '-Xa' option instead of '-Xc', to enable some needed non-ANSI - Sunisms. - THIS SYSTEM IS NO LONGER SUPPORTED. - -NeXT: Not supported anymore. Start with the MacOSX/Darwin code if you - want to revive it. - QNX: Chris Herborth (chrish at qnx.com) writes: configure works best if you use GNU bash; a port is available on ftp.qnx.com in /usr/free. I used the following process to build, Modified: stackless/trunk/Tools/buildbot/kill_python.c ============================================================================== --- stackless/trunk/Tools/buildbot/kill_python.c (original) +++ stackless/trunk/Tools/buildbot/kill_python.c Mon Aug 14 12:38:35 2006 @@ -42,8 +42,19 @@ _strlwr(path); /* printf("%s\n", path); */ + + /* Check if we are running a buildbot version of Python. + + On Windows, this will always be a debug build from the + PCbuild directory. build\\PCbuild\\python_d.exe + + On Cygwin, the pathname is similar to other Unixes. + Use \\build\\python.exe to ensure we don't match + PCbuild\\python.exe which could be a normal instance + of Python running on vanilla Windows. + */ if ((strstr(path, "build\\pcbuild\\python_d.exe") != NULL) || - (strstr(path, "build\\python.exe") != NULL)) { + (strstr(path, "\\build\\python.exe") != NULL)) { printf("Terminating %s (pid %d)\n", path, pids[i]); if (!TerminateProcess(hProcess, 1)) { printf("Termination failed: %d\n", GetLastError()); Modified: stackless/trunk/Tools/faqwiz/faqw.py ============================================================================== --- stackless/trunk/Tools/faqwiz/faqw.py (original) +++ stackless/trunk/Tools/faqwiz/faqw.py Mon Aug 14 12:38:35 2006 @@ -27,7 +27,7 @@ except SystemExit, n: sys.exit(n) except: - t, v, tb = sys.exc_type, sys.exc_value, sys.exc_traceback + t, v, tb = sys.exc_info() print import cgi cgi.print_exception(t, v, tb) Modified: stackless/trunk/Tools/msi/uuids.py ============================================================================== --- stackless/trunk/Tools/msi/uuids.py (original) +++ stackless/trunk/Tools/msi/uuids.py Mon Aug 14 12:38:35 2006 @@ -27,6 +27,7 @@ '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3 '2.5.111': '{c797ecf8-a8e6-4fec-bb99-526b65f28626}', # 2.5b1 '2.5.112': '{32beb774-f625-439d-b587-7187487baf15}', # 2.5b2 + '2.5.113': '{89f23918-11cf-4f08-be13-b9b2e6463fd9}', # 2.5b3 '2.5.121': '{8e9321bc-6b24-48a3-8fd4-c95f8e531e5f}', # 2.5c1 '2.5.122': '{a6cd508d-9599-45da-a441-cbffa9f7e070}', # 2.5c2 '2.5.150': '{0a2c5854-557e-48c8-835a-3b9f074bdcaa}', # 2.5.0 Modified: stackless/trunk/Tools/scripts/README ============================================================================== --- stackless/trunk/Tools/scripts/README (original) +++ stackless/trunk/Tools/scripts/README Mon Aug 14 12:38:35 2006 @@ -27,7 +27,6 @@ fixnotice.py Fix the copyright notice in source files fixps.py Fix Python scripts' first line (if #!) ftpmirror.py FTP mirror script -gencodec.py Create Python codecs from Unicode mapping files google.py Open a webbrowser with Google. gprof2html.py Transform gprof(1) output into useful HTML. h2py.py Translate #define's into Python assignments @@ -53,14 +52,14 @@ ptags.py Create vi tags file for Python modules pydoc Python documentation browser. pysource.py Find Python source files -redemo.py Basic regular expression demostration facility +redemo.py Basic regular expression demonstration facility reindent.py Change .py files to use 4-space indents. rgrep.py Reverse grep through a file (useful for big logfiles) setup.py Install all scripts listed here. suff.py Sort a list of files by suffix +svneol.py Sets svn:eol-style on all files in directory. texcheck.py Validate Python LaTeX formatting (Raymond Hettinger) texi2html.py Convert GNU texinfo files into HTML -trace.py Trace Python program or function execution treesync.py Synchronize source trees (very ideosyncratic) untabify.py Replace tabs with spaces in argument files which.py Find a program in $PATH Modified: stackless/trunk/Tools/webchecker/webchecker.py ============================================================================== --- stackless/trunk/Tools/webchecker/webchecker.py (original) +++ stackless/trunk/Tools/webchecker/webchecker.py Mon Aug 14 12:38:35 2006 @@ -760,7 +760,8 @@ try: names = os.listdir(path) except os.error, msg: - raise IOError, msg, sys.exc_traceback + exc_type, exc_value, exc_tb = sys.exc_info() + raise IOError, msg, exc_tb names.sort() s = MyStringIO("file:"+url, {'content-type': 'text/html'}) s.write('\n' % Modified: stackless/trunk/configure ============================================================================== --- stackless/trunk/configure (original) +++ stackless/trunk/configure Mon Aug 14 12:38:35 2006 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 47023 . +# From configure.in Revision: 47267 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for python 2.5. # @@ -21908,38 +21908,55 @@ echo "$as_me:$LINENO: checking for /dev/ptmx" >&5 echo $ECHO_N "checking for /dev/ptmx... $ECHO_C" >&6 - -if test -e /dev/ptmx -then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +if test "${ac_cv_file__dev_ptmx+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r "/dev/ptmx"; then + ac_cv_file__dev_ptmx=yes +else + ac_cv_file__dev_ptmx=no +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_file__dev_ptmx" >&5 +echo "${ECHO_T}$ac_cv_file__dev_ptmx" >&6 +if test $ac_cv_file__dev_ptmx = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DEV_PTMX 1 _ACEOF -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 fi echo "$as_me:$LINENO: checking for /dev/ptc" >&5 echo $ECHO_N "checking for /dev/ptc... $ECHO_C" >&6 - -if test -e /dev/ptc -then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +if test "${ac_cv_file__dev_ptc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r "/dev/ptc"; then + ac_cv_file__dev_ptc=yes +else + ac_cv_file__dev_ptc=no +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_file__dev_ptc" >&5 +echo "${ECHO_T}$ac_cv_file__dev_ptc" >&6 +if test $ac_cv_file__dev_ptc = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DEV_PTC 1 _ACEOF -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 fi + echo "$as_me:$LINENO: checking for %zd printf() format support" >&5 echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6 if test "$cross_compiling" = yes; then Modified: stackless/trunk/configure.in ============================================================================== --- stackless/trunk/configure.in (original) +++ stackless/trunk/configure.in Mon Aug 14 12:38:35 2006 @@ -3353,27 +3353,8 @@ AC_MSG_RESULT(no) ) -AC_MSG_CHECKING(for /dev/ptmx) - -if test -e /dev/ptmx -then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_DEV_PTMX, 1, - [Define if we have /dev/ptmx.]) -else - AC_MSG_RESULT(no) -fi - -AC_MSG_CHECKING(for /dev/ptc) - -if test -e /dev/ptc -then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_DEV_PTC, 1, - [Define if we have /dev/ptc.]) -else - AC_MSG_RESULT(no) -fi +AC_CHECK_FILE(/dev/ptmx, AC_DEFINE(HAVE_DEV_PTMX, 1, [Define if we have /dev/ptmx.])) +AC_CHECK_FILE(/dev/ptc, AC_DEFINE(HAVE_DEV_PTC, 1, [Define if we have /dev/ptc.])) AC_MSG_CHECKING(for %zd printf() format support) AC_TRY_RUN([#include Modified: stackless/trunk/pyconfig.h.in ============================================================================== --- stackless/trunk/pyconfig.h.in (original) +++ stackless/trunk/pyconfig.h.in Mon Aug 14 12:38:35 2006 @@ -85,6 +85,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H +/* Define if you have the 'is_term_resized' function. */ +#undef HAVE_CURSES_IS_TERM_RESIZED + +/* Define if you have the 'resizeterm' function. */ +#undef HAVE_CURSES_RESIZETERM + +/* Define if you have the 'resize_term' function. */ +#undef HAVE_CURSES_RESIZE_TERM + /* Define to 1 if you have the device macros. */ #undef HAVE_DEVICE_MACROS @@ -398,15 +407,6 @@ /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH -/* Define to 1 if you have the `is_term_resized' function. */ -#undef HAVE_CURSES_IS_TERM_RESIZED - -/* Define to 1 if you have the `resize_term' function. */ -#undef HAVE_CURSES_RESIZE_TERM - -/* Define to 1 if you have the `resizeterm' function. */ -#undef HAVE_CURSES_RESIZETERM - /* Define if you have readline 2.1 */ #undef HAVE_RL_CALLBACK -------------- next part -------------- _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 21 13:54:51 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 21 Aug 2006 13:54:51 +0200 (CEST) Subject: [Stackless-checkins] r51426 - stackless/branches/release25-maint Message-ID: <20060821115451.21C4A1E4003@bag.python.org> Author: richard.tew Date: Mon Aug 21 13:54:50 2006 New Revision: 51426 Added: stackless/branches/release25-maint/ - copied from r51425, stackless/trunk/ Log: Copied from the message in the branching changelist (r51333) in the Python trunk: Branching release25-maint. All further 2.5 releases (including the release candidates, the final release and all bugfix releases) will be from this branch, not the trunk. _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From stackless-checkins-owner at stackless.com Mon Aug 14 10:14:17 2006 From: stackless-checkins-owner at stackless.com (stackless-checkins-owner at stackless.com) Date: Mon, 14 Aug 2006 10:14:17 +0200 Subject: Stackless-checkins post from python-checkins@python.org requires approval Message-ID: As list administrator, your authorization is requested for the following mailing list posting: List: Stackless-checkins at stackless.com From: python-checkins at python.org Subject: r51275 - in stackless/trunk: Doc/api/api.tex Doc/api/exceptions.tex Doc/api/intro.tex Doc/api/refcounts.dat Doc/commontex/boilerplate.tex Doc/dist/dist.tex Doc/doc/doc.tex Doc/ext/newtypes.tex Doc/ext/windows.tex Doc/howto/doanddont.tex Doc/inst/inst.tex Doc/lib/email.tex Doc/lib/emailgenerator.tex Doc/lib/lib.tex Doc/lib/libanydbm.tex Doc/lib/libbase64.tex Doc/lib/libbinascii.tex Doc/lib/libbsddb.tex Doc/lib/libcompileall.tex Doc/lib/libcsv.tex Doc/lib/libctypes.tex Doc/lib/libfuncs.tex Doc/lib/libgettext.tex Doc/lib/libimp.tex Doc/lib/libinspect.tex Doc/lib/liblogging.tex Doc/lib/libmailbox.tex Doc/lib/libmimetypes.tex Doc/lib/libnew.tex Doc/lib/liboptparse.tex Doc/lib/libossaudiodev.tex Doc/lib/libpickle.tex Doc/lib/libpkgutil.tex Doc/lib/libposixpath.tex Doc/lib/librandom.tex Doc/lib/libre.tex Doc/lib/libreadline.tex Doc/lib/libshelve.tex Doc/lib/libsocket.tex Doc/lib/libsocksvr.tex Doc/lib/libsqlite3.tex Doc/lib/libstdtypes.tex Doc/lib/libstringio.tex Doc/lib/l! ibsubprocess.tex Doc/lib/libsys.tex Doc/lib/libtime.tex Doc/lib/libturtle.tex Doc/lib/libtypes.tex Doc/lib/libundoc.tex Doc/lib/libunicodedata.tex Doc/lib/liburllib.tex Doc/lib/liburllib2.tex Doc/lib/libuuid.tex Doc/lib/libweakref.tex Doc/lib/libwebbrowser.tex Doc/lib/libzipfile.tex Doc/lib/sqlite3/complete_statement.py Doc/lib/tkinter.tex Doc/mac/libmacfs.tex Doc/mac/libmacos.tex Doc/mac/using.tex Doc/ref/ref3.tex Doc/whatsnew/whatsnew20.tex Doc/whatsnew/whatsnew21.tex Doc/whatsnew/whatsnew23.tex Doc/whatsnew/whatsnew24.tex Doc/whatsnew/whatsnew25.tex Include/patchlevel.h Include/pyerrors.h Include/weakrefobject.h Lib/binhex.py Lib/bsddb/test/test_basics.py Lib/compiler/future.py Lib/compiler/transformer.py Lib/ctypes/__init__.py Lib/ctypes/test/test_varsize_struct.py Lib/ctypes/util.py Lib/distutils/__init__.py Lib/distutils/msvccompiler.py Lib/doctest.py Lib/email/__init__.py Lib/email/message.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py Lib/email! /utils.py Lib/encodings/mbcs.py Lib/gzip.py Lib/httplib.py Lib/idlelib/CREDITS.txt Lib/idlelib/CallTipWindow.py Lib/idlelib/CallTips.py Lib/idlelib/CodeContext.py Lib/idlelib/ColorDelegator.py Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/ParenMatch.py Lib/idlelib/PyShell.py Lib/idlelib/ScriptBinding.py Lib/id Reason: Message body is too big: 568776 bytes with a limit of 500 KB At your convenience, visit: http://www.stackless.com/mailman/admindb/stackless-checkins to approve or deny the request. -------------- next part -------------- An embedded message was scrubbed... From: "richard.tew" Subject: r51275 - in stackless/trunk: Doc/api/api.tex Doc/api/exceptions.tex Doc/api/intro.tex Doc/api/refcounts.dat Doc/commontex/boilerplate.tex Doc/dist/dist.tex Doc/doc/doc.tex Doc/ext/newtypes.tex Doc/ext/windows.tex Doc/howto/doanddont.tex Doc/inst/inst.tex Doc/lib/email.tex Doc/lib/emailgenerator.tex Doc/lib/lib.tex Doc/lib/libanydbm.tex Doc/lib/libbase64.tex Doc/lib/libbinascii.tex Doc/lib/libbsddb.tex Doc/lib/libcompileall.tex Doc/lib/libcsv.tex Doc/lib/libctypes.tex Doc/lib/libfuncs.tex Doc/lib/libgettext.tex Doc/lib/libimp.tex Doc/lib/libinspect.tex Doc/lib/liblogging.tex Doc/lib/libmailbox.tex Doc/lib/libmimetypes.tex Doc/lib/libnew.tex Doc/lib/liboptparse.tex Doc/lib/libossaudiodev.tex Doc/lib/libpickle.tex Doc/lib/libpkgutil.tex Doc/lib/libposixpath.tex Doc/lib/librandom.tex Doc/lib/libre.tex Doc/lib/libreadline.tex Doc/lib/libshelve.tex Doc/lib/libsocket.tex Doc/lib/libsocksvr.tex Doc/lib/libsqlite3.tex Doc/lib/libstdtypes.tex Doc/lib/libstringio.tex Doc/lib/l! ibsubprocess.tex Doc/lib/libsys.tex Doc/lib/libtime.tex Doc/lib/libturtle.tex Doc/lib/libtypes.tex Doc/lib/libundoc.tex Doc/lib/libunicodedata.tex Doc/lib/liburllib.tex Doc/lib/liburllib2.tex Doc/lib/libuuid.tex Doc/lib/libweakref.tex Doc/lib/libwebbrowser.tex Doc/lib/libzipfile.tex Doc/lib/sqlite3/complete_statement.py Doc/lib/tkinter.tex Doc/mac/libmacfs.tex Doc/mac/libmacos.tex Doc/mac/using.tex Doc/ref/ref3.tex Doc/whatsnew/whatsnew20.tex Doc/whatsnew/whatsnew21.tex Doc/whatsnew/whatsnew23.tex Doc/whatsnew/whatsnew24.tex Doc/whatsnew/whatsnew25.tex Include/patchlevel.h Include/pyerrors.h Include/weakrefobject.h Lib/binhex.py Lib/bsddb/test/test_basics.py Lib/compiler/future.py Lib/compiler/transformer.py Lib/ctypes/__init__.py Lib/ctypes/test/test_varsize_struct.py Lib/ctypes/util.py Lib/distutils/__init__.py Lib/distutils/msvccompiler.py Lib/doctest.py Lib/email/__init__.py Lib/email/message.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py Lib/email! /utils.py Lib/encodings/mbcs.py Lib/gzip.py Lib/httplib.py Lib/idlelib/CREDITS.txt Lib/idlelib/CallTipWindow.py Lib/idlelib/CallTips.py Lib/idlelib/CodeContext.py Lib/idlelib/ColorDelegator.py Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/ParenMatch.py Lib/idlelib/PyShell.py Lib/idlelib/ScriptBinding.py Lib/id Date: Mon, 14 Aug 2006 12:39:05 +0200 (CEST) Size: 572559 Url: http://www.stackless.com/pipermail/stackless-checkins/attachments/20060814/2ef901fd/attachment.eml -------------- next part -------------- An embedded message was scrubbed... From: stackless-checkins-request at stackless.com Subject: confirm b64060fa259ae6080a6933c17d5b5567557f7bd1 Date: no date Size: 652 Url: http://www.stackless.com/pipermail/stackless-checkins/attachments/20060814/2ef901fd/attachment-0001.eml From python-checkins at python.org Wed Aug 23 14:03:42 2006 From: python-checkins at python.org (richard.tew) Date: Wed, 23 Aug 2006 14:03:42 +0200 (CEST) Subject: [Stackless-checkins] r51504 - stackless/trunk/PCbuild/uthread_ccp.py Message-ID: <20060823120342.3581D1E400C@bag.python.org> Author: richard.tew Date: Wed Aug 23 14:03:41 2006 New Revision: 51504 Modified: stackless/trunk/PCbuild/uthread_ccp.py Log: Removed use of local storage, something from EVE's framework. Modified: stackless/trunk/PCbuild/uthread_ccp.py ============================================================================== --- stackless/trunk/PCbuild/uthread_ccp.py (original) +++ stackless/trunk/PCbuild/uthread_ccp.py Wed Aug 23 14:03:41 2006 @@ -606,10 +606,10 @@ try: while 1: BeNice() - ctx, callingContext, func, loc, args, keywords = queue.get() + ctx, callingContext, func, args, keywords = queue.get() if (queue.channel.balance >= 0): new(PoolHelper, queue).context = "uthread::PoolHelper" - SetLocalStorage(loc) + #SetLocalStorage(loc) # _tmpctx = t.PushTimer(ctx) try: apply( func, args, keywords ) @@ -617,8 +617,8 @@ ctx = None callingContext = None func = None - t.localStorage = {} - loc = None + #t.localStorage = {} + #loc = None args = None keywords = None # t.PopTimer(_tmpctx) @@ -671,11 +671,11 @@ __uthread__queue__ = Queue() for i in range(60): new(PoolHelper, __uthread__queue__).context = "uthread::PoolHelper" - if unsafe or worker: - st = None - else: - st = copy.copy(GetLocalStorage()) - __uthread__queue__.non_blocking_put( (str(ctx), callingContext, func, st, args, keywords,) ) + #if unsafe or worker: + # st = None + #else: + # st = copy.copy(GetLocalStorage()) + __uthread__queue__.non_blocking_put( (str(ctx), callingContext, func, args, keywords,) ) return None def Pool(ctx,func,*args,**keywords): _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 21 12:39:15 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 21 Aug 2006 12:39:15 +0200 (CEST) Subject: [Stackless-checkins] r51422 - in stackless/Python-2.4.3/dev/Stackless: core/stackless_impl.h core/stacklesseval.c test/test_exit_tasklet_killing.py Message-ID: <20060821103915.271E81E4003@bag.python.org> Author: richard.tew Date: Mon Aug 21 12:39:14 2006 New Revision: 51422 Added: stackless/Python-2.4.3/dev/Stackless/test/test_exit_tasklet_killing.py (contents, props changed) Modified: stackless/Python-2.4.3/dev/Stackless/core/stackless_impl.h stackless/Python-2.4.3/dev/Stackless/core/stacklesseval.c Log: Fix for error reported by Michael Brenner via the Stackless mailing list. When the interpreter exits, all the remaining tasklets are killed via slp_kill_tasks_with_stacks in the main tasklet. However, it is not possible to loop over the tasklets one by one killing them due to how scheduling works and that you need to schedule a tasklet to kill it. When a tasklet is scheduled, and it finishes or blocks, the next tasklet in the list is then scheduled. So what would happen is that every tasklet in the scheduler between the tasklet to be killed and the main tasklet, would be scheduled before we were back to the main tasklet and the killing of tasklets. This is definitely not what we want. The fix moves the main tasklet after the one we are killing, so that we are directly back to the tasklet killing loop when the one being killed exits. At this time there is no reproducibility case to include as a unit test, so the script which reproduces the problem is included in the test directory. Modified: stackless/Python-2.4.3/dev/Stackless/core/stackless_impl.h ============================================================================== --- stackless/Python-2.4.3/dev/Stackless/core/stackless_impl.h (original) +++ stackless/Python-2.4.3/dev/Stackless/core/stackless_impl.h Mon Aug 21 12:39:14 2006 @@ -356,6 +356,8 @@ PyTaskletObject *next, int stackless); +PyAPI_FUNC(int) initialize_main_and_current(); + /* setting the tasklet's tempval, optimized for no change */ #define TASKLET_SETVAL(task, val) \ Modified: stackless/Python-2.4.3/dev/Stackless/core/stacklesseval.c ============================================================================== --- stackless/Python-2.4.3/dev/Stackless/core/stacklesseval.c (original) +++ stackless/Python-2.4.3/dev/Stackless/core/stacklesseval.c Mon Aug 21 12:39:14 2006 @@ -290,7 +290,8 @@ while (1) { PyCStackObject *csfirst = slp_cstack_chain, *cs; - PyTaskletObject *t; + PyTaskletObject *t, *task; + PyTaskletObject **chain; if (csfirst == NULL) break; @@ -310,6 +311,26 @@ t = cs->task; Py_INCREF(t); + /* We need to ensure that the tasklet 't' is in the scheduler + * tasklet chain before this one (our main). This ensures + * that this one is directly switched back to after 't' is + * killed. The reason we do this this is because if another + * tasklet is switched to, this is of course it being scheduled + * and run. Why we do not need to do this for tasklets blocked + * on channels is that when they are scheduled to be run and + * killed, they will be implicitly placed before this one, + * leaving it to run next. + */ + if (!t->flags.blocked) { + chain = &t; + SLP_CHAIN_REMOVE(PyTaskletObject, chain, task, next, prev) + chain = &cs->tstate->st.main; + task = cs->task; + SLP_CHAIN_INSERT(PyTaskletObject, chain, task, next, prev); + cs->tstate->st.current = cs->tstate->st.main; + t = cs->task; + } + PyTasklet_Kill(t); PyErr_Clear(); @@ -325,6 +346,8 @@ { PyThreadState *ts = PyThreadState_Get(); + if (ts->st.main == NULL) + initialize_main_and_current(); slp_kill_tasks_with_stacks(allthreads ? NULL : ts); } Added: stackless/Python-2.4.3/dev/Stackless/test/test_exit_tasklet_killing.py ============================================================================== --- (empty file) +++ stackless/Python-2.4.3/dev/Stackless/test/test_exit_tasklet_killing.py Mon Aug 21 12:39:14 2006 @@ -0,0 +1,170 @@ +# This is Grant Olson's example code from his tutorial, which when it completes +# leaves a state which causes the garbage collection to crash, because when a +# tasklet is scheduled with TaskletExit raised on it, the scheduler naturally +# moves onto the next tasklet to schedule that, which is really unsuitable +# as we are killing off tasklets, not running the scheduler. +# +# I am not sure it is possible to reduce this to a reproducibility case. +# + +import stackless + +debug=1 +def debugPrint(x): + if debug:print x + +class EventHandler: + def __init__(self,*outputs): + if outputs==None: + self.outputs=[] + else: + self.outputs=list(outputs) + + self.channel = stackless.channel() + self.listener = stackless.tasklet(self.listen)() + + def listen(self): + while 1: + val = self.channel.receive() + self.processMessage(val) + for output in self.outputs: + self.notify(output) + + def processMessage(self,val): + pass + + def notify(self,output): + pass + + def registerOutput(self,output): + self.outputs.append(output) + + def __call__(self,val): + self.channel.send(val) + +class Switch(EventHandler): + def __init__(self,initialState=0,*outputs): + EventHandler.__init__(self,*outputs) + self.state = initialState + + def processMessage(self,val): + debugPrint("Setting input to %s" % val) + self.state = val + + def notify(self,output): + output((self,self.state)) + +class Reporter(EventHandler): + def __init__(self,msg="%(sender)s send message %(value)s"): + EventHandler.__init__(self) + self.msg = msg + + def processMessage(self,msg): + sender,value=msg + print self.msg % {'sender':sender,'value':value} + +class Inverter(EventHandler): + def __init__(self,input,*outputs): + EventHandler.__init__(self,*outputs) + self.input = input + input.registerOutput(self) + self.state = 0 + + def processMessage(self,msg): + sender,value = msg + debugPrint("Inverter received %s from %s" % (value,msg)) + if value: + self.state = 0 + else: + self.state = 1 + + def notify(self,output): + output((self,self.state)) + +class AndGate(EventHandler): + def __init__(self,inputA,inputB,*outputs): + EventHandler.__init__(self,*outputs) + + self.inputA = inputA + self.inputAstate = inputA.state + inputA.registerOutput(self) + + self.inputB = inputB + self.inputBstate = inputB.state + inputB.registerOutput(self) + + self.state = 0 + + def processMessage(self,msg): + sender, value = msg + debugPrint("AndGate received %s from %s" % (value,sender)) + + if sender is self.inputA: + self.inputAstate = value + elif sender is self.inputB: + self.inputBstate = value + else: + raise RuntimeError("Didn't expect message from %s" % sender) + + if self.inputAstate and self.inputBstate: + self.state = 1 + else: + self.state = 0 + debugPrint("AndGate's new state => %s" % self.state) + + def notify(self,output): + output((self,self.state)) + +class OrGate(EventHandler): + def __init__(self,inputA,inputB,*outputs): + EventHandler.__init__(self,*outputs) + + self.inputA = inputA + self.inputAstate = inputA.state + inputA.registerOutput(self) + + self.inputB = inputB + self.inputBstate = inputB.state + inputB.registerOutput(self) + + self.state = 0 + + def processMessage(self,msg): + sender, value = msg + debugPrint("OrGate received %s from %s" % (value,sender)) + + if sender is self.inputA: + self.inputAstate = value + elif sender is self.inputB: + self.inputBstate = value + else: + raise RuntimeError("Didn't expect message from %s" % sender) + + if self.inputAstate or self.inputBstate: + self.state = 1 + else: + self.state = 0 + debugPrint("OrGate's new state => %s" % self.state) + + def notify(self,output): + output((self,self.state)) + + +if __name__ == "__main__": + # half adder + inputA = Switch() + inputB = Switch() + result = Reporter("Result = %(value)s") + carry = Reporter("Carry = %(value)s") + andGateA = AndGate(inputA,inputB,carry) + orGate = OrGate(inputA,inputB) + inverter = Inverter(andGateA) + andGateB = AndGate(orGate,inverter,result) + inputA(1) + inputB(1) + inputB(0) + inputA(0) + #print "STATE", [ x.channel.balance for x in [ inputA, inputB, result, carry, andGateA, orGate, inverter, andGateB ]] + #print "STATE", [ x.listener for x in [ inputA, inputB, result, carry, andGateA, orGate, inverter, andGateB ]] + #print "STATE", [ x.channel.__reduce__()[2][2] and x.channel.__reduce__()[2][2][0] for x in [ inputA, inputB, result, carry, andGateA, orGate, inverter, andGateB ]] + #print "STATE", [ x.channel.__reduce__()[2][2] and x.channel.__reduce__()[2][2][0].tempval for x in [ inputA, inputB, result, carry, andGateA, orGate, inverter, andGateB ]] _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 22 10:34:42 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:34:42 +0200 (CEST) Subject: [Stackless-checkins] r51469 - stackless/branches/release25-maint/Makefile.pre.in Message-ID: <20060822083442.D5A291E4009@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:34:42 2006 New Revision: 51469 Modified: stackless/branches/release25-maint/Makefile.pre.in Log: Added teststackless Makefile section, from patch by Jeff Senn. Ported from r51468. Modified: stackless/branches/release25-maint/Makefile.pre.in ============================================================================== --- stackless/branches/release25-maint/Makefile.pre.in (original) +++ stackless/branches/release25-maint/Makefile.pre.in Tue Aug 22 10:34:42 2006 @@ -621,6 +621,9 @@ -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall +teststackless: all platform + pushd Stackless/unittests; $(RUNSHARED) ../../$(BUILDPYTHON) -E -tt runAll.py; popd + # Run the unitests for both architectures in a Universal build on OSX # Must be run on an Intel box. testuniversal: all platform _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 22 10:09:11 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:09:11 +0200 (CEST) Subject: [Stackless-checkins] r51465 - stackless/tags/python-2.5c1 Message-ID: <20060822080911.B70431E4009@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:09:11 2006 New Revision: 51465 Added: stackless/tags/python-2.5c1/ - copied from r51464, stackless/branches/release25-maint/ Log: Tagging the 2.5c1 release in the Stackless release25-maint branch. _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Aug 25 15:15:11 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 25 Aug 2006 15:15:11 +0200 (CEST) Subject: [Stackless-checkins] r51613 - stackless/branches/release25-maint/PCbuild/publish_binaries.py Message-ID: <20060825131511.6BA121E4015@bag.python.org> Author: richard.tew Date: Fri Aug 25 15:15:11 2006 New Revision: 51613 Modified: stackless/branches/release25-maint/PCbuild/publish_binaries.py Log: Updated publish_binaries.py script to generate specific 2.5 binaries. Modified: stackless/branches/release25-maint/PCbuild/publish_binaries.py ============================================================================== --- stackless/branches/release25-maint/PCbuild/publish_binaries.py (original) +++ stackless/branches/release25-maint/PCbuild/publish_binaries.py Fri Aug 25 15:15:11 2006 @@ -16,7 +16,7 @@ fileList = [ r"..\Lib\copy_reg.py", r"..\Lib\pickle.py" ] for debug in ("", "_d"): for suffix in ("dll", "lib", "exp"): - fileList.append("python24%s.%s" % (debug, suffix)) + fileList.append("python25%s.%s" % (debug, suffix)) pathBySuffix = { "dll": "", @@ -26,7 +26,7 @@ } -zname = os.path.join(exp_path, "python24.zip") +zname = os.path.join(exp_path, "python25.zip") z = ZipFile(zname, "w", ZIP_DEFLATED) for fileName in fileList: if os.path.exists(fileName): _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 21 12:54:18 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 21 Aug 2006 12:54:18 +0200 (CEST) Subject: [Stackless-checkins] r51423 - in stackless/trunk/Stackless: core/stackless_impl.h core/stacklesseval.c test/test_exit_tasklet_killing.py Message-ID: <20060821105418.6498D1E4003@bag.python.org> Author: richard.tew Date: Mon Aug 21 12:54:17 2006 New Revision: 51423 Added: stackless/trunk/Stackless/test/test_exit_tasklet_killing.py - copied unchanged from r51422, stackless/Python-2.4.3/dev/Stackless/test/test_exit_tasklet_killing.py Modified: stackless/trunk/Stackless/core/stackless_impl.h stackless/trunk/Stackless/core/stacklesseval.c Log: Merged in r51422 from stackless/Python-2.4.3/dev. Text from the commit message repeated: Fix for error reported by Michael Brenner via the Stackless mailing list. When the interpreter exits, all the remaining tasklets are killed via slp_kill_tasks_with_stacks in the main tasklet. However, it is not possible to loop over the tasklets one by one killing them due to how scheduling works and that you need to schedule a tasklet to kill it. When a tasklet is scheduled, and it finishes or blocks, the next tasklet in the list is then scheduled. So what would happen is that every tasklet in the scheduler between the tasklet to be killed and the main tasklet, would be scheduled before we were back to the main tasklet and the killing of tasklets. This is definitely not what we want. The fix moves the main tasklet after the one we are killing, so that we are directly back to the tasklet killing loop when the one being killed exits. At this time there is no reproducibility case to include as a unit test, so the script which reproduces the problem is included in the test directory. Modified: stackless/trunk/Stackless/core/stackless_impl.h ============================================================================== --- stackless/trunk/Stackless/core/stackless_impl.h (original) +++ stackless/trunk/Stackless/core/stackless_impl.h Mon Aug 21 12:54:17 2006 @@ -356,6 +356,8 @@ PyTaskletObject *next, int stackless); +PyAPI_FUNC(int) initialize_main_and_current(); + /* setting the tasklet's tempval, optimized for no change */ #define TASKLET_SETVAL(task, val) \ Modified: stackless/trunk/Stackless/core/stacklesseval.c ============================================================================== --- stackless/trunk/Stackless/core/stacklesseval.c (original) +++ stackless/trunk/Stackless/core/stacklesseval.c Mon Aug 21 12:54:17 2006 @@ -290,7 +290,8 @@ while (1) { PyCStackObject *csfirst = slp_cstack_chain, *cs; - PyTaskletObject *t; + PyTaskletObject *t, *task; + PyTaskletObject **chain; if (csfirst == NULL) break; @@ -310,6 +311,26 @@ t = cs->task; Py_INCREF(t); + /* We need to ensure that the tasklet 't' is in the scheduler + * tasklet chain before this one (our main). This ensures + * that this one is directly switched back to after 't' is + * killed. The reason we do this this is because if another + * tasklet is switched to, this is of course it being scheduled + * and run. Why we do not need to do this for tasklets blocked + * on channels is that when they are scheduled to be run and + * killed, they will be implicitly placed before this one, + * leaving it to run next. + */ + if (!t->flags.blocked) { + chain = &t; + SLP_CHAIN_REMOVE(PyTaskletObject, chain, task, next, prev) + chain = &cs->tstate->st.main; + task = cs->task; + SLP_CHAIN_INSERT(PyTaskletObject, chain, task, next, prev); + cs->tstate->st.current = cs->tstate->st.main; + t = cs->task; + } + PyTasklet_Kill(t); PyErr_Clear(); @@ -325,6 +346,8 @@ { PyThreadState *ts = PyThreadState_Get(); + if (ts->st.main == NULL) + initialize_main_and_current(); slp_kill_tasks_with_stacks(allthreads ? NULL : ts); } _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 22 10:06:29 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:06:29 +0200 (CEST) Subject: [Stackless-checkins] r51463 - stackless/tags/python-2.5b3 Message-ID: <20060822080629.25BA41E4009@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:06:28 2006 New Revision: 51463 Added: stackless/tags/python-2.5b3/ - copied from r51299, stackless/trunk/ Log: Tagging the 2.5b3 release in the Stackless trunk. _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 21 13:54:19 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 21 Aug 2006 13:54:19 +0200 (CEST) Subject: [Stackless-checkins] r51425 - stackless/branches Message-ID: <20060821115419.489831E4003@bag.python.org> Author: richard.tew Date: Mon Aug 21 13:54:18 2006 New Revision: 51425 Added: stackless/branches/ Log: Added branches folder, in the hope it will solve my branching problem. _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Aug 25 14:53:35 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 25 Aug 2006 14:53:35 +0200 (CEST) Subject: [Stackless-checkins] r51609 - in stackless/Python-2.4.3/dev: PCbuild/publish_binaries.py Stackless/module/stacklessmodule.c Message-ID: <20060825125335.B4D791E4010@bag.python.org> Author: richard.tew Date: Fri Aug 25 14:53:35 2006 New Revision: 51609 Modified: stackless/Python-2.4.3/dev/PCbuild/publish_binaries.py stackless/Python-2.4.3/dev/Stackless/module/stacklessmodule.c Log: Added Jeff Senn's patch to allow running of stackless.run() on other threads other than the initial one. Corrected the publish_binaries.py script to handle the actual SVN structure rather than how I had it laid out on my harddrive. Modified: stackless/Python-2.4.3/dev/PCbuild/publish_binaries.py ============================================================================== --- stackless/Python-2.4.3/dev/PCbuild/publish_binaries.py (original) +++ stackless/Python-2.4.3/dev/PCbuild/publish_binaries.py Fri Aug 25 14:53:35 2006 @@ -1,7 +1,7 @@ from zipfile import * import os, sys, md5 -exp_path = r"..\..\binaries-pc" +exp_path = r"..\..\..\binaries-pc" prog = """ import md5 Modified: stackless/Python-2.4.3/dev/Stackless/module/stacklessmodule.c ============================================================================== --- stackless/Python-2.4.3/dev/Stackless/module/stacklessmodule.c (original) +++ stackless/Python-2.4.3/dev/Stackless/module/stacklessmodule.c Fri Aug 25 14:53:35 2006 @@ -216,9 +216,9 @@ int err; if (ts->st.main == NULL) return PyStackless_RunWatchdog_M(timeout); - if (ts != slp_initial_tstate || ts->st.current != ts->st.main) + if (ts->st.current != ts->st.main) RUNTIME_ERROR( - "run() must be run from the main thread's main tasklet.", + "run() must be run from the main tasklet.", NULL); if (timeout <= 0) { _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 21 12:59:37 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 21 Aug 2006 12:59:37 +0200 (CEST) Subject: [Stackless-checkins] r51424 - stackless/binaries-pc/python24.zip stackless/binaries-pc/python24.zip.md5.py Message-ID: <20060821105937.4C8531E4003@bag.python.org> Author: richard.tew Date: Mon Aug 21 12:59:15 2006 New Revision: 51424 Modified: stackless/binaries-pc/python24.zip stackless/binaries-pc/python24.zip.md5.py Log: Updated binaries for the fix in r51422. Modified: stackless/binaries-pc/python24.zip ============================================================================== Binary files. No diff available. Modified: stackless/binaries-pc/python24.zip.md5.py ============================================================================== --- stackless/binaries-pc/python24.zip.md5.py (original) +++ stackless/binaries-pc/python24.zip.md5.py Mon Aug 21 12:59:15 2006 @@ -1,6 +1,6 @@ import md5 -expected = "7ddbb149d33923e8352ec19b259a16c2" +expected = "e7a21e896dd56d37d3d794b6d9b8661b" fname = r"python24.zip" print "expected digest", expected received = md5.md5(file(fname, "rb").read()).hexdigest() _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 22 10:08:10 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:08:10 +0200 (CEST) Subject: [Stackless-checkins] r51464 - stackless/tags/python-2.5b2 Message-ID: <20060822080810.1FA9E1E4009@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:08:09 2006 New Revision: 51464 Added: stackless/tags/python-2.5b2/ - copied from r51101, stackless/trunk/ Log: Tagging the 2.5b2 release in the Stackless trunk. _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Mon Aug 21 11:10:27 2006 From: python-checkins at python.org (richard.tew) Date: Mon, 21 Aug 2006 11:10:27 +0200 (CEST) Subject: [Stackless-checkins] r51421 - in stackless/trunk: Doc/api/abstract.tex Doc/api/concrete.tex Doc/api/exceptions.tex Doc/api/init.tex Doc/commontex/boilerplate.tex Doc/dist/dist.tex Doc/howto/sockets.tex Doc/lib/libctypes.tex Doc/lib/libexcs.tex Doc/lib/libinspect.tex Doc/lib/liblinecache.tex Doc/lib/libturtle.tex Doc/lib/libunittest.tex Doc/lib/libwarnings.tex Doc/ref/ref2.tex Doc/ref/ref3.tex Doc/whatsnew/whatsnew25.tex Include/abstract.h Include/object.h Include/patchlevel.h Include/pyerrors.h Include/unicodeobject.h Lib/Cookie.py Lib/cgi.py Lib/compiler/ast.py Lib/compiler/pycodegen.py Lib/compiler/symbols.py Lib/ctypes/__init__.py Lib/ctypes/test/test_as_parameter.py Lib/ctypes/test/test_functions.py Lib/ctypes/test/test_numbers.py Lib/ctypes/test/test_prototypes.py Lib/ctypes/test/test_python_api.py Lib/distutils/__init__.py Lib/idlelib Lib/idlelib/Bindings.py Lib/idlelib/CREDITS.txt Lib/idlelib/CodeContext.py Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/PyShell.py L! ib/idlelib/ScriptBinding.py Lib/idlelib/idlever.py Lib/logging/__init__.py Lib/logging/config.py Lib/site.py Lib/string.py Lib/tabnanny.py Lib/test/exception_hierarchy.txt Lib/test/inspect_fodder2.py Lib/test/output/test_cgi Lib/test/regrtest.py Lib/test/test_bigaddrspace.py Lib/test/test_builtin.py Lib/test/test_bz2.py Lib/test/test_cgi.py Lib/test/test_code.py Lib/test/test_compiler.py Lib/test/test_descr.py Lib/test/test_format.py Lib/test/test_index.py Lib/test/test_inspect.py Lib/test/test_logging.py Lib/test/test_mailbox.py Lib/test/test_shutil.py Lib/test/test_signal.py Lib/test/test_socketserver.py Lib/test/test_struct.py Lib/test/test_support.py Lib/test/test_threading.py Lib/test/test_threadsignals.py Lib/test/test_trace.py Lib/test/test_traceback.py Lib/test/test_types.py Lib/test/test_uuid.py Lib/test/test_xml_etree_c.py Lib/tokenize.py Lib/trace.py Lib/traceback.py Lib/uuid.py Lib/webbrowser.py Lib/xml/etree Misc/ACKS Misc/NEWS Misc/PURIFY.README Misc/README.kl! ocwork Misc/RPM/python-2.5.spec Modules/Setup.dist Modules/_bsddb.c Modules/_codecsmodule.c Modules/_ctypes/_ctypes.c Modules/_ctypes/_ctypes_test.c Modules/_ctypes/callbacks.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_ctypes/ctypes.h Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Mod Message-ID: <20060821091027.C3A4B1E4003@bag.python.org> Author: richard.tew Date: Mon Aug 21 11:10:05 2006 New Revision: 51421 Added: stackless/trunk/Lib/ctypes/test/test_as_parameter.py - copied unchanged from r51332, python/trunk/Lib/ctypes/test/test_as_parameter.py stackless/trunk/Lib/test/test_bigaddrspace.py - copied unchanged from r51332, python/trunk/Lib/test/test_bigaddrspace.py Modified: stackless/trunk/Doc/api/abstract.tex stackless/trunk/Doc/api/concrete.tex stackless/trunk/Doc/api/exceptions.tex stackless/trunk/Doc/api/init.tex stackless/trunk/Doc/commontex/boilerplate.tex stackless/trunk/Doc/dist/dist.tex stackless/trunk/Doc/howto/sockets.tex stackless/trunk/Doc/lib/libctypes.tex stackless/trunk/Doc/lib/libexcs.tex stackless/trunk/Doc/lib/libinspect.tex stackless/trunk/Doc/lib/liblinecache.tex stackless/trunk/Doc/lib/libturtle.tex stackless/trunk/Doc/lib/libunittest.tex stackless/trunk/Doc/lib/libwarnings.tex stackless/trunk/Doc/ref/ref2.tex stackless/trunk/Doc/ref/ref3.tex stackless/trunk/Doc/whatsnew/whatsnew25.tex stackless/trunk/Include/abstract.h stackless/trunk/Include/object.h stackless/trunk/Include/patchlevel.h stackless/trunk/Include/pyerrors.h stackless/trunk/Include/unicodeobject.h stackless/trunk/Lib/Cookie.py stackless/trunk/Lib/cgi.py stackless/trunk/Lib/compiler/ast.py stackless/trunk/Lib/compiler/pycodegen.py stackless/trunk/Lib/compiler/symbols.py stackless/trunk/Lib/ctypes/__init__.py stackless/trunk/Lib/ctypes/test/test_functions.py stackless/trunk/Lib/ctypes/test/test_numbers.py stackless/trunk/Lib/ctypes/test/test_prototypes.py stackless/trunk/Lib/ctypes/test/test_python_api.py stackless/trunk/Lib/distutils/__init__.py stackless/trunk/Lib/idlelib/ (props changed) stackless/trunk/Lib/idlelib/Bindings.py stackless/trunk/Lib/idlelib/CREDITS.txt stackless/trunk/Lib/idlelib/CodeContext.py stackless/trunk/Lib/idlelib/EditorWindow.py stackless/trunk/Lib/idlelib/NEWS.txt stackless/trunk/Lib/idlelib/PyShell.py stackless/trunk/Lib/idlelib/ScriptBinding.py stackless/trunk/Lib/idlelib/idlever.py stackless/trunk/Lib/logging/__init__.py stackless/trunk/Lib/logging/config.py stackless/trunk/Lib/site.py stackless/trunk/Lib/string.py stackless/trunk/Lib/tabnanny.py stackless/trunk/Lib/test/exception_hierarchy.txt stackless/trunk/Lib/test/inspect_fodder2.py stackless/trunk/Lib/test/output/test_cgi stackless/trunk/Lib/test/regrtest.py stackless/trunk/Lib/test/test_builtin.py stackless/trunk/Lib/test/test_bz2.py stackless/trunk/Lib/test/test_cgi.py stackless/trunk/Lib/test/test_code.py stackless/trunk/Lib/test/test_compiler.py stackless/trunk/Lib/test/test_descr.py stackless/trunk/Lib/test/test_format.py stackless/trunk/Lib/test/test_index.py stackless/trunk/Lib/test/test_inspect.py stackless/trunk/Lib/test/test_logging.py stackless/trunk/Lib/test/test_mailbox.py stackless/trunk/Lib/test/test_shutil.py stackless/trunk/Lib/test/test_signal.py stackless/trunk/Lib/test/test_socketserver.py stackless/trunk/Lib/test/test_struct.py stackless/trunk/Lib/test/test_support.py stackless/trunk/Lib/test/test_threading.py stackless/trunk/Lib/test/test_threadsignals.py stackless/trunk/Lib/test/test_trace.py stackless/trunk/Lib/test/test_traceback.py stackless/trunk/Lib/test/test_types.py stackless/trunk/Lib/test/test_uuid.py stackless/trunk/Lib/test/test_xml_etree_c.py stackless/trunk/Lib/tokenize.py stackless/trunk/Lib/trace.py stackless/trunk/Lib/traceback.py stackless/trunk/Lib/uuid.py stackless/trunk/Lib/webbrowser.py stackless/trunk/Lib/xml/etree/ (props changed) stackless/trunk/Misc/ACKS stackless/trunk/Misc/NEWS stackless/trunk/Misc/PURIFY.README stackless/trunk/Misc/README.klocwork stackless/trunk/Misc/RPM/python-2.5.spec stackless/trunk/Modules/Setup.dist stackless/trunk/Modules/_bsddb.c stackless/trunk/Modules/_codecsmodule.c stackless/trunk/Modules/_ctypes/_ctypes.c stackless/trunk/Modules/_ctypes/_ctypes_test.c stackless/trunk/Modules/_ctypes/callbacks.c stackless/trunk/Modules/_ctypes/callproc.c stackless/trunk/Modules/_ctypes/cfield.c stackless/trunk/Modules/_ctypes/ctypes.h stackless/trunk/Modules/_ctypes/libffi/configure stackless/trunk/Modules/_ctypes/libffi/configure.ac stackless/trunk/Modules/_ctypes/libffi/fficonfig.py.in stackless/trunk/Modules/_cursesmodule.c stackless/trunk/Modules/_elementtree.c stackless/trunk/Modules/_hotshot.c stackless/trunk/Modules/_sre.c stackless/trunk/Modules/_struct.c stackless/trunk/Modules/_testcapimodule.c stackless/trunk/Modules/_tkinter.c stackless/trunk/Modules/arraymodule.c stackless/trunk/Modules/bz2module.c stackless/trunk/Modules/collectionsmodule.c stackless/trunk/Modules/expat/xmlparse.c stackless/trunk/Modules/mmapmodule.c stackless/trunk/Modules/operator.c stackless/trunk/Modules/posixmodule.c stackless/trunk/Modules/rgbimgmodule.c stackless/trunk/Modules/socketmodule.c stackless/trunk/Modules/unicodedata.c stackless/trunk/Modules/zipimport.c stackless/trunk/Objects/abstract.c stackless/trunk/Objects/bufferobject.c stackless/trunk/Objects/classobject.c stackless/trunk/Objects/descrobject.c stackless/trunk/Objects/dictnotes.txt stackless/trunk/Objects/dictobject.c stackless/trunk/Objects/exceptions.c stackless/trunk/Objects/intobject.c stackless/trunk/Objects/listobject.c stackless/trunk/Objects/longobject.c stackless/trunk/Objects/object.c stackless/trunk/Objects/sliceobject.c stackless/trunk/Objects/stringobject.c stackless/trunk/Objects/structseq.c stackless/trunk/Objects/tupleobject.c stackless/trunk/Objects/typeobject.c stackless/trunk/Objects/unicodeobject.c stackless/trunk/PCbuild/_msi.vcproj stackless/trunk/PCbuild/_ssl.mak stackless/trunk/PCbuild/_ssl.vcproj stackless/trunk/PCbuild/build_ssl.py stackless/trunk/Parser/ (props changed) stackless/trunk/Parser/grammar.c stackless/trunk/Parser/parsetok.c stackless/trunk/Python/ast.c stackless/trunk/Python/bltinmodule.c stackless/trunk/Python/ceval.c stackless/trunk/Python/compile.c stackless/trunk/Python/errors.c stackless/trunk/Python/getargs.c stackless/trunk/Python/import.c stackless/trunk/Python/marshal.c stackless/trunk/Python/pystate.c stackless/trunk/Python/pythonrun.c stackless/trunk/Python/symtable.c stackless/trunk/README stackless/trunk/Tools/buildbot/ (props changed) stackless/trunk/Tools/msi/msi.py stackless/trunk/configure stackless/trunk/configure.in stackless/trunk/setup.py Log: Merged in the Python trunk changes from 2.5b3 (r51065) to 2.5c1 (r51332). The Stackless trunk will continue to mirror the Python trunk, so it will be branched to a 'release25-maint' branch to match how core Python development is done. Modified: stackless/trunk/Doc/api/abstract.tex ============================================================================== --- stackless/trunk/Doc/api/abstract.tex (original) +++ stackless/trunk/Doc/api/abstract.tex Mon Aug 21 11:10:05 2006 @@ -693,12 +693,31 @@ \samp{float(\var{o})}.\bifuncindex{float} \end{cfuncdesc} -\begin{cfuncdesc}{Py_ssize_t}{PyNumber_Index}{PyObject *o} - Returns the \var{o} converted to a Py_ssize_t integer on success, or - -1 with an exception raised on failure. +\begin{cfuncdesc}{PyObject*}{PyNumber_Index}{PyObject *o} + Returns the \var{o} converted to a Python int or long on success or \NULL{} + with a TypeError exception raised on failure. \versionadded{2.5} \end{cfuncdesc} +\begin{cfuncdesc}{Py_ssize_t}{PyNumber_AsSsize_t}{PyObject *o, PyObject *exc} + Returns \var{o} converted to a Py_ssize_t value if \var{o} + can be interpreted as an integer. If \var{o} can be converted to a Python + int or long but the attempt to convert to a Py_ssize_t value + would raise an \exception{OverflowError}, then the \var{exc} argument + is the type of exception that will be raised (usually \exception{IndexError} + or \exception{OverflowError}). If \var{exc} is \NULL{}, then the exception + is cleared and the value is clipped to \var{PY_SSIZE_T_MIN} + for a negative integer or \var{PY_SSIZE_T_MAX} for a positive integer. + \versionadded{2.5} +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyIndex_Check}{PyObject *o} + Returns True if \var{o} is an index integer (has the nb_index slot of + the tp_as_number structure filled in). + \versionadded{2.5} +\end{cfuncdesc} + + \section{Sequence Protocol \label{sequence}} \begin{cfuncdesc}{int}{PySequence_Check}{PyObject *o} Modified: stackless/trunk/Doc/api/concrete.tex ============================================================================== --- stackless/trunk/Doc/api/concrete.tex (original) +++ stackless/trunk/Doc/api/concrete.tex Mon Aug 21 11:10:05 2006 @@ -31,7 +31,7 @@ \begin{cvardesc}{PyObject*}{PyType_Type} This is the type object for type objects; it is the same object as - \code{types.TypeType} in the Python layer. + \code{type} and \code{types.TypeType} in the Python layer. \withsubitem{(in module types)}{\ttindex{TypeType}} \end{cvardesc} @@ -117,7 +117,8 @@ \begin{cvardesc}{PyTypeObject}{PyInt_Type} This instance of \ctype{PyTypeObject} represents the Python plain - integer type. This is the same object as \code{types.IntType}. + integer type. This is the same object as \code{int} and + \code{types.IntType}. \withsubitem{(in modules types)}{\ttindex{IntType}} \end{cvardesc} @@ -260,7 +261,8 @@ \begin{cvardesc}{PyTypeObject}{PyLong_Type} This instance of \ctype{PyTypeObject} represents the Python long - integer type. This is the same object as \code{types.LongType}. + integer type. This is the same object as \code{long} and + \code{types.LongType}. \withsubitem{(in modules types)}{\ttindex{LongType}} \end{cvardesc} @@ -411,7 +413,8 @@ \begin{cvardesc}{PyTypeObject}{PyFloat_Type} This instance of \ctype{PyTypeObject} represents the Python floating - point type. This is the same object as \code{types.FloatType}. + point type. This is the same object as \code{float} and + \code{types.FloatType}. \withsubitem{(in modules types)}{\ttindex{FloatType}} \end{cvardesc} @@ -520,7 +523,8 @@ \begin{cvardesc}{PyTypeObject}{PyComplex_Type} This instance of \ctype{PyTypeObject} represents the Python complex - number type. + number type. It is the same object as \code{complex} and + \code{types.ComplexType}. \end{cvardesc} \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} @@ -580,8 +584,8 @@ \begin{cvardesc}{PyTypeObject}{PyString_Type} This instance of \ctype{PyTypeObject} represents the Python string - type; it is the same object as \code{types.TypeType} in the Python - layer. + type; it is the same object as \code{str} and \code{types.StringType} + in the Python layer. \withsubitem{(in module types)}{\ttindex{StringType}}. \end{cvardesc} @@ -850,7 +854,8 @@ \begin{cvardesc}{PyTypeObject}{PyUnicode_Type} This instance of \ctype{PyTypeObject} represents the Python Unicode - type. + type. It is exposed to Python code as \code{unicode} and + \code{types.UnicodeType}. \end{cvardesc} The following APIs are really C macros and can be used to do fast @@ -1555,6 +1560,26 @@ greater than, respectively. \end{cfuncdesc} +\begin{cfuncdesc}{int}{PyUnicode_RichCompare}{PyObject *left, + PyObject *right, + int op} + + Rich compare two unicode strings and return one of the following: + \begin{itemize} + \item \code{NULL} in case an exception was raised + \item \constant{Py_True} or \constant{Py_False} for successful comparisons + \item \constant{Py_NotImplemented} in case the type combination is unknown + \end{itemize} + + Note that \constant{Py_EQ} and \constant{Py_NE} comparisons can cause a + \exception{UnicodeWarning} in case the conversion of the arguments to + Unicode fails with a \exception{UnicodeDecodeError}. + + Possible values for \var{op} are + \constant{Py_GT}, \constant{Py_GE}, \constant{Py_EQ}, + \constant{Py_NE}, \constant{Py_LT}, and \constant{Py_LE}. +\end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyUnicode_Format}{PyObject *format, PyObject *args} Return a new string object from \var{format} and \var{args}; this @@ -1623,8 +1648,9 @@ \begin{cvardesc}{PyTypeObject}{PyBuffer_Type} The instance of \ctype{PyTypeObject} which represents the Python - buffer type; it is the same object as \code{types.BufferType} in the - Python layer.\withsubitem{(in module types)}{\ttindex{BufferType}}. + buffer type; it is the same object as \code{buffer} and + \code{types.BufferType} in the Python layer. + \withsubitem{(in module types)}{\ttindex{BufferType}}. \end{cvardesc} \begin{cvardesc}{int}{Py_END_OF_BUFFER} @@ -1698,8 +1724,8 @@ \begin{cvardesc}{PyTypeObject}{PyTuple_Type} This instance of \ctype{PyTypeObject} represents the Python tuple - type; it is the same object as \code{types.TupleType} in the Python - layer.\withsubitem{(in module types)}{\ttindex{TupleType}}. + type; it is the same object as \code{tuple} and \code{types.TupleType} + in the Python layer.\withsubitem{(in module types)}{\ttindex{TupleType}}. \end{cvardesc} \begin{cfuncdesc}{int}{PyTuple_Check}{PyObject *p} @@ -1795,8 +1821,8 @@ \begin{cvardesc}{PyTypeObject}{PyList_Type} This instance of \ctype{PyTypeObject} represents the Python list - type. This is the same object as \code{types.ListType}. - \withsubitem{(in module types)}{\ttindex{ListType}} + type. This is the same object as \code{list} and \code{types.ListType} + in the Python layer.\withsubitem{(in module types)}{\ttindex{ListType}} \end{cvardesc} \begin{cfuncdesc}{int}{PyList_Check}{PyObject *p} @@ -1924,7 +1950,7 @@ \begin{cvardesc}{PyTypeObject}{PyDict_Type} This instance of \ctype{PyTypeObject} represents the Python dictionary type. This is exposed to Python programs as - \code{types.DictType} and \code{types.DictionaryType}. + \code{dict} and \code{types.DictType}. \withsubitem{(in module types)}{\ttindex{DictType}\ttindex{DictionaryType}} \end{cvardesc} @@ -2139,7 +2165,8 @@ \begin{cvardesc}{PyTypeObject}{PyFile_Type} This instance of \ctype{PyTypeObject} represents the Python file - type. This is exposed to Python programs as \code{types.FileType}. + type. This is exposed to Python programs as \code{file} and + \code{types.FileType}. \withsubitem{(in module types)}{\ttindex{FileType}} \end{cvardesc} @@ -2588,7 +2615,7 @@ \begin{cvardesc}{PyTypeObject}{PySlice_Type} The type object for slice objects. This is the same as - \code{types.SliceType}. + \code{slice} and \code{types.SliceType}. \withsubitem{(in module types)}{\ttindex{SliceType}} \end{cvardesc} Modified: stackless/trunk/Doc/api/exceptions.tex ============================================================================== --- stackless/trunk/Doc/api/exceptions.tex (original) +++ stackless/trunk/Doc/api/exceptions.tex Mon Aug 21 11:10:05 2006 @@ -288,10 +288,11 @@ names are \samp{PyExc_} followed by the Python exception name. These have the type \ctype{PyObject*}; they are all class objects. Their names are \cdata{PyExc_Warning}, \cdata{PyExc_UserWarning}, - \cdata{PyExc_DeprecationWarning}, \cdata{PyExc_SyntaxWarning}, - \cdata{PyExc_RuntimeWarning}, and \cdata{PyExc_FutureWarning}. - \cdata{PyExc_Warning} is a subclass of \cdata{PyExc_Exception}; the - other warning categories are subclasses of \cdata{PyExc_Warning}. + \cdata{PyExc_UnicodeWarning}, \cdata{PyExc_DeprecationWarning}, + \cdata{PyExc_SyntaxWarning}, \cdata{PyExc_RuntimeWarning}, and + \cdata{PyExc_FutureWarning}. \cdata{PyExc_Warning} is a subclass of + \cdata{PyExc_Exception}; the other warning categories are subclasses + of \cdata{PyExc_Warning}. For information about warning control, see the documentation for the \module{warnings} module and the \programopt{-W} option in the Modified: stackless/trunk/Doc/api/init.tex ============================================================================== --- stackless/trunk/Doc/api/init.tex (original) +++ stackless/trunk/Doc/api/init.tex Mon Aug 21 11:10:05 2006 @@ -696,15 +696,15 @@ \end{cfuncdesc} \begin{cfuncdesc}{int}{PyThreadState_SetAsyncExc}{long id, PyObject *exc} - Asynchronously raise an exception in a thread. + Asynchronously raise an exception in a thread. The \var{id} argument is the thread id of the target thread; \var{exc} is the exception object to be raised. This function does not steal any references to \var{exc}. - To prevent naive misuse, you must write your own C extension - to call this. Must be called with the GIL held. - Returns the number of thread states modified; if it returns a number - greater than one, you're in trouble, and you should call it again - with \var{exc} set to \constant{NULL} to revert the effect. + To prevent naive misuse, you must write your own C extension + to call this. Must be called with the GIL held. + Returns the number of thread states modified; this is normally one, but + will be zero if the thread id isn't found. If \var{exc} is + \constant{NULL}, the pending exception (if any) for the thread is cleared. This raises no exceptions. \versionadded{2.3} \end{cfuncdesc} Modified: stackless/trunk/Doc/commontex/boilerplate.tex ============================================================================== --- stackless/trunk/Doc/commontex/boilerplate.tex (original) +++ stackless/trunk/Doc/commontex/boilerplate.tex Mon Aug 21 11:10:05 2006 @@ -5,5 +5,5 @@ Email: \email{docs at python.org} } -\date{3rd August, 2006} % XXX update before final release! +\date{17th August, 2006} % XXX update before final release! \input{patchlevel} % include Python version information Modified: stackless/trunk/Doc/dist/dist.tex ============================================================================== --- stackless/trunk/Doc/dist/dist.tex (original) +++ stackless/trunk/Doc/dist/dist.tex Mon Aug 21 11:10:05 2006 @@ -1992,6 +1992,7 @@ script for this could be \begin{verbatim} from distutils.core import setup +from distutils.extension import Extension setup(name='foobar', version='1.0', ext_modules=[Extension('foo', ['foo.c'])], @@ -2006,6 +2007,7 @@ extension: \begin{verbatim} from distutils.core import setup +from distutils.extension import Extension setup(name='foobar', version='1.0', ext_modules=[Extension('foopkg.foo', ['foo.c'])], Modified: stackless/trunk/Doc/howto/sockets.tex ============================================================================== --- stackless/trunk/Doc/howto/sockets.tex (original) +++ stackless/trunk/Doc/howto/sockets.tex Mon Aug 21 11:10:05 2006 @@ -213,34 +213,39 @@ is a fixed length message: \begin{verbatim} - class mysocket: - '''demonstration class only - - coded for clarity, not efficiency''' - def __init__(self, sock=None): - if sock is None: - self.sock = socket.socket( - socket.AF_INET, socket.SOCK_STREAM) - else: - self.sock = sock - def connect(host, port): - self.sock.connect((host, port)) - def mysend(msg): - totalsent = 0 - while totalsent < MSGLEN: - sent = self.sock.send(msg[totalsent:]) - if sent == 0: - raise RuntimeError, \\ - "socket connection broken" - totalsent = totalsent + sent - def myreceive(): - msg = '' - while len(msg) < MSGLEN: - chunk = self.sock.recv(MSGLEN-len(msg)) - if chunk == '': - raise RuntimeError, \\ - "socket connection broken" - msg = msg + chunk - return msg +class mysocket: + '''demonstration class only + - coded for clarity, not efficiency + ''' + + def __init__(self, sock=None): + if sock is None: + self.sock = socket.socket( + socket.AF_INET, socket.SOCK_STREAM) + else: + self.sock = sock + + def connect(self, host, port): + self.sock.connect((host, port)) + + def mysend(self, msg): + totalsent = 0 + while totalsent < MSGLEN: + sent = self.sock.send(msg[totalsent:]) + if sent == 0: + raise RuntimeError, \\ + "socket connection broken" + totalsent = totalsent + sent + + def myreceive(self): + msg = '' + while len(msg) < MSGLEN: + chunk = self.sock.recv(MSGLEN-len(msg)) + if chunk == '': + raise RuntimeError, \\ + "socket connection broken" + msg = msg + chunk + return msg \end{verbatim} The sending code here is usable for almost any messaging scheme - in Modified: stackless/trunk/Doc/lib/libctypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libctypes.tex (original) +++ stackless/trunk/Doc/lib/libctypes.tex Mon Aug 21 11:10:05 2006 @@ -199,8 +199,13 @@ There are, however, enough ways to crash Python with \code{ctypes}, so you should be careful anyway. -Python integers, strings and unicode strings are the only objects that -can directly be used as parameters in these function calls. +\code{None}, integers, longs, byte strings and unicode strings are the +only native Python objects that can directly be used as parameters in +these function calls. \code{None} is passed as a C \code{NULL} pointer, +byte strings and unicode strings are passed as pointer to the memory +block that contains their data (\code{char *} or \code{wchar{\_}t *}). Python +integers and Python longs are passed as the platforms default C +\code{int} type, their value is masked to fit into the C type. Before we move on calling functions with other parameter types, we have to learn more about \code{ctypes} data types. @@ -227,7 +232,18 @@ \code{char} } { -character +1-character +string +} +\lineiii{ +\class{c{\_}wchar} +} +{ +\code{wchar{\_}t} +} +{ +1-character +unicode string } \lineiii{ \class{c{\_}byte} @@ -236,7 +252,7 @@ \code{char} } { -integer +int/long } \lineiii{ \class{c{\_}ubyte} @@ -245,7 +261,7 @@ \code{unsigned char} } { -integer +int/long } \lineiii{ \class{c{\_}short} @@ -254,7 +270,7 @@ \code{short} } { -integer +int/long } \lineiii{ \class{c{\_}ushort} @@ -263,7 +279,7 @@ \code{unsigned short} } { -integer +int/long } \lineiii{ \class{c{\_}int} @@ -272,7 +288,7 @@ \code{int} } { -integer +int/long } \lineiii{ \class{c{\_}uint} @@ -281,7 +297,7 @@ \code{unsigned int} } { -integer +int/long } \lineiii{ \class{c{\_}long} @@ -290,7 +306,7 @@ \code{long} } { -integer +int/long } \lineiii{ \class{c{\_}ulong} @@ -299,7 +315,7 @@ \code{unsigned long} } { -long +int/long } \lineiii{ \class{c{\_}longlong} @@ -309,7 +325,7 @@ \code{long long} } { -long +int/long } \lineiii{ \class{c{\_}ulonglong} @@ -319,7 +335,7 @@ \code{unsigned long long} } { -long +int/long } \lineiii{ \class{c{\_}float} @@ -368,8 +384,8 @@ \code{void *} } { -integer or -\code{None} +int/long +or \code{None} } \end{tableiii} \end{quote} @@ -554,11 +570,11 @@ \subsubsection{Return types\label{ctypes-return-types}} -By default functions are assumed to return integers. Other return -types can be specified by setting the \member{restype} attribute of the -function object. +By default functions are assumed to return the C \code{int} type. Other +return types can be specified by setting the \member{restype} attribute of +the function object. -Here is a more advanced example, it uses the strchr function, which +Here is a more advanced example, it uses the \code{strchr} function, which expects a string pointer and a char, and returns a pointer to a string: \begin{verbatim} @@ -1611,8 +1627,8 @@ \begin{datadescni}{pythonapi} An instance of \class{PyDLL} that exposes Python C api functions as -attributes. Note that all these functions are assumed to return -integers, which is of course not always the truth, so you have to +attributes. Note that all these functions are assumed to return C +\code{int}, which is of course not always the truth, so you have to assign the correct \member{restype} attribute to use these functions. \end{datadescni} @@ -1642,8 +1658,8 @@ anything. It is possible to assign a callable Python object that is not a -ctypes type, in this case the function is assumed to return an -integer, and the callable will be called with this integer, +ctypes type, in this case the function is assumed to return a +C \code{int}, and the callable will be called with this integer, allowing to do further processing or error checking. Using this is deprecated, for more flexible postprocessing or error checking use a ctypes data type as \member{restype} and assign a callable to the @@ -2283,9 +2299,12 @@ or error information for a function or method call. \end{classdesc*} -\begin{classdesc*}{py_object} -Represents the C \code{PyObject *} datatype. -\end{classdesc*} +\code{py{\_}object} : classdesc* +\begin{quote} + +Represents the C \code{PyObject *} datatype. Calling this with an +without an argument creates a \code{NULL} \code{PyObject *} pointer. +\end{quote} The \code{ctypes.wintypes} module provides quite some other Windows specific data types, for example \code{HWND}, \code{WPARAM}, or \code{DWORD}. @@ -2324,9 +2343,9 @@ the second item specifies the type of the field; it can be any ctypes data type. -For integer type fields, a third optional item can be given. It -must be a small positive integer defining the bit width of the -field. +For integer type fields like \class{c{\_}int}, a third optional item can +be given. It must be a small positive integer defining the bit +width of the field. Field names must be unique within one structure or union. This is not checked, only one field can be accessed when names are Modified: stackless/trunk/Doc/lib/libexcs.tex ============================================================================== --- stackless/trunk/Doc/lib/libexcs.tex (original) +++ stackless/trunk/Doc/lib/libexcs.tex Mon Aug 21 11:10:05 2006 @@ -456,6 +456,11 @@ \versionadded{2.5} \end{excdesc} +\begin{excdesc}{UnicodeWarning} +Base class for warnings related to Unicode. +\versionadded{2.5} +\end{excdesc} + The class hierarchy for built-in exceptions is: \verbatiminput{../../Lib/test/exception_hierarchy.txt} Modified: stackless/trunk/Doc/lib/libinspect.tex ============================================================================== --- stackless/trunk/Doc/lib/libinspect.tex (original) +++ stackless/trunk/Doc/lib/libinspect.tex Mon Aug 21 11:10:05 2006 @@ -291,18 +291,18 @@ \end{funcdesc} \begin{funcdesc}{formatargspec}{args\optional{, varargs, varkw, defaults, - argformat, varargsformat, varkwformat, defaultformat}} + formatarg, formatvarargs, formatvarkw, formatvalue, join}} Format a pretty argument spec from the four values returned by - \function{getargspec()}. The other four arguments are the + \function{getargspec()}. The format* arguments are the corresponding optional formatting functions that are called to turn names and values into strings. \end{funcdesc} \begin{funcdesc}{formatargvalues}{args\optional{, varargs, varkw, locals, - argformat, varargsformat, varkwformat, valueformat}} + formatarg, formatvarargs, formatvarkw, formatvalue, join}} Format a pretty argument spec from the four values returned by - \function{getargvalues()}. The other four arguments are the + \function{getargvalues()}. The format* arguments are the corresponding optional formatting functions that are called to turn names and values into strings. \end{funcdesc} Modified: stackless/trunk/Doc/lib/liblinecache.tex ============================================================================== --- stackless/trunk/Doc/lib/liblinecache.tex (original) +++ stackless/trunk/Doc/lib/liblinecache.tex Mon Aug 21 11:10:05 2006 @@ -38,7 +38,7 @@ \begin{funcdesc}{checkcache}{\optional{filename}} Check the cache for validity. Use this function if files in the cache may have changed on disk, and you require the updated version. If -\var{filename} is omitted, it will check the whole cache entries. +\var{filename} is omitted, it will check all the entries in the cache. \end{funcdesc} Example: Modified: stackless/trunk/Doc/lib/libturtle.tex ============================================================================== --- stackless/trunk/Doc/lib/libturtle.tex (original) +++ stackless/trunk/Doc/lib/libturtle.tex Mon Aug 21 11:10:05 2006 @@ -253,12 +253,13 @@ \subsection{Turtle, Pen and RawPen Objects \label{pen-rawpen-objects}} -\class{Turtle}, \class{Pen} and \class{RawPen} objects have all the -global functions described above, except for \function{demo()} as -methods, which manipulate the given pen. +Most of the global functions available in the module are also +available as methods of the \class{Turtle}, \class{Pen} and +\class{RawPen} classes, affecting only the state of the given pen. The only method which is more powerful as a method is -\function{degrees()}. +\function{degrees()}, which takes an optional argument letting +you specify the number of units corresponding to a full circle: \begin{methoddesc}{degrees}{\optional{fullcircle}} \var{fullcircle} is by default 360. This can cause the pen to have any Modified: stackless/trunk/Doc/lib/libunittest.tex ============================================================================== --- stackless/trunk/Doc/lib/libunittest.tex (original) +++ stackless/trunk/Doc/lib/libunittest.tex Mon Aug 21 11:10:05 2006 @@ -10,19 +10,19 @@ \versionadded{2.1} -The Python unit testing framework, often referred to as ``PyUnit,'' is +The Python unit testing framework, sometimes referred to as ``PyUnit,'' is a Python language version of JUnit, by Kent Beck and Erich Gamma. JUnit is, in turn, a Java version of Kent's Smalltalk testing framework. Each is the de facto standard unit testing framework for its respective language. -PyUnit supports test automation, sharing of setup and shutdown code -for tests, aggregation of tests into collections, and independence of +\module{unittest} supports test automation, sharing of setup and shutdown +code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework. The \module{unittest} module provides classes that make it easy to support these qualities for a set of tests. -To achieve this, PyUnit supports some important concepts: +To achieve this, \module{unittest} supports some important concepts: \begin{definitions} \term{test fixture} @@ -33,10 +33,9 @@ \term{test case} A \dfn{test case} is the smallest unit of testing. It checks for a -specific response to a particular set of inputs. PyUnit provides a -base class, \class{TestCase}, which may be used to create new test -cases. You may provide your own implementation that does not subclass -from \class{TestCase}, of course. +specific response to a particular set of inputs. \module{unittest} +provides a base class, \class{TestCase}, which may be used to create +new test cases. \term{test suite} A \dfn{test suite} is a collection of test cases, test suites, or @@ -54,8 +53,8 @@ The test case and test fixture concepts are supported through the \class{TestCase} and \class{FunctionTestCase} classes; the former should be used when creating new tests, and the latter can be used when -integrating existing test code with a PyUnit-driven framework. When -building test fixtures using \class{TestCase}, the \method{setUp()} +integrating existing test code with a \module{unittest}-driven framework. +When building test fixtures using \class{TestCase}, the \method{setUp()} and \method{tearDown()} methods can be overridden to provide initialization and cleanup for the fixture. With \class{FunctionTestCase}, existing functions can be passed to the @@ -74,19 +73,17 @@ A test runner is an object that provides a single method, \method{run()}, which accepts a \class{TestCase} or \class{TestSuite} object as a parameter, and returns a result object. The class -\class{TestResult} is provided for use as the result object. PyUnit -provide the \class{TextTestRunner} as an example test runner which -reports test results on the standard error stream by default. -Alternate runners can be implemented for other environments (such as -graphical environments) without any need to derive from a specific -class. +\class{TestResult} is provided for use as the result object. +\module{unittest} provides the \class{TextTestRunner} as an example +test runner which reports test results on the standard error stream by +default. Alternate runners can be implemented for other environments +(such as graphical environments) without any need to derive from a +specific class. \begin{seealso} \seemodule{doctest}{Another test-support module with a very different flavor.} - \seetitle[http://pyunit.sourceforge.net/]{PyUnit Web Site}{The - source for further information on PyUnit.} \seetitle[http://www.XProgramming.com/testfram.htm]{Simple Smalltalk Testing: With Patterns}{Kent Beck's original paper on testing frameworks using the pattern shared by @@ -166,7 +163,7 @@ with: \begin{verbatim} -suite = unittest.makeSuite(TestSequenceFunctions) +suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions) unittest.TextTestRunner(verbosity=2).run(suite) \end{verbatim} @@ -194,8 +191,8 @@ The basic building blocks of unit testing are \dfn{test cases} --- single scenarios that must be set up and checked for correctness. In -PyUnit, test cases are represented by instances of the -\class{TestCase} class in the \refmodule{unittest} module. To make +\module{unittest}, test cases are represented by instances of +\module{unittest}'s \class{TestCase} class. To make your own test cases you must write subclasses of \class{TestCase}, or use \class{FunctionTestCase}. @@ -207,7 +204,7 @@ self contained, such that it can be run either in isolation or in arbitrary combination with any number of other test cases. -The simplest test case subclass will simply override the +The simplest \class{TestCase} subclass will simply override the \method{runTest()} method in order to perform specific testing code: \begin{verbatim} @@ -221,12 +218,13 @@ Note that in order to test something, we use the one of the \method{assert*()} or \method{fail*()} methods provided by the -\class{TestCase} base class. If the test fails when the test case -runs, an exception will be raised, and the testing framework will -identify the test case as a \dfn{failure}. Other exceptions that do -not arise from checks made through the \method{assert*()} and -\method{fail*()} methods are identified by the testing framework as -\dfn{errors}. +\class{TestCase} base class. If the test fails, an exception will be +raised, and \module{unittest} will identify the test case as a +\dfn{failure}. Any other exceptions will be treated as \dfn{errors}. +This helps you identify where the problem is: \dfn{failures} are caused by +incorrect results - a 5 where you expected a 6. \dfn{Errors} are caused by +incorrect code - e.g., a \exception{TypeError} caused by an incorrect +function call. The way to run a test case will be described later. For now, note that to construct an instance of such a test case, we call its @@ -237,7 +235,7 @@ \end{verbatim} Now, such test cases can be numerous, and their set-up can be -repetitive. In the above case, constructing a ``Widget'' in each of +repetitive. In the above case, constructing a \class{Widget} in each of 100 Widget test case subclasses would mean unsightly duplication. Luckily, we can factor out such set-up code by implementing a method @@ -283,7 +281,7 @@ \end{verbatim} If \method{setUp()} succeeded, the \method{tearDown()} method will be -run regardless of whether or not \method{runTest()} succeeded. +run whether \method{runTest()} succeeded or not. Such a working environment for the testing code is called a \dfn{fixture}. @@ -292,8 +290,8 @@ we would end up subclassing \class{SimpleWidgetTestCase} into many small one-method classes such as \class{DefaultWidgetSizeTestCase}. This is time-consuming and -discouraging, so in the same vein as JUnit, PyUnit provides a simpler -mechanism: +discouraging, so in the same vein as JUnit, \module{unittest} provides +a simpler mechanism: \begin{verbatim} import unittest @@ -329,9 +327,9 @@ \end{verbatim} Test case instances are grouped together according to the features -they test. PyUnit provides a mechanism for this: the \class{test -suite}, represented by the class \class{TestSuite} in the -\refmodule{unittest} module: +they test. \module{unittest} provides a mechanism for this: the +\dfn{test suite}, represented by \module{unittest}'s \class{TestSuite} +class: \begin{verbatim} widgetTestSuite = unittest.TestSuite() @@ -354,28 +352,30 @@ or even: \begin{verbatim} -class WidgetTestSuite(unittest.TestSuite): - def __init__(self): - unittest.TestSuite.__init__(self,map(WidgetTestCase, - ("testDefaultSize", - "testResize"))) -\end{verbatim} +def suite(): + tests = ["testDefaultSize", "testResize"] -(The latter is admittedly not for the faint-hearted!) + return unittest.TestSuite(map(WidgetTestCase, tests)) +\end{verbatim} Since it is a common pattern to create a \class{TestCase} subclass -with many similarly named test functions, there is a convenience -function called \function{makeSuite()} that constructs a test suite -that comprises all of the test cases in a test case class: +with many similarly named test functions, \module{unittest} provides a +\class{TestLoader} class that can be used to automate the process of +creating a test suite and populating it with individual tests. +For example, \begin{verbatim} -suite = unittest.makeSuite(WidgetTestCase) +suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase) \end{verbatim} -Note that when using the \function{makeSuite()} function, the order in -which the various test cases will be run by the test suite is the -order determined by sorting the test function names using the -\function{cmp()} built-in function. +will create a test suite that will run +\code{WidgetTestCase.testDefaultSize()} and \code{WidgetTestCase.testResize}. +\class{TestLoader} uses the \code{'test'} method name prefix to identify +test methods automatically. + +Note that the order in which the various test cases will be run is +determined by sorting the test function names with the built-in +\function{cmp()} function. Often it is desirable to group suites of test cases together, so as to run tests for the whole system at once. This is easy, since @@ -385,13 +385,13 @@ \begin{verbatim} suite1 = module1.TheTestSuite() suite2 = module2.TheTestSuite() -alltests = unittest.TestSuite((suite1, suite2)) +alltests = unittest.TestSuite([suite1, suite2]) \end{verbatim} You can place the definitions of test cases and test suites in the same modules as the code they are to test (such as \file{widget.py}), but there are several advantages to placing the test code in a -separate module, such as \file{widgettests.py}: +separate module, such as \file{test_widget.py}: \begin{itemize} \item The test module can be run standalone from the command line. @@ -412,13 +412,12 @@ \label{legacy-unit-tests}} Some users will find that they have existing test code that they would -like to run from PyUnit, without converting every old test function to -a \class{TestCase} subclass. +like to run from \module{unittest}, without converting every old test +function to a \class{TestCase} subclass. -For this reason, PyUnit provides a \class{FunctionTestCase} class. -This subclass of \class{TestCase} can be used to wrap an existing test -function. Set-up and tear-down functions can also optionally be -wrapped. +For this reason, \module{unittest} provides a \class{FunctionTestCase} +class. This subclass of \class{TestCase} can be used to wrap an existing +test function. Set-up and tear-down functions can also be provided. Given the following test function: @@ -436,7 +435,8 @@ \end{verbatim} If there are additional set-up and tear-down methods that should be -called as part of the test case's operation, they can also be provided: +called as part of the test case's operation, they can also be provided +like so: \begin{verbatim} testcase = unittest.FunctionTestCase(testSomething, @@ -444,9 +444,19 @@ tearDown=deleteSomethingDB) \end{verbatim} -\note{PyUnit supports the use of \exception{AssertionError} -as an indicator of test failure, but does not recommend it. Future -versions may treat \exception{AssertionError} differently.} +To make migrating existing test suites easier, \module{unittest} +supports tests raising \exception{AssertionError} to indicate test failure. +However, it is recommended that you use the explicit +\method{TestCase.fail*()} and \method{TestCase.assert*()} methods instead, +as future versions of \module{unittest} may treat \exception{AssertionError} +differently. + +\note{Even though \class{FunctionTestCase} can be used to quickly convert +an existing test base over to a \module{unittest}-based system, this +approach is not recommended. Taking the time to set up proper +\class{TestCase} subclasses will make future test refactorings infinitely +easier.} + \subsection{Classes and functions @@ -454,11 +464,12 @@ \begin{classdesc}{TestCase}{} Instances of the \class{TestCase} class represent the smallest - testable units in a set of tests. This class is intended to be used - as a base class, with specific tests being implemented by concrete - subclasses. This class implements the interface needed by the test - runner to allow it to drive the test, and methods that the test code - can use to check for and report various kinds of failures. + testable units in the \module{unittest} universe. This class is + intended to be used as a base class, with specific tests being + implemented by concrete subclasses. This class implements the + interface needed by the test runner to allow it to drive the + test, and methods that the test code can use to check for and + report various kinds of failure. \end{classdesc} \begin{classdesc}{FunctionTestCase}{testFunc\optional{, @@ -474,33 +485,33 @@ \begin{classdesc}{TestSuite}{\optional{tests}} This class represents an aggregation of individual tests cases and test suites. The class presents the interface needed by the test - runner to allow it to be run as any other test case, but all the - contained tests and test suites are executed. Additional methods - are provided to add test cases and suites to the aggregation. If - \var{tests} is given, it must be a sequence of individual tests that - will be added to the suite. + runner to allow it to be run as any other test case. Running a + \class{TestSuite} instance is the same as iterating over the suite, + running each test individually. + + If \var{tests} is given, it must be an iterable of individual test cases or + other test suites that will be used to build the suite initially. + Additional methods are provided to add test cases and suites to the + collection later on. \end{classdesc} \begin{classdesc}{TestLoader}{} This class is responsible for loading tests according to various criteria and returning them wrapped in a \class{TestSuite}. It can load all tests within a given module or \class{TestCase} - class. When loading from a module, it considers all - \class{TestCase}-derived classes. For each such class, it creates - an instance for each method with a name beginning with the string - \samp{test}. + subclass. \end{classdesc} \begin{datadesc}{defaultTestLoader} - Instance of the \class{TestLoader} class which can be shared. If no + Instance of the \class{TestLoader} class intended to be shared. If no customization of the \class{TestLoader} is needed, this instance can - always be used instead of creating new instances. + be used instead of repeatedly creating new instances. \end{datadesc} \begin{classdesc}{TextTestRunner}{\optional{stream\optional{, descriptions\optional{, verbosity}}}} A basic test runner implementation which prints results on standard - output. It has a few configurable parameters, but is essentially + error. It has a few configurable parameters, but is essentially very simple. Graphical applications which run test suites should provide alternate implementations. \end{classdesc} @@ -510,7 +521,8 @@ testRunner\optional{, testRunner}}}}}} A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. The simplest use - for this function is: + for this function is to include the following line at the end of a + test script: \begin{verbatim} if __name__ == '__main__': @@ -518,10 +530,11 @@ \end{verbatim} \end{funcdesc} -In some cases, the existing tests may have be written using the +In some cases, the existing tests may have been written using the \refmodule{doctest} module. If so, that module provides a \class{DocTestSuite} class that can automatically build -\class{unittest.TestSuite} instances from the existing test code. +\class{unittest.TestSuite} instances from the existing +\module{doctest}-based tests. \versionadded{2.3} @@ -538,7 +551,7 @@ check conditions and report failures, and some inquiry methods allowing information about the test itself to be gathered. -Methods in the first group are: +Methods in the first group (running the test) are: \begin{methoddesc}[TestCase]{setUp}{} Method called to prepare the test fixture. This is called @@ -562,8 +575,10 @@ Run the test, collecting the result into the test result object passed as \var{result}. If \var{result} is omitted or \constant{None}, a temporary result object is created and used, but is not made - available to the caller. This is equivalent to simply calling the - \class{TestCase} instance. + available to the caller. + + The same effect may be had by simply calling the \class{TestCase} + instance. \end{methoddesc} \begin{methoddesc}[TestCase]{debug}{} @@ -664,10 +679,8 @@ information on the test: \begin{methoddesc}[TestCase]{countTestCases}{} - Return the number of tests represented by the this test object. For - \class{TestCase} instances, this will always be \code{1}, but this - method is also implemented by the \class{TestSuite} class, which can - return larger values. + Return the number of tests represented by this test object. For + \class{TestCase} instances, this will always be \code{1}. \end{methoddesc} \begin{methoddesc}[TestCase]{defaultTestResult}{} @@ -678,7 +691,7 @@ \begin{methoddesc}[TestCase]{id}{} Return a string identifying the specific test case. This is usually the full name of the test method, including the module and class - names. + name. \end{methoddesc} \begin{methoddesc}[TestCase]{shortDescription}{} @@ -694,21 +707,23 @@ \class{TestSuite} objects behave much like \class{TestCase} objects, except they do not actually implement a test. Instead, they are used -to aggregate tests into groups that should be run together. Some -additional methods are available to add tests to \class{TestSuite} +to aggregate tests into groups of tests that should be run together. +Some additional methods are available to add tests to \class{TestSuite} instances: \begin{methoddesc}[TestSuite]{addTest}{test} - Add a \class{TestCase} or \class{TestSuite} to the set of tests that - make up the suite. + Add a \class{TestCase} or \class{TestSuite} to the suite. \end{methoddesc} \begin{methoddesc}[TestSuite]{addTests}{tests} - Add all the tests from a sequence of \class{TestCase} and + Add all the tests from an iterable of \class{TestCase} and \class{TestSuite} instances to this test suite. + + This is equivalent to iterating over \var{tests}, calling + \method{addTest()} for each element. \end{methoddesc} -The \method{run()} method is also slightly different: +\class{TestSuite} shares the following methods with \class{TestCase}: \begin{methoddesc}[TestSuite]{run}{result} Run the tests associated with this suite, collecting the result into @@ -717,6 +732,17 @@ result object to be passed in. \end{methoddesc} +\begin{methoddesc}[TestSuite]{debug}{} + Run the tests associated with this suite without collecting the result. + This allows exceptions raised by the test to be propagated to the caller + and can be used to support running tests under a debugger. +\end{methoddesc} + +\begin{methoddesc}[TestSuite]{countTestCases}{} + Return the number of tests represented by this test object, including + all individual tests and sub-suites. +\end{methoddesc} + In the typical usage of a \class{TestSuite} object, the \method{run()} method is invoked by a \class{TestRunner} rather than by the end-user test harness. @@ -727,7 +753,7 @@ A \class{TestResult} object stores the results of a set of tests. The \class{TestCase} and \class{TestSuite} classes ensure that results are -properly stored; test authors do not need to worry about recording the +properly recorded; test authors do not need to worry about recording the outcome of tests. Testing frameworks built on top of \refmodule{unittest} may want @@ -745,28 +771,41 @@ be of interest when inspecting the results of running a set of tests: \begin{memberdesc}[TestResult]{errors} - A list containing pairs of \class{TestCase} instances and the - formatted tracebacks for tests which raised an exception but did not - signal a test failure. + A list containing 2-tuples of \class{TestCase} instances and + formatted tracebacks. Each tuple represents a test which raised an + unexpected exception. \versionchanged[Contains formatted tracebacks instead of \function{sys.exc_info()} results]{2.2} \end{memberdesc} \begin{memberdesc}[TestResult]{failures} - A list containing pairs of \class{TestCase} instances and the - formatted tracebacks for tests which signalled a failure in the code - under test. + A list containing 2-tuples of \class{TestCase} instances and + formatted tracebacks. Each tuple represents a test where a failure + was explicitly signalled using the \method{TestCase.fail*()} or + \method{TestCase.assert*()} methods. \versionchanged[Contains formatted tracebacks instead of \function{sys.exc_info()} results]{2.2} \end{memberdesc} \begin{memberdesc}[TestResult]{testsRun} - The number of tests which have been started. + The total number of tests run so far. \end{memberdesc} \begin{methoddesc}[TestResult]{wasSuccessful}{} - Returns true if all tests run so far have passed, otherwise returns - false. + Returns \constant{True} if all tests run so far have passed, + otherwise returns \constant{False}. +\end{methoddesc} + +\begin{methoddesc}[TestResult]{stop}{} + This method can be called to signal that the set of tests being run + should be aborted by setting the \class{TestResult}'s \code{shouldStop} + attribute to \constant{True}. \class{TestRunner} objects should respect + this flag and return without running any additional tests. + + For example, this feature is used by the \class{TextTestRunner} class + to stop the test framework when the user signals an interrupt from + the keyboard. Interactive tools which provide \class{TestRunner} + implementations can use this in a similar manner. \end{methoddesc} @@ -786,10 +825,9 @@ \end{methoddesc} \begin{methoddesc}[TestResult]{addError}{test, err} - Called when the test case \var{test} raises an exception without - signalling a test failure. \var{err} is a tuple of the form - returned by \function{sys.exc_info()}: \code{(\var{type}, - \var{value}, \var{traceback})}. + Called when the test case \var{test} raises an unexpected exception + \var{err} is a tuple of the form returned by \function{sys.exc_info()}: + \code{(\var{type}, \var{value}, \var{traceback})}. \end{methoddesc} \begin{methoddesc}[TestResult]{addFailure}{test, err} @@ -800,23 +838,10 @@ \end{methoddesc} \begin{methoddesc}[TestResult]{addSuccess}{test} - This method is called for a test that does not fail; \var{test} is - the test case object. + Called when the test case \var{test} succeeds. \end{methoddesc} -One additional method is available for \class{TestResult} objects: - -\begin{methoddesc}[TestResult]{stop}{} - This method can be called to signal that the set of tests being run - should be aborted. Once this has been called, the - \class{TestRunner} object return to its caller without running any - additional tests. This is used by the \class{TextTestRunner} class - to stop the test framework when the user signals an interrupt from - the keyboard. Interactive tools which provide runners can use this - in a similar manner. -\end{methoddesc} - \subsection{TestLoader Objects \label{testloader-objects}} @@ -824,15 +849,15 @@ The \class{TestLoader} class is used to create test suites from classes and modules. Normally, there is no need to create an instance of this class; the \refmodule{unittest} module provides an instance -that can be shared as the \code{defaultTestLoader} module attribute. -Using a subclass or instance would allow customization of some +that can be shared as \code{unittest.defaultTestLoader}. +Using a subclass or instance, however, allows customization of some configurable properties. \class{TestLoader} objects have the following methods: \begin{methoddesc}[TestLoader]{loadTestsFromTestCase}{testCaseClass} Return a suite of all tests cases contained in the - \class{TestCase}-derived class \class{testCaseClass}. + \class{TestCase}-derived \class{testCaseClass}. \end{methoddesc} \begin{methoddesc}[TestLoader]{loadTestsFromModule}{module} @@ -842,7 +867,7 @@ method defined for the class. \warning{While using a hierarchy of - \class{Testcase}-derived classes can be convenient in sharing + \class{TestCase}-derived classes can be convenient in sharing fixtures and helper functions, defining test methods on base classes that are not intended to be instantiated directly does not play well with this method. Doing so, however, can be useful when the @@ -853,21 +878,23 @@ Return a suite of all tests cases given a string specifier. The specifier \var{name} is a ``dotted name'' that may resolve - either to a module, a test case class, a test method within a test - case class, or a callable object which returns a \class{TestCase} or - \class{TestSuite} instance. For example, if you have a module - \module{SampleTests} containing a \class{TestCase}-derived class - \class{SampleTestCase} with three test methods (\method{test_one()}, - \method{test_two()}, and \method{test_three()}), the specifier - \code{'SampleTests.SampleTestCase'} would cause this method to - return a suite which will run all three test methods. Using the - specifier \code{'SampleTests.SampleTestCase.test_two'} would cause - it to return a test suite which will run only the + either to a module, a test case class, a \class{TestSuite} instance, + a test method within a test case class, or a callable object which + returns a \class{TestCase} or \class{TestSuite} instance. + + For example, if you have a module \module{SampleTests} containing a + \class{TestCase}-derived class \class{SampleTestCase} with three test + methods (\method{test_one()}, \method{test_two()}, and + \method{test_three()}), the specifier \code{'SampleTests.SampleTestCase'} + would cause this method to return a suite which will run all three test + methods. Using the specifier \code{'SampleTests.SampleTestCase.test_two'} + would cause it to return a test suite which will run only the \method{test_two()} test method. The specifier can refer to modules and packages which have not been imported; they will be imported as a side-effect. - The method optionally resolves \var{name} relative to a given module. + The method optionally resolves \var{name} relative to the given + \var{module}. \end{methoddesc} \begin{methoddesc}[TestLoader]{loadTestsFromNames}{names\optional{, module}} @@ -888,17 +915,22 @@ \begin{memberdesc}[TestLoader]{testMethodPrefix} String giving the prefix of method names which will be interpreted as test methods. The default value is \code{'test'}. + + This affects \method{getTestCaseNames()} and all the + \method{loadTestsFrom*()} methods. \end{memberdesc} \begin{memberdesc}[TestLoader]{sortTestMethodsUsing} Function to be used to compare method names when sorting them in - \method{getTestCaseNames()}. The default value is the built-in - \function{cmp()} function; it can be set to \constant{None} to disable - the sort. + \method{getTestCaseNames()} and all the \method{loadTestsFrom*()} methods. + The default value is the built-in \function{cmp()} function; the attribute + can also be set to \constant{None} to disable the sort. \end{memberdesc} \begin{memberdesc}[TestLoader]{suiteClass} Callable object that constructs a test suite from a list of tests. No methods on the resulting object are needed. The default value is the \class{TestSuite} class. + + This affects all the \method{loadTestsFrom*()} methods. \end{memberdesc} Modified: stackless/trunk/Doc/lib/libwarnings.tex ============================================================================== --- stackless/trunk/Doc/lib/libwarnings.tex (original) +++ stackless/trunk/Doc/lib/libwarnings.tex Mon Aug 21 11:10:05 2006 @@ -76,6 +76,9 @@ \lineii{ImportWarning}{Base category for warnings triggered during the process of importing a module (ignored by default).} + +\lineii{UnicodeWarning}{Base category for warnings related to Unicode.} + \end{tableii} While these are technically built-in exceptions, they are documented Modified: stackless/trunk/Doc/ref/ref2.tex ============================================================================== --- stackless/trunk/Doc/ref/ref2.tex (original) +++ stackless/trunk/Doc/ref/ref2.tex Mon Aug 21 11:10:05 2006 @@ -56,7 +56,7 @@ A physical line is a sequence of characters terminated by an end-of-line sequence. In source files, any of the standard platform line -termination sequences can be used - the \UNIX form using \ASCII{} LF +termination sequences can be used - the \UNIX{} form using \ASCII{} LF (linefeed), the Windows form using the \ASCII{} sequence CR LF (return followed by linefeed), or the Macintosh form using the \ASCII{} CR (return) character. All of these forms can be used equally, regardless Modified: stackless/trunk/Doc/ref/ref3.tex ============================================================================== --- stackless/trunk/Doc/ref/ref3.tex (original) +++ stackless/trunk/Doc/ref/ref3.tex Mon Aug 21 11:10:05 2006 @@ -1307,6 +1307,11 @@ since the dictionary implementation requires that a key's hash value is immutable (if the object's hash value changes, it will be in the wrong hash bucket). + +\versionchanged[\method{__hash__()} may now also return a long +integer object; the 32-bit integer is then derived from the hash +of that object]{2.5} + \withsubitem{(object method)}{\ttindex{__cmp__()}} \end{methoddesc} Modified: stackless/trunk/Doc/whatsnew/whatsnew25.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew25.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew25.tex Mon Aug 21 11:10:05 2006 @@ -3,10 +3,9 @@ % $Id$ % Fix XXX comments -% Count up the patches and bugs \title{What's New in Python 2.5} -\release{0.4} +\release{1.0} \author{A.M. Kuchling} \authoraddress{\email{amk at amk.ca}} @@ -39,11 +38,16 @@ language feature or another; none of them are broad modifications to Python's semantics. +As well as the language and library additions, other improvements and +bugfixes were made throughout the source tree. A search through the +SVN change logs finds there were 353 patches applied and 458 bugs +fixed between Python 2.4 and 2.5. (Both figures are likely to be +underestimates.) + This article doesn't try to be a complete specification of the new features; instead changes are briefly introduced using helpful examples. For full details, you should always refer to the -documentation for Python 2.5. -% XXX add hyperlink when the documentation becomes available online. +documentation for Python 2.5 at \url{http://docs.python.org}. If you want to understand the complete implementation and design rationale, refer to the PEP for a particular new feature. @@ -746,7 +750,6 @@ database, or rolled back, meaning that the changes are all discarded and the database is unchanged. See any database textbook for more information.) -% XXX find a shorter reference? Let's assume there's an object representing a database connection. Our goal will be to let the user write code like this: @@ -1094,10 +1097,10 @@ \item Both 8-bit and Unicode strings have new \method{partition(sep)} and \method{rpartition(sep)} methods that simplify a common use case. + The \method{find(S)} method is often used to get an index which is then used to slice the string and obtain the pieces that are before and after the separator. - \method{partition(sep)} condenses this pattern into a single method call that returns a 3-tuple containing the substring before the separator, the separator itself, and the @@ -1159,6 +1162,15 @@ all of the values returned by the iterator evaluate as true. (Suggested by Guido van~Rossum, and implemented by Raymond Hettinger.) +\item The result of a class's \method{__hash__()} method can now +be either a long integer or a regular integer. If a long integer is +returned, the hash of that value is taken. In earlier versions the +hash value was required to be a regular integer, but in 2.5 the +\function{id()} built-in was changed to always return non-negative +numbers, and users often seem to use \code{id(self)} in +\method{__hash__()} methods (though this is discouraged). +% Bug #1536021 + \item ASCII is now the default encoding for modules. It's now a syntax error if a module contains string literals with 8-bit characters but doesn't have an encoding declaration. In Python 2.4 @@ -1170,6 +1182,35 @@ # -*- coding: latin1 -*- \end{verbatim} +\item A new warning, \class{UnicodeWarning}, is triggered when +you attempt to compare a Unicode string and an 8-bit string +that can't be converted to Unicode using the default ASCII encoding. +The result of the comparison is false: + +\begin{verbatim} +>>> chr(128) == unichr(128) # Can't convert chr(128) to Unicode +__main__:1: UnicodeWarning: Unicode equal comparison failed + to convert both arguments to Unicode - interpreting them + as being unequal +False +>>> chr(127) == unichr(127) # chr(127) can be converted +True +\end{verbatim} + +Previously this would raise a \class{UnicodeDecodeError} exception, +but in 2.5 this could result in puzzling problems when accessing a +dictionary. If you looked up \code{unichr(128)} and \code{chr(128)} +was being used as a key, you'd get a \class{UnicodeDecodeError} +exception. Other changes in 2.5 resulted in this exception being +raised instead of suppressed by the code in \file{dictobject.c} that +implements dictionaries. + +Raising an exception for such a comparison is strictly correct, but +the change might have broken code, so instead +\class{UnicodeWarning} was introduced. + +(Implemented by Marc-Andr\'e Lemburg.) + \item One error that Python programmers sometimes make is forgetting to include an \file{__init__.py} module in a package directory. Debugging this mistake can be confusing, and usually requires running @@ -1291,9 +1332,6 @@ \end{itemize} -The net result of the 2.5 optimizations is that Python 2.5 runs the -pystone benchmark around XXX\% faster than Python 2.4. - %====================================================================== \section{New, Improved, and Removed Modules\label{modules}} @@ -1489,6 +1527,29 @@ (Contributed by Raymond Hettinger.) +\item The \function{format()} function in the \module{locale} module +has been modified and two new functions were added, +\function{format_string()} and \function{currency()}. + +The \function{format()} function's \var{val} parameter could +previously be a string as long as no more than one \%char specifier +appeared; now the parameter must be exactly one \%char specifier with +no surrounding text. An optional \var{monetary} parameter was also +added which, if \code{True}, will use the locale's rules for +formatting currency in placing a separator between groups of three +digits. + +To format strings with multiple \%char specifiers, use the new +\function{format_string()} function that works like \function{format()} +but also supports mixing \%char specifiers with +arbitrary text. + +A new \function{currency()} function was also added that formats a +number according to the current locale's settings. + +(Contributed by Georg Brandl.) +% Patch 1180296 + \item The \module{mailbox} module underwent a massive rewrite to add the capability to modify mailboxes in addition to reading them. A new set of classes that include \class{mbox}, \class{MH}, and @@ -2214,13 +2275,20 @@ carried out by Martin von~L\"owis. The procedure was developed as \pep{347}. +\item Coverity, a company that markets a source code analysis tool +called Prevent, provided the results of their examination of the Python +source code. The analysis found about 60 bugs that +were quickly fixed. Many of the bugs were refcounting problems, often +occurring in error-handling code. See +\url{http://scan.coverity.com} for the statistics. + \item The largest change to the C API came from \pep{353}, which modifies the interpreter to use a \ctype{Py_ssize_t} type definition instead of \ctype{int}. See the earlier section~\ref{pep-353} for a discussion of this change. -\item The design of the bytecode compiler has changed a great deal, to -no longer generate bytecode by traversing the parse tree. Instead +\item The design of the bytecode compiler has changed a great deal, +no longer generating bytecode by traversing the parse tree. Instead the parse tree is converted to an abstract syntax tree (or AST), and it is the abstract syntax tree that's traversed to produce the bytecode. @@ -2261,6 +2329,32 @@ Armin Rigo, and Neil Schemenauer, plus the participants in a number of AST sprints at conferences such as PyCon. +\item Evan Jones's patch to obmalloc, first described in a talk +at PyCon DC 2005, was applied. Python 2.4 allocated small objects in +256K-sized arenas, but never freed arenas. With this patch, Python +will free arenas when they're empty. The net effect is that on some +platforms, when you allocate many objects, Python's memory usage may +actually drop when you delete them and the memory may be returned to +the operating system. (Implemented by Evan Jones, and reworked by Tim +Peters.) + +Note that this change means extension modules must be more careful +when allocating memory. Python's API has many different +functions for allocating memory that are grouped into families. For +example, \cfunction{PyMem_Malloc()}, \cfunction{PyMem_Realloc()}, and +\cfunction{PyMem_Free()} are one family that allocates raw memory, +while \cfunction{PyObject_Malloc()}, \cfunction{PyObject_Realloc()}, +and \cfunction{PyObject_Free()} are another family that's supposed to +be used for creating Python objects. + +Previously these different families all reduced to the platform's +\cfunction{malloc()} and \cfunction{free()} functions. This meant +it didn't matter if you got things wrong and allocated memory with the +\cfunction{PyMem} function but freed it with the \cfunction{PyObject} +function. With 2.5's changes to obmalloc, these families now do different +things and mismatches will probably result in a segfault. You should +carefully test your C extension modules with Python 2.5. + \item The built-in set types now have an official C API. Call \cfunction{PySet_New()} and \cfunction{PyFrozenSet_New()} to create a new set, \cfunction{PySet_Add()} and \cfunction{PySet_Discard()} to @@ -2336,54 +2430,6 @@ %====================================================================== -\section{Other Changes and Fixes \label{section-other}} - -As usual, there were a bunch of other improvements and bugfixes -scattered throughout the source tree. A search through the SVN change -logs finds there were 334 patches applied and 443 bugs fixed between -Python 2.4 and 2.5. Both figures are likely to be underestimates. - -Some of the more notable changes are: - -\begin{itemize} - -\item Evan Jones's patch to obmalloc, first described in a talk -at PyCon DC 2005, was applied. Python 2.4 allocated small objects in -256K-sized arenas, but never freed arenas. With this patch, Python -will free arenas when they're empty. The net effect is that on some -platforms, when you allocate many objects, Python's memory usage may -actually drop when you delete them, and the memory may be returned to -the operating system. (Implemented by Evan Jones, and reworked by Tim -Peters.) - -Note that this change means extension modules need to be more careful -with how they allocate memory. Python's API has many different -functions for allocating memory that are grouped into families. For -example, \cfunction{PyMem_Malloc()}, \cfunction{PyMem_Realloc()}, and -\cfunction{PyMem_Free()} are one family that allocates raw memory, -while \cfunction{PyObject_Malloc()}, \cfunction{PyObject_Realloc()}, -and \cfunction{PyObject_Free()} are another family that's supposed to -be used for creating Python objects. - -Previously these different families all reduced to the platform's -\cfunction{malloc()} and \cfunction{free()} functions. This meant -it didn't matter if you got things wrong and allocated memory with the -\cfunction{PyMem} function but freed it with the \cfunction{PyObject} -function. With the obmalloc change, these families now do different -things, and mismatches will probably result in a segfault. You should -carefully test your C extension modules with Python 2.5. - -\item Coverity, a company that markets a source code analysis tool - called Prevent, provided the results of their examination of the Python - source code. The analysis found about 60 bugs that - were quickly fixed. Many of the bugs were refcounting problems, often - occurring in error-handling code. See - \url{http://scan.coverity.com} for the statistics. - -\end{itemize} - - -%====================================================================== \section{Porting to Python 2.5\label{porting}} This section lists previously described changes that may require @@ -2401,11 +2447,22 @@ described in section~\ref{pep-342}, it's now possible for \member{gi_frame} to be \code{None}. +\item A new warning, \class{UnicodeWarning}, is triggered when +you attempt to compare a Unicode string and an 8-bit string that can't +be converted to Unicode using the default ASCII encoding. Previously +such comparisons would raise a \class{UnicodeDecodeError} exception. + \item Library: the \module{csv} module is now stricter about multi-line quoted fields. If your files contain newlines embedded within fields, the input should be split into lines in a manner which preserves the newline characters. +\item Library: the \module{locale} module's +\function{format()} function's would previously +accept any string as long as no more than one \%char specifier +appeared. In Python 2.5, the argument must be exactly one \%char +specifier with no surrounding text. + \item Library: The \module{pickle} and \module{cPickle} modules no longer accept a return value of \code{None} from the \method{__reduce__()} method; the method must return a tuple of @@ -2441,10 +2498,10 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: Nick Coghlan, Phillip J. Eby, Lars Gust\"abel, Raymond Hettinger, Ralf -W. Grosse-Kunstleve, Kent Johnson, Martin von~L\"owis, Fredrik Lundh, -Andrew McNamara, Skip Montanaro, -Gustavo Niemeyer, James Pryor, Mike Rovner, Scott Weikart, Barry -Warsaw, Thomas Wouters. +article: Georg Brandl, Nick Coghlan, Phillip J. Eby, Lars Gust\"abel, +Raymond Hettinger, Ralf W. Grosse-Kunstleve, Kent Johnson, Iain Lowe, +Martin von~L\"owis, Fredrik Lundh, Andrew McNamara, Skip Montanaro, +Gustavo Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott +Weikart, Barry Warsaw, Thomas Wouters. \end{document} Modified: stackless/trunk/Include/abstract.h ============================================================================== --- stackless/trunk/Include/abstract.h (original) +++ stackless/trunk/Include/abstract.h Mon Aug 21 11:10:05 2006 @@ -758,13 +758,27 @@ */ - PyAPI_FUNC(Py_ssize_t) PyNumber_Index(PyObject *); +#define PyIndex_Check(obj) \ + ((obj)->ob_type->tp_as_number != NULL && \ + PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_INDEX) && \ + (obj)->ob_type->tp_as_number->nb_index != NULL) + + PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); /* - Returns the object converted to Py_ssize_t on success - or -1 with an error raised on failure. + Returns the object converted to a Python long or int + or NULL with an error raised on failure. */ + PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); + + /* + Returns the object converted to Py_ssize_t by going through + PyNumber_Index first. If an overflow error occurs while + converting the int-or-long to Py_ssize_t, then the second argument + is the error-type to return. If it is NULL, then the overflow error + is cleared and the value is clipped. + */ PyAPI_FUNC(PyObject *) PyNumber_Int(PyObject *o); Modified: stackless/trunk/Include/object.h ============================================================================== --- stackless/trunk/Include/object.h (original) +++ stackless/trunk/Include/object.h Mon Aug 21 11:10:05 2006 @@ -211,7 +211,7 @@ binaryfunc nb_inplace_true_divide; /* Added in release 2.5 */ - lenfunc nb_index; + unaryfunc nb_index; } PyNumberMethods; typedef struct { Modified: stackless/trunk/Include/patchlevel.h ============================================================================== --- stackless/trunk/Include/patchlevel.h (original) +++ stackless/trunk/Include/patchlevel.h Mon Aug 21 11:10:05 2006 @@ -22,11 +22,11 @@ #define PY_MAJOR_VERSION 2 #define PY_MINOR_VERSION 5 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 3 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.5b3" +#define PY_VERSION "2.5c1" /* Subversion Revision number of this file (not of the repository) */ #define PY_PATCHLEVEL_REVISION "$Revision$" Modified: stackless/trunk/Include/pyerrors.h ============================================================================== --- stackless/trunk/Include/pyerrors.h (original) +++ stackless/trunk/Include/pyerrors.h Mon Aug 21 11:10:05 2006 @@ -176,6 +176,7 @@ PyAPI_DATA(PyObject *) PyExc_RuntimeWarning; PyAPI_DATA(PyObject *) PyExc_FutureWarning; PyAPI_DATA(PyObject *) PyExc_ImportWarning; +PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; /* Convenience functions */ Modified: stackless/trunk/Include/unicodeobject.h ============================================================================== --- stackless/trunk/Include/unicodeobject.h (original) +++ stackless/trunk/Include/unicodeobject.h Mon Aug 21 11:10:05 2006 @@ -189,6 +189,7 @@ # define PyUnicode_RSplit PyUnicodeUCS2_RSplit # define PyUnicode_Replace PyUnicodeUCS2_Replace # define PyUnicode_Resize PyUnicodeUCS2_Resize +# define PyUnicode_RichCompare PyUnicodeUCS2_RichCompare # define PyUnicode_SetDefaultEncoding PyUnicodeUCS2_SetDefaultEncoding # define PyUnicode_Split PyUnicodeUCS2_Split # define PyUnicode_Splitlines PyUnicodeUCS2_Splitlines @@ -266,6 +267,7 @@ # define PyUnicode_RSplit PyUnicodeUCS4_RSplit # define PyUnicode_Replace PyUnicodeUCS4_Replace # define PyUnicode_Resize PyUnicodeUCS4_Resize +# define PyUnicode_RichCompare PyUnicodeUCS4_RichCompare # define PyUnicode_SetDefaultEncoding PyUnicodeUCS4_SetDefaultEncoding # define PyUnicode_Split PyUnicodeUCS4_Split # define PyUnicode_Splitlines PyUnicodeUCS4_Splitlines @@ -1139,6 +1141,28 @@ PyObject *right /* Right string */ ); +/* Rich compare two strings and return one of the following: + + - NULL in case an exception was raised + - Py_True or Py_False for successfuly comparisons + - Py_NotImplemented in case the type combination is unknown + + Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in + case the conversion of the arguments to Unicode fails with a + UnicodeDecodeError. + + Possible values for op: + + Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_RichCompare( + PyObject *left, /* Left string */ + PyObject *right, /* Right string */ + int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ + ); + /* Apply a argument tuple or dictionary to a format string and return the resulting Unicode string. */ Modified: stackless/trunk/Lib/Cookie.py ============================================================================== --- stackless/trunk/Lib/Cookie.py (original) +++ stackless/trunk/Lib/Cookie.py Mon Aug 21 11:10:05 2006 @@ -305,8 +305,10 @@ '\375' : '\\375', '\376' : '\\376', '\377' : '\\377' } +_idmap = ''.join(chr(x) for x in xrange(256)) + def _quote(str, LegalChars=_LegalChars, - idmap=string._idmap, translate=string.translate): + idmap=_idmap, translate=string.translate): # # If the string does not need to be double-quoted, # then just return the string. Otherwise, surround @@ -440,7 +442,7 @@ def set(self, key, val, coded_val, LegalChars=_LegalChars, - idmap=string._idmap, translate=string.translate ): + idmap=_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 key.lower() in self._reserved: Modified: stackless/trunk/Lib/cgi.py ============================================================================== --- stackless/trunk/Lib/cgi.py (original) +++ stackless/trunk/Lib/cgi.py Mon Aug 21 11:10:05 2006 @@ -251,6 +251,10 @@ XXX This should really be subsumed by FieldStorage altogether -- no point in having two implementations of the same parsing algorithm. + Also, FieldStorage protects itself better against certain DoS attacks + by limiting the size of the data read in one chunk. The API here + does not support that kind of protection. This also affects parse() + since it can call parse_multipart(). """ boundary = "" @@ -699,7 +703,7 @@ def read_lines_to_eof(self): """Internal: read lines until EOF.""" while 1: - line = self.fp.readline() + line = self.fp.readline(1<<16) if not line: self.done = -1 break @@ -710,12 +714,13 @@ next = "--" + self.outerboundary last = next + "--" delim = "" + last_line_lfend = True while 1: - line = self.fp.readline() + line = self.fp.readline(1<<16) if not line: self.done = -1 break - if line[:2] == "--": + if line[:2] == "--" and last_line_lfend: strippedline = line.strip() if strippedline == next: break @@ -726,11 +731,14 @@ if line[-2:] == "\r\n": delim = "\r\n" line = line[:-2] + last_line_lfend = True elif line[-1] == "\n": delim = "\n" line = line[:-1] + last_line_lfend = True else: delim = "" + last_line_lfend = False self.__write(odelim + line) def skip_lines(self): @@ -739,18 +747,20 @@ return next = "--" + self.outerboundary last = next + "--" + last_line_lfend = True while 1: - line = self.fp.readline() + line = self.fp.readline(1<<16) if not line: self.done = -1 break - if line[:2] == "--": + if line[:2] == "--" and last_line_lfend: strippedline = line.strip() if strippedline == next: break if strippedline == last: self.done = 1 break + last_line_lfend = line.endswith('\n') def make_file(self, binary=None): """Overridable: return a readable & writable file. Modified: stackless/trunk/Lib/compiler/ast.py ============================================================================== --- stackless/trunk/Lib/compiler/ast.py (original) +++ stackless/trunk/Lib/compiler/ast.py Mon Aug 21 11:10:05 2006 @@ -583,11 +583,9 @@ def __init__(self, code, lineno=None): self.code = code self.lineno = lineno - self.argnames = ['[outmost-iterable]'] + self.argnames = ['.0'] self.varargs = self.kwargs = None - - def getChildren(self): return self.code, Modified: stackless/trunk/Lib/compiler/pycodegen.py ============================================================================== --- stackless/trunk/Lib/compiler/pycodegen.py (original) +++ stackless/trunk/Lib/compiler/pycodegen.py Mon Aug 21 11:10:05 2006 @@ -382,16 +382,7 @@ self.set_lineno(node) for default in node.defaults: self.visit(default) - frees = gen.scope.get_free_vars() - if frees: - for name in frees: - self.emit('LOAD_CLOSURE', name) - self.emit('LOAD_CONST', gen) - self.emit('MAKE_CLOSURE', len(node.defaults)) - else: - self.emit('LOAD_CONST', gen) - self.emit('MAKE_FUNCTION', len(node.defaults)) - + self._makeClosure(gen, len(node.defaults)) for i in range(ndecorators): self.emit('CALL_FUNCTION', 1) @@ -405,14 +396,7 @@ for base in node.bases: self.visit(base) self.emit('BUILD_TUPLE', len(node.bases)) - frees = gen.scope.get_free_vars() - for name in frees: - self.emit('LOAD_CLOSURE', name) - self.emit('LOAD_CONST', gen) - if frees: - self.emit('MAKE_CLOSURE', 0) - else: - self.emit('MAKE_FUNCTION', 0) + self._makeClosure(gen, 0) self.emit('CALL_FUNCTION', 0) self.emit('BUILD_CLASS') self.storeName(node.name) @@ -644,22 +628,25 @@ self.newBlock() self.emit('POP_TOP') - def visitGenExpr(self, node): - gen = GenExprCodeGenerator(node, self.scopes, self.class_name, - self.get_module()) - walk(node.code, gen) - gen.finish() - self.set_lineno(node) + def _makeClosure(self, gen, args): frees = gen.scope.get_free_vars() if frees: for name in frees: self.emit('LOAD_CLOSURE', name) + self.emit('BUILD_TUPLE', len(frees)) self.emit('LOAD_CONST', gen) - self.emit('MAKE_CLOSURE', 0) + self.emit('MAKE_CLOSURE', args) else: self.emit('LOAD_CONST', gen) - self.emit('MAKE_FUNCTION', 0) + self.emit('MAKE_FUNCTION', args) + def visitGenExpr(self, node): + gen = GenExprCodeGenerator(node, self.scopes, self.class_name, + self.get_module()) + walk(node.code, gen) + gen.finish() + self.set_lineno(node) + self._makeClosure(gen, 0) # precomputation of outmost iterable self.visit(node.code.quals[0].iter) self.emit('GET_ITER') @@ -671,18 +658,19 @@ stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): - start, anchor = self.visit(for_) + start, anchor, end = self.visit(for_) cont = None for if_ in for_.ifs: if cont is None: cont = self.newBlock() self.visit(if_, cont) - stack.insert(0, (start, cont, anchor)) + stack.insert(0, (start, cont, anchor, end)) self.visit(node.expr) self.emit('YIELD_VALUE') + self.emit('POP_TOP') - for start, cont, anchor in stack: + for start, cont, anchor, end in stack: if cont: skip_one = self.newBlock() self.emit('JUMP_FORWARD', skip_one) @@ -691,14 +679,22 @@ self.nextBlock(skip_one) self.emit('JUMP_ABSOLUTE', start) self.startBlock(anchor) + self.emit('POP_BLOCK') + self.setups.pop() + self.startBlock(end) + self.emit('LOAD_CONST', None) def visitGenExprFor(self, node): start = self.newBlock() anchor = self.newBlock() + end = self.newBlock() + + self.setups.push((LOOP, start)) + self.emit('SETUP_LOOP', end) if node.is_outmost: - self.loadName('[outmost-iterable]') + self.loadName('.0') else: self.visit(node.iter) self.emit('GET_ITER') @@ -708,7 +704,7 @@ self.emit('FOR_ITER', anchor) self.nextBlock() self.visit(node.assign) - return start, anchor + return start, anchor, end def visitGenExprIf(self, node, branch): self.set_lineno(node, force=True) Modified: stackless/trunk/Lib/compiler/symbols.py ============================================================================== --- stackless/trunk/Lib/compiler/symbols.py (original) +++ stackless/trunk/Lib/compiler/symbols.py Mon Aug 21 11:10:05 2006 @@ -188,7 +188,7 @@ i = self.__counter self.__counter += 1 self.__super_init("generator expression<%d>"%i, module, klass) - self.add_param('[outmost-iterable]') + self.add_param('.0') def get_names(self): keys = Scope.get_names(self) Modified: stackless/trunk/Lib/ctypes/__init__.py ============================================================================== --- stackless/trunk/Lib/ctypes/__init__.py (original) +++ stackless/trunk/Lib/ctypes/__init__.py Mon Aug 21 11:10:05 2006 @@ -5,7 +5,7 @@ import os as _os, sys as _sys -__version__ = "1.0.0" +__version__ = "1.0.1" from _ctypes import Union, Structure, Array from _ctypes import _Pointer @@ -135,6 +135,11 @@ class py_object(_SimpleCData): _type_ = "O" + def __repr__(self): + try: + return super(py_object, self).__repr__() + except ValueError: + return "%s()" % type(self).__name__ class c_short(_SimpleCData): _type_ = "h" Modified: stackless/trunk/Lib/ctypes/test/test_functions.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_functions.py (original) +++ stackless/trunk/Lib/ctypes/test/test_functions.py Mon Aug 21 11:10:05 2006 @@ -222,6 +222,7 @@ def callback(v): args.append(v) + return v CallBack = CFUNCTYPE(c_int, c_int) Modified: stackless/trunk/Lib/ctypes/test/test_numbers.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_numbers.py (original) +++ stackless/trunk/Lib/ctypes/test/test_numbers.py Mon Aug 21 11:10:05 2006 @@ -19,7 +19,7 @@ result.append((min(a, b, c, d), max(a, b, c, d))) return result -ArgType = type(c_int(0)._as_parameter_) +ArgType = type(byref(c_int(0))) unsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong] signed_types = [c_byte, c_short, c_int, c_long, c_longlong] @@ -80,19 +80,6 @@ for t in signed_types + unsigned_types + float_types: self.failUnlessEqual(ArgType, type(t.from_param(0))) - def test_as_parameter(self): - # The _as_parameter_ property must also - # be a PyCArgObject instance - for t in signed_types + unsigned_types + float_types: - parm = t()._as_parameter_ - self.failUnlessEqual(ArgType, type(parm)) - - # _as_parameter_ is readonly! - # - # Python 2.3 and 2.4 raise a TypeError when trying to set - # a readonly attribute, 2.5 raises an AttributeError. - self.assertRaises((AttributeError, TypeError), setattr, t(), "_as_parameter_", None) - def test_byref(self): # calling byref returns also a PyCArgObject instance for t in signed_types + unsigned_types + float_types: Modified: stackless/trunk/Lib/ctypes/test/test_prototypes.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_prototypes.py (original) +++ stackless/trunk/Lib/ctypes/test/test_prototypes.py Mon Aug 21 11:10:05 2006 @@ -125,13 +125,18 @@ self.failUnlessEqual(None, func(c_wchar_p(None))) self.failUnlessEqual(u"123", func(c_wchar_p(u"123"))) -## def test_instance(self): -## func = testdll._testfunc_p_p + def test_instance(self): + func = testdll._testfunc_p_p + func.restype = c_void_p -## class X: -## _as_parameter_ = 0 + class X: + _as_parameter_ = None -## self.failUnlessEqual(0, func(X())) + func.argtypes = c_void_p, + self.failUnlessEqual(None, func(X())) + + func.argtypes = None + self.failUnlessEqual(None, func(X())) try: c_wchar Modified: stackless/trunk/Lib/ctypes/test/test_python_api.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_python_api.py (original) +++ stackless/trunk/Lib/ctypes/test/test_python_api.py Mon Aug 21 11:10:05 2006 @@ -78,5 +78,10 @@ # not enough arguments self.failUnlessRaises(TypeError, PyOS_snprintf, buf) + def test_pyobject_repr(self): + self.failUnlessEqual(repr(py_object()), "py_object()") + self.failUnlessEqual(repr(py_object(42)), "py_object(42)") + self.failUnlessEqual(repr(py_object(object)), "py_object(%r)" % object) + if __name__ == "__main__": unittest.main() Modified: stackless/trunk/Lib/distutils/__init__.py ============================================================================== --- stackless/trunk/Lib/distutils/__init__.py (original) +++ stackless/trunk/Lib/distutils/__init__.py Mon Aug 21 11:10:05 2006 @@ -12,6 +12,12 @@ __revision__ = "$Id$" -import sys -__version__ = "%d.%d.%d" % sys.version_info[:3] -del sys +# Distutils version +# +# Please coordinate with Marc-Andre Lemburg when adding +# new features to distutils that would warrant bumping the version number. +# +# In general, major and minor version should loosely follow the Python +# version number the distutils code was shipped with. +# +__version__ = "2.5.0" Modified: stackless/trunk/Lib/idlelib/Bindings.py ============================================================================== --- stackless/trunk/Lib/idlelib/Bindings.py (original) +++ stackless/trunk/Lib/idlelib/Bindings.py Mon Aug 21 11:10:05 2006 @@ -22,9 +22,9 @@ None, ('_Save', '<>'), ('Save _As...', '<>'), - ('Save Co_py As...', '<>'), + ('Save Cop_y As...', '<>'), None, - ('_Print Window', '<>'), + ('Prin_t Window', '<>'), None, ('_Close', '<>'), ('E_xit', '<>'), Modified: stackless/trunk/Lib/idlelib/CREDITS.txt ============================================================================== --- stackless/trunk/Lib/idlelib/CREDITS.txt (original) +++ stackless/trunk/Lib/idlelib/CREDITS.txt Mon Aug 21 11:10:05 2006 @@ -19,13 +19,13 @@ subprocess, and made a number of usability enhancements. Other contributors include Raymond Hettinger, Tony Lownds (Mac integration), -Neal Norwitz (code check and clean-up), Noam Raphael (Code Context, Call Tips, -many other patches), and Chui Tey (RPC integration, debugger integration and -persistent breakpoints). +Neal Norwitz (code check and clean-up), Ronald Oussoren (Mac integration), +Noam Raphael (Code Context, Call Tips, many other patches), and Chui Tey (RPC +integration, debugger integration and persistent breakpoints). Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, -Martin v. L?wis, Jason Orendorff, Josh Robb, Nigel Rowe, Bruce Sherwood, -and Jeff Shute have submitted useful patches. Thanks, guys! +Jim Jewett, Martin v. L?wis, Jason Orendorff, Josh Robb, Nigel Rowe, +Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys! For additional details refer to NEWS.txt and Changelog. Modified: stackless/trunk/Lib/idlelib/CodeContext.py ============================================================================== --- stackless/trunk/Lib/idlelib/CodeContext.py (original) +++ stackless/trunk/Lib/idlelib/CodeContext.py Mon Aug 21 11:10:05 2006 @@ -15,7 +15,7 @@ from sys import maxint as INFINITY BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while"]) + "if", "try", "while", "with"]) UPDATEINTERVAL = 100 # millisec FONTUPDATEINTERVAL = 1000 # millisec Modified: stackless/trunk/Lib/idlelib/EditorWindow.py ============================================================================== --- stackless/trunk/Lib/idlelib/EditorWindow.py (original) +++ stackless/trunk/Lib/idlelib/EditorWindow.py Mon Aug 21 11:10:05 2006 @@ -1277,13 +1277,13 @@ "Toggle tabs", "Turn tabs " + ("on", "off")[self.usetabs] + "?\nIndent width " + - ("will be", "remains at")[self.usetabs] + " 8.", + ("will be", "remains at")[self.usetabs] + " 8." + + "\n Note: a tab is always 8 columns", parent=self.text): self.usetabs = not self.usetabs - # Try to prevent mixed tabs/spaces. - # User must reset indent width manually after using tabs - # if he insists on getting into trouble. - self.indentwidth = 8 + # Try to prevent inconsistent indentation. + # User must change indent width manually after using tabs. + self.indentwidth = 8 return "break" # XXX this isn't bound to anything -- see tabwidth comments Modified: stackless/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- stackless/trunk/Lib/idlelib/NEWS.txt (original) +++ stackless/trunk/Lib/idlelib/NEWS.txt Mon Aug 21 11:10:05 2006 @@ -1,3 +1,28 @@ +What's New in IDLE 1.2c1? +========================= + +*Release date: 17-AUG-2006* + +- File menu hotkeys: there were three 'p' assignments. Reassign the + 'Save Copy As' and 'Print' hotkeys to 'y' and 't'. Change the + Shell hotkey from 's' to 'l'. + +- IDLE honors new quit() and exit() commands from site.py Quitter() object. + Patch 1540892, Jim Jewett + +- The 'with' statement is now a Code Context block opener. + Patch 1540851, Jim Jewett + +- Retrieval of previous shell command was not always preserving indentation + (since 1.2a1) Patch 1528468 Tal Einat. + +- Changing tokenize (39046) to detect dedent broke tabnanny check (since 1.2a1) + +- ToggleTab dialog was setting indent to 8 even if cancelled (since 1.2a1). + +- When used w/o subprocess, all exceptions were preceded by an error + message claiming they were IDLE internal errors (since 1.2a1). + What's New in IDLE 1.2b3? ========================= Modified: stackless/trunk/Lib/idlelib/PyShell.py ============================================================================== --- stackless/trunk/Lib/idlelib/PyShell.py (original) +++ stackless/trunk/Lib/idlelib/PyShell.py Mon Aug 21 11:10:05 2006 @@ -478,9 +478,6 @@ import sys as _sys _sys.path = %r del _sys - _msg = 'Use File/Exit or your end-of-file key to quit IDLE' - __builtins__.quit = __builtins__.exit = _msg - del _msg \n""" % (sys.path,)) active_seq = None @@ -514,7 +511,10 @@ print >>sys.__stderr__, errmsg, what print >>console, errmsg, what # we received a response to the currently active seq number: - self.tkconsole.endexecuting() + try: + self.tkconsole.endexecuting() + except AttributeError: # shell may have closed + pass # Reschedule myself if not self.tkconsole.closing: self.tkconsole.text.after(self.tkconsole.pollinterval, @@ -593,7 +593,7 @@ source = source.encode(IOBinding.encoding) except UnicodeError: self.tkconsole.resetoutput() - self.write("Unsupported characters in input") + self.write("Unsupported characters in input\n") return try: # InteractiveInterpreter.runsource() calls its runcode() method, @@ -713,20 +713,30 @@ else: exec code in self.locals except SystemExit: - if tkMessageBox.askyesno( - "Exit?", - "Do you want to exit altogether?", - default="yes", - master=self.tkconsole.text): - raise + if not self.tkconsole.closing: + if tkMessageBox.askyesno( + "Exit?", + "Do you want to exit altogether?", + default="yes", + master=self.tkconsole.text): + raise + else: + self.showtraceback() else: - self.showtraceback() + raise except: - print>>sys.stderr, "IDLE internal error in runcode()" + if use_subprocess: + print >> self.tkconsole.stderr, \ + "IDLE internal error in runcode()" self.showtraceback() + if use_subprocess: + self.tkconsole.endexecuting() finally: if not use_subprocess: - self.tkconsole.endexecuting() + try: + self.tkconsole.endexecuting() + except AttributeError: # shell may have closed + pass def write(self, s): "Override base class method" @@ -790,7 +800,7 @@ if use_subprocess: ms = self.menu_specs if ms[2][0] != "shell": - ms.insert(2, ("shell", "_Shell")) + ms.insert(2, ("shell", "She_ll")) self.interp = ModifiedInterpreter(self) if flist is None: root = Tk() @@ -800,9 +810,6 @@ # OutputWindow.__init__(self, flist, None, None) # - import __builtin__ - __builtin__.quit = __builtin__.exit = "To exit, type Ctrl-D." - # ## self.config(usetabs=1, indentwidth=8, context_use_ps1=1) self.usetabs = True # indentwidth must be 8 when using tabs. See note in EditorWindow: @@ -1134,21 +1141,27 @@ return "break" def recall(self, s, event): + # remove leading and trailing empty or whitespace lines + s = re.sub(r'^\s*\n', '' , s) + s = re.sub(r'\n\s*$', '', s) + lines = s.split('\n') self.text.undo_block_start() try: self.text.tag_remove("sel", "1.0", "end") self.text.mark_set("insert", "end-1c") - s = s.strip() - lines = s.split('\n') - prefix = self.text.get("insert linestart","insert").rstrip() - if prefix and prefix[-1]==':': + prefix = self.text.get("insert linestart", "insert") + if prefix.rstrip().endswith(':'): self.newline_and_indent_event(event) - self.text.insert("insert",lines[0].strip()) + prefix = self.text.get("insert linestart", "insert") + self.text.insert("insert", lines[0].strip()) if len(lines) > 1: - self.newline_and_indent_event(event) + orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0) + new_base_indent = re.search(r'^([ \t]*)', prefix).group(0) for line in lines[1:]: - self.text.insert("insert", line.strip()) - self.newline_and_indent_event(event) + if line.startswith(orig_base_indent): + # replace orig base indentation with new indentation + line = new_base_indent + line[len(orig_base_indent):] + self.text.insert('insert', '\n'+line.rstrip()) finally: self.text.see("insert") self.text.undo_block_stop() Modified: stackless/trunk/Lib/idlelib/ScriptBinding.py ============================================================================== --- stackless/trunk/Lib/idlelib/ScriptBinding.py (original) +++ stackless/trunk/Lib/idlelib/ScriptBinding.py Mon Aug 21 11:10:05 2006 @@ -76,6 +76,9 @@ self.editwin.gotoline(nag.get_lineno()) self.errorbox("Tab/space error", indent_message) return False + except IndentationError: + # From tokenize(), let compile() in checksyntax find it again. + pass return True def checksyntax(self, filename): Modified: stackless/trunk/Lib/idlelib/idlever.py ============================================================================== --- stackless/trunk/Lib/idlelib/idlever.py (original) +++ stackless/trunk/Lib/idlelib/idlever.py Mon Aug 21 11:10:05 2006 @@ -1 +1 @@ -IDLE_VERSION = "1.2b3" +IDLE_VERSION = "1.2c1" Modified: stackless/trunk/Lib/logging/__init__.py ============================================================================== --- stackless/trunk/Lib/logging/__init__.py (original) +++ stackless/trunk/Lib/logging/__init__.py Mon Aug 21 11:10:05 2006 @@ -1337,14 +1337,14 @@ """ root.manager.disable = level -def shutdown(): +def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ - for h in _handlerList[:]: # was _handlers.keys(): + for h in handlerList[:]: #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: Modified: stackless/trunk/Lib/logging/config.py ============================================================================== --- stackless/trunk/Lib/logging/config.py (original) +++ stackless/trunk/Lib/logging/config.py Mon Aug 21 11:10:05 2006 @@ -79,7 +79,7 @@ logging._acquireLock() try: logging._handlers.clear() - logging._handlerList = [] + del logging._handlerList[:] # Handlers add themselves to logging._handlers handlers = _install_handlers(cp, formatters) _install_loggers(cp, handlers) Modified: stackless/trunk/Lib/site.py ============================================================================== --- stackless/trunk/Lib/site.py (original) +++ stackless/trunk/Lib/site.py Mon Aug 21 11:10:05 2006 @@ -27,7 +27,7 @@ '#' are skipped. Lines starting with 'import' are executed. For example, suppose sys.prefix and sys.exec_prefix are set to -/usr/local and there is a directory /usr/local/lib/python1.5/site-packages +/usr/local and there is a directory /usr/local/lib/python2.5/site-packages with three subdirectories, foo, bar and spam, and two path configuration files, foo.pth and bar.pth. Assume foo.pth contains the following: @@ -44,8 +44,8 @@ Then the following directories are added to sys.path, in this order: - /usr/local/lib/python1.5/site-packages/bar - /usr/local/lib/python1.5/site-packages/foo + /usr/local/lib/python2.5/site-packages/bar + /usr/local/lib/python2.5/site-packages/foo Note that bletch is omitted because it doesn't exist; bar precedes foo because bar.pth comes alphabetically before foo.pth; and spam is @@ -242,6 +242,12 @@ def __repr__(self): return 'Use %s() or %s to exit' % (self.name, eof) def __call__(self, code=None): + # Shells like IDLE catch the SystemExit, but listen when their + # stdin wrapper is closed. + try: + sys.stdin.close() + except: + pass raise SystemExit(code) __builtin__.quit = Quitter('quit') __builtin__.exit = Quitter('exit') Modified: stackless/trunk/Lib/string.py ============================================================================== --- stackless/trunk/Lib/string.py (original) +++ stackless/trunk/Lib/string.py Mon Aug 21 11:10:05 2006 @@ -35,7 +35,6 @@ # Case conversion helpers # Use str to convert Unicode literal in case of -U -# Note that Cookie.py bogusly uses _idmap :( l = map(chr, xrange(256)) _idmap = str('').join(l) del l Modified: stackless/trunk/Lib/tabnanny.py ============================================================================== --- stackless/trunk/Lib/tabnanny.py (original) +++ stackless/trunk/Lib/tabnanny.py Mon Aug 21 11:10:05 2006 @@ -109,6 +109,10 @@ errprint("%r: Token Error: %s" % (file, msg)) return + except IndentationError, msg: + errprint("%r: Indentation Error: %s" % (file, msg)) + return + except NannyNag, nag: badline = nag.get_lineno() line = nag.get_line() Modified: stackless/trunk/Lib/test/exception_hierarchy.txt ============================================================================== --- stackless/trunk/Lib/test/exception_hierarchy.txt (original) +++ stackless/trunk/Lib/test/exception_hierarchy.txt Mon Aug 21 11:10:05 2006 @@ -46,3 +46,4 @@ +-- UserWarning +-- FutureWarning +-- ImportWarning + +-- UnicodeWarning Modified: stackless/trunk/Lib/test/inspect_fodder2.py ============================================================================== --- stackless/trunk/Lib/test/inspect_fodder2.py (original) +++ stackless/trunk/Lib/test/inspect_fodder2.py Mon Aug 21 11:10:05 2006 @@ -88,3 +88,12 @@ def func88(): # comment return 90 + +# line 92 +def f(): + class X: + def g(): + "doc" + return 42 + return X +method_in_dynamic_class = f().g.im_func Modified: stackless/trunk/Lib/test/output/test_cgi ============================================================================== --- stackless/trunk/Lib/test/output/test_cgi (original) +++ stackless/trunk/Lib/test/output/test_cgi Mon Aug 21 11:10:05 2006 @@ -38,3 +38,5 @@ Testing log Testing initlog 1 Testing log 2 +Test FieldStorage methods that use readline +Test basic FieldStorage multipart parsing Modified: stackless/trunk/Lib/test/regrtest.py ============================================================================== --- stackless/trunk/Lib/test/regrtest.py (original) +++ stackless/trunk/Lib/test/regrtest.py Mon Aug 21 11:10:05 2006 @@ -66,7 +66,9 @@ -M runs tests that require an exorbitant amount of memory. These tests typically try to ascertain containers keep working when containing more than -2 bilion objects, and only work on 64-bit systems. The passed-in memlimit, +2 billion objects, which only works on 64-bit systems. There are also some +tests that try to exhaust the address space of the process, which only makes +sense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit, which is a string in the form of '2.5Gb', determines howmuch memory the tests will limit themselves to (but they may go slightly over.) The number shouldn't be more memory than the machine has (including swap memory). You Modified: stackless/trunk/Lib/test/test_builtin.py ============================================================================== --- stackless/trunk/Lib/test/test_builtin.py (original) +++ stackless/trunk/Lib/test/test_builtin.py Mon Aug 21 11:10:05 2006 @@ -640,6 +640,19 @@ def f(): pass self.assertRaises(TypeError, hash, []) self.assertRaises(TypeError, hash, {}) + # Bug 1536021: Allow hash to return long objects + class X: + def __hash__(self): + return 2**100 + self.assertEquals(type(hash(X())), int) + class Y(object): + def __hash__(self): + return 2**100 + self.assertEquals(type(hash(Y())), int) + class Z(long): + def __hash__(self): + return self + self.assertEquals(hash(Z(42)), hash(42L)) def test_hex(self): self.assertEqual(hex(16), '0x10') @@ -1432,6 +1445,14 @@ self.assertEqual(input('testing\n'), 2) self.assertEqual(raw_input(), 'The quick brown fox jumps over the lazy dog.') self.assertEqual(raw_input('testing\n'), 'Dear John') + + # SF 1535165: don't segfault on closed stdin + # sys.stdout must be a regular file for triggering + sys.stdout = savestdout + sys.stdin.close() + self.assertRaises(ValueError, input) + + sys.stdout = BitBucket() sys.stdin = cStringIO.StringIO("NULL\0") self.assertRaises(TypeError, input, 42, 42) sys.stdin = cStringIO.StringIO(" 'whitespace'") Modified: stackless/trunk/Lib/test/test_bz2.py ============================================================================== --- stackless/trunk/Lib/test/test_bz2.py (original) +++ stackless/trunk/Lib/test/test_bz2.py Mon Aug 21 11:10:05 2006 @@ -166,10 +166,21 @@ sio = StringIO(self.TEXT) bz2f.writelines(sio.readlines()) bz2f.close() + # patch #1535500 + self.assertRaises(ValueError, bz2f.writelines, ["a"]) f = open(self.filename, 'rb') self.assertEqual(self.decompress(f.read()), self.TEXT) f.close() + def testWriteMethodsOnReadOnlyFile(self): + bz2f = BZ2File(self.filename, "w") + bz2f.write("abc") + bz2f.close() + + bz2f = BZ2File(self.filename, "r") + self.assertRaises(IOError, bz2f.write, "a") + self.assertRaises(IOError, bz2f.writelines, ["a"]) + def testSeekForward(self): # "Test BZ2File.seek(150, 0)" self.createTempFile() @@ -258,7 +269,7 @@ bz2f = BZ2File(self.filename) xlines = list(bz2f.xreadlines()) bz2f.close() - self.assertEqual(lines, ['Test']) + self.assertEqual(xlines, ['Test']) class BZ2CompressorTest(BaseTest): Modified: stackless/trunk/Lib/test/test_cgi.py ============================================================================== --- stackless/trunk/Lib/test/test_cgi.py (original) +++ stackless/trunk/Lib/test/test_cgi.py Mon Aug 21 11:10:05 2006 @@ -2,6 +2,8 @@ import cgi import os import sys +import tempfile +from StringIO import StringIO class HackedSysModule: # The regression test will have real values in sys.argv, which @@ -203,4 +205,71 @@ cgi.initlog("%s", "Testing log 3") cgi.log("Testing log 4") + print "Test FieldStorage methods that use readline" + # FieldStorage uses readline, which has the capacity to read all + # contents of the input file into memory; we use readline's size argument + # to prevent that for files that do not contain any newlines in + # non-GET/HEAD requests + class TestReadlineFile: + def __init__(self, file): + self.file = file + self.numcalls = 0 + + def readline(self, size=None): + self.numcalls += 1 + if size: + return self.file.readline(size) + else: + return self.file.readline() + + def __getattr__(self, name): + file = self.__dict__['file'] + a = getattr(file, name) + if not isinstance(a, int): + setattr(self, name, a) + return a + + f = TestReadlineFile(tempfile.TemporaryFile()) + f.write('x' * 256 * 1024) + f.seek(0) + env = {'REQUEST_METHOD':'PUT'} + fs = cgi.FieldStorage(fp=f, environ=env) + # if we're not chunking properly, readline is only called twice + # (by read_binary); if we are chunking properly, it will be called 5 times + # as long as the chunksize is 1 << 16. + verify(f.numcalls > 2) + + print "Test basic FieldStorage multipart parsing" + env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'} + postdata = """-----------------------------721837373350705526688164684 +Content-Disposition: form-data; name="id" + +1234 +-----------------------------721837373350705526688164684 +Content-Disposition: form-data; name="title" + + +-----------------------------721837373350705526688164684 +Content-Disposition: form-data; name="file"; filename="test.txt" +Content-Type: text/plain + +Testing 123. + +-----------------------------721837373350705526688164684 +Content-Disposition: form-data; name="submit" + + Add\x20 +-----------------------------721837373350705526688164684-- +""" + fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env) + verify(len(fs.list) == 4) + expect = [{'name':'id', 'filename':None, 'value':'1234'}, + {'name':'title', 'filename':None, 'value':''}, + {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'}, + {'name':'submit', 'filename':None, 'value':' Add '}] + for x in range(len(fs.list)): + for k, exp in expect[x].items(): + got = getattr(fs.list[x], k) + verify(got == exp) + main() Modified: stackless/trunk/Lib/test/test_code.py ============================================================================== --- stackless/trunk/Lib/test/test_code.py (original) +++ stackless/trunk/Lib/test/test_code.py Mon Aug 21 11:10:05 2006 @@ -61,6 +61,23 @@ flags: 67 consts: ('None',) +>>> def optimize_away(): +... 'doc string' +... 'not a docstring' +... 53 +... 53L + +>>> dump(optimize_away.func_code) +name: optimize_away +argcount: 0 +names: () +varnames: () +cellvars: () +freevars: () +nlocals: 0 +flags: 67 +consts: ("'doc string'", 'None') + """ def consts(t): Modified: stackless/trunk/Lib/test/test_compiler.py ============================================================================== --- stackless/trunk/Lib/test/test_compiler.py (original) +++ stackless/trunk/Lib/test/test_compiler.py Mon Aug 21 11:10:05 2006 @@ -104,6 +104,26 @@ self.assertEquals(flatten([1, [2]]), [1, 2]) self.assertEquals(flatten((1, (2,))), [1, 2]) + def testNestedScope(self): + c = compiler.compile('def g():\n' + ' a = 1\n' + ' def f(): return a + 2\n' + ' return f()\n' + 'result = g()', + '', + 'exec') + dct = {} + exec c in dct + self.assertEquals(dct.get('result'), 3) + + def testGenExp(self): + c = compiler.compile('list((i,j) for i in range(3) if i < 3' + ' for j in range(4) if j > 2)', + '', + 'eval') + self.assertEquals(eval(c), [(0, 3), (1, 3), (2, 3)]) + + NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard) ############################################################################### Modified: stackless/trunk/Lib/test/test_descr.py ============================================================================== --- stackless/trunk/Lib/test/test_descr.py (original) +++ stackless/trunk/Lib/test/test_descr.py Mon Aug 21 11:10:05 2006 @@ -2024,6 +2024,16 @@ prop2 = property(fset=setter) vereq(prop2.__doc__, None) + # this segfaulted in 2.5b2 + try: + import _testcapi + except ImportError: + pass + else: + class X(object): + p = property(_testcapi.test_with_docstring) + + def supers(): if verbose: print "Testing super..." Modified: stackless/trunk/Lib/test/test_format.py ============================================================================== --- stackless/trunk/Lib/test/test_format.py (original) +++ stackless/trunk/Lib/test/test_format.py Mon Aug 21 11:10:05 2006 @@ -230,6 +230,14 @@ test_exc(u'no format', u'1', TypeError, "not all arguments converted during string formatting") +class Foobar(long): + def __oct__(self): + # Returning a non-string should not blow up. + return self + 1 + +test_exc('%o', Foobar(), TypeError, + "expected string or Unicode object, long found") + if sys.maxint == 2**31-1: # crashes 2.2.1 and earlier: try: Modified: stackless/trunk/Lib/test/test_index.py ============================================================================== --- stackless/trunk/Lib/test/test_index.py (original) +++ stackless/trunk/Lib/test/test_index.py Mon Aug 21 11:10:05 2006 @@ -1,6 +1,7 @@ import unittest from test import test_support import operator +from sys import maxint class oldstyle: def __index__(self): @@ -10,68 +11,116 @@ def __index__(self): return self.ind +class TrapInt(int): + def __index__(self): + return self + +class TrapLong(long): + def __index__(self): + return self + class BaseTestCase(unittest.TestCase): def setUp(self): self.o = oldstyle() self.n = newstyle() - self.o2 = oldstyle() - self.n2 = newstyle() def test_basic(self): self.o.ind = -2 self.n.ind = 2 - assert(self.seq[self.n] == self.seq[2]) - assert(self.seq[self.o] == self.seq[-2]) - assert(operator.index(self.o) == -2) - assert(operator.index(self.n) == 2) + self.assertEqual(operator.index(self.o), -2) + self.assertEqual(operator.index(self.n), 2) + + def test_slice(self): + self.o.ind = 1 + self.n.ind = 2 + slc = slice(self.o, self.o, self.o) + check_slc = slice(1, 1, 1) + self.assertEqual(slc.indices(self.o), check_slc.indices(1)) + slc = slice(self.n, self.n, self.n) + check_slc = slice(2, 2, 2) + self.assertEqual(slc.indices(self.n), check_slc.indices(2)) + + def test_wrappers(self): + self.o.ind = 4 + self.n.ind = 5 + self.assertEqual(6 .__index__(), 6) + self.assertEqual(-7L.__index__(), -7) + self.assertEqual(self.o.__index__(), 4) + self.assertEqual(self.n.__index__(), 5) + + def test_subclasses(self): + r = range(10) + self.assertEqual(r[TrapInt(5):TrapInt(10)], r[5:10]) + self.assertEqual(r[TrapLong(5):TrapLong(10)], r[5:10]) + self.assertEqual(slice(TrapInt()).indices(0), (0,0,1)) + self.assertEqual(slice(TrapLong(0)).indices(0), (0,0,1)) def test_error(self): self.o.ind = 'dumb' self.n.ind = 'bad' - myfunc = lambda x, obj: obj.seq[x] self.failUnlessRaises(TypeError, operator.index, self.o) self.failUnlessRaises(TypeError, operator.index, self.n) - self.failUnlessRaises(TypeError, myfunc, self.o, self) - self.failUnlessRaises(TypeError, myfunc, self.n, self) + self.failUnlessRaises(TypeError, slice(self.o).indices, 0) + self.failUnlessRaises(TypeError, slice(self.n).indices, 0) + + +class SeqTestCase(unittest.TestCase): + # This test case isn't run directly. It just defines common tests + # to the different sequence types below + def setUp(self): + self.o = oldstyle() + self.n = newstyle() + self.o2 = oldstyle() + self.n2 = newstyle() + + def test_index(self): + self.o.ind = -2 + self.n.ind = 2 + self.assertEqual(self.seq[self.n], self.seq[2]) + self.assertEqual(self.seq[self.o], self.seq[-2]) def test_slice(self): self.o.ind = 1 self.o2.ind = 3 self.n.ind = 2 self.n2.ind = 4 - assert(self.seq[self.o:self.o2] == self.seq[1:3]) - assert(self.seq[self.n:self.n2] == self.seq[2:4]) + self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3]) + self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4]) def test_repeat(self): self.o.ind = 3 self.n.ind = 2 - assert(self.seq * self.o == self.seq * 3) - assert(self.seq * self.n == self.seq * 2) - assert(self.o * self.seq == self.seq * 3) - assert(self.n * self.seq == self.seq * 2) + self.assertEqual(self.seq * self.o, self.seq * 3) + self.assertEqual(self.seq * self.n, self.seq * 2) + self.assertEqual(self.o * self.seq, self.seq * 3) + self.assertEqual(self.n * self.seq, self.seq * 2) def test_wrappers(self): - n = self.n - n.ind = 5 - assert n.__index__() == 5 - assert 6 .__index__() == 6 - assert -7L.__index__() == -7 - assert self.seq.__getitem__(n) == self.seq[5] - assert self.seq.__mul__(n) == self.seq * 5 - assert self.seq.__rmul__(n) == self.seq * 5 - - def test_infinite_recusion(self): - class Trap1(int): - def __index__(self): - return self - class Trap2(long): - def __index__(self): - return self - self.failUnlessRaises(TypeError, operator.getitem, self.seq, Trap1()) - self.failUnlessRaises(TypeError, operator.getitem, self.seq, Trap2()) + self.o.ind = 4 + self.n.ind = 5 + self.assertEqual(self.seq.__getitem__(self.o), self.seq[4]) + self.assertEqual(self.seq.__mul__(self.o), self.seq * 4) + self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4) + self.assertEqual(self.seq.__getitem__(self.n), self.seq[5]) + self.assertEqual(self.seq.__mul__(self.n), self.seq * 5) + self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5) + + def test_subclasses(self): + self.assertEqual(self.seq[TrapInt()], self.seq[0]) + self.assertEqual(self.seq[TrapLong()], self.seq[0]) + def test_error(self): + self.o.ind = 'dumb' + self.n.ind = 'bad' + indexobj = lambda x, obj: obj.seq[x] + self.failUnlessRaises(TypeError, indexobj, self.o, self) + self.failUnlessRaises(TypeError, indexobj, self.n, self) + sliceobj = lambda x, obj: obj.seq[x:] + self.failUnlessRaises(TypeError, sliceobj, self.o, self) + self.failUnlessRaises(TypeError, sliceobj, self.n, self) -class ListTestCase(BaseTestCase): + +class ListTestCase(SeqTestCase): seq = [0,10,20,30,40,50] def test_setdelitem(self): @@ -82,36 +131,36 @@ del lst[self.n] lst[self.o] = 'X' lst[self.n] = 'Y' - assert lst == list('abYdefghXj') + self.assertEqual(lst, list('abYdefghXj')) lst = [5, 6, 7, 8, 9, 10, 11] lst.__setitem__(self.n, "here") - assert lst == [5, 6, "here", 8, 9, 10, 11] + self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11]) lst.__delitem__(self.n) - assert lst == [5, 6, 8, 9, 10, 11] + self.assertEqual(lst, [5, 6, 8, 9, 10, 11]) def test_inplace_repeat(self): self.o.ind = 2 self.n.ind = 3 lst = [6, 4] lst *= self.o - assert lst == [6, 4, 6, 4] + self.assertEqual(lst, [6, 4, 6, 4]) lst *= self.n - assert lst == [6, 4, 6, 4] * 3 + self.assertEqual(lst, [6, 4, 6, 4] * 3) lst = [5, 6, 7, 8, 9, 11] l2 = lst.__imul__(self.n) - assert l2 is lst - assert lst == [5, 6, 7, 8, 9, 11] * 3 + self.assert_(l2 is lst) + self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3) -class TupleTestCase(BaseTestCase): +class TupleTestCase(SeqTestCase): seq = (0,10,20,30,40,50) -class StringTestCase(BaseTestCase): +class StringTestCase(SeqTestCase): seq = "this is a test" -class UnicodeTestCase(BaseTestCase): +class UnicodeTestCase(SeqTestCase): seq = u"this is a test" @@ -120,17 +169,54 @@ def test_xrange(self): n = newstyle() n.ind = 5 - assert xrange(1, 20)[n] == 6 - assert xrange(1, 20).__getitem__(n) == 6 + self.assertEqual(xrange(1, 20)[n], 6) + self.assertEqual(xrange(1, 20).__getitem__(n), 6) + +class OverflowTestCase(unittest.TestCase): + + def setUp(self): + self.pos = 2**100 + self.neg = -self.pos + + def test_large_longs(self): + self.assertEqual(self.pos.__index__(), self.pos) + self.assertEqual(self.neg.__index__(), self.neg) + + def _getitem_helper(self, base): + class GetItem(base): + def __len__(self): + return maxint + def __getitem__(self, key): + return key + def __getslice__(self, i, j): + return i, j + x = GetItem() + self.assertEqual(x[self.pos], self.pos) + self.assertEqual(x[self.neg], self.neg) + self.assertEqual(x[self.neg:self.pos], (-1, maxint)) + self.assertEqual(x[self.neg:self.pos:1].indices(maxint), (0, maxint, 1)) + + def test_getitem(self): + self._getitem_helper(object) + + def test_getitem_classic(self): + class Empty: pass + self._getitem_helper(Empty) + + def test_sequence_repeat(self): + self.failUnlessRaises(OverflowError, lambda: "a" * self.pos) + self.failUnlessRaises(OverflowError, lambda: "a" * self.neg) def test_main(): test_support.run_unittest( + BaseTestCase, ListTestCase, TupleTestCase, StringTestCase, UnicodeTestCase, XRangeTestCase, + OverflowTestCase, ) if __name__ == "__main__": Modified: stackless/trunk/Lib/test/test_inspect.py ============================================================================== --- stackless/trunk/Lib/test/test_inspect.py (original) +++ stackless/trunk/Lib/test/test_inspect.py Mon Aug 21 11:10:05 2006 @@ -274,6 +274,9 @@ def test_with_comment_instead_of_docstring(self): self.assertSourceEqual(mod2.func88, 88, 90) + def test_method_in_dynamic_class(self): + self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97) + # Helper for testing classify_class_attrs. def attrs_wo_objs(cls): return [t[:3] for t in inspect.classify_class_attrs(cls)] Modified: stackless/trunk/Lib/test/test_logging.py ============================================================================== --- stackless/trunk/Lib/test/test_logging.py (original) +++ stackless/trunk/Lib/test/test_logging.py Mon Aug 21 11:10:05 2006 @@ -493,7 +493,7 @@ try: logging._handlers.clear() logging._handlers.update(saved_handlers) - logging._handlerList = saved_handler_list + logging._handlerList[:] = saved_handler_list loggerDict = logging.getLogger().manager.loggerDict loggerDict.clear() loggerDict.update(saved_loggers) @@ -560,7 +560,7 @@ try: logging._handlers.clear() logging._handlers.update(saved_handlers) - logging._handlerList = saved_handler_list + logging._handlerList[:] = saved_handler_list loggerDict = logging.getLogger().manager.loggerDict loggerDict.clear() loggerDict.update(saved_loggers) Modified: stackless/trunk/Lib/test/test_mailbox.py ============================================================================== --- stackless/trunk/Lib/test/test_mailbox.py (original) +++ stackless/trunk/Lib/test/test_mailbox.py Mon Aug 21 11:10:05 2006 @@ -1,4 +1,5 @@ import os +import sys import time import stat import socket @@ -461,7 +462,7 @@ def setUp(self): TestMailbox.setUp(self) - if os.name in ('nt', 'os2'): + if os.name in ('nt', 'os2') or sys.platform == 'cygwin': self._box.colon = '!' def test_add_MM(self): @@ -736,11 +737,13 @@ # In the parent, sleep a bit to give the child time to acquire # the lock. time.sleep(0.5) - self.assertRaises(mailbox.ExternalClashError, - self._box.lock) + try: + self.assertRaises(mailbox.ExternalClashError, + self._box.lock) + finally: + # Wait for child to exit. Locking should now succeed. + exited_pid, status = os.waitpid(pid, 0) - # Wait for child to exit. Locking should now succeed. - exited_pid, status = os.waitpid(pid, 0) self._box.lock() self._box.unlock() Modified: stackless/trunk/Lib/test/test_shutil.py ============================================================================== --- stackless/trunk/Lib/test/test_shutil.py (original) +++ stackless/trunk/Lib/test/test_shutil.py Mon Aug 21 11:10:05 2006 @@ -74,31 +74,51 @@ except: pass - def test_copytree_simple(self): + def write_data(path, data): + f = open(path, "w") + f.write(data) + f.close() + + def read_data(path): + f = open(path) + data = f.read() + f.close() + return data + src_dir = tempfile.mkdtemp() dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') - open(os.path.join(src_dir, 'test.txt'), 'w').write('123') + + write_data(os.path.join(src_dir, 'test.txt'), '123') + os.mkdir(os.path.join(src_dir, 'test_dir')) - open(os.path.join(src_dir, 'test_dir', 'test.txt'), 'w').write('456') - # + write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456') + try: shutil.copytree(src_dir, dst_dir) self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt'))) self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir'))) - self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir', 'test.txt'))) - self.assertEqual(open(os.path.join(dst_dir, 'test.txt')).read(), '123') - self.assertEqual(open(os.path.join(dst_dir, 'test_dir', 'test.txt')).read(), '456') + self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir', + 'test.txt'))) + actual = read_data(os.path.join(dst_dir, 'test.txt')) + self.assertEqual(actual, '123') + actual = read_data(os.path.join(dst_dir, 'test_dir', 'test.txt')) + self.assertEqual(actual, '456') finally: - try: - os.remove(os.path.join(src_dir, 'test.txt')) - os.remove(os.path.join(dst_dir, 'test.txt')) - os.remove(os.path.join(src_dir, 'test_dir', 'test.txt')) - os.remove(os.path.join(dst_dir, 'test_dir', 'test.txt')) - os.removedirs(src_dir) - os.removedirs(dst_dir) - except: - pass + for path in ( + os.path.join(src_dir, 'test.txt'), + os.path.join(dst_dir, 'test.txt'), + os.path.join(src_dir, 'test_dir', 'test.txt'), + os.path.join(dst_dir, 'test_dir', 'test.txt'), + ): + if os.path.exists(path): + os.remove(path) + for path in ( + os.path.join(src_dir, 'test_dir'), + os.path.join(dst_dir, 'test_dir'), + ): + if os.path.exists(path): + os.removedirs(path) if hasattr(os, "symlink"): Modified: stackless/trunk/Lib/test/test_signal.py ============================================================================== --- stackless/trunk/Lib/test/test_signal.py (original) +++ stackless/trunk/Lib/test/test_signal.py Mon Aug 21 11:10:05 2006 @@ -6,11 +6,16 @@ if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos': raise TestSkipped, "Can't test signal on %s" % sys.platform +MAX_DURATION = 20 # Entire test should last at most 20 sec. + if verbose: x = '-x' else: x = '+x' + pid = os.getpid() +if verbose: + print "test runner's pid is", pid # Shell script that will send us asynchronous signals script = """ @@ -31,7 +36,7 @@ global a_called a_called = True if verbose: - print "handlerA", args + print "handlerA invoked", args class HandlerBCalled(Exception): pass @@ -40,87 +45,110 @@ global b_called b_called = True if verbose: - print "handlerB", args + print "handlerB invoked", args raise HandlerBCalled, args -MAX_DURATION = 20 -signal.alarm(MAX_DURATION) # Entire test should last at most 20 sec. +# Set up a child to send signals to us (the parent) after waiting long +# enough to receive the alarm. It seems we miss the alarm for some +# reason. This will hopefully stop the hangs on Tru64/Alpha. +# Alas, it doesn't. Tru64 appears to miss all the signals at times, or +# seemingly random subsets of them, and nothing done in force_test_exit +# so far has actually helped. +def force_test_exit(): + # Sigh, both imports seem necessary to avoid errors. + import os + fork_pid = os.fork() + if fork_pid: + # In parent. + return fork_pid + + # In child. + import os, time + try: + # Wait 5 seconds longer than the expected alarm to give enough + # time for the normal sequence of events to occur. This is + # just a stop-gap to try to prevent the test from hanging. + time.sleep(MAX_DURATION + 5) + print >> sys.__stdout__, ' child should not have to kill parent' + for signame in "SIGHUP", "SIGUSR1", "SIGUSR2", "SIGALRM": + os.kill(pid, getattr(signal, signame)) + print >> sys.__stdout__, " child sent", signame, "to", pid + time.sleep(1) + finally: + os._exit(0) + +# Install handlers. hup = signal.signal(signal.SIGHUP, handlerA) usr1 = signal.signal(signal.SIGUSR1, handlerB) usr2 = signal.signal(signal.SIGUSR2, signal.SIG_IGN) alrm = signal.signal(signal.SIGALRM, signal.default_int_handler) -vereq(signal.getsignal(signal.SIGHUP), handlerA) -vereq(signal.getsignal(signal.SIGUSR1), handlerB) -vereq(signal.getsignal(signal.SIGUSR2), signal.SIG_IGN) - try: - signal.signal(4242, handlerB) - raise TestFailed, 'expected ValueError for invalid signal # to signal()' -except ValueError: - pass -try: - signal.getsignal(4242) - raise TestFailed, 'expected ValueError for invalid signal # to getsignal()' -except ValueError: - pass + signal.alarm(MAX_DURATION) + vereq(signal.getsignal(signal.SIGHUP), handlerA) + vereq(signal.getsignal(signal.SIGUSR1), handlerB) + vereq(signal.getsignal(signal.SIGUSR2), signal.SIG_IGN) + vereq(signal.getsignal(signal.SIGALRM), signal.default_int_handler) -try: - signal.signal(signal.SIGUSR1, None) - raise TestFailed, 'expected TypeError for non-callable' -except TypeError: - pass + # Try to ensure this test exits even if there is some problem with alarm. + # Tru64/Alpha often hangs and is ultimately killed by the buildbot. + fork_pid = force_test_exit() -# Set up a child to send an alarm signal to us (the parent) after waiting -# long enough to receive the alarm. It seems we miss the alarm for some -# reason. This will hopefully stop the hangs on Tru64/Alpha. -def force_test_exit(): - # Sigh, both imports seem necessary to avoid errors. - import os - fork_pid = os.fork() - if fork_pid == 0: - # In child - import os, time - try: - # Wait 5 seconds longer than the expected alarm to give enough - # time for the normal sequence of events to occur. This is - # just a stop-gap to prevent the test from hanging. - time.sleep(MAX_DURATION + 5) - print >> sys.__stdout__, ' child should not have to kill parent' - for i in range(3): - os.kill(pid, signal.SIGALARM) - finally: - os._exit(0) - # In parent (or error) - return fork_pid + try: + signal.getsignal(4242) + raise TestFailed('expected ValueError for invalid signal # to ' + 'getsignal()') + except ValueError: + pass -try: - os.system(script) + try: + signal.signal(4242, handlerB) + raise TestFailed('expected ValueError for invalid signal # to ' + 'signal()') + except ValueError: + pass - # Try to ensure this test exits even if there is some problem with alarm. - # Tru64/Alpha sometimes hangs and is ultimately killed by the buildbot. - fork_pid = force_test_exit() - print "starting pause() loop..." + try: + signal.signal(signal.SIGUSR1, None) + raise TestFailed('expected TypeError for non-callable') + except TypeError: + pass + # Launch an external script to send us signals. + # We expect the external script to: + # send HUP, which invokes handlerA to set a_called + # send USR1, which invokes handlerB to set b_called and raise + # HandlerBCalled + # send USR2, which is ignored + # + # Then we expect the alarm to go off, and its handler raises + # KeyboardInterrupt, finally getting us out of the loop. + os.system(script) try: + print "starting pause() loop..." while 1: - if verbose: - print "call pause()..." try: + if verbose: + print "call pause()..." signal.pause() if verbose: print "pause() returned" except HandlerBCalled: if verbose: print "HandlerBCalled exception caught" - else: - pass except KeyboardInterrupt: if verbose: - print "KeyboardInterrupt (assume the alarm() went off)" + print "KeyboardInterrupt (the alarm() went off)" + if not a_called: + print 'HandlerA not called' + + if not b_called: + print 'HandlerB not called' + +finally: # Forcibly kill the child we created to ping us if there was a test error. try: # Make sure we don't kill ourself if there was a fork error. @@ -128,16 +156,11 @@ os.kill(fork_pid, signal.SIGKILL) except: # If the child killed us, it has probably exited. Killing a - # non-existant process will raise an error which we don't care about. + # non-existent process will raise an error which we don't care about. pass - if not a_called: - print 'HandlerA not called' - - if not b_called: - print 'HandlerB not called' - -finally: + # Restore handlers. + signal.alarm(0) # cancel alarm in case we died early signal.signal(signal.SIGHUP, hup) signal.signal(signal.SIGUSR1, usr1) signal.signal(signal.SIGUSR2, usr2) Modified: stackless/trunk/Lib/test/test_socketserver.py ============================================================================== --- stackless/trunk/Lib/test/test_socketserver.py (original) +++ stackless/trunk/Lib/test/test_socketserver.py Mon Aug 21 11:10:05 2006 @@ -181,10 +181,19 @@ if hasattr(os, 'fork') and os.name not in ('os2',): dgramservers.append(ForkingUnixDatagramServer) +def sloppy_cleanup(): + # See http://python.org/sf/1540386 + # We need to reap children here otherwise a child from one server + # can be left running for the next server and cause a test failure. + time.sleep(DELAY) + reap_children() + def testall(): testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) + sloppy_cleanup() testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) if hasattr(socket, 'AF_UNIX'): + sloppy_cleanup() testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) # Alas, on Linux (at least) recvfrom() doesn't return a meaningful # client address so this cannot work: Modified: stackless/trunk/Lib/test/test_struct.py ============================================================================== --- stackless/trunk/Lib/test/test_struct.py (original) +++ stackless/trunk/Lib/test/test_struct.py Mon Aug 21 11:10:05 2006 @@ -15,9 +15,11 @@ except ImportError: PY_STRUCT_RANGE_CHECKING = 0 PY_STRUCT_OVERFLOW_MASKING = 1 + PY_STRUCT_FLOAT_COERCE = 2 else: - PY_STRUCT_RANGE_CHECKING = _struct._PY_STRUCT_RANGE_CHECKING - PY_STRUCT_OVERFLOW_MASKING = _struct._PY_STRUCT_OVERFLOW_MASKING + PY_STRUCT_RANGE_CHECKING = getattr(_struct, '_PY_STRUCT_RANGE_CHECKING', 0) + PY_STRUCT_OVERFLOW_MASKING = getattr(_struct, '_PY_STRUCT_OVERFLOW_MASKING', 0) + PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0) def string_reverse(s): return "".join(reversed(s)) @@ -46,33 +48,40 @@ raise TestFailed, "%s%s did not raise error" % ( func.__name__, args) +def with_warning_restore(func): + def _with_warning_restore(*args, **kw): + # The `warnings` module doesn't have an advertised way to restore + # its filter list. Cheat. + save_warnings_filters = warnings.filters[:] + # Grrr, we need this function to warn every time. Without removing + # the warningregistry, running test_tarfile then test_struct would fail + # on 64-bit platforms. + globals = func.func_globals + if '__warningregistry__' in globals: + del globals['__warningregistry__'] + warnings.filterwarnings("error", r"""^struct.*""", DeprecationWarning) + warnings.filterwarnings("error", r""".*format requires.*""", + DeprecationWarning) + try: + return func(*args, **kw) + finally: + warnings.filters[:] = save_warnings_filters[:] + return _with_warning_restore + def deprecated_err(func, *args): - # The `warnings` module doesn't have an advertised way to restore - # its filter list. Cheat. - save_warnings_filters = warnings.filters[:] - # Grrr, we need this function to warn every time. Without removing - # the warningregistry, running test_tarfile then test_struct would fail - # on 64-bit platforms. - globals = func.func_globals - if '__warningregistry__' in globals: - del globals['__warningregistry__'] - warnings.filterwarnings("error", r"""^struct.*""", DeprecationWarning) - warnings.filterwarnings("error", r""".*format requires.*""", - DeprecationWarning) try: - try: - func(*args) - except (struct.error, TypeError): - pass - except DeprecationWarning: - if not PY_STRUCT_OVERFLOW_MASKING: - raise TestFailed, "%s%s expected to raise struct.error" % ( - func.__name__, args) - else: - raise TestFailed, "%s%s did not raise error" % ( + func(*args) + except (struct.error, TypeError): + pass + except DeprecationWarning: + if not PY_STRUCT_OVERFLOW_MASKING: + raise TestFailed, "%s%s expected to raise struct.error" % ( func.__name__, args) - finally: - warnings.filters[:] = save_warnings_filters[:] + else: + raise TestFailed, "%s%s did not raise error" % ( + func.__name__, args) +deprecated_err = with_warning_restore(deprecated_err) + simple_err(struct.calcsize, 'Z') @@ -475,6 +484,9 @@ test_705836() +########################################################################### +# SF bug 1229380. No struct.pack exception for some out of range integers + def test_1229380(): import sys for endian in ('', '>', '<'): @@ -491,6 +503,37 @@ if PY_STRUCT_RANGE_CHECKING: test_1229380() +########################################################################### +# SF bug 1530559. struct.pack raises TypeError where it used to convert. + +def check_float_coerce(format, number): + if PY_STRUCT_FLOAT_COERCE == 2: + # Test for pre-2.5 struct module + packed = struct.pack(format, number) + floored = struct.unpack(format, packed)[0] + if floored != int(number): + raise TestFailed("did not correcly coerce float to int") + return + try: + func(*args) + except (struct.error, TypeError): + if PY_STRUCT_FLOAT_COERCE: + raise TestFailed("expected DeprecationWarning for float coerce") + except DeprecationWarning: + if not PY_STRUCT_FLOAT_COERCE: + raise TestFailed("expected to raise struct.error for float coerce") + else: + raise TestFailed("did not raise error for float coerce") + +check_float_coerce = with_warning_restore(deprecated_err) + +def test_1530559(): + for endian in ('', '>', '<'): + for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'): + check_float_coerce(endian + fmt, 1.0) + check_float_coerce(endian + fmt, 1.5) + +test_1530559() ########################################################################### # Packing and unpacking to/from buffers. Modified: stackless/trunk/Lib/test/test_support.py ============================================================================== --- stackless/trunk/Lib/test/test_support.py (original) +++ stackless/trunk/Lib/test/test_support.py Mon Aug 21 11:10:05 2006 @@ -314,6 +314,12 @@ _1G = 1024 * _1M _2G = 2 * _1G +# Hack to get at the maximum value an internal index can take. +class _Dummy: + def __getslice__(self, i, j): + return j +MAX_Py_ssize_t = _Dummy()[:] + def set_memlimit(limit): import re global max_memuse @@ -328,7 +334,9 @@ if m is None: raise ValueError('Invalid memory limit %r' % (limit,)) memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()]) - if memlimit < 2.5*_1G: + if memlimit > MAX_Py_ssize_t: + memlimit = MAX_Py_ssize_t + if memlimit < _2G - 1: raise ValueError('Memory limit %r too low to be useful' % (limit,)) max_memuse = memlimit @@ -371,6 +379,17 @@ return wrapper return decorator +def bigaddrspacetest(f): + """Decorator for tests that fill the address space.""" + def wrapper(self): + if max_memuse < MAX_Py_ssize_t: + if verbose: + sys.stderr.write("Skipping %s because of memory " + "constraint\n" % (f.__name__,)) + else: + return f(self) + return wrapper + #======================================================================= # Preliminary PyUNIT integration. Modified: stackless/trunk/Lib/test/test_threading.py ============================================================================== --- stackless/trunk/Lib/test/test_threading.py (original) +++ stackless/trunk/Lib/test/test_threading.py Mon Aug 21 11:10:05 2006 @@ -89,7 +89,12 @@ def test_various_ops_small_stack(self): if verbose: print 'with 256kB thread stack size...' - threading.stack_size(262144) + try: + threading.stack_size(262144) + except thread.error: + if verbose: + print 'platform does not support changing thread stack size' + return self.test_various_ops() threading.stack_size(0) @@ -97,7 +102,12 @@ def test_various_ops_large_stack(self): if verbose: print 'with 1MB thread stack size...' - threading.stack_size(0x100000) + try: + threading.stack_size(0x100000) + except thread.error: + if verbose: + print 'platform does not support changing thread stack size' + return self.test_various_ops() threading.stack_size(0) @@ -121,6 +131,76 @@ threading._DummyThread)) del threading._active[tid] + # PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently) + # exposed at the Python level. This test relies on ctypes to get at it. + def test_PyThreadState_SetAsyncExc(self): + try: + import ctypes + except ImportError: + if verbose: + print "test_PyThreadState_SetAsyncExc can't import ctypes" + return # can't do anything + + set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc + + class AsyncExc(Exception): + pass + + exception = ctypes.py_object(AsyncExc) + + # `worker_started` is set by the thread when it's inside a try/except + # block waiting to catch the asynchronously set AsyncExc exception. + # `worker_saw_exception` is set by the thread upon catching that + # exception. + worker_started = threading.Event() + worker_saw_exception = threading.Event() + + class Worker(threading.Thread): + def run(self): + self.id = thread.get_ident() + self.finished = False + + try: + while True: + worker_started.set() + time.sleep(0.1) + except AsyncExc: + self.finished = True + worker_saw_exception.set() + + t = Worker() + t.setDaemon(True) # so if this fails, we don't hang Python at shutdown + t.start() + if verbose: + print " started worker thread" + + # Try a thread id that doesn't make sense. + if verbose: + print " trying nonsensical thread id" + result = set_async_exc(ctypes.c_long(-1), exception) + self.assertEqual(result, 0) # no thread states modified + + # Now raise an exception in the worker thread. + if verbose: + print " waiting for worker thread to get started" + worker_started.wait() + if verbose: + print " verifying worker hasn't exited" + self.assert_(not t.finished) + if verbose: + print " attempting to raise asynch exception in worker" + result = set_async_exc(ctypes.c_long(t.id), exception) + self.assertEqual(result, 1) # one thread state modified + if verbose: + print " waiting for worker to say it caught the exception" + worker_saw_exception.wait(timeout=10) + self.assert_(t.finished) + if verbose: + print " all OK -- joining worker" + if t.finished: + t.join() + # else the thread is still running, and we have no way to kill it + def test_main(): test.test_support.run_unittest(ThreadTests) Modified: stackless/trunk/Lib/test/test_threadsignals.py ============================================================================== --- stackless/trunk/Lib/test/test_threadsignals.py (original) +++ stackless/trunk/Lib/test/test_threadsignals.py Mon Aug 21 11:10:05 2006 @@ -49,7 +49,7 @@ # and might be out of order.) If we haven't seen # the signals yet, send yet another signal and # wait for it return. - if signal_blackboard[signal.SIGUSR2]['tripped'] == 0 \ + if signal_blackboard[signal.SIGUSR1]['tripped'] == 0 \ or signal_blackboard[signal.SIGUSR2]['tripped'] == 0: signal.alarm(1) signal.pause() Modified: stackless/trunk/Lib/test/test_trace.py ============================================================================== --- stackless/trunk/Lib/test/test_trace.py (original) +++ stackless/trunk/Lib/test/test_trace.py Mon Aug 21 11:10:05 2006 @@ -244,8 +244,8 @@ self.run_test(one_instr_line) def test_04_no_pop_blocks(self): self.run_test(no_pop_blocks) -## def test_05_no_pop_tops(self): -## self.run_test(no_pop_tops) + def test_05_no_pop_tops(self): + self.run_test(no_pop_tops) def test_06_call(self): self.run_test(call) def test_07_raise(self): Modified: stackless/trunk/Lib/test/test_traceback.py ============================================================================== --- stackless/trunk/Lib/test/test_traceback.py (original) +++ stackless/trunk/Lib/test/test_traceback.py Mon Aug 21 11:10:05 2006 @@ -130,15 +130,24 @@ def test_string_exception1(self): str_type = "String Exception" err = traceback.format_exception_only(str_type, None) - self.assert_(len(err) == 1) - self.assert_(err[0] == str_type + '\n') + self.assertEqual(len(err), 1) + self.assertEqual(err[0], str_type + '\n') def test_string_exception2(self): str_type = "String Exception" str_value = "String Value" err = traceback.format_exception_only(str_type, str_value) - self.assert_(len(err) == 1) - self.assert_(err[0] == str_type + ': ' + str_value + '\n') + self.assertEqual(len(err), 1) + self.assertEqual(err[0], str_type + ': ' + str_value + '\n') + + def test_format_exception_only_bad__str__(self): + class X(Exception): + def __str__(self): + 1/0 + err = traceback.format_exception_only(X, X()) + self.assertEqual(len(err), 1) + str_value = '' % X.__name__ + self.assertEqual(err[0], X.__name__ + ': ' + str_value + '\n') def test_main(): Modified: stackless/trunk/Lib/test/test_types.py ============================================================================== --- stackless/trunk/Lib/test/test_types.py (original) +++ stackless/trunk/Lib/test/test_types.py Mon Aug 21 11:10:05 2006 @@ -233,6 +233,7 @@ try: buffer('asdf', -1) except ValueError: pass else: raise TestFailed, "buffer('asdf', -1) should raise ValueError" +cmp(buffer("abc"), buffer("def")) # used to raise a warning: tp_compare didn't return -1, 0, or 1 try: buffer(None) except TypeError: pass Modified: stackless/trunk/Lib/test/test_uuid.py ============================================================================== --- stackless/trunk/Lib/test/test_uuid.py (original) +++ stackless/trunk/Lib/test/test_uuid.py Mon Aug 21 11:10:05 2006 @@ -16,12 +16,13 @@ def test_UUID(self): equal = self.assertEqual ascending = [] - for (string, curly, hex, bytes, fields, integer, urn, + for (string, curly, hex, bytes, bytes_le, fields, integer, urn, time, clock_seq, variant, version) in [ ('00000000-0000-0000-0000-000000000000', '{00000000-0000-0000-0000-000000000000}', '00000000000000000000000000000000', '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', (0, 0, 0, 0, 0, 0), 0, 'urn:uuid:00000000-0000-0000-0000-000000000000', @@ -30,6 +31,7 @@ '{00010203-0405-0607-0809-0a0b0c0d0e0f}', '000102030405060708090a0b0c0d0e0f', '\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\x0d\x0e\x0f', + '\x03\x02\x01\0\x05\x04\x07\x06\x08\t\n\x0b\x0c\x0d\x0e\x0f', (0x00010203L, 0x0405, 0x0607, 8, 9, 0x0a0b0c0d0e0fL), 0x000102030405060708090a0b0c0d0e0fL, 'urn:uuid:00010203-0405-0607-0809-0a0b0c0d0e0f', @@ -38,6 +40,7 @@ '{02d9e6d5-9467-382e-8f9b-9300a64ac3cd}', '02d9e6d59467382e8f9b9300a64ac3cd', '\x02\xd9\xe6\xd5\x94\x67\x38\x2e\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd', + '\xd5\xe6\xd9\x02\x67\x94\x2e\x38\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd', (0x02d9e6d5L, 0x9467, 0x382e, 0x8f, 0x9b, 0x9300a64ac3cdL), 0x02d9e6d59467382e8f9b9300a64ac3cdL, 'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd', @@ -46,6 +49,7 @@ '{12345678-1234-5678-1234-567812345678}', '12345678123456781234567812345678', '\x12\x34\x56\x78'*4, + '\x78\x56\x34\x12\x34\x12\x78\x56\x12\x34\x56\x78\x12\x34\x56\x78', (0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678), 0x12345678123456781234567812345678, 'urn:uuid:12345678-1234-5678-1234-567812345678', @@ -54,6 +58,7 @@ '{6ba7b810-9dad-11d1-80b4-00c04fd430c8}', '6ba7b8109dad11d180b400c04fd430c8', '\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', + '\x10\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', (0x6ba7b810L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L), 0x6ba7b8109dad11d180b400c04fd430c8L, 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8', @@ -62,6 +67,7 @@ '{6ba7b811-9dad-11d1-80b4-00c04fd430c8}', '6ba7b8119dad11d180b400c04fd430c8', '\x6b\xa7\xb8\x11\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', + '\x11\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', (0x6ba7b811L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L), 0x6ba7b8119dad11d180b400c04fd430c8L, 'urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8', @@ -70,6 +76,7 @@ '{6ba7b812-9dad-11d1-80b4-00c04fd430c8}', '6ba7b8129dad11d180b400c04fd430c8', '\x6b\xa7\xb8\x12\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', + '\x12\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', (0x6ba7b812L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L), 0x6ba7b8129dad11d180b400c04fd430c8L, 'urn:uuid:6ba7b812-9dad-11d1-80b4-00c04fd430c8', @@ -78,6 +85,7 @@ '{6ba7b814-9dad-11d1-80b4-00c04fd430c8}', '6ba7b8149dad11d180b400c04fd430c8', '\x6b\xa7\xb8\x14\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', + '\x14\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8', (0x6ba7b814L, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8L), 0x6ba7b8149dad11d180b400c04fd430c8L, 'urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8', @@ -86,6 +94,7 @@ '{7d444840-9dc0-11d1-b245-5ffdce74fad2}', '7d4448409dc011d1b2455ffdce74fad2', '\x7d\x44\x48\x40\x9d\xc0\x11\xd1\xb2\x45\x5f\xfd\xce\x74\xfa\xd2', + '\x40\x48\x44\x7d\xc0\x9d\xd1\x11\xb2\x45\x5f\xfd\xce\x74\xfa\xd2', (0x7d444840L, 0x9dc0, 0x11d1, 0xb2, 0x45, 0x5ffdce74fad2L), 0x7d4448409dc011d1b2455ffdce74fad2L, 'urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2', @@ -94,6 +103,7 @@ '{e902893a-9d22-3c7e-a7b8-d6e313b71d9f}', 'e902893a9d223c7ea7b8d6e313b71d9f', '\xe9\x02\x89\x3a\x9d\x22\x3c\x7e\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f', + '\x3a\x89\x02\xe9\x22\x9d\x7e\x3c\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f', (0xe902893aL, 0x9d22, 0x3c7e, 0xa7, 0xb8, 0xd6e313b71d9fL), 0xe902893a9d223c7ea7b8d6e313b71d9fL, 'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f', @@ -102,6 +112,7 @@ '{eb424026-6f54-4ef8-a4d0-bb658a1fc6cf}', 'eb4240266f544ef8a4d0bb658a1fc6cf', '\xeb\x42\x40\x26\x6f\x54\x4e\xf8\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf', + '\x26\x40\x42\xeb\x54\x6f\xf8\x4e\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf', (0xeb424026L, 0x6f54, 0x4ef8, 0xa4, 0xd0, 0xbb658a1fc6cfL), 0xeb4240266f544ef8a4d0bb658a1fc6cfL, 'urn:uuid:eb424026-6f54-4ef8-a4d0-bb658a1fc6cf', @@ -110,6 +121,7 @@ '{f81d4fae-7dec-11d0-a765-00a0c91e6bf6}', 'f81d4fae7dec11d0a76500a0c91e6bf6', '\xf8\x1d\x4f\xae\x7d\xec\x11\xd0\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6', + '\xae\x4f\x1d\xf8\xec\x7d\xd0\x11\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6', (0xf81d4faeL, 0x7dec, 0x11d0, 0xa7, 0x65, 0x00a0c91e6bf6L), 0xf81d4fae7dec11d0a76500a0c91e6bf6L, 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6', @@ -118,6 +130,7 @@ '{fffefdfc-fffe-fffe-fffe-fffefdfcfbfa}', 'fffefdfcfffefffefffefffefdfcfbfa', '\xff\xfe\xfd\xfc\xff\xfe\xff\xfe\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa', + '\xfc\xfd\xfe\xff\xfe\xff\xfe\xff\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa', (0xfffefdfcL, 0xfffe, 0xfffe, 0xff, 0xfe, 0xfffefdfcfbfaL), 0xfffefdfcfffefffefffefffefdfcfbfaL, 'urn:uuid:fffefdfc-fffe-fffe-fffe-fffefdfcfbfa', @@ -126,6 +139,7 @@ '{ffffffff-ffff-ffff-ffff-ffffffffffff}', 'ffffffffffffffffffffffffffffffff', '\xff'*16, + '\xff'*16, (0xffffffffL, 0xffffL, 0xffffL, 0xff, 0xff, 0xffffffffffffL), 0xffffffffffffffffffffffffffffffffL, 'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff', @@ -134,12 +148,14 @@ equivalents = [] # Construct each UUID in several different ways. for u in [uuid.UUID(string), uuid.UUID(curly), uuid.UUID(hex), - uuid.UUID(bytes=bytes), uuid.UUID(fields=fields), - uuid.UUID(int=integer), uuid.UUID(urn)]: + uuid.UUID(bytes=bytes), uuid.UUID(bytes_le=bytes_le), + uuid.UUID(fields=fields), uuid.UUID(int=integer), + uuid.UUID(urn)]: # Test all conversions and properties of the UUID object. equal(str(u), string) equal(int(u), integer) equal(u.bytes, bytes) + equal(u.bytes_le, bytes_le) equal(u.fields, fields) equal(u.time_low, fields[0]) equal(u.time_mid, fields[1]) @@ -189,6 +205,11 @@ badvalue(lambda: uuid.UUID(bytes='\0'*15)) badvalue(lambda: uuid.UUID(bytes='\0'*17)) + # Badly formed bytes_le. + badvalue(lambda: uuid.UUID(bytes_le='abc')) + badvalue(lambda: uuid.UUID(bytes_le='\0'*15)) + badvalue(lambda: uuid.UUID(bytes_le='\0'*17)) + # Badly formed fields. badvalue(lambda: uuid.UUID(fields=(1,))) badvalue(lambda: uuid.UUID(fields=(1, 2, 3, 4, 5))) @@ -221,51 +242,43 @@ uuid.UUID(h) uuid.UUID(hex=h) uuid.UUID(bytes=b) + uuid.UUID(bytes_le=b) uuid.UUID(fields=f) uuid.UUID(int=i) # Wrong number of arguments (positional). badtype(lambda: uuid.UUID()) badtype(lambda: uuid.UUID(h, b)) - badtype(lambda: uuid.UUID(h, b, f)) - badtype(lambda: uuid.UUID(h, b, f, i)) - - # Duplicate arguments (named). - badtype(lambda: uuid.UUID(hex=h, bytes=b)) - badtype(lambda: uuid.UUID(hex=h, fields=f)) - badtype(lambda: uuid.UUID(hex=h, int=i)) - badtype(lambda: uuid.UUID(bytes=b, fields=f)) - badtype(lambda: uuid.UUID(bytes=b, int=i)) - badtype(lambda: uuid.UUID(fields=f, int=i)) - badtype(lambda: uuid.UUID(hex=h, bytes=b, fields=f)) - badtype(lambda: uuid.UUID(hex=h, bytes=b, int=i)) - badtype(lambda: uuid.UUID(hex=h, fields=f, int=i)) - badtype(lambda: uuid.UUID(bytes=b, int=i, fields=f)) - badtype(lambda: uuid.UUID(hex=h, bytes=b, int=i, fields=f)) - - # Duplicate arguments (positional and named). - badtype(lambda: uuid.UUID(h, hex=h)) - badtype(lambda: uuid.UUID(h, bytes=b)) - badtype(lambda: uuid.UUID(h, fields=f)) - badtype(lambda: uuid.UUID(h, int=i)) - badtype(lambda: uuid.UUID(h, hex=h, bytes=b)) - badtype(lambda: uuid.UUID(h, hex=h, fields=f)) - badtype(lambda: uuid.UUID(h, hex=h, int=i)) - badtype(lambda: uuid.UUID(h, bytes=b, fields=f)) - badtype(lambda: uuid.UUID(h, bytes=b, int=i)) - badtype(lambda: uuid.UUID(h, fields=f, int=i)) - badtype(lambda: uuid.UUID(h, hex=h, bytes=b, fields=f)) - badtype(lambda: uuid.UUID(h, hex=h, bytes=b, int=i)) - badtype(lambda: uuid.UUID(h, hex=h, fields=f, int=i)) - badtype(lambda: uuid.UUID(h, bytes=b, int=i, fields=f)) - badtype(lambda: uuid.UUID(h, hex=h, bytes=b, int=i, fields=f)) + badtype(lambda: uuid.UUID(h, b, b)) + badtype(lambda: uuid.UUID(h, b, b, f)) + badtype(lambda: uuid.UUID(h, b, b, f, i)) + + # Duplicate arguments. + for hh in [[], [('hex', h)]]: + for bb in [[], [('bytes', b)]]: + for bble in [[], [('bytes_le', b)]]: + for ii in [[], [('int', i)]]: + for ff in [[], [('fields', f)]]: + args = dict(hh + bb + bble + ii + ff) + if len(args) != 0: + badtype(lambda: uuid.UUID(h, **args)) + if len(args) != 1: + badtype(lambda: uuid.UUID(**args)) # Immutability. u = uuid.UUID(h) badtype(lambda: setattr(u, 'hex', h)) badtype(lambda: setattr(u, 'bytes', b)) + badtype(lambda: setattr(u, 'bytes_le', b)) badtype(lambda: setattr(u, 'fields', f)) badtype(lambda: setattr(u, 'int', i)) + badtype(lambda: setattr(u, 'time_low', 0)) + badtype(lambda: setattr(u, 'time_mid', 0)) + badtype(lambda: setattr(u, 'time_hi_version', 0)) + badtype(lambda: setattr(u, 'time_hi_version', 0)) + badtype(lambda: setattr(u, 'clock_seq_hi_variant', 0)) + badtype(lambda: setattr(u, 'clock_seq_low', 0)) + badtype(lambda: setattr(u, 'node', 0)) def check_node(self, node, source): individual_group_bit = (node >> 40L) & 1 @@ -356,11 +369,17 @@ def test_uuid1(self): equal = self.assertEqual - # Make sure uuid4() generates UUIDs that are actually version 1. + # Make sure uuid1() generates UUIDs that are actually version 1. for u in [uuid.uuid1() for i in range(10)]: equal(u.variant, uuid.RFC_4122) equal(u.version, 1) + # Make sure the generated UUIDs are actually unique. + uuids = {} + for u in [uuid.uuid1() for i in range(1000)]: + uuids[u] = 1 + equal(len(uuids.keys()), 1000) + # Make sure the supplied node ID appears in the UUID. u = uuid.uuid1(0) equal(u.node, 0) @@ -408,6 +427,12 @@ equal(u.variant, uuid.RFC_4122) equal(u.version, 4) + # Make sure the generated UUIDs are actually unique. + uuids = {} + for u in [uuid.uuid1() for i in range(1000)]: + uuids[u] = 1 + equal(len(uuids.keys()), 1000) + def test_uuid5(self): equal = self.assertEqual Modified: stackless/trunk/Lib/test/test_xml_etree_c.py ============================================================================== --- stackless/trunk/Lib/test/test_xml_etree_c.py (original) +++ stackless/trunk/Lib/test/test_xml_etree_c.py Mon Aug 21 11:10:05 2006 @@ -204,6 +204,17 @@ "" % encoding ) +def bug_1534630(): + """ + >>> bob = ET.TreeBuilder() + >>> e = bob.data("data") + >>> e = bob.start("tag", {}) + >>> e = bob.end("tag") + >>> e = bob.close() + >>> serialize(ET, e) + '' + """ + def test_main(): from test import test_xml_etree_c test_support.run_doctest(test_xml_etree_c, verbosity=True) Modified: stackless/trunk/Lib/tokenize.py ============================================================================== --- stackless/trunk/Lib/tokenize.py (original) +++ stackless/trunk/Lib/tokenize.py Mon Aug 21 11:10:05 2006 @@ -273,7 +273,8 @@ while column < indents[-1]: if column not in indents: raise IndentationError( - "unindent does not match any outer indentation level") + "unindent does not match any outer indentation level", + ("", lnum, pos, line)) indents = indents[:-1] yield (DEDENT, '', (lnum, pos), (lnum, pos), line) Modified: stackless/trunk/Lib/trace.py ============================================================================== --- stackless/trunk/Lib/trace.py (original) +++ stackless/trunk/Lib/trace.py Mon Aug 21 11:10:05 2006 @@ -179,9 +179,11 @@ # looking in sys.path for the longest matching prefix. We'll # assume that the rest is the package name. + comparepath = os.path.normcase(path) longest = "" for dir in sys.path: - if path.startswith(dir) and path[len(dir)] == os.path.sep: + dir = os.path.normcase(dir) + if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep: if len(dir) > len(longest): longest = dir Modified: stackless/trunk/Lib/traceback.py ============================================================================== --- stackless/trunk/Lib/traceback.py (original) +++ stackless/trunk/Lib/traceback.py Mon Aug 21 11:10:05 2006 @@ -202,10 +202,11 @@ def _format_final_exc_line(etype, value): """Return a list of a single line -- normal case for format_exception_only""" - if value is None or not str(value): + valuestr = _some_str(value) + if value is None or not valuestr: line = "%s\n" % etype else: - line = "%s: %s\n" % (etype, _some_str(value)) + line = "%s: %s\n" % (etype, valuestr) return line def _some_str(value): Modified: stackless/trunk/Lib/uuid.py ============================================================================== --- stackless/trunk/Lib/uuid.py (original) +++ stackless/trunk/Lib/uuid.py Mon Aug 21 11:10:05 2006 @@ -45,8 +45,6 @@ """ __author__ = 'Ka-Ping Yee ' -__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-') -__version__ = '$Revision: 1.30 $'.split()[1] RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ 'reserved for NCS compatibility', 'specified in RFC 4122', @@ -57,15 +55,21 @@ UUID objects are immutable, hashable, and usable as dictionary keys. Converting a UUID to a string with str() yields something in the form '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts - four possible forms: a similar string of hexadecimal digits, or a - string of 16 raw bytes as an argument named 'bytes', or a tuple of - six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and - 48-bit values respectively) as an argument named 'fields', or a single - 128-bit integer as an argument named 'int'. + five possible forms: a similar string of hexadecimal digits, or a tuple + of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and + 48-bit values respectively) as an argument named 'fields', or a string + of 16 bytes (with all the integer fields in big-endian order) as an + argument named 'bytes', or a string of 16 bytes (with the first three + fields in little-endian order) as an argument named 'bytes_le', or a + single 128-bit integer as an argument named 'int'. UUIDs have these read-only attributes: - bytes the UUID as a 16-byte string + bytes the UUID as a 16-byte string (containing the six + integer fields in big-endian byte order) + + bytes_le the UUID as a 16-byte string (with time_low, time_mid, + and time_hi_version in little-endian byte order) fields a tuple of the six integer fields of the UUID, which are also available as six individual attributes @@ -94,10 +98,11 @@ when the variant is RFC_4122) """ - def __init__(self, hex=None, bytes=None, fields=None, int=None, - version=None): + def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, + int=None, version=None): r"""Create a UUID from either a string of 32 hexadecimal digits, - a string of 16 bytes as the 'bytes' argument, a tuple of six + a string of 16 bytes as the 'bytes' argument, a string of 16 bytes + in little-endian order as the 'bytes_le' argument, a tuple of six integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version, 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as the 'fields' argument, or a single 128-bit integer as the 'int' @@ -109,23 +114,31 @@ UUID('12345678123456781234567812345678') UUID('urn:uuid:12345678-1234-5678-1234-567812345678') UUID(bytes='\x12\x34\x56\x78'*4) + UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' + + '\x12\x34\x56\x78\x12\x34\x56\x78') UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)) UUID(int=0x12345678123456781234567812345678) - Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given. - The 'version' argument is optional; if given, the resulting UUID - will have its variant and version number set according to RFC 4122, - overriding bits in the given 'hex', 'bytes', 'fields', or 'int'. + Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must + be given. The 'version' argument is optional; if given, the resulting + UUID will have its variant and version set according to RFC 4122, + overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. """ - if [hex, bytes, fields, int].count(None) != 3: - raise TypeError('need just one of hex, bytes, fields, or int') + if [hex, bytes, bytes_le, fields, int].count(None) != 4: + raise TypeError('need one of hex, bytes, bytes_le, fields, or int') if hex is not None: hex = hex.replace('urn:', '').replace('uuid:', '') hex = hex.strip('{}').replace('-', '') if len(hex) != 32: raise ValueError('badly formed hexadecimal UUID string') int = long(hex, 16) + if bytes_le is not None: + if len(bytes_le) != 16: + raise ValueError('bytes_le is not a 16-char string') + bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + + bytes_le[8:]) if bytes is not None: if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') @@ -194,6 +207,13 @@ bytes = property(get_bytes) + def get_bytes_le(self): + bytes = self.bytes + return (bytes[3] + bytes[2] + bytes[1] + bytes[0] + + bytes[5] + bytes[4] + bytes[7] + bytes[6] + bytes[8:]) + + bytes_le = property(get_bytes_le) + def get_fields(self): return (self.time_low, self.time_mid, self.time_hi_version, self.clock_seq_hi_variant, self.clock_seq_low, self.node) @@ -448,6 +468,8 @@ if _node is not None: return _node +_last_timestamp = None + def uuid1(node=None, clock_seq=None): """Generate a UUID from a host ID, sequence number, and the current time. If 'node' is not given, getnode() is used to obtain the hardware @@ -460,11 +482,15 @@ _uuid_generate_time(_buffer) return UUID(bytes=_buffer.raw) + global _last_timestamp import time nanoseconds = int(time.time() * 1e9) # 0x01b21dd213814000 is the number of 100-ns intervals between the # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. timestamp = int(nanoseconds/100) + 0x01b21dd213814000L + if timestamp == _last_timestamp: + timestamp += 1 + _last_timestamp = timestamp if clock_seq is None: import random clock_seq = random.randrange(1<<14L) # instead of stable storage Modified: stackless/trunk/Lib/webbrowser.py ============================================================================== --- stackless/trunk/Lib/webbrowser.py (original) +++ stackless/trunk/Lib/webbrowser.py Mon Aug 21 11:10:05 2006 @@ -434,13 +434,13 @@ # The default Gnome browser if _iscommand("gconftool-2"): # get the web browser string from gconftool - gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command' + gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command 2>/dev/null' out = os.popen(gc) commd = out.read().strip() retncode = out.close() # if successful, register it - if retncode == None and len(commd) != 0: + if retncode is None and commd: register("gnome", None, BackgroundBrowser(commd)) # First, the Mozilla/Netscape browsers Modified: stackless/trunk/Misc/ACKS ============================================================================== --- stackless/trunk/Misc/ACKS (original) +++ stackless/trunk/Misc/ACKS Mon Aug 21 11:10:05 2006 @@ -412,6 +412,7 @@ Michael McLay Gordon McMillan Jay T. Miller +Chris McDonough Andrew McNamara Caolan McNamara Craig McPheeters Modified: stackless/trunk/Misc/NEWS ============================================================================== --- stackless/trunk/Misc/NEWS (original) +++ stackless/trunk/Misc/NEWS Mon Aug 21 11:10:05 2006 @@ -4,6 +4,173 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 2.5 release candidate 1? +============================================= + +*Release date: 17-AUG-2006* + +Core and builtins +----------------- + +- Unicode objects will no longer raise an exception when being + compared equal or unequal to a string and a UnicodeDecodeError + exception occurs, e.g. as result of a decoding failure. + + Instead, the equal (==) and unequal (!=) comparison operators will + now issue a UnicodeWarning and interpret the two objects as + unequal. The UnicodeWarning can be filtered as desired using + the warning framework, e.g. silenced completely, turned into an + exception, logged, etc. + + Note that compare operators other than equal and unequal will still + raise UnicodeDecodeError exceptions as they've always done. + +- Fix segfault when doing string formatting on subclasses of long. + +- Fix bug related to __len__ functions using values > 2**32 on 64-bit machines + with new-style classes. + +- Fix bug related to __len__ functions returning negative values with + classic classes. + +- Patch #1538606, Fix __index__() clipping. There were some problems + discovered with the API and how integers that didn't fit into Py_ssize_t + were handled. This patch attempts to provide enough alternatives + to effectively use __index__. + +- Bug #1536021: __hash__ may now return long int; the final hash + value is obtained by invoking hash on the long int. + +- Bug #1536786: buffer comparison could emit a RuntimeWarning. + +- Bug #1535165: fixed a segfault in input() and raw_input() when + sys.stdin is closed. + +- On Windows, the PyErr_Warn function is now exported from + the Python dll again. + +- Bug #1191458: tracing over for loops now produces a line event + on each iteration. Fixing this problem required changing the .pyc + magic number. This means that .pyc files generated before 2.5c1 + will be regenerated. + +- Bug #1333982: string/number constants were inappropriately stored + in the byte code and co_consts even if they were not used, ie + immediately popped off the stack. + +- Fixed a reference-counting problem in property(). + + +Library +------- + +- Fix a bug in the ``compiler`` package that caused invalid code to be + generated for generator expressions. + +- The distutils version has been changed to 2.5.0. The change to + keep it programmatically in sync with the Python version running + the code (introduced in 2.5b3) has been reverted. It will continue + to be maintained manually as static string literal. + +- If the Python part of a ctypes callback function returns None, + and this cannot be converted to the required C type, an exception is + printed with PyErr_WriteUnraisable. Before this change, the C + callback returned arbitrary values to the calling code. + +- The __repr__ method of a NULL ctypes.py_object() no longer raises + an exception. + +- uuid.UUID now has a bytes_le attribute. This returns the UUID in + little-endian byte order for Windows. In addition, uuid.py gained some + workarounds for clocks with low resolution, to stop the code yielding + duplicate UUIDs. + +- Patch #1540892: site.py Quitter() class attempts to close sys.stdin + before raising SystemExit, allowing IDLE to honor quit() and exit(). + +- Bug #1224621: make tabnanny recognize IndentationErrors raised by tokenize. + +- Patch #1536071: trace.py should now find the full module name of a + file correctly even on Windows. + +- logging's atexit hook now runs even if the rest of the module has + already been cleaned up. + +- Bug #1112549, fix DoS attack on cgi.FieldStorage. + +- Bug #1531405, format_exception no longer raises an exception if + str(exception) raised an exception. + +- Fix a bug in the ``compiler`` package that caused invalid code to be + generated for nested functions. + + +Extension Modules +----------------- + +- Patch #1511317: don't crash on invalid hostname (alias) info. + +- Patch #1535500: fix segfault in BZ2File.writelines and make sure it + raises the correct exceptions. + +- Patch # 1536908: enable building ctypes on OpenBSD/AMD64. The + '-no-stack-protector' compiler flag for OpenBSD has been removed. + +- Patch #1532975 was applied, which fixes Bug #1533481: ctypes now + uses the _as_parameter_ attribute when objects are passed to foreign + function calls. The ctypes version number was changed to 1.0.1. + +- Bug #1530559, struct.pack raises TypeError where it used to convert. + Passing float arguments to struct.pack when integers are expected + now triggers a DeprecationWarning. + + +Tests +----- + +- test_socketserver should now work on cygwin and not fail sporadically + on other platforms. + +- test_mailbox should now work on cygwin versions 2006-08-10 and later. + +- Bug #1535182: really test the xreadlines() method of bz2 objects. + +- test_threading now skips testing alternate thread stack sizes on + platforms that don't support changing thread stack size. + + +Documentation +------------- + +- Patch #1534922: unittest docs were corrected and enhanced. + + +Build +----- + +- Bug #1535502, build _hashlib on Windows, and use masm assembler + code in OpenSSL. + +- Bug #1534738, win32 debug version of _msi should be _msi_d.pyd. + +- Bug #1530448, ctypes build failure on Solaris 10 was fixed. + + +C API +----- + +- New API for Unicode rich comparisons: PyUnicode_RichCompare() + +- Bug #1069160. Internal correctness changes were made to + ``PyThreadState_SetAsyncExc()``. A test case was added, and + the documentation was changed to state that the return value + is always 1 (normal) or 0 (if the specified thread wasn't found). + + +Mac +--- + + What's New in Python 2.5 beta 3? ================================ @@ -12,7 +179,7 @@ Core and builtins ----------------- -- _PyWeakref_GetWeakrefCount() now returns a Py_ssize_t, it previously +- _PyWeakref_GetWeakrefCount() now returns a Py_ssize_t; it previously returned a long (see PEP 353). - Bug #1515471: string.replace() accepts character buffers again. @@ -51,10 +218,10 @@ - Bug #1520864: unpacking singleton tuples in a 'for' loop (for x, in) works again. Fixing this problem required changing the .pyc magic number. - This means that .pyc files generated before 2.5c1 will be regenerated. + This means that .pyc files generated before 2.5b3 will be regenerated. - Bug #1524317: Compiling Python ``--without-threads`` failed. - The Python core compiles again then, and, in a build without threads, the + The Python core compiles again, and, in a build without threads, the new ``sys._current_frames()`` returns a dictionary with one entry, mapping the faux "thread id" 0 to the current frame. @@ -70,14 +237,14 @@ - os.urandom no longer masks unrelated exceptions like SystemExit or KeyboardInterrupt. -- Bug #1525866: Don't copy directory stat times in +- Bug #1525866: Don't copy directory stat times in shutil.copytree on Windows - Bug #1002398: The documentation for os.path.sameopenfile now correctly refers to file descriptors, not file objects. -- Rename of the xml package to xmlcore, and the import hackery done to - make it appear at both names, has been removed. Bug #1511497, +- The renaming of the xml package to xmlcore, and the import hackery done + to make it appear at both names, has been removed. Bug #1511497, #1513611, and probably others. - Bug #1441397: The compiler module now recognizes module and function @@ -89,7 +256,7 @@ side effects from one test to the next affect outcomes. ``DocTestFinder`` has been changed to sort the list of tests it returns. -- The distutils version has been changed to 2.5.0, and are now kept +- The distutils version has been changed to 2.5.0, and is now kept in sync with sys.version_info[:3]. - Bug #978833: Really close underlying socket in _socketobject.close. @@ -203,7 +370,7 @@ - Bug #1527397: PythonLauncher now launches scripts with the working directory set to the directory that contains the script instead of the user home - directory. That latter was an implementation accident and not what users + directory. That latter was an implementation accident and not what users expect. @@ -376,6 +543,7 @@ - Patch #1504046: Add documentation for xml.etree. + What's New in Python 2.5 beta 1? ================================ Modified: stackless/trunk/Misc/PURIFY.README ============================================================================== --- stackless/trunk/Misc/PURIFY.README (original) +++ stackless/trunk/Misc/PURIFY.README Mon Aug 21 11:10:05 2006 @@ -1,6 +1,6 @@ Purify (tm) and Quantify (tm) are commercial software quality -assurance tools available from Rational Software Corporation -. Purify is essentially a memory access +assurance tools available from IBM . +Purify is essentially a memory access verifier and leak detector; Quantify is a C level profiler. The rest of this file assumes you generally know how to use Purify and Quantify, and that you have installed valid licenses for these @@ -20,6 +20,17 @@ make PURIFY=quantify +Starting with Python 2.3, pymalloc is enabled by default. This +will cause many supurious warnings. Modify Objects/obmalloc.c +and enable Py_USING_MEMORY_DEBUGGER by uncommenting it. +README.valgrind has more details about why this is necessary. +See below about setting up suppressions. Some tests may not +run well with Purify due to heavy memory or CPU usage. These +tests may include: test_largefile, test_import, and test_long. + +Please report any findings (problems or no warnings) to python-dev at python.org. +It may be useful to submit a bug report for any problems. + When running the regression test (make test), I have found it useful to set my PURIFYOPTIONS environment variable using the following (bash) shell function. Check out the Purify documentation for @@ -52,6 +63,11 @@ suppress umr ...; "nismodule.c" suppress umr ...; "pwdmodule.c" +Note: this list is very old and may not be accurate any longer. +It's possible some of these no longer need to be suppressed. +You will also need to suppress warnings (at least umr) +from Py_ADDRESS_IN_RANGE. + This will still leave you with just a few UMR, mostly in the readline library, which you can safely ignore. A lot of work has gone into Python 1.5 to plug as many leaks as possible. Modified: stackless/trunk/Misc/README.klocwork ============================================================================== --- stackless/trunk/Misc/README.klocwork (original) +++ stackless/trunk/Misc/README.klocwork Mon Aug 21 11:10:05 2006 @@ -23,4 +23,8 @@ False positives were also annotated so that the comments can be reviewed and reversed if the analysis was incorrect. +A second run was performed on 10-Aug-2006. The tool was tuned to remove +some false positives and perform some additional checks. ~150 new +warnings were produced, primarily related to dereferencing NULL pointers. + Contact python-dev at python.org for more information. Modified: stackless/trunk/Misc/RPM/python-2.5.spec ============================================================================== --- stackless/trunk/Misc/RPM/python-2.5.spec (original) +++ stackless/trunk/Misc/RPM/python-2.5.spec Mon Aug 21 11:10:05 2006 @@ -33,7 +33,7 @@ ################################# %define name python -%define version 2.5b3 +%define version 2.5c1 %define libvers 2.5 %define release 1pydotorg %define __prefix /usr Modified: stackless/trunk/Modules/Setup.dist ============================================================================== --- stackless/trunk/Modules/Setup.dist (original) +++ stackless/trunk/Modules/Setup.dist Mon Aug 21 11:10:05 2006 @@ -59,7 +59,7 @@ # # In addition, *static* explicitly declares the following modules to # be static. Lines containing "*static*" and "*shared*" may thus -# alternate thoughout this file. +# alternate throughout this file. # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules @@ -234,16 +234,19 @@ #rgbimg rgbimgmodule.c # Read SGI RGB image files (but coded portably) -# The md5 module implements the RSA Data Security, Inc. MD5 +# Note that the _md5 and _sha modules are normally only built if the +# system does not have the OpenSSL libs containing an optimized version. + +# The _md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5.c and md5.h are included here. -#md5 md5module.c md5.c +#_md5 md5module.c md5.c -# The sha module implements the SHA checksum algorithm. +# The _sha module implements the SHA checksum algorithm. # (NIST's Secure Hash Algorithm.) -#sha shamodule.c +#_sha shamodule.c # SGI IRIX specific modules -- off by default. Modified: stackless/trunk/Modules/_bsddb.c ============================================================================== --- stackless/trunk/Modules/_bsddb.c (original) +++ stackless/trunk/Modules/_bsddb.c Mon Aug 21 11:10:05 2006 @@ -1797,7 +1797,6 @@ DBC** cursors; DBC* dbc; - if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags)) return NULL; @@ -1811,6 +1810,11 @@ length = PyObject_Length(cursorsObj); cursors = malloc((length+1) * sizeof(DBC*)); + if (!cursors) { + PyErr_NoMemory(); + return NULL; + } + cursors[length] = NULL; for (x=0; xdb->verify(self->db, fileName, dbName, outFile, flags); MYDB_END_ALLOW_THREADS; - if (outFileName) + if (outFile) fclose(outFile); /* DB.verify acts as a DB handle destructor (like close); this was Modified: stackless/trunk/Modules/_codecsmodule.c ============================================================================== --- stackless/trunk/Modules/_codecsmodule.c (original) +++ stackless/trunk/Modules/_codecsmodule.c Mon Aug 21 11:10:05 2006 @@ -192,7 +192,8 @@ buf = PyString_AS_STRING (str); len = PyString_GET_SIZE (str); memmove(buf, buf+1, len-2); - _PyString_Resize(&str, len-2); + if (_PyString_Resize(&str, len-2) < 0) + return NULL; return codec_tuple(str, PyString_Size(str)); } Modified: stackless/trunk/Modules/_ctypes/_ctypes.c ============================================================================== --- stackless/trunk/Modules/_ctypes/_ctypes.c (original) +++ stackless/trunk/Modules/_ctypes/_ctypes.c Mon Aug 21 11:10:05 2006 @@ -140,6 +140,31 @@ accessible fields somehow. */ +static PyCArgObject * +StructUnionType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + StgDictObject *stgdict; + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = 'V'; + stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for structure/union instances */ + parg->pffi_type = &stgdict->ffi_type_pointer; + /* For structure parameters (by value), parg->value doesn't contain the structure + data itself, instead parg->value.p *points* to the structure's data + See also _ctypes.c, function _call_function_pointer(). + */ + parg->value.p = self->b_ptr; + parg->size = self->b_size; + Py_INCREF(self); + parg->obj = (PyObject *)self; + return parg; +} + static PyObject * StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct) { @@ -172,6 +197,8 @@ Py_DECREF(result->tp_dict); result->tp_dict = (PyObject *)dict; + dict->paramfunc = StructUnionType_paramfunc; + fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); if (!fields) { StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); @@ -287,6 +314,7 @@ static PyObject * CDataType_from_param(PyObject *type, PyObject *value) { + PyObject *as_parameter; if (1 == PyObject_IsInstance(value, type)) { Py_INCREF(value); return value; @@ -300,7 +328,6 @@ /* If we got a PyCArgObject, we must check if the object packed in it is an instance of the type's dict->proto */ -// if(dict && ob && dict->proto == (PyObject *)ob->ob_type){ if(dict && ob && PyObject_IsInstance(ob, dict->proto)) { Py_INCREF(value); @@ -330,6 +357,13 @@ } /* ... and leave the rest */ #endif + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = CDataType_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } PyErr_Format(PyExc_TypeError, "expected %s instance instead of %s", ((PyTypeObject *)type)->tp_name, @@ -540,6 +574,23 @@ return 0; } +static PyCArgObject * +PointerType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(self); + parg->obj = (PyObject *)self; + parg->value.p = *(void **)self->b_ptr; + return parg; +} + static PyObject * PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -563,6 +614,7 @@ stgdict->align = getentry("P")->pffi_type->alignment; stgdict->length = 1; stgdict->ffi_type_pointer = ffi_type_pointer; + stgdict->paramfunc = PointerType_paramfunc; proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ if (proto && -1 == PointerType_SetProto(stgdict, proto)) { @@ -640,6 +692,7 @@ the item types are the same. */ StgDictObject *v = PyObject_stgdict(value); + assert(v); /* Cannot be NULL for pointer or array objects */ if (PyObject_IsSubclass(v->proto, typedict->proto)) { Py_INCREF(value); return value; @@ -906,6 +959,19 @@ return 0; } +static PyCArgObject * +ArrayType_paramfunc(CDataObject *self) +{ + PyCArgObject *p = new_CArgObject(); + if (p == NULL) + return NULL; + p->tag = 'P'; + p->pffi_type = &ffi_type_pointer; + p->value.p = (char *)self->b_ptr; + Py_INCREF(self); + p->obj = (PyObject *)self; + return p; +} static PyObject * ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -961,6 +1027,8 @@ Py_INCREF(proto); stgdict->proto = proto; + stgdict->paramfunc = &ArrayType_paramfunc; + /* Arrays are passed as pointers to function calls. */ stgdict->ffi_type_pointer = ffi_type_pointer; @@ -1055,6 +1123,7 @@ static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) { + PyObject *as_parameter; #if (PYTHON_API_VERSION < 1012) # error not supported #endif @@ -1067,6 +1136,8 @@ struct fielddesc *fd = getentry("Z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1083,7 +1154,9 @@ if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_wchar array instance or pointer(c_wchar(...)) */ StgDictObject *dt = PyObject_stgdict(value); - StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; + StgDictObject *dict; + assert(dt); /* Cannot be NULL for pointer or array objects */ + dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == getentry("u")->setfunc)) { Py_INCREF(value); return value; @@ -1098,6 +1171,13 @@ return value; } } + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = c_wchar_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } /* XXX better message */ PyErr_SetString(PyExc_TypeError, "wrong type"); @@ -1107,6 +1187,7 @@ static PyObject * c_char_p_from_param(PyObject *type, PyObject *value) { + PyObject *as_parameter; #if (PYTHON_API_VERSION < 1012) # error not supported #endif @@ -1119,6 +1200,8 @@ struct fielddesc *fd = getentry("z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1135,7 +1218,9 @@ if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_char array instance or pointer(c_char(...)) */ StgDictObject *dt = PyObject_stgdict(value); - StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; + StgDictObject *dict; + assert(dt); /* Cannot be NULL for pointer or array objects */ + dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == getentry("c")->setfunc)) { Py_INCREF(value); return value; @@ -1150,6 +1235,13 @@ return value; } } + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = c_char_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } /* XXX better message */ PyErr_SetString(PyExc_TypeError, "wrong type"); @@ -1160,6 +1252,7 @@ c_void_p_from_param(PyObject *type, PyObject *value) { StgDictObject *stgd; + PyObject *as_parameter; #if (PYTHON_API_VERSION < 1012) # error not supported #endif @@ -1176,6 +1269,8 @@ struct fielddesc *fd = getentry("P"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'P'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1191,6 +1286,8 @@ struct fielddesc *fd = getentry("z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1206,6 +1303,8 @@ struct fielddesc *fd = getentry("Z"); parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; parg->obj = fd->setfunc(&parg->value, value, 0); @@ -1242,6 +1341,8 @@ CFuncPtrObject *func; func = (CFuncPtrObject *)value; parg = new_CArgObject(); + if (parg == NULL) + return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'P'; Py_INCREF(value); @@ -1269,6 +1370,13 @@ return (PyObject *)parg; } } + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = c_void_p_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; + } /* XXX better message */ PyErr_SetString(PyExc_TypeError, "wrong type"); @@ -1355,6 +1463,33 @@ return (PyObject *)result; } +static PyCArgObject * +SimpleType_paramfunc(CDataObject *self) +{ + StgDictObject *dict; + char *fmt; + PyCArgObject *parg; + struct fielddesc *fd; + + dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ + fmt = PyString_AsString(dict->proto); + assert(fmt); + + fd = getentry(fmt); + assert(fd); + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = fmt[0]; + parg->pffi_type = fd->pffi_type; + Py_INCREF(self); + parg->obj = (PyObject *)self; + memcpy(&parg->value, self->b_ptr, self->b_size); + return parg; +} static PyObject * SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -1404,6 +1539,8 @@ stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; + + stgdict->paramfunc = SimpleType_paramfunc; /* if (result->tp_base != &Simple_Type) { stgdict->setfunc = NULL; @@ -1502,23 +1639,6 @@ /* * This is a *class method*. * Convert a parameter into something that ConvParam can handle. - * - * This is either an instance of the requested type, a Python integer, or a - * 'magic' 3-tuple. - * - * (These are somewhat related to Martin v. Loewis 'Enhanced Argument Tuples', - * described in PEP 286.) - * - * The tuple must contain - * - * - a format character, currently 'ifdqc' are understood - * which will inform ConvParam about how to push the argument on the stack. - * - * - a corresponding Python object: i - integer, f - float, d - float, - * q - longlong, c - integer - * - * - any object which can be used to keep the original parameter alive - * as long as the tuple lives. */ static PyObject * SimpleType_from_param(PyObject *type, PyObject *value) @@ -1527,6 +1647,7 @@ char *fmt; PyCArgObject *parg; struct fielddesc *fd; + PyObject *as_parameter; /* If the value is already an instance of the requested type, we can use it as is */ @@ -1552,11 +1673,20 @@ parg->tag = fmt[0]; parg->pffi_type = fd->pffi_type; parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; + if (parg->obj) + return (PyObject *)parg; + PyErr_Clear(); + Py_DECREF(parg); + + as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); + if (as_parameter) { + value = SimpleType_from_param(type, as_parameter); + Py_DECREF(as_parameter); + return value; } - return (PyObject *)parg; + PyErr_SetString(PyExc_TypeError, + "wrong type"); + return NULL; } static PyMethodDef SimpleType_methods[] = { @@ -1721,6 +1851,23 @@ } +static PyCArgObject * +CFuncPtrType_paramfunc(CDataObject *self) +{ + PyCArgObject *parg; + + parg = new_CArgObject(); + if (parg == NULL) + return NULL; + + parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; + Py_INCREF(self); + parg->obj = (PyObject *)self; + parg->value.p = *(void **)self->b_ptr; + return parg; +} + static PyObject * CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1732,6 +1879,8 @@ if (!stgdict) return NULL; + stgdict->paramfunc = CFuncPtrType_paramfunc; + /* create the new instance (which is a class, since we are a metatype!) */ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds); @@ -1921,6 +2070,7 @@ CData_clear(CDataObject *self) { StgDictObject *dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ Py_CLEAR(self->b_objects); if ((self->b_needsfree) && ((size_t)dict->size > sizeof(self->b_value))) @@ -2218,7 +2368,9 @@ StgDictObject *p1, *p2; PyObject *keep; p1 = PyObject_stgdict(value); + assert(p1); /* Cannot be NULL for array instances */ p2 = PyType_stgdict(type); + assert(p2); /* Cannot be NULL for pointer types */ if (p1->proto != p2->proto) { PyErr_Format(PyExc_TypeError, @@ -2308,23 +2460,6 @@ CFuncPtr_Type */ -static PyObject * -CFuncPtr_as_parameter(CDataObject *self) -{ - PyCArgObject *parg; - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; - parg->value.p = *(void **)self->b_ptr; - return (PyObject *)parg; -} - static int CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob) { @@ -2384,7 +2519,7 @@ return self->restype; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); + assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ if (dict->restype) { Py_INCREF(dict->restype); return dict->restype; @@ -2426,7 +2561,7 @@ return self->argtypes; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); + assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ if (dict->argtypes) { Py_INCREF(dict->argtypes); return dict->argtypes; @@ -2444,9 +2579,6 @@ { "argtypes", (getter)CFuncPtr_get_argtypes, (setter)CFuncPtr_set_argtypes, "specify the argument types", NULL }, - { "_as_parameter_", (getter)CFuncPtr_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, { NULL, NULL } }; @@ -2475,6 +2607,8 @@ where n is 0, 4, 8, 12, ..., 128 */ mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ + if (!mangled_name) + return NULL; for (i = 0; i < 32; ++i) { sprintf(mangled_name, "_%s@%d", name, i*4); address = (PPROC)GetProcAddress(handle, mangled_name); @@ -2520,8 +2654,12 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags) { int i, len; - StgDictObject *dict = PyType_stgdict((PyObject *)type); - PyObject *argtypes = dict->argtypes; + StgDictObject *dict; + PyObject *argtypes; + + dict = PyType_stgdict((PyObject *)type); + assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */ + argtypes = dict->argtypes; if (paramflags == NULL || dict->argtypes == NULL) return 1; @@ -2744,6 +2882,8 @@ if (ptr == NULL) return NULL; ob = (CDataObject *)GenericCData_new(type, args, kwds); + if (ob == NULL) + return NULL; *(void **)ob->b_ptr = ptr; return (PyObject *)ob; } @@ -2791,6 +2931,8 @@ return NULL; self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + if (self == NULL) + return NULL; Py_INCREF(callable); self->callable = callable; @@ -3129,7 +3271,7 @@ int outmask; unsigned int numretvals; - assert(dict); /* if not, it's a bug */ + assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ restype = self->restype ? self->restype : dict->restype; converters = self->converters ? self->converters : dict->converters; checker = self->checker ? self->checker : dict->checker; @@ -3349,30 +3491,6 @@ return -1; } -static PyObject * -Struct_as_parameter(CDataObject *self) -{ - PyCArgObject *parg; - StgDictObject *stgdict; - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = 'V'; - stgdict = PyObject_stgdict((PyObject *)self); - parg->pffi_type = &stgdict->ffi_type_pointer; - /* For structure parameters (by value), parg->value doesn't contain the structure - data itself, instead parg->value.p *points* to the structure's data - See also _ctypes.c, function _call_function_pointer(). - */ - parg->value.p = self->b_ptr; - parg->size = self->b_size; - Py_INCREF(self); - parg->obj = (PyObject *)self; - return (PyObject *)parg; -} - static int Struct_init(PyObject *self, PyObject *args, PyObject *kwds) { @@ -3447,13 +3565,6 @@ return 0; } -static PyGetSetDef Struct_getsets[] = { - { "_as_parameter_", (getter)Struct_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, - { NULL, NULL } -}; - static PyTypeObject Struct_Type = { PyObject_HEAD_INIT(NULL) 0, @@ -3485,7 +3596,7 @@ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - Struct_getsets, /* tp_getset */ + 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3528,7 +3639,7 @@ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - Struct_getsets, /* tp_getset */ + 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3581,7 +3692,7 @@ } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); + assert(stgdict); /* Cannot be NULL for array instances */ /* Would it be clearer if we got the item size from stgdict->proto's stgdict? */ @@ -3612,6 +3723,7 @@ len = ihigh - ilow; stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array object instances */ proto = stgdict->proto; itemdict = PyType_stgdict(proto); if (itemdict->getfunc == getentry("c")->getfunc) { @@ -3650,6 +3762,7 @@ } stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL for array object instances */ if (index < 0 || index >= stgdict->length) { PyErr_SetString(PyExc_IndexError, "invalid index"); @@ -3726,26 +3839,6 @@ 0, /* sq_inplace_repeat; */ }; -static PyObject * -Array_as_parameter(CDataObject *self) -{ - PyCArgObject *p = new_CArgObject(); - if (p == NULL) - return NULL; - p->tag = 'P'; - p->pffi_type = &ffi_type_pointer; - p->value.p = (char *)self->b_ptr; - Py_INCREF(self); - p->obj = (PyObject *)self; - return (PyObject *)p; -} - -static PyGetSetDef Array_getsets[] = { - { "_as_parameter_", (getter)Array_as_parameter, - (setter)NULL, "convert to a parameter", NULL }, - { NULL }, -}; - PyTypeObject Array_Type = { PyObject_HEAD_INIT(NULL) 0, @@ -3777,7 +3870,7 @@ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - Array_getsets, /* tp_getset */ + 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3861,6 +3954,7 @@ PyObject *result; StgDictObject *dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ assert(dict->setfunc); result = dict->setfunc(self->b_ptr, value, dict->size); if (!result) @@ -3886,40 +3980,14 @@ { StgDictObject *dict; dict = PyObject_stgdict((PyObject *)self); + assert(dict); /* Cannot be NULL for CDataObject instances */ assert(dict->getfunc); - dict = PyObject_stgdict((PyObject *)self); return dict->getfunc(self->b_ptr, self->b_size); } -static PyObject * -Simple_as_parameter(CDataObject *self) -{ - StgDictObject *dict = PyObject_stgdict((PyObject *)self); - char *fmt = PyString_AsString(dict->proto); - PyCArgObject *parg; - struct fielddesc *fd; - - fd = getentry(fmt); - assert(fd); - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = fmt[0]; - parg->pffi_type = fd->pffi_type; - Py_INCREF(self); - parg->obj = (PyObject *)self; - memcpy(&parg->value, self->b_ptr, self->b_size); - return (PyObject *)parg; -} - static PyGetSetDef Simple_getsets[] = { { "value", (getter)Simple_get_value, (setter)Simple_set_value, "current value", NULL }, - { "_as_parameter_", (getter)Simple_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, { NULL, NULL } }; @@ -4086,11 +4154,10 @@ } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); - assert(stgdict->proto); + assert(stgdict); /* Cannot be NULL for pointer object instances */ proto = stgdict->proto; - /* XXXXXX MAKE SURE PROTO IS NOT NULL! */ + assert(proto); itemdict = PyType_stgdict(proto); size = itemdict->size; offset = index * itemdict->size; @@ -4121,11 +4188,11 @@ } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); - assert(stgdict->proto); + assert(stgdict); /* Cannot be NULL fr pointer instances */ proto = stgdict->proto; - /* XXXXXX MAKE SURE PROTO IS NOT NULL! */ + assert(proto); + itemdict = PyType_stgdict(proto); size = itemdict->size; offset = index * itemdict->size; @@ -4146,7 +4213,7 @@ } stgdict = PyObject_stgdict((PyObject *)self); - assert(stgdict); + assert(stgdict); /* Cannot be NULL fr pointer instances */ return CData_FromBaseObj(stgdict->proto, (PyObject *)self, 0, *(void **)self->b_ptr); @@ -4165,7 +4232,7 @@ return -1; } stgdict = PyObject_stgdict((PyObject *)self); - /* should have been catched in Pointer_new() */ + assert(stgdict); /* Cannot be NULL fr pointer instances */ assert(stgdict->proto); if (!CDataObject_Check(value) || 0 == PyObject_IsInstance(value, stgdict->proto)) { @@ -4194,30 +4261,10 @@ return KeepRef(self, 0, keep); } -static PyObject * -Pointer_as_parameter(CDataObject *self) -{ - PyCArgObject *parg; - - parg = new_CArgObject(); - if (parg == NULL) - return NULL; - - parg->tag = 'P'; - parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; - parg->value.p = *(void **)self->b_ptr; - return (PyObject *)parg; -} - static PyGetSetDef Pointer_getsets[] = { { "contents", (getter)Pointer_get_contents, (setter)Pointer_set_contents, "the object this pointer points to (read-write)", NULL }, - { "_as_parameter_", (getter)Pointer_as_parameter, NULL, - "return a magic value so that this can be converted to a C parameter (readonly)", - NULL }, { NULL, NULL } }; @@ -4261,8 +4308,11 @@ len = ihigh - ilow; stgdict = PyObject_stgdict((PyObject *)self); + assert(stgdict); /* Cannot be NULL fr pointer instances */ proto = stgdict->proto; + assert(proto); itemdict = PyType_stgdict(proto); + assert(itemdict); if (itemdict->getfunc == getentry("c")->getfunc) { char *ptr = *(char **)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); @@ -4678,7 +4728,7 @@ #endif PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL)); PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI)); - PyModule_AddStringConstant(m, "__version__", "1.0.0"); + PyModule_AddStringConstant(m, "__version__", "1.0.1"); PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove)); PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset)); Modified: stackless/trunk/Modules/_ctypes/_ctypes_test.c ============================================================================== --- stackless/trunk/Modules/_ctypes/_ctypes_test.c (original) +++ stackless/trunk/Modules/_ctypes/_ctypes_test.c Mon Aug 21 11:10:05 2006 @@ -197,18 +197,6 @@ #endif -EXPORT(int) _testfunc_ppp(char ***p) -{ - static char message[] = "Hello, World"; - if (p) { - *p = (char **)malloc(sizeof(char *)); - printf("malloc returned %p\n", *p); - **p = message; - return 1; - } - return 0; -} - typedef struct { char *name; char *value; Modified: stackless/trunk/Modules/_ctypes/callbacks.c ============================================================================== --- stackless/trunk/Modules/_ctypes/callbacks.c (original) +++ stackless/trunk/Modules/_ctypes/callbacks.c Mon Aug 21 11:10:05 2006 @@ -205,7 +205,7 @@ result = PyObject_CallObject(callable, arglist); CHECK("'calling callback function'", result); - if ((restype != &ffi_type_void) && result && result != Py_None) { + if ((restype != &ffi_type_void) && result) { PyObject *keep; assert(setfunc); #ifdef WORDS_BIGENDIAN @@ -225,13 +225,13 @@ itself knows how to manage the refcount of these objects. */ if (keep == NULL) /* Could not convert callback result. */ - PyErr_WriteUnraisable(Py_None); + PyErr_WriteUnraisable(callable); else if (keep == Py_None) /* Nothing to keep */ Py_DECREF(keep); else if (setfunc != getentry("O")->setfunc) { if (-1 == PyErr_Warn(PyExc_RuntimeWarning, "memory leak in callback function.")) - PyErr_WriteUnraisable(Py_None); + PyErr_WriteUnraisable(callable); } } Py_XDECREF(result); Modified: stackless/trunk/Modules/_ctypes/callproc.c ============================================================================== --- stackless/trunk/Modules/_ctypes/callproc.c (original) +++ stackless/trunk/Modules/_ctypes/callproc.c Mon Aug 21 11:10:05 2006 @@ -465,7 +465,21 @@ */ static int ConvParam(PyObject *obj, int index, struct argument *pa) { + StgDictObject *dict; pa->keep = NULL; /* so we cannot forget it later */ + + dict = PyObject_stgdict(obj); + if (dict) { + PyCArgObject *carg; + assert(dict->paramfunc); + /* If it has an stgdict, it is a CDataObject */ + carg = dict->paramfunc((CDataObject *)obj); + pa->ffi_type = carg->pffi_type; + memcpy(&pa->value, &carg->value, sizeof(pa->value)); + pa->keep = (PyObject *)carg; + return 0; + } + if (PyCArg_CheckExact(obj)) { PyCArgObject *carg = (PyCArgObject *)obj; pa->ffi_type = carg->pffi_type; @@ -548,25 +562,12 @@ as parameters (they have to expose the '_as_parameter_' attribute) */ - if (arg == 0) { - PyErr_Format(PyExc_TypeError, - "Don't know how to convert parameter %d", index); - return -1; + if (arg) { + int result; + result = ConvParam(arg, index, pa); + Py_DECREF(arg); + return result; } - if (PyCArg_CheckExact(arg)) { - PyCArgObject *carg = (PyCArgObject *)arg; - pa->ffi_type = carg->pffi_type; - memcpy(&pa->value, &carg->value, sizeof(pa->value)); - pa->keep = arg; - return 0; - } - if (PyInt_Check(arg)) { - pa->ffi_type = &ffi_type_sint; - pa->value.i = PyInt_AS_LONG(arg); - pa->keep = arg; - return 0; - } - Py_DECREF(arg); PyErr_Format(PyExc_TypeError, "Don't know how to convert parameter %d", index); return -1; @@ -915,6 +916,10 @@ #endif args = (struct argument *)alloca(sizeof(struct argument) * argcount); + if (!args) { + PyErr_NoMemory(); + return NULL; + } memset(args, 0, sizeof(struct argument) * argcount); argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; #ifdef MS_WIN32 @@ -968,6 +973,10 @@ avalues = (void **)alloca(sizeof(void *) * argcount); atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount); + if (!resbuf || !avalues || !atypes) { + PyErr_NoMemory(); + goto cleanup; + } for (i = 0; i < argcount; ++i) { atypes[i] = args[i].ffi_type; if (atypes[i]->type == FFI_TYPE_STRUCT) @@ -1068,6 +1077,11 @@ return NULL; #ifdef _UNICODE name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR)); + if (!name) { + PyErr_NoMemory(); + return NULL; + } + { int r; char *aname = PyString_AsString(nameobj); Modified: stackless/trunk/Modules/_ctypes/cfield.c ============================================================================== --- stackless/trunk/Modules/_ctypes/cfield.c (original) +++ stackless/trunk/Modules/_ctypes/cfield.c Mon Aug 21 11:10:05 2006 @@ -105,6 +105,12 @@ StgDictObject *idict; if (adict && adict->proto) { idict = PyType_stgdict(adict->proto); + if (!idict) { + PyErr_SetString(PyExc_TypeError, + "has no _stginfo_"); + Py_DECREF(self); + return NULL; + } if (idict->getfunc == getentry("c")->getfunc) { struct fielddesc *fd = getentry("s"); getfunc = fd->getfunc; @@ -1094,7 +1100,7 @@ if (!PyErr_Occurred()) /* Set an error if not yet set */ PyErr_SetString(PyExc_ValueError, - "PyObject is NULL?"); + "PyObject is NULL"); return NULL; } Py_INCREF(ob); Modified: stackless/trunk/Modules/_ctypes/ctypes.h ============================================================================== --- stackless/trunk/Modules/_ctypes/ctypes.h (original) +++ stackless/trunk/Modules/_ctypes/ctypes.h Mon Aug 21 11:10:05 2006 @@ -23,9 +23,11 @@ #define PY_LONG_LONG LONG_LONG #endif +typedef struct tagPyCArgObject PyCArgObject; typedef struct tagCDataObject CDataObject; typedef PyObject *(* GETFUNC)(void *, unsigned size); typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size); +typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj); /* A default buffer in CDataObject, which can be used for small C types. If this buffer is too small, PyMem_Malloc will be called to create a larger one, @@ -205,6 +207,7 @@ PyObject *proto; /* Only for Pointer/ArrayObject */ SETFUNC setfunc; /* Only for simple objects */ GETFUNC getfunc; /* Only for simple objects */ + PARAMFUNC paramfunc; /* Following fields only used by CFuncPtrType_Type instances */ PyObject *argtypes; /* tuple of CDataObjects */ @@ -283,7 +286,7 @@ #define DICTFLAG_FINAL 0x1000 -typedef struct { +struct tagPyCArgObject { PyObject_HEAD ffi_type *pffi_type; char tag; @@ -302,7 +305,7 @@ } value; PyObject *obj; int size; /* for the 'V' tag */ -} PyCArgObject; +}; extern PyTypeObject PyCArg_Type; extern PyCArgObject *new_CArgObject(void); Modified: stackless/trunk/Modules/_ctypes/libffi/configure ============================================================================== --- stackless/trunk/Modules/_ctypes/libffi/configure (original) +++ stackless/trunk/Modules/_ctypes/libffi/configure Mon Aug 21 11:10:05 2006 @@ -3470,6 +3470,7 @@ TARGETDIR="unknown" case "$host" in +x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;; mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;; sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; Modified: stackless/trunk/Modules/_ctypes/libffi/configure.ac ============================================================================== --- stackless/trunk/Modules/_ctypes/libffi/configure.ac (original) +++ stackless/trunk/Modules/_ctypes/libffi/configure.ac Mon Aug 21 11:10:05 2006 @@ -21,6 +21,7 @@ TARGETDIR="unknown" case "$host" in +x86_64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86;; mips*-*-openbsd*) TARGET=MIPS; TARGETDIR=mips;; sparc-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; sparc64-*-openbsd*) TARGET=SPARC; TARGETDIR=sparc;; Modified: stackless/trunk/Modules/_ctypes/libffi/fficonfig.py.in ============================================================================== --- stackless/trunk/Modules/_ctypes/libffi/fficonfig.py.in (original) +++ stackless/trunk/Modules/_ctypes/libffi/fficonfig.py.in Mon Aug 21 11:10:05 2006 @@ -43,6 +43,3 @@ ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources] ffi_cflags = '@CFLAGS@' -# I think this may no longer be needed: -if sys.platform == "openbsd3": - ffi_cflags += " -fno-stack-protector" Modified: stackless/trunk/Modules/_cursesmodule.c ============================================================================== --- stackless/trunk/Modules/_cursesmodule.c (original) +++ stackless/trunk/Modules/_cursesmodule.c Mon Aug 21 11:10:05 2006 @@ -1784,7 +1784,6 @@ PyCurses_InitScr(PyObject *self) { WINDOW *win; - PyObject *nlines, *cols; if (initialised == TRUE) { wrefresh(stdscr); @@ -1803,7 +1802,12 @@ /* This was moved from initcurses() because it core dumped on SGI, where they're not defined until you've called initscr() */ #define SetDictInt(string,ch) \ - PyDict_SetItemString(ModDict,string,PyInt_FromLong((long) (ch))); + do { \ + PyObject *o = PyInt_FromLong((long) (ch)); \ + if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \ + Py_DECREF(o); \ + } \ + } while (0) /* Here are some graphic symbols you can use */ SetDictInt("ACS_ULCORNER", (ACS_ULCORNER)); @@ -1872,12 +1876,8 @@ SetDictInt("ACS_STERLING", (ACS_STERLING)); #endif - nlines = PyInt_FromLong((long) LINES); - PyDict_SetItemString(ModDict, "LINES", nlines); - Py_DECREF(nlines); - cols = PyInt_FromLong((long) COLS); - PyDict_SetItemString(ModDict, "COLS", cols); - Py_DECREF(cols); + SetDictInt("LINES", LINES); + SetDictInt("COLS", COLS); return (PyObject *)PyCursesWindow_New(win); } @@ -2554,6 +2554,8 @@ /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); + if (d == NULL) + return; ModDict = d; /* For PyCurses_InitScr to use later */ /* Add a CObject for the C API */ @@ -2667,6 +2669,10 @@ if (strncmp(key_n,"KEY_F(",6)==0) { char *p1, *p2; key_n2 = malloc(strlen(key_n)+1); + if (!key_n2) { + PyErr_NoMemory(); + break; + } p1 = key_n; p2 = key_n2; while (*p1) { @@ -2679,7 +2685,7 @@ *p2 = (char)0; } else key_n2 = key_n; - PyDict_SetItemString(d,key_n2,PyInt_FromLong((long) key)); + SetDictInt(key_n2,key); if (key_n2 != key_n) free(key_n2); } Modified: stackless/trunk/Modules/_elementtree.c ============================================================================== --- stackless/trunk/Modules/_elementtree.c (original) +++ stackless/trunk/Modules/_elementtree.c Mon Aug 21 11:10:05 2006 @@ -48,7 +48,7 @@ #include "Python.h" -#define VERSION "1.0.6-snapshot" +#define VERSION "1.0.6" /* -------------------------------------------------------------------- */ /* configuration */ @@ -809,7 +809,7 @@ PyObject* text = element_get_text(item); if (text == Py_None) return PyString_FromString(""); - Py_INCREF(text); + Py_XINCREF(text); return text; } } @@ -1599,6 +1599,10 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) { if (!self->data) { + if (self->last == (ElementObject*) Py_None) { + /* ignore calls to data before the first call to start */ + Py_RETURN_NONE; + } /* store the first item as is */ Py_INCREF(data); self->data = data; } else { Modified: stackless/trunk/Modules/_hotshot.c ============================================================================== --- stackless/trunk/Modules/_hotshot.c (original) +++ stackless/trunk/Modules/_hotshot.c Mon Aug 21 11:10:05 2006 @@ -313,6 +313,11 @@ return err; buf = (char *)malloc(len); + if (!buf) { + PyErr_NoMemory(); + return ERR_EXCEPTION; + } + for (i=0; i < len; i++) { ch = fgetc(self->logfp); buf[i] = ch; Modified: stackless/trunk/Modules/_sre.c ============================================================================== --- stackless/trunk/Modules/_sre.c (original) +++ stackless/trunk/Modules/_sre.c Mon Aug 21 11:10:05 2006 @@ -1166,6 +1166,9 @@ /* install new repeat context */ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep)); + /* XXX(nnorwitz): anything else we need to do on error? */ + if (!ctx->u.rep) + RETURN_FAILURE; ctx->u.rep->count = -1; ctx->u.rep->pattern = ctx->pattern; ctx->u.rep->prev = state->repeat; Modified: stackless/trunk/Modules/_struct.c ============================================================================== --- stackless/trunk/Modules/_struct.c (original) +++ stackless/trunk/Modules/_struct.c Mon Aug 21 11:10:05 2006 @@ -31,6 +31,17 @@ static PyObject *pyint_zero = NULL; #endif +/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float + arguments for integer formats with a warning for backwards + compatibility. */ + +#define PY_STRUCT_FLOAT_COERCE 1 + +#ifdef PY_STRUCT_FLOAT_COERCE +#define FLOAT_COERCE "integer argument expected, got float" +#endif + + /* The translation function for each format character is table driven */ typedef struct _formatdef { char format; @@ -135,6 +146,21 @@ { long x = PyInt_AsLong(v); if (x == -1 && PyErr_Occurred()) { +#ifdef PY_STRUCT_FLOAT_COERCE + if (PyFloat_Check(v)) { + PyObject *o; + int res; + PyErr_Clear(); + if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0) + return -1; + o = PyNumber_Int(v); + if (o == NULL) + return -1; + res = get_long(o, p); + Py_DECREF(o); + return res; + } +#endif if (PyErr_ExceptionMatches(PyExc_TypeError)) PyErr_SetString(StructError, "required argument is not an integer"); @@ -225,6 +251,21 @@ PyObject *wrapped; long x; PyErr_Clear(); +#ifdef PY_STRUCT_FLOAT_COERCE + if (PyFloat_Check(v)) { + PyObject *o; + int res; + PyErr_Clear(); + if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0) + return -1; + o = PyNumber_Int(v); + if (o == NULL) + return -1; + res = get_wrapped_long(o, p); + Py_DECREF(o); + return res; + } +#endif if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) return -1; wrapped = PyNumber_And(v, pylong_ulong_mask); @@ -249,6 +290,21 @@ if (x == -1 && PyErr_Occurred()) { PyObject *wrapped; PyErr_Clear(); +#ifdef PY_STRUCT_FLOAT_COERCE + if (PyFloat_Check(v)) { + PyObject *o; + int res; + PyErr_Clear(); + if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0) + return -1; + o = PyNumber_Int(v); + if (o == NULL) + return -1; + res = get_wrapped_ulong(o, p); + Py_DECREF(o); + return res; + } +#endif wrapped = PyNumber_And(v, pylong_ulong_mask); if (wrapped == NULL) return -1; @@ -1815,4 +1871,8 @@ #ifdef PY_STRUCT_OVERFLOW_MASKING PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1); #endif +#ifdef PY_STRUCT_FLOAT_COERCE + PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1); +#endif + } Modified: stackless/trunk/Modules/_testcapimodule.c ============================================================================== --- stackless/trunk/Modules/_testcapimodule.c (original) +++ stackless/trunk/Modules/_testcapimodule.c Mon Aug 21 11:10:05 2006 @@ -706,6 +706,13 @@ #undef CHECK_1_FORMAT } +/* This is here to provide a docstring for test_descr. */ +static PyObject * +test_with_docstring(PyObject *self) +{ + Py_RETURN_NONE; +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, @@ -716,6 +723,8 @@ {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, + {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, + PyDoc_STR("This is a pretty normal docstring.")}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_b", getargs_b, METH_VARARGS}, Modified: stackless/trunk/Modules/_tkinter.c ============================================================================== --- stackless/trunk/Modules/_tkinter.c (original) +++ stackless/trunk/Modules/_tkinter.c Mon Aug 21 11:10:05 2006 @@ -2493,8 +2493,10 @@ } v = Tktt_New(func); - v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, - (ClientData)v); + if (v) { + v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, + (ClientData)v); + } return (PyObject *) v; } Modified: stackless/trunk/Modules/arraymodule.c ============================================================================== --- stackless/trunk/Modules/arraymodule.c (original) +++ stackless/trunk/Modules/arraymodule.c Mon Aug 21 11:10:05 2006 @@ -702,6 +702,8 @@ /* Special case "a[i:j] = a" -- copy b first */ int ret; v = array_slice(b, 0, n); + if (!v) + return -1; ret = array_ass_slice(a, ilow, ihigh, v); Py_DECREF(v); return ret; @@ -1570,14 +1572,11 @@ return s; } -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) - static PyObject* array_subscr(arrayobject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i==-1 && PyErr_Occurred()) { return NULL; } @@ -1625,9 +1624,8 @@ static int array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i==-1 && PyErr_Occurred()) return -1; if (i < 0) @@ -1708,6 +1706,8 @@ if (self == av) { value = array_slice(av, 0, av->ob_size); av = (arrayobject*)value; + if (!av) + return -1; } else { Py_INCREF(value); Modified: stackless/trunk/Modules/bz2module.c ============================================================================== --- stackless/trunk/Modules/bz2module.c (original) +++ stackless/trunk/Modules/bz2module.c Mon Aug 21 11:10:05 2006 @@ -812,12 +812,12 @@ case MODE_CLOSED: PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - goto cleanup;; + goto cleanup; default: PyErr_SetString(PyExc_IOError, "file is not ready for writing"); - goto cleanup;; + goto cleanup; } self->f_softspace = 0; @@ -861,6 +861,21 @@ int bzerror; ACQUIRE_LOCK(self); + switch (self->mode) { + case MODE_WRITE: + break; + + case MODE_CLOSED: + PyErr_SetString(PyExc_ValueError, + "I/O operation on closed file"); + goto error; + + default: + PyErr_SetString(PyExc_IOError, + "file is not ready for writing"); + goto error; + } + islist = PyList_Check(seq); if (!islist) { iter = PyObject_GetIter(seq); Modified: stackless/trunk/Modules/collectionsmodule.c ============================================================================== --- stackless/trunk/Modules/collectionsmodule.c (original) +++ stackless/trunk/Modules/collectionsmodule.c Mon Aug 21 11:10:05 2006 @@ -211,6 +211,7 @@ PyErr_SetString(PyExc_IndexError, "pop from an empty deque"); return NULL; } + assert(deque->leftblock != NULL); item = deque->leftblock->data[deque->leftindex]; deque->leftindex++; deque->len--; @@ -226,7 +227,6 @@ } else { assert(deque->leftblock != deque->rightblock); prevblock = deque->leftblock->rightlink; - assert(deque->leftblock != NULL); PyMem_Free(deque->leftblock); assert(prevblock != NULL); prevblock->leftlink = NULL; Modified: stackless/trunk/Modules/expat/xmlparse.c ============================================================================== --- stackless/trunk/Modules/expat/xmlparse.c (original) +++ stackless/trunk/Modules/expat/xmlparse.c Mon Aug 21 11:10:05 2006 @@ -2795,6 +2795,8 @@ unsigned long uriHash = 0; ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); + if (!id) + return XML_ERROR_NO_MEMORY; b = id->prefix->binding; if (!b) return XML_ERROR_UNBOUND_PREFIX; @@ -5340,6 +5342,8 @@ return NULL; id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), sizeof(PREFIX)); + if (!id->prefix) + return NULL; if (id->prefix->name == poolStart(&dtd->pool)) poolFinish(&dtd->pool); else Modified: stackless/trunk/Modules/mmapmodule.c ============================================================================== --- stackless/trunk/Modules/mmapmodule.c (original) +++ stackless/trunk/Modules/mmapmodule.c Mon Aug 21 11:10:05 2006 @@ -808,8 +808,6 @@ }; -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) - /* extract the map size from the given PyObject Returns -1 on error, with an appropriate Python exception raised. On @@ -817,31 +815,19 @@ static Py_ssize_t _GetMapSize(PyObject *o) { - PyNumberMethods *nb = o->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(o) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(o); + if (PyIndex_Check(o)) { + Py_ssize_t i = PyNumber_AsSsize_t(o, PyExc_OverflowError); if (i==-1 && PyErr_Occurred()) return -1; - if (i < 0) - goto onnegoverflow; - if (i==PY_SSIZE_T_MAX) - goto onposoverflow; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "memory mapped size must be positive"); + return -1; + } return i; } - else { - PyErr_SetString(PyExc_TypeError, - "map size must be an integral value"); - return -1; - } - - onnegoverflow: - PyErr_SetString(PyExc_OverflowError, - "memory mapped size must be positive"); - return -1; - onposoverflow: - PyErr_SetString(PyExc_OverflowError, - "memory mapped size is too large (limited by C int)"); + PyErr_SetString(PyExc_TypeError, "map size must be an integral value"); return -1; } @@ -1140,6 +1126,15 @@ {NULL, NULL} /* Sentinel */ }; +static void +setint(PyObject *d, const char *name, long value) +{ + PyObject *o = PyInt_FromLong(value); + if (o && PyDict_SetItemString(d, name, o) == 0) { + Py_DECREF(o); + } +} + PyMODINIT_FUNC initmmap(void) { @@ -1152,47 +1147,40 @@ if (module == NULL) return; dict = PyModule_GetDict(module); + if (!dict) + return; mmap_module_error = PyExc_EnvironmentError; - Py_INCREF(mmap_module_error); PyDict_SetItemString(dict, "error", mmap_module_error); #ifdef PROT_EXEC - PyDict_SetItemString(dict, "PROT_EXEC", PyInt_FromLong(PROT_EXEC) ); + setint(dict, "PROT_EXEC", PROT_EXEC); #endif #ifdef PROT_READ - PyDict_SetItemString(dict, "PROT_READ", PyInt_FromLong(PROT_READ) ); + setint(dict, "PROT_READ", PROT_READ); #endif #ifdef PROT_WRITE - PyDict_SetItemString(dict, "PROT_WRITE", PyInt_FromLong(PROT_WRITE) ); + setint(dict, "PROT_WRITE", PROT_WRITE); #endif #ifdef MAP_SHARED - PyDict_SetItemString(dict, "MAP_SHARED", PyInt_FromLong(MAP_SHARED) ); + setint(dict, "MAP_SHARED", MAP_SHARED); #endif #ifdef MAP_PRIVATE - PyDict_SetItemString(dict, "MAP_PRIVATE", - PyInt_FromLong(MAP_PRIVATE) ); + setint(dict, "MAP_PRIVATE", MAP_PRIVATE); #endif #ifdef MAP_DENYWRITE - PyDict_SetItemString(dict, "MAP_DENYWRITE", - PyInt_FromLong(MAP_DENYWRITE) ); + setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); #endif #ifdef MAP_EXECUTABLE - PyDict_SetItemString(dict, "MAP_EXECUTABLE", - PyInt_FromLong(MAP_EXECUTABLE) ); + setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); #endif #ifdef MAP_ANONYMOUS - PyDict_SetItemString(dict, "MAP_ANON", PyInt_FromLong(MAP_ANONYMOUS) ); - PyDict_SetItemString(dict, "MAP_ANONYMOUS", - PyInt_FromLong(MAP_ANONYMOUS) ); + setint(dict, "MAP_ANON", MAP_ANONYMOUS); + setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); #endif - PyDict_SetItemString(dict, "PAGESIZE", - PyInt_FromLong((long)my_getpagesize())); - - PyDict_SetItemString(dict, "ACCESS_READ", - PyInt_FromLong(ACCESS_READ)); - PyDict_SetItemString(dict, "ACCESS_WRITE", - PyInt_FromLong(ACCESS_WRITE)); - PyDict_SetItemString(dict, "ACCESS_COPY", - PyInt_FromLong(ACCESS_COPY)); + setint(dict, "PAGESIZE", (long)my_getpagesize()); + + setint(dict, "ACCESS_READ", ACCESS_READ); + setint(dict, "ACCESS_WRITE", ACCESS_WRITE); + setint(dict, "ACCESS_COPY", ACCESS_COPY); } Modified: stackless/trunk/Modules/operator.c ============================================================================== --- stackless/trunk/Modules/operator.c (original) +++ stackless/trunk/Modules/operator.c Mon Aug 21 11:10:05 2006 @@ -139,15 +139,7 @@ static PyObject * op_index(PyObject *s, PyObject *a) { - Py_ssize_t i; - PyObject *a1; - if (!PyArg_UnpackTuple(a,"index", 1, 1, &a1)) - return NULL; - i = PyNumber_Index(a1); - if (i == -1 && PyErr_Occurred()) - return NULL; - else - return PyInt_FromSsize_t(i); + return PyNumber_Index(a); } static PyObject* @@ -249,7 +241,7 @@ spam1(is_, "is_(a, b) -- Same as a is b.") spam1(is_not, "is_not(a, b) -- Same as a is not b.") -spam2(index, __index__, "index(a) -- Same as a.__index__()") +spam2o(index, __index__, "index(a) -- Same as a.__index__()") spam2(add,__add__, "add(a, b) -- Same as a + b.") spam2(sub,__sub__, "sub(a, b) -- Same as a - b.") spam2(mul,__mul__, "mul(a, b) -- Same as a * b.") Modified: stackless/trunk/Modules/posixmodule.c ============================================================================== --- stackless/trunk/Modules/posixmodule.c (original) +++ stackless/trunk/Modules/posixmodule.c Mon Aug 21 11:10:05 2006 @@ -1121,6 +1121,8 @@ #else ival = PyInt_FromLong((long)sec); #endif + if (!ival) + return; if (_stat_float_times) { fval = PyFloat_FromDouble(sec + 1e-9*nsec); } else { Modified: stackless/trunk/Modules/rgbimgmodule.c ============================================================================== --- stackless/trunk/Modules/rgbimgmodule.c (original) +++ stackless/trunk/Modules/rgbimgmodule.c Mon Aug 21 11:10:05 2006 @@ -410,6 +410,11 @@ addlongimgtag(base, xsize, ysize); #endif verdat = (unsigned char *)malloc(xsize); + if (!verdat) { + Py_CLEAR(rv); + goto finally; + } + fseek(inf, 512, SEEK_SET); for (z = 0; z < zsize; z++) { lptr = base; @@ -431,10 +436,14 @@ copybw((Py_Int32 *) base, xsize * ysize); } finally: - free(starttab); - free(lengthtab); - free(rledat); - free(verdat); + if (starttab) + free(starttab); + if (lengthtab) + free(lengthtab); + if (rledat) + free(rledat); + if (verdat) + free(verdat); fclose(inf); return rv; } Modified: stackless/trunk/Modules/socketmodule.c ============================================================================== --- stackless/trunk/Modules/socketmodule.c (original) +++ stackless/trunk/Modules/socketmodule.c Mon Aug 21 11:10:05 2006 @@ -3041,17 +3041,20 @@ if ((addr_list = PyList_New(0)) == NULL) goto err; - for (pch = h->h_aliases; *pch != NULL; pch++) { - int status; - tmp = PyString_FromString(*pch); - if (tmp == NULL) - goto err; + /* SF #1511317: h_aliases can be NULL */ + if (h->h_aliases) { + for (pch = h->h_aliases; *pch != NULL; pch++) { + int status; + tmp = PyString_FromString(*pch); + if (tmp == NULL) + goto err; - status = PyList_Append(name_list, tmp); - Py_DECREF(tmp); + status = PyList_Append(name_list, tmp); + Py_DECREF(tmp); - if (status) - goto err; + if (status) + goto err; + } } for (pch = h->h_addr_list; *pch != NULL; pch++) { Modified: stackless/trunk/Modules/unicodedata.c ============================================================================== --- stackless/trunk/Modules/unicodedata.c (original) +++ stackless/trunk/Modules/unicodedata.c Mon Aug 21 11:10:05 2006 @@ -1,8 +1,8 @@ /* ------------------------------------------------------------------------ - unicodedata -- Provides access to the Unicode 3.2 data base. + unicodedata -- Provides access to the Unicode 4.1 data base. - Data was extracted from the Unicode 3.2 UnicodeData.txt file. + Data was extracted from the Unicode 4.1 UnicodeData.txt file. Written by Marc-Andre Lemburg (mal at lemburg.com). Modified for Python 2.0 by Fredrik Lundh (fredrik at pythonware.com) @@ -1078,6 +1078,7 @@ { Py_UCS4 code; Py_UNICODE str[1]; + char errbuf[256]; char* name; int namelen; @@ -1085,11 +1086,19 @@ return NULL; if (!_getcode(self, name, namelen, &code)) { + /* XXX(nnorwitz): why are we allocating for the error msg? + Why not always use snprintf? */ char fmt[] = "undefined character name '%s'"; char *buf = PyMem_MALLOC(sizeof(fmt) + namelen); - sprintf(buf, fmt, name); + if (buf) + sprintf(buf, fmt, name); + else { + buf = errbuf; + PyOS_snprintf(buf, sizeof(errbuf), fmt, name); + } PyErr_SetString(PyExc_KeyError, buf); - PyMem_FREE(buf); + if (buf != errbuf) + PyMem_FREE(buf); return NULL; } @@ -1173,11 +1182,11 @@ "This module provides access to the Unicode Character Database which\n\ defines character properties for all Unicode characters. The data in\n\ this database is based on the UnicodeData.txt file version\n\ -3.2.0 which is publically available from ftp://ftp.unicode.org/.\n\ +4.1.0 which is publically available from ftp://ftp.unicode.org/.\n\ \n\ The module uses the same names and symbols as defined by the\n\ -UnicodeData File Format 3.2.0 (see\n\ -http://www.unicode.org/Public/3.2-Update/UnicodeData-3.2.0.html)."); +UnicodeData File Format 4.1.0 (see\n\ +http://www.unicode.org/Public/4.1.0/ucd/UCD.html)."); PyMODINIT_FUNC initunicodedata(void) Modified: stackless/trunk/Modules/zipimport.c ============================================================================== --- stackless/trunk/Modules/zipimport.c (original) +++ stackless/trunk/Modules/zipimport.c Mon Aug 21 11:10:05 2006 @@ -950,6 +950,9 @@ char *buf, *q, *p = PyString_AsString(source); PyObject *fixed_source; + if (!p) + return NULL; + /* one char extra for trailing \n and one for terminating \0 */ buf = (char *)PyMem_Malloc(PyString_Size(source) + 2); if (buf == NULL) { Modified: stackless/trunk/Objects/abstract.c ============================================================================== --- stackless/trunk/Objects/abstract.c (original) +++ stackless/trunk/Objects/abstract.c Mon Aug 21 11:10:05 2006 @@ -9,8 +9,6 @@ #define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \ Py_TPFLAGS_CHECKTYPES) -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) - /* Shorthands to return certain errors */ @@ -123,9 +121,9 @@ return m->mp_subscript(o, key); if (o->ob_type->tp_as_sequence) { - PyNumberMethods *nb = key->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(key) && nb->nb_index != NULL) { - Py_ssize_t key_value = nb->nb_index(key); + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); if (key_value == -1 && PyErr_Occurred()) return NULL; return PySequence_GetItem(o, key_value); @@ -152,9 +150,9 @@ return m->mp_ass_subscript(o, key, value); if (o->ob_type->tp_as_sequence) { - PyNumberMethods *nb = key->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(key) && nb->nb_index != NULL) { - Py_ssize_t key_value = nb->nb_index(key); + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); if (key_value == -1 && PyErr_Occurred()) return -1; return PySequence_SetItem(o, key_value, value); @@ -184,9 +182,9 @@ return m->mp_ass_subscript(o, key, (PyObject*)NULL); if (o->ob_type->tp_as_sequence) { - PyNumberMethods *nb = key->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(key) && nb->nb_index != NULL) { - Py_ssize_t key_value = nb->nb_index(key); + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); if (key_value == -1 && PyErr_Occurred()) return -1; return PySequence_DelItem(o, key_value); @@ -654,9 +652,8 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) { Py_ssize_t count; - PyNumberMethods *nb = n->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(n) && nb->nb_index != NULL) { - count = nb->nb_index(n); + if (PyIndex_Check(n)) { + count = PyNumber_AsSsize_t(n, PyExc_OverflowError); if (count == -1 && PyErr_Occurred()) return NULL; } @@ -939,23 +936,87 @@ return x; } -/* Return a Py_ssize_t integer from the object item */ -Py_ssize_t +/* Return a Python Int or Long from the object item + Raise TypeError if the result is not an int-or-long + or if the object cannot be interpreted as an index. +*/ +PyObject * PyNumber_Index(PyObject *item) { - Py_ssize_t value = -1; - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - value = nb->nb_index(item); + PyObject *result = NULL; + if (item == NULL) + return null_error(); + if (PyInt_Check(item) || PyLong_Check(item)) { + Py_INCREF(item); + return item; + } + if (PyIndex_Check(item)) { + result = item->ob_type->tp_as_number->nb_index(item); + if (result && + !PyInt_Check(result) && !PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__index__ returned non-(int,long) " \ + "(type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } } else { PyErr_Format(PyExc_TypeError, "'%.200s' object cannot be interpreted " "as an index", item->ob_type->tp_name); } - return value; + return result; +} + +/* Return an error on Overflow only if err is not NULL*/ + +Py_ssize_t +PyNumber_AsSsize_t(PyObject *item, PyObject *err) +{ + Py_ssize_t result; + PyObject *runerr; + PyObject *value = PyNumber_Index(item); + if (value == NULL) + return -1; + + /* We're done if PyInt_AsSsize_t() returns without error. */ + result = PyInt_AsSsize_t(value); + if (result != -1 || !(runerr = PyErr_Occurred())) + goto finish; + + /* Error handling code -- only manage OverflowError differently */ + if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) + goto finish; + + PyErr_Clear(); + /* If no error-handling desired then the default clipping + is sufficient. + */ + if (!err) { + assert(PyLong_Check(value)); + /* Whether or not it is less than or equal to + zero is determined by the sign of ob_size + */ + if (_PyLong_Sign(value) < 0) + result = PY_SSIZE_T_MIN; + else + result = PY_SSIZE_T_MAX; + } + else { + /* Otherwise replace the error with caller's error object. */ + PyErr_Format(err, + "cannot fit '%.200s' into an index-sized integer", + item->ob_type->tp_name); + } + + finish: + Py_DECREF(value); + return result; } + PyObject * PyNumber_Int(PyObject *o) { @@ -1115,7 +1176,7 @@ if (m && m->sq_length) return m->sq_length(s); - type_error("non-sequence object of type '%.200s' has no len()", s); + type_error("object of type '%.200s' has no len()", s); return -1; } @@ -1706,7 +1767,7 @@ if (m && m->mp_length) return m->mp_length(o); - type_error("non-mapping object of type '%.200s' has no len()", o); + type_error("object of type '%.200s' has no len()", o); return -1; } Modified: stackless/trunk/Objects/bufferobject.c ============================================================================== --- stackless/trunk/Objects/bufferobject.c (original) +++ stackless/trunk/Objects/bufferobject.c Mon Aug 21 11:10:05 2006 @@ -272,7 +272,7 @@ if (min_len > 0) { cmp = memcmp(p1, p2, min_len); if (cmp != 0) - return cmp; + return cmp < 0 ? -1 : 1; } return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0; } Modified: stackless/trunk/Objects/classobject.c ============================================================================== --- stackless/trunk/Objects/classobject.c (original) +++ stackless/trunk/Objects/classobject.c Mon Aug 21 11:10:05 2006 @@ -104,8 +104,14 @@ op->cl_name = name; if (getattrstr == NULL) { getattrstr = PyString_InternFromString("__getattr__"); + if (getattrstr == NULL) + return NULL; setattrstr = PyString_InternFromString("__setattr__"); + if (setattrstr == NULL) + return NULL; delattrstr = PyString_InternFromString("__delattr__"); + if (delattrstr == NULL) + return NULL; } op->cl_getattr = class_lookup(op, getattrstr, &dummy); op->cl_setattr = class_lookup(op, setattrstr, &dummy); @@ -523,11 +529,14 @@ PyObject *init; static PyObject *initstr; + if (initstr == NULL) { + initstr = PyString_InternFromString("__init__"); + if (initstr == NULL) + return NULL; + } inst = (PyInstanceObject *) PyInstance_NewRaw(klass, NULL); if (inst == NULL) return NULL; - if (initstr == NULL) - initstr = PyString_InternFromString("__init__"); init = instance_getattr2(inst, initstr); if (init == NULL) { if (PyErr_Occurred()) { @@ -613,9 +622,12 @@ /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); /* Execute __del__ method, if any. */ - if (delstr == NULL) + if (delstr == NULL) { delstr = PyString_InternFromString("__del__"); - if ((del = instance_getattr2(inst, delstr)) != NULL) { + if (delstr == NULL) + PyErr_WriteUnraisable((PyObject*)inst); + } + if (delstr && (del = instance_getattr2(inst, delstr)) != NULL) { PyObject *res = PyEval_CallObject(del, (PyObject *)NULL); if (res == NULL) PyErr_WriteUnraisable(del); @@ -841,8 +853,11 @@ PyObject *res; static PyObject *reprstr; - if (reprstr == NULL) + if (reprstr == NULL) { reprstr = PyString_InternFromString("__repr__"); + if (reprstr == NULL) + return NULL; + } func = instance_getattr(inst, reprstr); if (func == NULL) { PyObject *classname, *mod; @@ -877,8 +892,11 @@ PyObject *res; static PyObject *strstr; - if (strstr == NULL) + if (strstr == NULL) { strstr = PyString_InternFromString("__str__"); + if (strstr == NULL) + return NULL; + } func = instance_getattr(inst, strstr); if (func == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) @@ -899,8 +917,11 @@ long outcome; static PyObject *hashstr, *eqstr, *cmpstr; - if (hashstr == NULL) + if (hashstr == NULL) { hashstr = PyString_InternFromString("__hash__"); + if (hashstr == NULL) + return -1; + } func = instance_getattr(inst, hashstr); if (func == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) @@ -909,15 +930,21 @@ /* If there is no __eq__ and no __cmp__ method, we hash on the address. If an __eq__ or __cmp__ method exists, there must be a __hash__. */ - if (eqstr == NULL) + if (eqstr == NULL) { eqstr = PyString_InternFromString("__eq__"); + if (eqstr == NULL) + return -1; + } func = instance_getattr(inst, eqstr); if (func == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; PyErr_Clear(); - if (cmpstr == NULL) + if (cmpstr == NULL) { cmpstr = PyString_InternFromString("__cmp__"); + if (cmpstr == NULL) + return -1; + } func = instance_getattr(inst, cmpstr); if (func == NULL) { if (!PyErr_ExceptionMatches( @@ -935,11 +962,9 @@ Py_DECREF(func); if (res == NULL) return -1; - if (PyInt_Check(res)) { - outcome = PyInt_AsLong(res); - if (outcome == -1) - outcome = -2; - } + if (PyInt_Check(res) || PyLong_Check(res)) + /* This already converts a -1 result to -2. */ + outcome = res->ob_type->tp_hash(res); else { PyErr_SetString(PyExc_TypeError, "__hash__() should return an int"); @@ -967,8 +992,11 @@ PyObject *res; Py_ssize_t outcome; - if (lenstr == NULL) + if (lenstr == NULL) { lenstr = PyString_InternFromString("__len__"); + if (lenstr == NULL) + return -1; + } func = instance_getattr(inst, lenstr); if (func == NULL) return -1; @@ -977,24 +1005,25 @@ if (res == NULL) return -1; if (PyInt_Check(res)) { - Py_ssize_t temp = PyInt_AsSsize_t(res); - if (temp == -1 && PyErr_Occurred()) { + outcome = PyInt_AsSsize_t(res); + if (outcome == -1 && PyErr_Occurred()) { Py_DECREF(res); return -1; } - outcome = (Py_ssize_t)temp; -#if SIZEOF_SIZE_T < SIZEOF_LONG +#if SIZEOF_SIZE_T < SIZEOF_INT /* Overflow check -- range of PyInt is more than C int */ - if (outcome != temp) { + if (outcome != (int)outcome) { PyErr_SetString(PyExc_OverflowError, "__len__() should return 0 <= outcome < 2**31"); outcome = -1; } else #endif - if (outcome < 0) + if (outcome < 0) { PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); + outcome = -1; + } } else { PyErr_SetString(PyExc_TypeError, @@ -1012,8 +1041,11 @@ PyObject *arg; PyObject *res; - if (getitemstr == NULL) + if (getitemstr == NULL) { getitemstr = PyString_InternFromString("__getitem__"); + if (getitemstr == NULL) + return NULL; + } func = instance_getattr(inst, getitemstr); if (func == NULL) return NULL; @@ -1036,13 +1068,19 @@ PyObject *res; if (value == NULL) { - if (delitemstr == NULL) + if (delitemstr == NULL) { delitemstr = PyString_InternFromString("__delitem__"); + if (delitemstr == NULL) + return -1; + } func = instance_getattr(inst, delitemstr); } else { - if (setitemstr == NULL) + if (setitemstr == NULL) { setitemstr = PyString_InternFromString("__setitem__"); + if (setitemstr == NULL) + return -1; + } func = instance_getattr(inst, setitemstr); } if (func == NULL) @@ -1075,8 +1113,11 @@ { PyObject *func, *res; - if (getitemstr == NULL) + if (getitemstr == NULL) { getitemstr = PyString_InternFromString("__getitem__"); + if (getitemstr == NULL) + return NULL; + } func = instance_getattr(inst, getitemstr); if (func == NULL) return NULL; @@ -1091,8 +1132,11 @@ PyObject *func, *arg, *res; static PyObject *getslicestr; - if (getslicestr == NULL) + if (getslicestr == NULL) { getslicestr = PyString_InternFromString("__getslice__"); + if (getslicestr == NULL) + return NULL; + } func = instance_getattr(inst, getslicestr); if (func == NULL) { @@ -1100,8 +1144,11 @@ return NULL; PyErr_Clear(); - if (getitemstr == NULL) + if (getitemstr == NULL) { getitemstr = PyString_InternFromString("__getitem__"); + if (getitemstr == NULL) + return NULL; + } func = instance_getattr(inst, getitemstr); if (func == NULL) return NULL; @@ -1125,13 +1172,19 @@ PyObject *func, *arg, *res; if (item == NULL) { - if (delitemstr == NULL) + if (delitemstr == NULL) { delitemstr = PyString_InternFromString("__delitem__"); + if (delitemstr == NULL) + return -1; + } func = instance_getattr(inst, delitemstr); } else { - if (setitemstr == NULL) + if (setitemstr == NULL) { setitemstr = PyString_InternFromString("__setitem__"); + if (setitemstr == NULL) + return -1; + } func = instance_getattr(inst, setitemstr); } if (func == NULL) @@ -1160,17 +1213,23 @@ static PyObject *setslicestr, *delslicestr; if (value == NULL) { - if (delslicestr == NULL) + if (delslicestr == NULL) { delslicestr = PyString_InternFromString("__delslice__"); + if (delslicestr == NULL) + return -1; + } func = instance_getattr(inst, delslicestr); if (func == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; PyErr_Clear(); - if (delitemstr == NULL) + if (delitemstr == NULL) { delitemstr = PyString_InternFromString("__delitem__"); + if (delitemstr == NULL) + return -1; + } func = instance_getattr(inst, delitemstr); if (func == NULL) return -1; @@ -1181,17 +1240,23 @@ arg = Py_BuildValue("(nn)", i, j); } else { - if (setslicestr == NULL) + if (setslicestr == NULL) { setslicestr = PyString_InternFromString("__setslice__"); + if (setslicestr == NULL) + return -1; + } func = instance_getattr(inst, setslicestr); if (func == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; PyErr_Clear(); - if (setitemstr == NULL) + if (setitemstr == NULL) { setitemstr = PyString_InternFromString("__setitem__"); + if (setitemstr == NULL) + return -1; + } func = instance_getattr(inst, setitemstr); if (func == NULL) return -1; @@ -1464,7 +1529,8 @@ #define UNARY(funcname, methodname) \ static PyObject *funcname(PyInstanceObject *self) { \ static PyObject *o; \ - if (o == NULL) o = PyString_InternFromString(methodname); \ + if (o == NULL) { o = PyString_InternFromString(methodname); \ + if (o == NULL) return NULL; } \ return generic_unary_op(self, o); \ } @@ -1636,14 +1702,20 @@ long outcome; static PyObject *nonzerostr; - if (nonzerostr == NULL) + if (nonzerostr == NULL) { nonzerostr = PyString_InternFromString("__nonzero__"); + if (nonzerostr == NULL) + return -1; + } if ((func = instance_getattr(self, nonzerostr)) == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; PyErr_Clear(); - if (lenstr == NULL) + if (lenstr == NULL) { lenstr = PyString_InternFromString("__len__"); + if (lenstr == NULL) + return -1; + } if ((func = instance_getattr(self, lenstr)) == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; @@ -1673,40 +1745,28 @@ return outcome > 0; } -static Py_ssize_t +static PyObject * instance_index(PyInstanceObject *self) { PyObject *func, *res; - Py_ssize_t outcome; static PyObject *indexstr = NULL; if (indexstr == NULL) { indexstr = PyString_InternFromString("__index__"); if (indexstr == NULL) - return -1; + return NULL; } if ((func = instance_getattr(self, indexstr)) == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) - return -1; + return NULL; PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "object cannot be interpreted as an index"); - return -1; + return NULL; } res = PyEval_CallObject(func, (PyObject *)NULL); Py_DECREF(func); - if (res == NULL) - return -1; - if (PyInt_Check(res) || PyLong_Check(res)) { - outcome = res->ob_type->tp_as_number->nb_index(res); - } - else { - PyErr_SetString(PyExc_TypeError, - "__index__ must return an int or a long"); - outcome = -1; - } - Py_DECREF(res); - return outcome; + return res; } @@ -1937,8 +1997,11 @@ { PyObject *func; - if (nextstr == NULL) + if (nextstr == NULL) { nextstr = PyString_InternFromString("next"); + if (nextstr == NULL) + return NULL; + } if ((func = instance_getattr(self, nextstr)) != NULL) { PyObject *res = PyEval_CallObject(func, (PyObject *)NULL); @@ -2032,7 +2095,7 @@ instance_truediv, /* nb_true_divide */ instance_ifloordiv, /* nb_inplace_floor_divide */ instance_itruediv, /* nb_inplace_true_divide */ - (lenfunc)instance_index, /* nb_index */ + (unaryfunc)instance_index, /* nb_index */ }; PyTypeObject PyInstance_Type = { Modified: stackless/trunk/Objects/descrobject.c ============================================================================== --- stackless/trunk/Objects/descrobject.c (original) +++ stackless/trunk/Objects/descrobject.c Mon Aug 21 11:10:05 2006 @@ -1218,7 +1218,6 @@ property_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL; - PyObject *get_doc = NULL; static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0}; propertyobject *gs = (propertyobject *)self; @@ -1233,20 +1232,22 @@ if (del == Py_None) del = NULL; - /* if no docstring given and the getter has one, use that one */ - if ((doc == NULL || doc == Py_None) && get != NULL && - PyObject_HasAttrString(get, "__doc__")) { - if (!(get_doc = PyObject_GetAttrString(get, "__doc__"))) - return -1; - Py_DECREF(get_doc); /* it is INCREF'd again below */ - doc = get_doc; - } - Py_XINCREF(get); Py_XINCREF(set); Py_XINCREF(del); Py_XINCREF(doc); + /* if no docstring given and the getter has one, use that one */ + if ((doc == NULL || doc == Py_None) && get != NULL) { + PyObject *get_doc = PyObject_GetAttrString(get, "__doc__"); + if (get_doc != NULL) { + Py_XDECREF(doc); + doc = get_doc; /* get_doc already INCREF'd by GetAttr */ + } else { + PyErr_Clear(); + } + } + gs->prop_get = get; gs->prop_set = set; gs->prop_del = del; Modified: stackless/trunk/Objects/dictnotes.txt ============================================================================== --- stackless/trunk/Objects/dictnotes.txt (original) +++ stackless/trunk/Objects/dictnotes.txt Mon Aug 21 11:10:05 2006 @@ -243,7 +243,7 @@ Caching Lookups --------------- The idea is to exploit key access patterns by anticipating future lookups -based of previous lookups. +based on previous lookups. The simplest incarnation is to save the most recently accessed entry. This gives optimal performance for use cases where every get is followed Modified: stackless/trunk/Objects/dictobject.c ============================================================================== --- stackless/trunk/Objects/dictobject.c (original) +++ stackless/trunk/Objects/dictobject.c Mon Aug 21 11:10:05 2006 @@ -532,7 +532,7 @@ /* Note that, for historical reasons, PyDict_GetItem() suppresses all errors * that may occur (originally dicts supported only string keys, and exceptions * weren't possible). So, while the original intent was that a NULL return - * meant the key wasn't present, it reality it can mean that, or that an error + * meant the key wasn't present, in reality it can mean that, or that an error * (suppressed) occurred while computing the key's hash, or that some error * (suppressed) occurred when comparing keys in the dict's internal probe * sequence. A nasty example of the latter is when a Python-coded comparison Modified: stackless/trunk/Objects/exceptions.c ============================================================================== --- stackless/trunk/Objects/exceptions.c (original) +++ stackless/trunk/Objects/exceptions.c Mon Aug 21 11:10:05 2006 @@ -1956,6 +1956,14 @@ "Base class for warnings about probable mistakes in module imports"); +/* + * UnicodeWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, UnicodeWarning, + "Base class for warnings about Unicode related problems, mostly\n" + "related to conversion problems."); + + /* Pre-computed MemoryError instance. Best to create this as early as * possible and not wait until a MemoryError is actually raised! */ @@ -2059,6 +2067,7 @@ PRE_INIT(RuntimeWarning) PRE_INIT(FutureWarning) PRE_INIT(ImportWarning) + PRE_INIT(UnicodeWarning) m = Py_InitModule4("exceptions", functions, exceptions_doc, (PyObject *)NULL, PYTHON_API_VERSION); @@ -2127,6 +2136,7 @@ POST_INIT(RuntimeWarning) POST_INIT(FutureWarning) POST_INIT(ImportWarning) + POST_INIT(UnicodeWarning) PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL); if (!PyExc_MemoryErrorInst) Modified: stackless/trunk/Objects/intobject.c ============================================================================== --- stackless/trunk/Objects/intobject.c (original) +++ stackless/trunk/Objects/intobject.c Mon Aug 21 11:10:05 2006 @@ -193,16 +193,21 @@ PyIntObject *io; Py_ssize_t val; #endif - if (op && !PyInt_CheckExact(op) && PyLong_Check(op)) + + if (op == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + if (PyInt_Check(op)) + return PyInt_AS_LONG((PyIntObject*) op); + if (PyLong_Check(op)) return _PyLong_AsSsize_t(op); #if SIZEOF_SIZE_T == SIZEOF_LONG return PyInt_AsLong(op); #else - if (op && PyInt_Check(op)) - return PyInt_AS_LONG((PyIntObject*) op); - - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + if ((nb = op->ob_type->tp_as_number) == NULL || (nb->nb_int == NULL && nb->nb_long == 0)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1; @@ -1079,7 +1084,7 @@ int_true_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ - PyInt_AsSsize_t, /* nb_index */ + (unaryfunc)int_int, /* nb_index */ }; PyTypeObject PyInt_Type = { Modified: stackless/trunk/Objects/listobject.c ============================================================================== --- stackless/trunk/Objects/listobject.c (original) +++ stackless/trunk/Objects/listobject.c Mon Aug 21 11:10:05 2006 @@ -2450,14 +2450,13 @@ "list() -> new list\n" "list(sequence) -> new list initialized from sequence's items"); -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) static PyObject * list_subscript(PyListObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) @@ -2504,9 +2503,8 @@ static int list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) @@ -2541,6 +2539,10 @@ garbage = (PyObject**) PyMem_MALLOC(slicelength*sizeof(PyObject*)); + if (!garbage) { + PyErr_NoMemory(); + return -1; + } /* drawing pictures might help understand these for loops */ @@ -2589,9 +2591,9 @@ else { seq = PySequence_Fast(value, "must assign iterable to extended slice"); - if (!seq) - return -1; } + if (!seq) + return -1; if (PySequence_Fast_GET_SIZE(seq) != slicelength) { PyErr_Format(PyExc_ValueError, Modified: stackless/trunk/Objects/longobject.c ============================================================================== --- stackless/trunk/Objects/longobject.c (original) +++ stackless/trunk/Objects/longobject.c Mon Aug 21 11:10:05 2006 @@ -240,8 +240,11 @@ return -1; } -static Py_ssize_t -_long_as_ssize_t(PyObject *vv) { +/* Get a Py_ssize_t from a long int object. + Returns -1 and sets an error condition if overflow occurs. */ + +Py_ssize_t +_PyLong_AsSsize_t(PyObject *vv) { register PyLongObject *v; size_t x, prev; Py_ssize_t i; @@ -277,45 +280,7 @@ overflow: PyErr_SetString(PyExc_OverflowError, "long int too large to convert to int"); - if (sign > 0) - return PY_SSIZE_T_MAX; - else - return PY_SSIZE_T_MIN; -} - -/* Get a Py_ssize_t from a long int object. - Returns -1 and sets an error condition if overflow occurs. */ - -Py_ssize_t -_PyLong_AsSsize_t(PyObject *vv) -{ - Py_ssize_t x; - - x = _long_as_ssize_t(vv); - if (PyErr_Occurred()) return -1; - return x; -} - - -/* Get a Py_ssize_t from a long int object. - Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, - and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1. - On error, return -1 with an exception set. -*/ - -static Py_ssize_t -long_index(PyObject *vv) -{ - Py_ssize_t x; - - x = _long_as_ssize_t(vv); - if (PyErr_Occurred()) { - /* If overflow error, ignore the error */ - if (x != -1) { - PyErr_Clear(); - } - } - return x; + return -1; } /* Get a C unsigned long int from a long int object. @@ -3405,7 +3370,7 @@ long_true_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ - long_index, /* nb_index */ + long_long, /* nb_index */ }; PyTypeObject PyLong_Type = { Modified: stackless/trunk/Objects/object.c ============================================================================== --- stackless/trunk/Objects/object.c (original) +++ stackless/trunk/Objects/object.c Mon Aug 21 11:10:05 2006 @@ -731,23 +731,6 @@ return (vv < ww) ? -1 : (vv > ww) ? 1 : 0; } -#ifdef Py_USING_UNICODE - /* Special case for Unicode */ - if (PyUnicode_Check(v) || PyUnicode_Check(w)) { - c = PyUnicode_Compare(v, w); - if (!PyErr_Occurred()) - return c; - /* TypeErrors are ignored: if Unicode coercion fails due - to one of the arguments not having the right type, we - continue as defined by the coercion protocol (see - above). Luckily, decoding errors are reported as - ValueErrors and are not masked by this technique. */ - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return -2; - PyErr_Clear(); - } -#endif - /* None is smaller than anything */ if (v == Py_None) return -1; Modified: stackless/trunk/Objects/sliceobject.c ============================================================================== --- stackless/trunk/Objects/sliceobject.c (original) +++ stackless/trunk/Objects/sliceobject.c Mon Aug 21 11:10:05 2006 @@ -252,7 +252,7 @@ { Py_ssize_t ilen, start, stop, step, slicelength; - ilen = PyInt_AsSsize_t(len); + ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError); if (ilen == -1 && PyErr_Occurred()) { return NULL; Modified: stackless/trunk/Objects/stringobject.c ============================================================================== --- stackless/trunk/Objects/stringobject.c (original) +++ stackless/trunk/Objects/stringobject.c Mon Aug 21 11:10:05 2006 @@ -1184,14 +1184,11 @@ return x; } -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) - static PyObject* string_subscript(PyStringObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) @@ -4228,12 +4225,17 @@ if (!result) return NULL; + buf = PyString_AsString(result); + if (!buf) { + Py_DECREF(result); + return NULL; + } + /* To modify the string in-place, there can only be one reference. */ if (result->ob_refcnt != 1) { PyErr_BadInternalCall(); return NULL; } - buf = PyString_AsString(result); llen = PyString_Size(result); if (llen > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong"); Modified: stackless/trunk/Objects/structseq.c ============================================================================== --- stackless/trunk/Objects/structseq.c (original) +++ stackless/trunk/Objects/structseq.c Mon Aug 21 11:10:05 2006 @@ -215,6 +215,8 @@ PyObject *tup; int result; tup = make_tuple(obj); + if (!tup) + return -1; result = PySequence_Contains(tup, o); Py_DECREF(tup); return result; @@ -226,6 +228,8 @@ PyObject *tup; long result; tup = make_tuple((PyStructSequence*) obj); + if (!tup) + return -1; result = PyObject_Hash(tup); Py_DECREF(tup); return result; Modified: stackless/trunk/Objects/tupleobject.c ============================================================================== --- stackless/trunk/Objects/tupleobject.c (original) +++ stackless/trunk/Objects/tupleobject.c Mon Aug 21 11:10:05 2006 @@ -577,14 +577,11 @@ (objobjproc)tuplecontains, /* sq_contains */ }; -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) - static PyObject* tuplesubscript(PyTupleObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) Modified: stackless/trunk/Objects/typeobject.c ============================================================================== --- stackless/trunk/Objects/typeobject.c (original) +++ stackless/trunk/Objects/typeobject.c Mon Aug 21 11:10:05 2006 @@ -1497,7 +1497,7 @@ if (obj->ob_type->tp_weaklistoffset == 0) { PyErr_SetString(PyExc_AttributeError, - "This object has no __weaklist__"); + "This object has no __weakref__"); return NULL; } assert(obj->ob_type->tp_weaklistoffset > 0); @@ -3591,7 +3591,7 @@ if (!PyArg_UnpackTuple(args, "", 1, 1, &o)) return NULL; - i = PyNumber_Index(o); + i = PyNumber_AsSsize_t(o, PyExc_OverflowError); if (i == -1 && PyErr_Occurred()) return NULL; return (*func)(self, i); @@ -3602,7 +3602,7 @@ { Py_ssize_t i; - i = PyNumber_Index(arg); + i = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) { @@ -4174,19 +4174,17 @@ { static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); - Py_ssize_t temp; Py_ssize_t len; if (res == NULL) return -1; - temp = PyInt_AsSsize_t(res); - len = (int)temp; + len = PyInt_AsSsize_t(res); Py_DECREF(res); if (len == -1 && PyErr_Occurred()) return -1; -#if SIZEOF_SIZE_T < SIZEOF_LONG +#if SIZEOF_SIZE_T < SIZEOF_INT /* Overflow check -- range of PyInt is more than C ssize_t */ - if (len != temp) { + if (len != (int)len) { PyErr_SetString(PyExc_OverflowError, "__len__() should return 0 <= outcome < 2**31"); return -1; @@ -4408,26 +4406,11 @@ } -static Py_ssize_t +static PyObject * slot_nb_index(PyObject *self) { static PyObject *index_str; - PyObject *temp = call_method(self, "__index__", &index_str, "()"); - Py_ssize_t result; - - if (temp == NULL) - return -1; - if (PyInt_CheckExact(temp) || PyLong_CheckExact(temp)) { - result = temp->ob_type->tp_as_number->nb_index(temp); - } - else { - PyErr_Format(PyExc_TypeError, - "__index__ must return an int or a long, " - "not '%.200s'", temp->ob_type->tp_name); - result = -1; - } - Py_DECREF(temp); - return result; + return call_method(self, "__index__", &index_str, "()"); } @@ -4633,7 +4616,10 @@ Py_DECREF(func); if (res == NULL) return -1; - h = PyInt_AsLong(res); + if (PyLong_Check(res)) + h = PyLong_Type.tp_hash(res); + else + h = PyInt_AsLong(res); Py_DECREF(res); } else { @@ -5266,7 +5252,7 @@ "oct(x)"), UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, "hex(x)"), - NBSLOT("__index__", nb_index, slot_nb_index, wrap_lenfunc, + NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, "x[y:z] <==> x[y.__index__():z.__index__()]"), IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+"), Modified: stackless/trunk/Objects/unicodeobject.c ============================================================================== --- stackless/trunk/Objects/unicodeobject.c (original) +++ stackless/trunk/Objects/unicodeobject.c Mon Aug 21 11:10:05 2006 @@ -5405,6 +5405,82 @@ return -1; } +PyObject *PyUnicode_RichCompare(PyObject *left, + PyObject *right, + int op) +{ + int result; + + result = PyUnicode_Compare(left, right); + if (result == -1 && PyErr_Occurred()) + goto onError; + + /* Convert the return value to a Boolean */ + switch (op) { + case Py_EQ: + result = (result == 0); + break; + case Py_NE: + result = (result != 0); + break; + case Py_LE: + result = (result <= 0); + break; + case Py_GE: + result = (result >= 0); + break; + case Py_LT: + result = (result == -1); + break; + case Py_GT: + result = (result == 1); + break; + } + return PyBool_FromLong(result); + + onError: + + /* Standard case + + Type errors mean that PyUnicode_FromObject() could not convert + one of the arguments (usually the right hand side) to Unicode, + ie. we can't handle the comparison request. However, it is + possible that the other object knows a comparison method, which + is why we return Py_NotImplemented to give the other object a + chance. + + */ + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + if (op != Py_EQ && op != Py_NE) + return NULL; + + /* Equality comparison. + + This is a special case: we silence any PyExc_UnicodeDecodeError + and instead turn it into a PyErr_UnicodeWarning. + + */ + if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) + return NULL; + PyErr_Clear(); + if (PyErr_Warn(PyExc_UnicodeWarning, + (op == Py_EQ) ? + "Unicode equal comparison " + "failed to convert both arguments to Unicode - " + "interpreting them as being unequal" : + "Unicode unequal comparison " + "failed to convert both arguments to Unicode - " + "interpreting them as being unequal" + ) < 0) + return NULL; + result = (op == Py_NE); + return PyBool_FromLong(result); +} + int PyUnicode_Contains(PyObject *container, PyObject *element) { @@ -6985,14 +7061,11 @@ PyUnicode_Contains, /* sq_contains */ }; -#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) - static PyObject* unicode_subscript(PyUnicodeObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) @@ -7862,7 +7935,7 @@ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - (cmpfunc) unicode_compare, /* tp_compare */ + 0, /* tp_compare */ unicode_repr, /* tp_repr */ &unicode_as_number, /* tp_as_number */ &unicode_as_sequence, /* tp_as_sequence */ @@ -7878,7 +7951,7 @@ unicode_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - 0, /* tp_richcompare */ + PyUnicode_RichCompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ Modified: stackless/trunk/PCbuild/_msi.vcproj ============================================================================== --- stackless/trunk/PCbuild/_msi.vcproj (original) +++ stackless/trunk/PCbuild/_msi.vcproj Mon Aug 21 11:10:05 2006 @@ -36,11 +36,11 @@ Modified: stackless/trunk/PCbuild/_ssl.mak ============================================================================== --- stackless/trunk/PCbuild/_ssl.mak (original) +++ stackless/trunk/PCbuild/_ssl.mak Mon Aug 21 11:10:05 2006 @@ -1,21 +1,37 @@ !IFDEF DEBUG -MODULE=_ssl_d.pyd -TEMP_DIR=x86-temp-debug/_ssl +SUFFIX=_d.pyd +TEMP=x86-temp-debug/ CFLAGS=/Od /Zi /MDd /LDd /DDEBUG /D_DEBUG /DWIN32 SSL_LIB_DIR=$(SSL_DIR)/out32.dbg !ELSE -MODULE=_ssl.pyd -TEMP_DIR=x86-temp-release/_ssl +SUFFIX=.pyd +TEMP=x86-temp-release/ CFLAGS=/Ox /MD /LD /DWIN32 SSL_LIB_DIR=$(SSL_DIR)/out32 !ENDIF INCLUDES=-I ../Include -I ../PC -I $(SSL_DIR)/inc32 -LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib -SOURCE=../Modules/_ssl.c $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib +SSL_LIBS=gdi32.lib wsock32.lib user32.lib advapi32.lib /LIBPATH:$(SSL_LIB_DIR) libeay32.lib ssleay32.lib +SSL_SOURCE=../Modules/_ssl.c -$(MODULE): $(SOURCE) ../PC/*.h ../Include/*.h - @if not exist "$(TEMP_DIR)/." mkdir "$(TEMP_DIR)" - cl /nologo $(SOURCE) $(CFLAGS) /Fo$(TEMP_DIR)\$*.obj $(INCLUDES) /link /out:$(MODULE) $(LIBS) +HASH_LIBS=gdi32.lib user32.lib advapi32.lib /libpath:$(SSL_LIB_DIR) libeay32.lib +HASH_SOURCE=../Modules/_hashopenssl.c + +all: _ssl$(SUFFIX) _hashlib$(SUFFIX) + +# Split compile/link into two steps to better support VSExtComp +_ssl$(SUFFIX): $(SSL_SOURCE) $(SSL_LIB_DIR)/libeay32.lib $(SSL_LIB_DIR)/ssleay32.lib ../PC/*.h ../Include/*.h + @if not exist "$(TEMP)/_ssl/." mkdir "$(TEMP)/_ssl" + cl /nologo /c $(SSL_SOURCE) $(CFLAGS) /Fo$(TEMP)\_ssl\$*.obj $(INCLUDES) + link /nologo @<< + /dll /out:_ssl$(SUFFIX) $(TEMP)\_ssl\$*.obj $(SSL_LIBS) +<< + +_hashlib$(SUFFIX): $(HASH_SOURCE) $(SSL_LIB_DIR)/libeay32.lib ../PC/*.h ../Include/*.h + @if not exist "$(TEMP)/_hashlib/." mkdir "$(TEMP)/_hashlib" + cl /nologo /c $(HASH_SOURCE) $(CFLAGS) /Fo$(TEMP)\_hashlib\$*.obj $(INCLUDES) + link /nologo @<< + /dll /out:_hashlib$(SUFFIX) $(HASH_LIBS) $(TEMP)\_hashlib\$*.obj +<< Modified: stackless/trunk/PCbuild/_ssl.vcproj ============================================================================== --- stackless/trunk/PCbuild/_ssl.vcproj (original) +++ stackless/trunk/PCbuild/_ssl.vcproj Mon Aug 21 11:10:05 2006 @@ -75,6 +75,9 @@ + + Modified: stackless/trunk/PCbuild/build_ssl.py ============================================================================== --- stackless/trunk/PCbuild/build_ssl.py (original) +++ stackless/trunk/PCbuild/build_ssl.py Mon Aug 21 11:10:05 2006 @@ -1,7 +1,7 @@ -# Script for building the _ssl module for Windows. +# Script for building the _ssl and _hashlib modules for Windows. # Uses Perl to setup the OpenSSL environment correctly # and build OpenSSL, then invokes a simple nmake session -# for _ssl.pyd itself. +# for the actual _ssl.pyd and _hashlib.pyd DLLs. # THEORETICALLY, you can: # * Unpack the latest SSL release one level above your main Python source @@ -10,8 +10,8 @@ # * Install ActivePerl and ensure it is somewhere on your path. # * Run this script from the PCBuild directory. # -# it should configure and build SSL, then build the ssl Python extension -# without intervention. +# it should configure and build SSL, then build the _ssl and _hashlib +# Python extensions without intervention. import os, sys, re @@ -59,7 +59,8 @@ candidates = [] for s in sources: try: - s = os.path.abspath(s) + # note: do not abspath s; the build will fail if any + # higher up directory name has spaces in it. fnames = os.listdir(s) except os.error: fnames = [] @@ -82,31 +83,9 @@ print "Found an SSL directory at '%s'" % (best_name,) else: print "Could not find an SSL directory in '%s'" % (sources,) + sys.stdout.flush() return best_name -def run_32all_py(): - # ms\32all.bat will reconfigure OpenSSL and then try to build - # all outputs (debug/nondebug/dll/lib). So we filter the file - # to exclude any "nmake" commands and then execute. - tempname = "ms\\32all_py.bat" - - in_bat = open("ms\\32all.bat") - temp_bat = open(tempname,"w") - while 1: - cmd = in_bat.readline() - print 'cmd', repr(cmd) - if not cmd: break - if cmd.strip()[:5].lower() == "nmake": - continue - temp_bat.write(cmd) - in_bat.close() - temp_bat.close() - os.system(tempname) - try: - os.remove(tempname) - except: - pass - def run_configure(configure, do_script): os.system("perl Configure "+configure) os.system(do_script) @@ -117,12 +96,14 @@ arch = "x86" debug = False configure = "VC-WIN32" - makefile = "32.mak" + do_script = "ms\\do_masm" + makefile = "ms\\nt.mak" elif sys.argv[1] == "Debug": arch = "x86" debug = True configure = "VC-WIN32" - makefile="d32.mak" + do_script = "ms\\do_masm" + makefile="ms\\d32.mak" elif sys.argv[1] == "ReleaseItanium": arch = "ia64" debug = False @@ -148,8 +129,9 @@ sys.exit(1) print "Found a working perl at '%s'" % (perl,) + sys.stdout.flush() # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live. - ssl_dir = find_best_ssl_dir(("../..",)) + ssl_dir = find_best_ssl_dir(("..\\..",)) if ssl_dir is None: sys.exit(1) @@ -159,29 +141,35 @@ # If the ssl makefiles do not exist, we invoke Perl to generate them. if not os.path.isfile(makefile): print "Creating the makefiles..." + sys.stdout.flush() # Put our working Perl at the front of our path - os.environ["PATH"] = os.path.split(perl)[0] + \ + os.environ["PATH"] = os.path.dirname(perl) + \ os.pathsep + \ os.environ["PATH"] - if arch=="x86": - run_32all_py() - else: - run_configure(configure, do_script) + if arch=="x86" and debug: + # the do_masm script in openssl doesn't generate a debug + # build makefile so we generate it here: + os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile) + run_configure(configure, do_script) # Now run make. print "Executing nmake over the ssl makefiles..." - rc = os.system("nmake /nologo -f "+makefile) + sys.stdout.flush() + rc = os.system("nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)) if rc: - print "Executing d32.mak failed" + print "Executing "+makefile+" failed" print rc sys.exit(rc) finally: os.chdir(old_cd) # And finally, we can build the _ssl module itself for Python. - defs = "SSL_DIR=%s" % (ssl_dir,) + defs = "SSL_DIR=\"%s\"" % (ssl_dir,) if debug: defs = defs + " " + "DEBUG=1" - rc = os.system('nmake /nologo -f _ssl.mak ' + defs + " " + make_flags) + makeCommand = 'nmake /nologo -f _ssl.mak ' + defs + " " + make_flags + print "Executing:", makeCommand + sys.stdout.flush() + rc = os.system(makeCommand) sys.exit(rc) if __name__=='__main__': Modified: stackless/trunk/Parser/grammar.c ============================================================================== --- stackless/trunk/Parser/grammar.c (original) +++ stackless/trunk/Parser/grammar.c Mon Aug 21 11:10:05 2006 @@ -199,6 +199,10 @@ else name_len = strlen(src); dest = (char *)malloc(name_len + 1); + if (!dest) { + printf("Can't alloc dest '%s'\n", src); + return; + } strncpy(dest, src, name_len); dest[name_len] = '\0'; free(lb->lb_str); Modified: stackless/trunk/Parser/parsetok.c ============================================================================== --- stackless/trunk/Parser/parsetok.c (original) +++ stackless/trunk/Parser/parsetok.c Mon Aug 21 11:10:05 2006 @@ -229,6 +229,11 @@ } } else if (tok->encoding != NULL) { node* r = PyNode_New(encoding_decl); + if (!r) { + err_ret->error = E_NOMEM; + n = NULL; + goto done; + } r->n_str = tok->encoding; r->n_nchildren = 1; r->n_child = n; @@ -236,6 +241,7 @@ n = r; } +done: PyTokenizer_Free(tok); return n; Modified: stackless/trunk/Python/ast.c ============================================================================== --- stackless/trunk/Python/ast.c (original) +++ stackless/trunk/Python/ast.c Mon Aug 21 11:10:05 2006 @@ -2197,6 +2197,8 @@ } else { alias_ty a = alias_for_import_name(c, CHILD(n, 0)); + if (!a) + return NULL; if (strcmp(STR(CHILD(n, 1)), "as") != 0) { ast_error(n, "must use 'as' in import"); return NULL; Modified: stackless/trunk/Python/bltinmodule.c ============================================================================== --- stackless/trunk/Python/bltinmodule.c (original) +++ stackless/trunk/Python/bltinmodule.c Mon Aug 21 11:10:05 2006 @@ -768,7 +768,7 @@ PyObject *d; d = PyEval_GetGlobals(); - Py_INCREF(d); + Py_XINCREF(d); return d; } @@ -1199,7 +1199,7 @@ PyObject *d; d = PyEval_GetLocals(); - Py_INCREF(d); + Py_XINCREF(d); return d; } @@ -1734,7 +1734,7 @@ if (PyFile_WriteString(" ", fout) != 0) return NULL; } - if (PyFile_Check(fin) && PyFile_Check(fout) + if (PyFile_AsFile(fin) && PyFile_AsFile(fout) && isatty(fileno(PyFile_AsFile(fin))) && isatty(fileno(PyFile_AsFile(fout)))) { PyObject *po; Modified: stackless/trunk/Python/ceval.c ============================================================================== --- stackless/trunk/Python/ceval.c (original) +++ stackless/trunk/Python/ceval.c Mon Aug 21 11:10:05 2006 @@ -2900,6 +2900,7 @@ return NULL; } + assert(tstate != NULL); assert(globals != NULL); f = PyFrame_New(tstate, co, globals, locals); if (f == NULL) @@ -3954,6 +3955,7 @@ PyFrame_New() that doesn't take locals, but does take builtins without sanity checking them. */ + assert(tstate != NULL); f = PyFrame_New(tstate, co, globals, NULL); if (f == NULL) return NULL; @@ -3977,7 +3979,6 @@ #else retval = PyEval_EvalFrameEx(f,0); #endif - assert(tstate != NULL); ++tstate->recursion_depth; Py_DECREF(f); --tstate->recursion_depth; @@ -4202,12 +4203,14 @@ if (v != NULL) { Py_ssize_t x; if (PyInt_Check(v)) { - x = PyInt_AsSsize_t(v); + /* XXX(nnorwitz): I think PyInt_AS_LONG is correct, + however, it looks like it should be AsSsize_t. + There should be a comment here explaining why. + */ + x = PyInt_AS_LONG(v); } - else if (v->ob_type->tp_as_number && - PyType_HasFeature(v->ob_type, Py_TPFLAGS_HAVE_INDEX) - && v->ob_type->tp_as_number->nb_index) { - x = v->ob_type->tp_as_number->nb_index(v); + else if (PyIndex_Check(v)) { + x = PyNumber_AsSsize_t(v, NULL); if (x == -1 && PyErr_Occurred()) return 0; } @@ -4223,10 +4226,8 @@ } #undef ISINDEX -#define ISINDEX(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x) || \ - ((x)->ob_type->tp_as_number && \ - PyType_HasFeature((x)->ob_type, Py_TPFLAGS_HAVE_INDEX) \ - && (x)->ob_type->tp_as_number->nb_index)) +#define ISINDEX(x) ((x) == NULL || \ + PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x)) static PyObject * apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */ @@ -4466,6 +4467,11 @@ locals = PyEval_GetLocals(); plain = 1; } + if (!globals || !locals) { + PyErr_SetString(PyExc_SystemError, + "globals and locals cannot be NULL"); + return -1; + } } else if (locals == Py_None) locals = globals; @@ -4561,6 +4567,14 @@ { /* This function implements 'variable += expr' when both arguments are strings. */ + Py_ssize_t v_len = PyString_GET_SIZE(v); + Py_ssize_t w_len = PyString_GET_SIZE(w); + Py_ssize_t new_len = v_len + w_len; + if (new_len < 0) { + PyErr_SetString(PyExc_OverflowError, + "strings are too large to concat"); + return NULL; + } if (v->ob_refcnt == 2) { /* In the common case, there are 2 references to the value @@ -4605,9 +4619,7 @@ /* Now we own the last reference to 'v', so we can resize it * in-place. */ - Py_ssize_t v_len = PyString_GET_SIZE(v); - Py_ssize_t w_len = PyString_GET_SIZE(w); - if (_PyString_Resize(&v, v_len + w_len) != 0) { + if (_PyString_Resize(&v, new_len) != 0) { /* XXX if _PyString_Resize() fails, 'v' has been * deallocated so it cannot be put back into 'variable'. * The MemoryError is raised when there is no value in Modified: stackless/trunk/Python/compile.c ============================================================================== --- stackless/trunk/Python/compile.c (original) +++ stackless/trunk/Python/compile.c Mon Aug 21 11:10:05 2006 @@ -143,7 +143,7 @@ PyFutureFeatures *c_future; /* pointer to module's __future__ */ PyCompilerFlags *c_flags; - int c_interactive; + int c_interactive; /* true if in interactive mode */ int c_nestlevel; struct compiler_unit *u; /* compiler state for current block */ @@ -204,8 +204,8 @@ const char *p, *name = PyString_AsString(ident); char *buffer; size_t nlen, plen; - if (privateobj == NULL || name == NULL || name[0] != '_' || - name[1] != '_') { + if (privateobj == NULL || !PyString_Check(privateobj) || + name == NULL || name[0] != '_' || name[1] != '_') { Py_INCREF(ident); return ident; } @@ -1990,11 +1990,8 @@ n = asdl_seq_LEN(s->v.FunctionDef.body); /* if there was a docstring, we need to skip the first statement */ for (i = docstring; i < n; i++) { - stmt_ty s2 = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i); - if (i == 0 && s2->kind == Expr_kind && - s2->v.Expr.value->kind == Str_kind) - continue; - VISIT_IN_SCOPE(c, stmt, s2); + st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i); + VISIT_IN_SCOPE(c, stmt, st); } co = assemble(c, 1); compiler_exit_scope(c); @@ -2217,6 +2214,10 @@ VISIT(c, expr, s->v.For.iter); ADDOP(c, GET_ITER); compiler_use_next_block(c, start); + /* XXX(nnorwitz): is there a better way to handle this? + for loops are special, we want to be able to trace them + each time around, so we need to set an extra line number. */ + c->u->u_lineno_set = false; ADDOP_JREL(c, FOR_ITER, cleanup); VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); @@ -2744,11 +2745,13 @@ case Global_kind: break; case Expr_kind: - VISIT(c, expr, s->v.Expr.value); if (c->c_interactive && c->c_nestlevel <= 1) { + VISIT(c, expr, s->v.Expr.value); ADDOP(c, PRINT_EXPR); } - else { + else if (s->v.Expr.value->kind != Str_kind && + s->v.Expr.value->kind != Num_kind) { + VISIT(c, expr, s->v.Expr.value); ADDOP(c, POP_TOP); } break; @@ -4139,7 +4142,10 @@ assert(d_bytecode >= 0); assert(d_lineno >= 0); - if (d_lineno == 0) + /* XXX(nnorwitz): is there a better way to handle this? + for loops are special, we want to be able to trace them + each time around, so we need to set an extra line number. */ + if (d_lineno == 0 && i->i_opcode != FOR_ITER) return 1; if (d_bytecode > 255) { @@ -4444,6 +4450,41 @@ return co; } + +/* For debugging purposes only */ +#if 0 +static void +dump_instr(const struct instr *i) +{ + const char *jrel = i->i_jrel ? "jrel " : ""; + const char *jabs = i->i_jabs ? "jabs " : ""; + char arg[128]; + + *arg = '\0'; + if (i->i_hasarg) + sprintf(arg, "arg: %d ", i->i_oparg); + + fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", + i->i_lineno, i->i_opcode, arg, jabs, jrel); +} + +static void +dump_basicblock(const basicblock *b) +{ + const char *seen = b->b_seen ? "seen " : ""; + const char *b_return = b->b_return ? "return " : ""; + fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n", + b->b_iused, b->b_startdepth, b->b_offset, seen, b_return); + if (b->b_instr) { + int i; + for (i = 0; i < b->b_iused; i++) { + fprintf(stderr, " [%02d] ", i); + dump_instr(b->b_instr + i); + } + } +} +#endif + static PyCodeObject * assemble(struct compiler *c, int addNone) { Modified: stackless/trunk/Python/errors.c ============================================================================== --- stackless/trunk/Python/errors.c (original) +++ stackless/trunk/Python/errors.c Mon Aug 21 11:10:05 2006 @@ -664,7 +664,7 @@ #undef PyErr_Warn -int +PyAPI_FUNC(int) PyErr_Warn(PyObject *category, char *message) { return PyErr_WarnEx(category, message, 1); Modified: stackless/trunk/Python/getargs.c ============================================================================== --- stackless/trunk/Python/getargs.c (original) +++ stackless/trunk/Python/getargs.c Mon Aug 21 11:10:05 2006 @@ -206,6 +206,9 @@ if (level == 0) max++; level++; + if (level >= 30) + Py_FatalError("too many tuple nesting levels " + "in argument format string"); break; case ')': if (level == 0) Modified: stackless/trunk/Python/import.c ============================================================================== --- stackless/trunk/Python/import.c (original) +++ stackless/trunk/Python/import.c Mon Aug 21 11:10:05 2006 @@ -62,9 +62,11 @@ Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) Python 2.5b3: 62101 (fix wrong code: for x, in ...) Python 2.5b3: 62111 (fix wrong code: x += yield) + Python 2.5c1: 62121 (fix wrong lnotab with for loops and + storing constants that should have been removed) . */ -#define MAGIC (62111 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62121 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the @@ -931,7 +933,8 @@ if (Py_VerboseFlag) PySys_WriteStderr("import %s # from %s\n", name, pathname); - write_compiled_module(co, cpathname, mtime); + if (cpathname) + write_compiled_module(co, cpathname, mtime); } m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname); Py_DECREF(co); @@ -1230,6 +1233,8 @@ for (i = 0; i < npath; i++) { PyObject *copy = NULL; PyObject *v = PyList_GetItem(path, i); + if (!v) + return NULL; #ifdef Py_USING_UNICODE if (PyUnicode_Check(v)) { copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v), @@ -3042,6 +3047,8 @@ if (m == NULL) goto failure; d = PyModule_GetDict(m); + if (d == NULL) + goto failure; if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure; if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure; Modified: stackless/trunk/Python/marshal.c ============================================================================== --- stackless/trunk/Python/marshal.c (original) +++ stackless/trunk/Python/marshal.c Mon Aug 21 11:10:05 2006 @@ -213,6 +213,10 @@ w_byte(TYPE_COMPLEX, p); temp = (PyFloatObject*)PyFloat_FromDouble( PyComplex_RealAsDouble(v)); + if (!temp) { + p->error = 1; + return; + } PyFloat_AsReprString(buf, temp); Py_DECREF(temp); n = strlen(buf); @@ -220,6 +224,10 @@ w_string(buf, (int)n, p); temp = (PyFloatObject*)PyFloat_FromDouble( PyComplex_ImagAsDouble(v)); + if (!temp) { + p->error = 1; + return; + } PyFloat_AsReprString(buf, temp); Py_DECREF(temp); n = strlen(buf); Modified: stackless/trunk/Python/pystate.c ============================================================================== --- stackless/trunk/Python/pystate.c (original) +++ stackless/trunk/Python/pystate.c Mon Aug 21 11:10:05 2006 @@ -361,28 +361,43 @@ /* Asynchronously raise an exception in a thread. Requested by Just van Rossum and Alex Martelli. To prevent naive misuse, you must write your own extension - to call this. Must be called with the GIL held. - Returns the number of tstates modified; if it returns a number - greater than one, you're in trouble, and you should call it again - with exc=NULL to revert the effect. This raises no exceptions. */ + to call this, or use ctypes. Must be called with the GIL held. + Returns the number of tstates modified (normally 1, but 0 if `id` didn't + match any known thread id). Can be called with exc=NULL to clear an + existing async exception. This raises no exceptions. */ int PyThreadState_SetAsyncExc(long id, PyObject *exc) { PyThreadState *tstate = PyThreadState_GET(); PyInterpreterState *interp = tstate->interp; PyThreadState *p; - int count = 0; + + /* Although the GIL is held, a few C API functions can be called + * without the GIL held, and in particular some that create and + * destroy thread and interpreter states. Those can mutate the + * list of thread states we're traversing, so to prevent that we lock + * head_mutex for the duration. + */ HEAD_LOCK(); for (p = interp->tstate_head; p != NULL; p = p->next) { - if (p->thread_id != id) - continue; - Py_CLEAR(p->async_exc); - Py_XINCREF(exc); - p->async_exc = exc; - count += 1; + if (p->thread_id == id) { + /* Tricky: we need to decref the current value + * (if any) in p->async_exc, but that can in turn + * allow arbitrary Python code to run, including + * perhaps calls to this function. To prevent + * deadlock, we need to release head_mutex before + * the decref. + */ + PyObject *old_exc = p->async_exc; + Py_XINCREF(exc); + p->async_exc = exc; + HEAD_UNLOCK(); + Py_XDECREF(old_exc); + return 1; + } } HEAD_UNLOCK(); - return count; + return 0; } Modified: stackless/trunk/Python/pythonrun.c ============================================================================== --- stackless/trunk/Python/pythonrun.c (original) +++ stackless/trunk/Python/pythonrun.c Mon Aug 21 11:10:05 2006 @@ -211,12 +211,16 @@ if (bimod == NULL) Py_FatalError("Py_Initialize: can't initialize __builtin__"); interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins dict"); Py_INCREF(interp->builtins); sysmod = _PySys_Init(); if (sysmod == NULL) Py_FatalError("Py_Initialize: can't initialize sys"); interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + Py_FatalError("Py_Initialize: can't initialize sys dict"); Py_INCREF(interp->sysdict); _PyImport_FixupExtension("sys", "sys"); PySys_SetPath(Py_GetPath()); Modified: stackless/trunk/Python/symtable.c ============================================================================== --- stackless/trunk/Python/symtable.c (original) +++ stackless/trunk/Python/symtable.c Mon Aug 21 11:10:05 2006 @@ -915,6 +915,8 @@ PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++st->st_cur->ste_tmpname); tmp = PyString_InternFromString(tmpname); + if (!tmp) + return 0; if (!symtable_add_def(st, tmp, DEF_LOCAL)) return 0; Py_DECREF(tmp); @@ -1323,8 +1325,11 @@ PyObject *name = (a->asname == NULL) ? a->name : a->asname; const char *base = PyString_AS_STRING(name); char *dot = strchr(base, '.'); - if (dot) + if (dot) { store_name = PyString_FromStringAndSize(base, dot - base); + if (!store_name) + return 0; + } else { store_name = name; Py_INCREF(store_name); Modified: stackless/trunk/README ============================================================================== --- stackless/trunk/README (original) +++ stackless/trunk/README Mon Aug 21 11:10:05 2006 @@ -1,5 +1,5 @@ -This is Python version 2.5 beta 3 -================================= +This is Python version 2.5 rc 1 +=============================== Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. All rights reserved. Modified: stackless/trunk/Tools/msi/msi.py ============================================================================== --- stackless/trunk/Tools/msi/msi.py (original) +++ stackless/trunk/Tools/msi/msi.py Mon Aug 21 11:10:05 2006 @@ -89,7 +89,8 @@ '_msi.pyd', '_ctypes.pyd', '_ctypes_test.pyd', - '_sqlite3.pyd' + '_sqlite3.pyd', + '_hashlib.pyd' ] # Well-known component UUIDs Modified: stackless/trunk/configure ============================================================================== --- stackless/trunk/configure (original) +++ stackless/trunk/configure Mon Aug 21 11:10:05 2006 @@ -1599,7 +1599,7 @@ # disables platform specific features beyond repair. # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE # has no effect, don't bother defining them - Darwin/[78].*) + Darwin/[789].*) define_xopen_source=no ;; Modified: stackless/trunk/configure.in ============================================================================== --- stackless/trunk/configure.in (original) +++ stackless/trunk/configure.in Mon Aug 21 11:10:05 2006 @@ -247,7 +247,7 @@ # disables platform specific features beyond repair. # On Mac OS X 10.3, defining _POSIX_C_SOURCE or _XOPEN_SOURCE # has no effect, don't bother defining them - Darwin/@<:@78@:>@.*) + Darwin/@<:@789@:>@.*) define_xopen_source=no ;; Modified: stackless/trunk/setup.py ============================================================================== --- stackless/trunk/setup.py (original) +++ stackless/trunk/setup.py Mon Aug 21 11:10:05 2006 @@ -902,8 +902,12 @@ # Curses support, requiring the System V version of curses, often # provided by the ncurses library. + panel_library = 'panel' if (self.compiler.find_library_file(lib_dirs, 'ncursesw')): curses_libs = ['ncursesw'] + # Bug 1464056: If _curses.so links with ncursesw, + # _curses_panel.so must link with panelw. + panel_library = 'panelw' exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) elif (self.compiler.find_library_file(lib_dirs, 'ncurses')): @@ -926,9 +930,9 @@ # If the curses module is enabled, check for the panel module if (module_enabled(exts, '_curses') and - self.compiler.find_library_file(lib_dirs, 'panel')): + self.compiler.find_library_file(lib_dirs, panel_library)): exts.append( Extension('_curses_panel', ['_curses_panel.c'], - libraries = ['panel'] + curses_libs) ) + libraries = [panel_library] + curses_libs) ) # Andrew Kuchling's zlib module. Note that some versions of zlib @@ -1349,6 +1353,7 @@ self.use_system_libffi = False include_dirs = [] extra_compile_args = [] + extra_link_args = [] sources = ['_ctypes/_ctypes.c', '_ctypes/callbacks.c', '_ctypes/callproc.c', @@ -1363,9 +1368,21 @@ # XXX Is this still needed? ## extra_link_args.extend(['-read_only_relocs', 'warning']) + elif sys.platform == 'sunos5': + # XXX This shouldn't be necessary; it appears that some + # of the assembler code is non-PIC (i.e. it has relocations + # when it shouldn't. The proper fix would be to rewrite + # the assembler code to be PIC. + # This only works with GCC; the Sun compiler likely refuses + # this option. If you want to compile ctypes with the Sun + # compiler, please research a proper solution, instead of + # finding some -z option for the Sun compiler. + extra_link_args.append('-mimpure-text') + ext = Extension('_ctypes', include_dirs=include_dirs, extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, libraries=[], sources=sources, depends=depends) -------------- next part -------------- _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 22 10:27:40 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:27:40 +0200 (CEST) Subject: [Stackless-checkins] r51467 - stackless/Python-2.4.3/dev/Makefile.pre.in Message-ID: <20060822082740.78BA11E400D@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:27:40 2006 New Revision: 51467 Modified: stackless/Python-2.4.3/dev/Makefile.pre.in Log: Added teststackless Makefile section, from patch by Jeff Senn. Modified: stackless/Python-2.4.3/dev/Makefile.pre.in ============================================================================== --- stackless/Python-2.4.3/dev/Makefile.pre.in (original) +++ stackless/Python-2.4.3/dev/Makefile.pre.in Tue Aug 22 10:27:40 2006 @@ -584,6 +584,9 @@ -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall +teststackless: all platform + pushd Stackless/unittests; $(RUNSHARED) ../../$(BUILDPYTHON) -E -tt runAll.py; popd + # Like testall, but with a single pass only buildbottest: all platform $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall -rw _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 22 10:32:37 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:32:37 +0200 (CEST) Subject: [Stackless-checkins] r51468 - stackless/trunk/Makefile.pre.in Message-ID: <20060822083237.292E51E4009@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:32:36 2006 New Revision: 51468 Modified: stackless/trunk/Makefile.pre.in Log: Added teststackless Makefile section, from patch by Jeff Senn. Ported from r51467. Modified: stackless/trunk/Makefile.pre.in ============================================================================== --- stackless/trunk/Makefile.pre.in (original) +++ stackless/trunk/Makefile.pre.in Tue Aug 22 10:32:36 2006 @@ -621,6 +621,9 @@ -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall $(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall +teststackless: all platform + pushd Stackless/unittests; $(RUNSHARED) ../../$(BUILDPYTHON) -E -tt runAll.py; popd + # Run the unitests for both architectures in a Universal build on OSX # Must be run on an Intel box. testuniversal: all platform _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Aug 25 15:01:55 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 25 Aug 2006 15:01:55 +0200 (CEST) Subject: [Stackless-checkins] r51612 - in stackless/branches/release25-maint: PCbuild/publish_binaries.py Stackless/module/stacklessmodule.c Message-ID: <20060825130155.976BC1E4004@bag.python.org> Author: richard.tew Date: Fri Aug 25 15:01:54 2006 New Revision: 51612 Modified: stackless/branches/release25-maint/PCbuild/publish_binaries.py stackless/branches/release25-maint/Stackless/module/stacklessmodule.c Log: Ported r51609. Added Jeff Senn's patch to allow running of stackless.run() on other threads other than the initial one. Corrected the publish_binaries.py script to handle the actual SVN structure rather than how I had it laid out on my harddrive. Modified: stackless/branches/release25-maint/PCbuild/publish_binaries.py ============================================================================== --- stackless/branches/release25-maint/PCbuild/publish_binaries.py (original) +++ stackless/branches/release25-maint/PCbuild/publish_binaries.py Fri Aug 25 15:01:54 2006 @@ -1,7 +1,7 @@ from zipfile import * import os, sys, md5 -exp_path = r"..\..\binaries-pc" +exp_path = r"..\..\..\binaries-pc" prog = """ import md5 Modified: stackless/branches/release25-maint/Stackless/module/stacklessmodule.c ============================================================================== --- stackless/branches/release25-maint/Stackless/module/stacklessmodule.c (original) +++ stackless/branches/release25-maint/Stackless/module/stacklessmodule.c Fri Aug 25 15:01:54 2006 @@ -216,9 +216,9 @@ int err; if (ts->st.main == NULL) return PyStackless_RunWatchdog_M(timeout); - if (ts != slp_initial_tstate || ts->st.current != ts->st.main) + if (ts->st.current != ts->st.main) RUNTIME_ERROR( - "run() must be run from the main thread's main tasklet.", + "run() must be run from the main tasklet.", NULL); if (timeout <= 0) { _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Aug 4 16:28:41 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 4 Aug 2006 16:28:41 +0200 (CEST) Subject: [Stackless-checkins] r51101 - in stackless/trunk/Stackless: embedemo/watchdog-c module/channelobject.c module/taskletobject.c platf/switch_ppc_macosx.h unittests/test_pickle.py Message-ID: <20060804142841.4D9801E4003@bag.python.org> Author: richard.tew Date: Fri Aug 4 16:28:40 2006 New Revision: 51101 Added: stackless/trunk/Stackless/embedemo/watchdog-c/ - copied from r51096, stackless/Python-2.4.3/dev/Stackless/embedemo/watchdog-c/ Modified: stackless/trunk/Stackless/module/channelobject.c stackless/trunk/Stackless/module/taskletobject.c stackless/trunk/Stackless/platf/switch_ppc_macosx.h stackless/trunk/Stackless/unittests/test_pickle.py Log: Changes merged in from the Stackless 2.4.3 branch.. Revision 47178: If your tasklet subclass was pickled, it would be reduced with the tasklet class rather than the subclass itself. This meant when it was unpickled, it would be an instance of tasklet, rather than your subclass. Now reduce uses the type of the tasklet, rather than being hardcoded to use the tasklet class itself. Revision 47195: An example of using the watchdog in C. Also implements a BeNice yielding function, but uses soft switching, so any tasklets which are blocked on it can be pickled. Needs a Sleep function, and perhaps some more work. Revision 47196: Changed the __reduce__ function for channels so that subclasses will get their class persisted and will be unpickled with the same custom class (rather than forced to have the tasklet class). Revision 47240: Patch from Jeff Senn to fix OS X compilation problems. One prevented Stackless from being compiled because one of the registers preserved was now clobbered in the generated assembly code. The other was a warning because of the types used in slp_switch. Modified: stackless/trunk/Stackless/module/channelobject.c ============================================================================== --- stackless/trunk/Stackless/module/channelobject.c (original) +++ stackless/trunk/Stackless/module/channelobject.c Fri Aug 4 16:28:40 2006 @@ -16,7 +16,7 @@ { PyChannelObject *ch = (PyChannelObject *) ob; - /* + /* * remove all tasklets and hope they will die. * Note that the channel might receive new actions * during tasklet deallocation, so we don't even know @@ -24,7 +24,7 @@ */ while (ch->balance) { int dir = ch->balance > 0 ? 1 : -1; - + ob = (PyObject *) slp_channel_remove(ch, dir); Py_DECREF(ob); } @@ -84,7 +84,7 @@ /* the special case to remove a specific tasklet */ PyTaskletObject * -slp_channel_remove_specific(PyChannelObject *channel, int dir, +slp_channel_remove_specific(PyChannelObject *channel, int dir, PyTaskletObject *task) { /* note: we assume that the task is in the channel! */ @@ -315,22 +315,22 @@ PyObject *args, *ret; PyObject *type, *value, *traceback; args = ret = NULL; - + args = Py_BuildValue("(OOii)", channel, task, sending, willblock); if (args != NULL) { - + PyErr_Fetch(&type, &value, &traceback); ret = PyObject_Call(channel_hook, args, NULL); - + if (ret != NULL) { PyErr_Restore(type, value, traceback); - } + } else { Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); } - + Py_XDECREF(ret); Py_DECREF(args); } @@ -368,7 +368,7 @@ static PyObject * PyChannel_Send_M(PyChannelObject *self, PyObject *arg) { - return PyStackless_CallMethod_Main((PyObject *) self, "send", "(O)", + return PyStackless_CallMethod_Main((PyObject *) self, "send", "(O)", arg); } @@ -390,7 +390,7 @@ } -/* +/* * This generic function exchanges values over a channel. * the action can be either send or receive. * Note that this works even across threads. The insert action @@ -527,7 +527,7 @@ static CHANNEL_SEND_EXCEPTION_HEAD(wrap_channel_send_exception) { - return PyObject_CallMethod((PyObject *) self, "send_exception", + return PyObject_CallMethod((PyObject *) self, "send_exception", "(OO)", klass, args); } @@ -654,11 +654,11 @@ # got nested structure ch.send_sequence(parser()) - parser() + parser() *********************************************************/ - + /* * iterator extension. * This is probably the fastest way to run through a channel @@ -697,7 +697,7 @@ over the channel. Combined with a generator, this is\n\ a very efficient way to build fast pipes."; -/* +/* * this is the traight-forward and simple implementation, * but here we have almost no speedup, since all switches * are hard. @@ -818,7 +818,7 @@ ts->frame = f->f_back; Py_DECREF(f); return retval; -} +} static PyObject * channel_send_sequence(PyChannelObject *self, PyObject *v) @@ -900,7 +900,7 @@ t = t->next; } tup = Py_BuildValue("(O()(iiO))", - &PyChannel_Type, + ch->ob_type, ch->balance, ch->flags, lis @@ -925,7 +925,7 @@ if (!PyArg_ParseTuple(args, "iiO!:channel", &balance, - &flags, + &flags, &PyList_Type, &lis)) return NULL; @@ -1053,7 +1053,7 @@ PyTypeObject *t = &_PyChannel_Type; if ( (t = PyFlexType_Build("stackless", "channel", t->tp_doc, - t, sizeof(PyChannel_HeapType), + t, sizeof(PyChannel_HeapType), channel_cmethods) ) == NULL) return -1; PyChannel_TypePtr = t; Modified: stackless/trunk/Stackless/module/taskletobject.c ============================================================================== --- stackless/trunk/Stackless/module/taskletobject.c (original) +++ stackless/trunk/Stackless/module/taskletobject.c Fri Aug 4 16:28:40 2006 @@ -277,7 +277,7 @@ if (PyList_Reverse(lis)) goto err_exit; assert(t->cstate != NULL); tup = Py_BuildValue("(O()(" TASKLET_TUPLEFMT "))", - &PyTasklet_Type, + t->ob_type, t->flags, t->tempval, t->cstate->nesting_level, Modified: stackless/trunk/Stackless/platf/switch_ppc_macosx.h ============================================================================== --- stackless/trunk/Stackless/platf/switch_ppc_macosx.h (original) +++ stackless/trunk/Stackless/platf/switch_ppc_macosx.h Fri Aug 4 16:28:40 2006 @@ -33,14 +33,15 @@ #define STACK_MAGIC 3 #define REGS_TO_SAVE "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", \ - "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r31", \ + "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", \ "cr2", "cr3", "cr4" static int slp_switch(void) { static int x = 0; - register int *stackref, stsizediff; + register intptr_t *stackref; + register int stsizediff; __asm__ volatile ( "; asm block 1\n" : /* no outputs */ @@ -70,7 +71,7 @@ * further self-processing support */ -/* +/* * if you want to add self-inspection tools, place them * here. See the x86_msvc for the necessary defines. * These features are highly experimental und not Modified: stackless/trunk/Stackless/unittests/test_pickle.py ============================================================================== --- stackless/trunk/Stackless/unittests/test_pickle.py (original) +++ stackless/trunk/Stackless/unittests/test_pickle.py Fri Aug 4 16:28:40 2006 @@ -10,6 +10,9 @@ VERBOSE = False glist = [] +def nothing(): + pass + def accumulate(ident, func, *args): rval = (ident, func(*args)) glist.append(rval) @@ -39,6 +42,9 @@ def run(self): self.channel.receive() +class CustomTasklet(tasklet): + __slots__ = [ "name" ] + def listtest(n, when): for i in range(n): if i == when: @@ -175,6 +181,12 @@ have_fromkeys = False class TestConcretePickledTasklets(TestPickledTasklets): + def testClassPersistence(self): + t1 = CustomTasklet(nothing)() + s = pickle.dumps(t1) + t2 = pickle.loads(s) + self.assertEquals(t1.__class__, t2.__class__) + def testGenerator(self): self.run_pickled(genoutertest, 20, 13) _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From stackless-checkins-bounces at stackless.com Mon Aug 14 10:14:17 2006 From: stackless-checkins-bounces at stackless.com (stackless-checkins-bounces at stackless.com) Date: Mon, 14 Aug 2006 10:14:17 +0200 Subject: [Python-checkins] Your message to Stackless-checkins awaits moderator approval Message-ID: Your mail to 'Stackless-checkins' with the subject r51275 - in stackless/trunk: Doc/api/api.tex Doc/api/exceptions.tex Doc/api/intro.tex Doc/api/refcounts.dat Doc/commontex/boilerplate.tex Doc/dist/dist.tex Doc/doc/doc.tex Doc/ext/newtypes.tex Doc/ext/windows.tex Doc/howto/doanddont.tex Doc/inst/inst.tex Doc/lib/email.tex Doc/lib/emailgenerator.tex Doc/lib/lib.tex Doc/lib/libanydbm.tex Doc/lib/libbase64.tex Doc/lib/libbinascii.tex Doc/lib/libbsddb.tex Doc/lib/libcompileall.tex Doc/lib/libcsv.tex Doc/lib/libctypes.tex Doc/lib/libfuncs.tex Doc/lib/libgettext.tex Doc/lib/libimp.tex Doc/lib/libinspect.tex Doc/lib/liblogging.tex Doc/lib/libmailbox.tex Doc/lib/libmimetypes.tex Doc/lib/libnew.tex Doc/lib/liboptparse.tex Doc/lib/libossaudiodev.tex Doc/lib/libpickle.tex Doc/lib/libpkgutil.tex Doc/lib/libposixpath.tex Doc/lib/librandom.tex Doc/lib/libre.tex Doc/lib/libreadline.tex Doc/lib/libshelve.tex Doc/lib/libsocket.tex Doc/lib/libsocksvr.tex Doc/lib/libsqlite3.tex Doc/lib/libstdtypes.tex Doc/lib/libstringio.tex Doc/lib/l! ibsubprocess.tex Doc/lib/libsys.tex Doc/lib/libtime.tex Doc/lib/libturtle.tex Doc/lib/libtypes.tex Doc/lib/libundoc.tex Doc/lib/libunicodedata.tex Doc/lib/liburllib.tex Doc/lib/liburllib2.tex Doc/lib/libuuid.tex Doc/lib/libweakref.tex Doc/lib/libwebbrowser.tex Doc/lib/libzipfile.tex Doc/lib/sqlite3/complete_statement.py Doc/lib/tkinter.tex Doc/mac/libmacfs.tex Doc/mac/libmacos.tex Doc/mac/using.tex Doc/ref/ref3.tex Doc/whatsnew/whatsnew20.tex Doc/whatsnew/whatsnew21.tex Doc/whatsnew/whatsnew23.tex Doc/whatsnew/whatsnew24.tex Doc/whatsnew/whatsnew25.tex Include/patchlevel.h Include/pyerrors.h Include/weakrefobject.h Lib/binhex.py Lib/bsddb/test/test_basics.py Lib/compiler/future.py Lib/compiler/transformer.py Lib/ctypes/__init__.py Lib/ctypes/test/test_varsize_struct.py Lib/ctypes/util.py Lib/distutils/__init__.py Lib/distutils/msvccompiler.py Lib/doctest.py Lib/email/__init__.py Lib/email/message.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py Lib/email! /utils.py Lib/encodings/mbcs.py Lib/gzip.py Lib/httplib.py Lib/idlelib/CREDITS.txt Lib/idlelib/CallTipWindow.py Lib/idlelib/CallTips.py Lib/idlelib/CodeContext.py Lib/idlelib/ColorDelegator.py Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/ParenMatch.py Lib/idlelib/PyShell.py Lib/idlelib/ScriptBinding.py Lib/id Is being held until the list moderator can review it for approval. The reason it is being held: Message body is too big: 568776 bytes with a limit of 500 KB Either the message will get posted to the list, or you will receive notification of the moderator's decision. If you would like to cancel this posting, please visit the following URL: http://www.stackless.com/mailman/confirm/stackless-checkins/b64060fa259ae6080a6933c17d5b5567557f7bd1 _______________________________________________ Python-checkins mailing list Python-checkins at python.org http://mail.python.org/mailman/listinfo/python-checkins From python-checkins at python.org Tue Aug 22 10:03:56 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 22 Aug 2006 10:03:56 +0200 (CEST) Subject: [Stackless-checkins] r51462 - stackless/tags Message-ID: <20060822080356.D2FC11E4009@bag.python.org> Author: richard.tew Date: Tue Aug 22 10:03:56 2006 New Revision: 51462 Added: stackless/tags/ Log: Added a tags folder, so I can mark the different Python releases in the stackless trunk and branches. It is convenient to be able to get the source for any of these so that bugs which are hidden by core Python changes can be worked on by getting the releases they were fixed in. _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Aug 25 15:16:01 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 25 Aug 2006 15:16:01 +0200 (CEST) Subject: [Stackless-checkins] r51614 - stackless/binaries-pc/python25.zip stackless/binaries-pc/python25.zip.md5.py Message-ID: <20060825131601.CBE921E4004@bag.python.org> Author: richard.tew Date: Fri Aug 25 15:15:37 2006 New Revision: 51614 Added: stackless/binaries-pc/python25.zip (contents, props changed) stackless/binaries-pc/python25.zip.md5.py (contents, props changed) Log: Added 2.5c1 Stackless binaries. Added: stackless/binaries-pc/python25.zip ============================================================================== Binary file. No diff available. Added: stackless/binaries-pc/python25.zip.md5.py ============================================================================== --- (empty file) +++ stackless/binaries-pc/python25.zip.md5.py Fri Aug 25 15:15:37 2006 @@ -0,0 +1,8 @@ + +import md5 +expected = "759db858571ce0c5064c74a9f0bc5c9d" +fname = r"python25.zip" +print "expected digest", expected +received = md5.md5(file(fname, "rb").read()).hexdigest() +print ("matched", "NOT MATCHED!!") [received != expected] +raw_input("press enter to continue") _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Tue Aug 15 09:19:39 2006 From: python-checkins at python.org (richard.tew) Date: Tue, 15 Aug 2006 09:19:39 +0200 (CEST) Subject: [Stackless-checkins] r51299 - stackless/trunk/Stackless/core/stackless_impl.h Message-ID: <20060815071939.DBA9A1E4006@bag.python.org> Author: richard.tew Date: Tue Aug 15 09:19:39 2006 New Revision: 51299 Modified: stackless/trunk/Stackless/core/stackless_impl.h Log: The arguments in the prototype declaration for slp_gen_send_ex were mismatched, and this gave a compilation error on Ubuntu Dapper with GCC 4.0.3, despite compiling fine on Windows with VS2003. Reported by S?bastien Pierre. Modified: stackless/trunk/Stackless/core/stackless_impl.h ============================================================================== --- stackless/trunk/Stackless/core/stackless_impl.h (original) +++ stackless/trunk/Stackless/core/stackless_impl.h Tue Aug 15 09:19:39 2006 @@ -110,7 +110,7 @@ PyAPI_DATA(PyTypeObject) PyGen_Type; PyAPI_FUNC(PyObject *) PyGenerator_New(struct _frame *f); -PyAPI_FUNC(PyObject *) slp_gen_send_ex(PyObject *gen, PyObject *arg, int exc); +PyAPI_FUNC(PyObject *) slp_gen_send_ex(PyGenObject *gen, PyObject *arg, int exc); #define PyGenerator_Check(op) PyObject_TypeCheck(op, &PyGen_Type) PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins