Piecewise-cubic lookup table generator
I needed to generate some C code for a fast lookup table using piecewise-cubic interpolation. If anybody else needs this, the Python code for it is at http://tinyurl.com/92zcs (alt.source, Google Groups). Will Ware -- http://mail.python.org/mailman/listinfo/python-list
Re: handy stacktrace class
Oh. Never mind, then. -- http://mail.python.org/mailman/listinfo/python-list
handy stacktrace class
I was fooling with some Python code, and starting to miss the
Exception.printStackTrace() feature in Java. Here is a stab at
something roughly analogous, which puts together a stacktrace
as an XML document.
import xml.dom.minidom
class Stacktrace(xml.dom.minidom.Document):
def __init__(self):
import sys
xml.dom.minidom.Document.__init__(self)
stacktrace = self.createElement("stacktrace")
self.appendChild(stacktrace)
try:
raise Exception
except:
tb = sys.exc_traceback
x = tb.tb_frame.f_back
while x != None:
f = x.f_code
frame = self.createElement("frame")
frame.setAttribute("func", f.co_name)
frame.setAttribute("file", f.co_filename)
frame.setAttribute("line", repr(f.co_firstlineno))
stacktrace.appendChild(frame)
x = x.f_back
def __repr__(self):
import xml.dom.ext
class MyStream:
def __init__(self):
self.str = ""
def write(self, x):
self.str += x
stream = MyStream()
xml.dom.ext.PrettyPrint(self, stream)
return stream.str[:-1] # trim trailing newline
The rational for doing this as an XML document was, uh, gee, I
thought I had a good reason at the time. I think I've seen XML
sequences of stacktraces elsewhere and it looked like a good idea.
My brief time of muddling about with xml.dom.minidom makes me
think that elements are inherently tied to a particular document
and can't just be lifted and moved to another document, as one
might want to do to, say, build a sequence of stacktraces while
debugging something. But I'm sure there's some kind of workaround
for that.
--
http://mail.python.org/mailman/listinfo/python-list
Pyrex on Darwin, gcc 3.3 optimization trouble
I am trying to build a Pyrex module on Mac OS X version 10.3.9 (don't know which big cat that is). It already builds fine on Mandrake Linux and Windows XP. I have one source file where gcc hangs if given an optimization setting of -O2 or -O3, but a level of -O works fine. Can anybody suggest an approach to debugging this? I'm comfortable on Linux but I can't find my way out of a paper bag on a Mac. Also, is there a Pyrex or distutils option for limiting the compiler optimization level, ideally on a per-platform basis? Thanks much Will Ware -- http://mail.python.org/mailman/listinfo/python-list
Re: Pyrex on Darwin, gcc 3.3 optimization trouble
In case anybody else has this problem, the solution is to add "-O" in extra_compile_args, which will override the "-O3" normally used. This is done in the setup.py file. -- http://mail.python.org/mailman/listinfo/python-list
Freezing a static executable
I am trying to freeze a static executable. I built a static Python executable this way: ./configure --disable-shared --prefix=/usr/local make make install Even that didn't give me a really static executable, though: $ ldd /usr/local/bin/python linux-gate.so.1 => (0xe000) libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7f44000) libdl.so.2 => /lib/libdl.so.2 (0xb7f4) libutil.so.1 => /lib/libutil.so.1 (0xb7f3c000) libm.so.6 => /lib/tls/libm.so.6 (0xb7f17000) libc.so.6 => /lib/tls/libc.so.6 (0xb7de9000) /lib/ld-linux.so.2 (0xb7f7) Then I typed this: /usr/local/bin/python /home/wware/Python-2.4.1/Tools/freeze/freeze.py foo.py ldd foo $ ldd foo linux-gate.so.1 => (0xe000) libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7f5a000) libdl.so.2 => /lib/libdl.so.2 (0xb7f56000) libutil.so.1 => /lib/libutil.so.1 (0xb7f52000) libm.so.6 => /lib/tls/libm.so.6 (0xb7f2d000) libc.so.6 => /lib/tls/libc.so.6 (0xb7dff000) /lib/ld-linux.so.2 (0xb7f86000) What stupid thing am I doing wrong? TIA for any advice Will Ware -- http://mail.python.org/mailman/listinfo/python-list
Restrictive APIs for Python
Python has no inherent provision for a restrictive API that blocks
accesses to methods and variables outside an allowed set.
Inexperienced Python programmers may fail to adhere to an agreed-upon
API, directly accessing the private internals of a class. Adherence to
defined APIs is a good thing. This function allows a class to specify
its API, and raise AttributeErrors for disallowed accesses.
def restrictiveApi(klas):
class newklas:
def __init__(self, *args):
self.__inst = apply(klas, args)
def __getattr__(self, attr):
# If the attribute is in the permitted API, then return
# the correct thing, no matter who asks for it.
#
if attr in self.__inst._PUBLIC:
return getattr(self.__inst, attr)
# If the attribute is outside the permitted API, then
# return it only if the calling class is in the list of
# friends. Otherwise raise an AttributeError.
#
elif hasattr(self.__inst, '_FRIENDS'):
# find the class of the method that called us
try:
raise Exception
except:
import sys
tb = sys.exc_info()[2]
callerClass = tb.tb_frame.f_back.\
f_locals['self'].__class__
# if it's a friend class, return the requested thing
if callerClass.__name__ in self.__inst._FRIENDS:
return getattr(self.__inst, attr)
# if not a friend, raise an AttributeError
raise AttributeError, attr
return newklas
To use this, a class needs to define two class variables, _PUBLIC and
_FRIENDS, both being lists (or tuples) of strings. The _PUBLIC list
gives the names of all methods and variables that should be considered
public, i.e. any other class may use them. The _FRIENDS list gives the
names of classes that are allowed free access to all methods and
variables in the protected class. The _FRIENDS list is optional.
Having defined _PUBLIC and optionally _FRIENDS, use something like the
following to protect your class. Restricting the API will incur a
performance overhead, so it's best to do it under the control of some
sort of debug flag.
if debug_flag:
from restrictive import restrictiveApi
MyClass = restrictiveApi(MyClass)
Examples ==
class ClassUnderTest:
# This class has a private variable called privateX. It can be
# set using the setX() method or gotten using the x() method.
# If another class appears in the _FRIENDS list, that class
# can access privateX directly.
#
_PUBLIC = ('x', 'setX')
_FRIENDS = ('FriendClass',)
def __init__(self, x): # __init__ is always callable by anybody
self.setX(x)
def x(self): # callable by anybody
return self.privateX
def setX(self, x): # callable by anybody
self.privateX = x
ClassUnderTest = restrictiveApi(ClassUnderTest)
class FriendClass:
def getX(self, cut):
return cut.privateX # this works fine
class StrangerClass:
def getX(self, cut):
return cut.privateX # this raises an AttributeError
--
http://mail.python.org/mailman/listinfo/python-list
Re: Restrictive APIs for Python
Gabriel Genellina wrote: > In Python, the usual way of saying "don't play with me" is prepending > an underscore: _private Thanks, I am familiar with that. > BTW, have you *ever* tested your code? Yes, we have a QA process. The problem is not that the code doesn't work, it does. It was developed by a mix of more and less experienced programmers, and early in the code's history, some hadn't been trained on the benefits of complying to an API, or Pythonic idioms like the leading underscore. So the code varies in its clarity, and some maintenance chores aren't as pleasant as they might be. I have found that the work of more experienced programmers often includes improving the quality of code written by less experienced programmers. Is this inconsistent with your own experience? -- http://mail.python.org/mailman/listinfo/python-list
Interpreting python profiler results
I'm working on a piece of software that uses PyQt and PyOpenGL for drawing acceleration. While profiling it to find opportunities to speed things up, I got this from the profiler: ncalls tottime percall cumtime percall filename:lineno(function) 12108/12084 55.3900.005 55.3900.005 :0(getattr) 29340.4300.0001.2400.000 files_mmp.py:344(_read_atom) 10.3100.310 59.240 59.240 :0(exec_loop) 29340.2100.0000.3100.000 chem.py:1774(best_atomtype_for_numbonds) 87370.1500.0000.1900.000 :0(map) 29440.1500.0000.4500.000 chem.py:288(__init__) more. I assume ":0(getattr)" means a getattr function in either PyQt or PyOpenGL. I grepped the sources of both looking for getattr, and it doesn't appear in PyQt but appears frequently in PyOpenGL. Does anybody know if I am correct in my conclusion that most of the program's time is being spent in some getattr function in PyOpenGL? Thanks Will Ware -- http://mail.python.org/mailman/listinfo/python-list
