me> I resemble that remark...
jc> ^^^^^^^^
jc> Resent?
My apologies. That was Bad American Humor(tm). It comes from the Garfield
comic strip. The main character is a very fat cat (Garfield) who uses that
response when he thinks he's being insulted but he's not sure (typically
when some other character in the strip comments on his culinary habits or
his waistline).
Skip Montanaro | http://www.mojam.com/
skip(a)mojam.com | http://www.musi-cal.com/
"Languages that change by catering to the tastes of non-users tend not to do
so well." - Doug Landauer
Currently, when you replace a class definition with an updated
version, it's really difficult to change existing class instances;
you'd have to essentially sweep every Python object and check if it's
an instance, starting at roots such as __main__ and sys.modules. This
makes developing code in a long-running process difficult, Zope being
the best example of this. When you modify a class definition used by
Zope code, you can't update existing instances floating around in
memory.
Over dinner, a friend and I were discussing this, and we thought it
probably isn't difficult to add an extra level of indirection to allow
fixing this. The only other option we could think of is either the
complete scan of all objects, or inserting a forwarding pointer into
PyClassObjects that points to the replacing class if !NULL, and then
chase pointers when accessing PyInstanceObject->in_class.
A quick hack to implement the extra indirection took about
half an hour. It does these things:
* Defines a PyClassHandle type:
struct _PyClassHandle {
PyClassHandle *next; /* ptr to next PyClassHandle in linked list */
PyClassObject *klass; /* The class object */
} ;
* The in_class attribute of PyInstanceObject becomes a
PyClassHandle* instead of a PyClassObject*, and all code
such as inst->in_class becomes inst->in_class->klass.
* As a quick hack to allow changing the class object referenced
by a handle, I added a .forward( <newclassobject> ) method to
class objects. This basically does self.handle->klass =
<newclassobject>.
The end result is that obj.__class__.forward(newclass) changes obj to
be an instance of newclass, and all other instances of obj.__class__
also mutate to become newclass instances.
Making this purely automatic seems hard; you'd have to catch things
like 'import ftplib; ftplib.FTP = myclass', which would require
automatically calling ftplib.FTP.forward( myclass ) to make all
existing FTP instances mutate. Would it be worthwhile to export some
hook for doing this in 1.6? The cost is adding an extra pointer deref
to all access to PyInstanceObject->in_class.
(This could probably also be added to ExtensionClass, and probably
doesn't need to be added to core Python to help out Zope. Just a
thought...)
--
A.M. Kuchling http://starship.python.net/crew/amk/
Here the skull of a consumptive child becomes part of a great machine for
calculating the motions of the stars. Here, a yellow bird frets within the
ribcage of an unjust man.
-- Welcome to Orqwith, in DOOM PATROL #22
Just to wrap up this thread (as if): a couple of people have pointed out
that two of the suggestions that came up w.r.t. Python syntax are really
about eliminating need for assignment-as-an-operator:
do:
line = readline()
while line:
print line
gets rid of a need for:
while (line = readline()):
print line
without the confusing-for-newcomers:
while 1:
line = readline()
if not line: break
print line
and the generalized case statement:
if x is:
expr1, expr2:
x is the result of expr1 or expr2
expr3:
x is the result of expr3
else:
x is undefined or None
does:
if ((x = expr1) or (x = expr2)):
code using x
elif x = expr3:
code using x
else:
code
(Don't know what other people's experience is, but this comes up a lot in
my code when I'm doing Awk-style coding, i.e. when RE matching drives
execution.) Looking through some C++ code I wrote last year, these two
cases (loop control and capturing successful conditions) account for at
least three quarters of my uses of assignment-as-operator.
My thanks to people for pointing this out,
Greg
Hi everybody,
I've just uploaded a new Unicode snapshot.
It includes a brand
new UTF-16 codec which is BOM mark aware, meaning that it recognizes
BOM marks on input and adjusts the byte order accordingly. On output
you can choose to have BOM marks written or specifically define
a byte order to use.
Also new in this snapshot is configuration code which figures
out the byte order on the installation machine... I looked
everywhere in the Python source code but couldn't find any
hint whether this was already done in some place, so I simply
added some autoconf magic to have two new symbols defined:
BYTEORDER_IS_LITTLE_ENDIAN and BYTEORDER_IS_BIG_ENDIAN
(mutually exclusive of course).
BTW, I changed the hash method of Unicode objects to use the
UTF-8 string as basis for the hash code. This means that
u'abc' and 'abc' will now be treated as the same dictionary
key !
Some documentation also made into the snapshot. See the
file Misc/unicode.txt for all the interesting details about
the implementation.
Note that the web page provides a prepatched version of the
interpreter for your convenience... just download, run
./configure and make and your done. Could someone with
access to a MS VC compiler please update the project files
and perhaps post me some feedback about any glitches ?! I have
never compiled Python on Windows myself and don't have the time
to figure out just now :-/. Thanks :-)
--
Marc-Andre Lemburg
______________________________________________________________________
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
I've got the first version of a patch against the current CVS tree
to treat ints and longs identically at the Python programmer's level:
ftp://starship.python.net/pub/crew/amk/new/long-python-patch-1
As an acid test, this patch changes PyInt_FromLong() to just call
PyLong_FromLong(). After some minor changes to the test suite to skip
tests of OverflowError, and to account for the string representation
of integers having an 'L' on the end, Python gets through the
test_builtin test suite. (test_pickle and test_cpickle fail with this
aggressive patch; I won't bother to fix that.) Obviously, these
changes won't be in any final version.
The patch adds a new API function:
extern DL_IMPORT(int) PyIntOrLong_AsLong Py_PROTO((PyObject *, long *));
It returns -1 if the PyObject is a long integer that's too large to
fit into a C long, so it's used like this:
if (PyIntOrLong_AsLong(fno, &value)) {
PyErr_SetString(...
The pystone results are puzzling; original Python gets 3154.57
pystones on my machine, and the patched version without PyInt_FromLong
returning longs gets a spurious value of 3367! With the
PyInt_FromLong change, it gets 2450.98 pystones, which is what you'd
expect.
Mostly I want comments on the approach, and am not claiming this
version is reliable. Still to do:
* Write test cases that exercise the new code.
* Start converting Python/structmember.c, and a bunch of files
in Modules/
* Begin changing places that raise OverflowError, to create long
integers instead. (Or maybe this is a bad idea; certainly it might
break existing code.)
--
A.M. Kuchling http://starship.python.net/crew/amk/
I'm an excuse for medical experiments and art theory. You must get me out of
here and out of the hospital.
-- Peter Greenaway, _A Zed and Two Noughts_ (1986)
Raises some interesting issues wrt 64-bit Windows.
-----Original Message-----
From: Trent Mick [mailto:trentm@ActiveState.com]
Sent: Tuesday, February 08, 2000 9:35 AM
To: Tim Peters; python-list(a)python.org
Subject: RE: 64-bit port of Python
[Trent and Tim talk about 64-bit porting issues in the Python code. Trent
also sneakily changes email addresses.]
[Tim Peters]:
> It's not what you suspect <wink>. Almost everything boiled down
> to mistaken
> and unintended assumptions that sizeof(int) == sizeof(long), in and around
> the implementations of (unbounded) long arithmetic, and
> overflow-checking of
> int arithmetic. All that stuff was fixed then. AFAIK, core Python code
> *never* casts a pointer to any sort of int, or vice versa, either
> explicitly or implicitly.
A couple of example where I think the Python core does just that:
"Modules/arraymodule.c::728":
static PyObject *
array_buffer_info(self, args)
arrayobject *self;
PyObject *args;
{
return Py_BuildValue("ll",
(long)(self->ob_item), (long)(self->ob_size));
}
where 'ob_item' is a pointer. "Python/bltinmodule.c::899":
static PyObject *
builtin_id(self, args)
PyObject *self;
PyObject *args;
{
PyObject *v;
if (!PyArg_ParseTuple(args, "O:id", &v))
return NULL;
return PyInt_FromLong((long)v);
}
Python sort of relies on C's 'long' to be the largest native integer. This
is evidenced by all the use of PyInt_FromLong() above. There are no format
specifiers in the PyArg_Parse*() and Py_BuildValue() functions for
converting a pointer. This was fine when 'long' would do. On Win64
sizeof(long)==4 and size(void*)==8.
I think this also brings up some wider issues in the Python source. For
instance, the python integer type uses the C 'long' type. Was it the
implicit intention that this be the system's largest native integral type,
i.e. 32-bits on a 32 sys and 64-bits on a 64-bit system? If so, then the
representation of the Python integer type will have to change (i.e. the use
of 'long' cannot be relied upon). One should then carry through and change
(or obselete) the *_AsLong(), *_FromLong() Python/C API functions to become
something like *_AsLargestNativeInt(), *_FromLargestNativeInt() (or some
less bulky name).
Alternatively, if the python integer type continues to use the C 'long' type
for 64-bit systems then the following ugly thing happens:
- A Python integer on a 64-bit Intel chip compiled with MSVC is 32-bits
wide.
- A Python integer on a 64-bit Intel chip compiled with gcc is 64-bits
wide.
That cannot be good.
Someone who thinks the Windows installation is a delight may wish to reply
to this msg from c.l.py <wink>.
-----Original Message-----
From: python-list-admin(a)python.org [mailto:python-list-admin@python.org]
On Behalf Of Steve Holden
Sent: Tuesday, February 08, 2000 10:06 AM
To: python-list(a)python.org
Subject: Redundant elements in sys.path
I noticed that both PythonWin and Idle have the same items, although
with different case representations, in sys.path. Since the filestore
isn't case-sensitive on Windows NT I'm wondering
a) How these duplicates came about (multiple installs?), and
b) What I can do to get rid of them (registry scoured, but
nothing probable found).
The code I used to detect this situation is no great shakes:
>>> s=list(sys.path)
>>> s.sort()
>>> for p in s:
... print p
Output from PythonWin:
C:\Program Files\Python
C:\Program Files\Python\DLLs
C:\Program Files\Python\DLLs
C:\Program Files\Python\Lib
C:\Program Files\Python\Lib\lib-tk
C:\Program Files\Python\Lib\plat-win
C:\Program Files\Python\Pythonwin
C:\Program Files\Python\Pythonwin
C:\Program Files\Python\lib
C:\Program Files\Python\lib\lib-tk
C:\Program Files\Python\lib\plat-win
C:\Program Files\Python\win32
C:\Program Files\Python\win32\lib
Output from Idle:
C:\PROGRA~1\PYTHON
C:\PROGRA~1\Python\Tools\idle
C:\Program Files\Python
C:\Program Files\Python
C:\Program Files\Python\DLLs
C:\Program Files\Python\DLLs
C:\Program Files\Python\Lib
C:\Program Files\Python\Lib\lib-tk
C:\Program Files\Python\Lib\plat-win
C:\Program Files\Python\Pythonwin
C:\Program Files\Python\lib
C:\Program Files\Python\lib\lib-tk
C:\Program Files\Python\lib\plat-win
C:\Program Files\Python\win32
C:\Program Files\Python\win32\lib
Since I'm not running from source distribution I'd appreciate it
if someone could explain how PYTHONPATH is initialized and how I
can simplify my environment to remove this duplication.
regards
Steve Holden
--
"If computing ever stops being fun, I'll stop doing it"
--
http://www.python.org/mailman/listinfo/python-list
probably intended for this forum, too...
---------- Forwarded message ----------
Date: Tue, 08 Feb 2000 09:04:27 -0500
From: James C. Ahlstrom <jim(a)interet.com>
To: Greg Stein <gstein(a)lyra.org>
Subject: Re: [Python-Dev] frozen exceptions.py (was: win32 specific exception
in the core?)
Greg Stein wrote:
> Why C? Implement it in Python and freeze the sucker. We all know that
> Python is much more maintainable. With a few simple changes, we can also
> make this freeze process very straight-forward and part of the standard
> build process.
>
> There are quite a few things that could be done in Python, then just
> frozen into the binary. Just wait until I start arguing for the parser and
> compiler to be written in Python, frozen in, and we dump their C
> equivalents... :-)
I agree completely. We need the ability to freeze in Python code
easily without damaging the user's ability to use freeze too. Lets
get this fixed right instead of just writing more C.
JimA
I'm fwd'ing this back to the list, because disagreement is more valuable to
share than agreement.
The C++, Fortran, Pascal or Java programmer can't *spell* the list [1,
"two"] in their languages without playing casting tricks. Of course the
elements are of different types, and for that very reason it's better to use
a tuple here instead(especially if it's always of length two!). "Different
data structures for different purposes" is as Pythonic as "different syntax
for different purposes", and paying attention to this can improve your
(that's the generic "your") Python programming life. I don't care if it's
not immediately obvious to new users (or even to you <wink>). Start from
ground zero and try to explain why Python has both ints and floats: there
is no *obvious* reason (even less so for having both ints and longs, btw).
Python wouldn't fall apart without tuples, but I'd miss them a lot (e.g., in
another vein, in an imperative language using immutable objects when
possible can greatly aid reasoning about code ("OK, they pass a tuple here,
so I don't have to worry at all about the callee mutating it") ...).
Python itself violates my "guidelines" in using a tuple to catch a vrbl
number of arguments, & I believe that's a minor design flaw (it should use a
list for this instead -- although you can't satisfy both "homogenous" &
"fixed length" at the same time here).
WRT Scheme, I don't believe it's a reasonable choice to teach newbies unless
they're CompSci majors; it would certainly be better if they had a language
that didn't need to be "layered". DrScheme effectively *did* "re-design
their language" by introducing subsets. Whether this is successful for
Mathias you'll have to argue with him; I don't see cause to believe SP/k is
relevant (neither the "subset" form of Fortran77 -- it was aiming at an
entirely different thing).
> -----Original Message-----
> From: gvwilson(a)nevex.com [mailto:gvwilson@nevex.com]
> Sent: Thursday, February 03, 2000 11:49 PM
> To: Tim Peters
> Subject: RE: [Python-Dev] re: syntax - "Aren't tuples redundant?"
>
>
> > Tim Peters wrote:
> > At heart, tuples are for Cartesian products of a fixed number of
> > possibly differing types, while lists are for arbitrary-length
> > sequences of a single type.
>
> Greg Wilson writes (to Tim Peters directly, in order to reduce bandwidth
> on the general list --- feel free to re-post there if you think there's
> any merit in what I've said below):
>
> Fooey. Programmers raised on C, Fortran, Pascal, or Java would tell you
> that the elements of [1, "two"] have different types. So (I believe)
> would most ten-year-olds, and they'd be right: I can't add 7 to "two", or
> take a slice of 1. I can grandparent them by fiat with a type "any", but
> that smells like I've decided what answer I want, and am now inventing
> what I need to get there.
>
> Footnote: every time someone's told me that a language has a "zen" that
> you have to "get", it's turned out that what they've really meant is that
> there's a set of "just-so" stories that you have to accept as gospel. I
> really don't want to offend anyone, but the justifications I'm hearing for
> Python tuples are starting to sound like that. I'd be very grateful if
> you could tell me what they actually buy programmers that lists don't,
> other than being usable as hash keys, and maintaining backward
> compatibility with earlier versions of Python.
>
> > BTW, despite the recent unpleasantness with the TeachScheme! folks,
> > there's a lot to be learned from DrScheme, part of which is the notion
> > of language "levels": the IDE can be set to restrict the newbie to
> > various (nested) subsets of the full language, so that new learners
> > are shielded from the hairier stuff until their confidence builds.
>
> I lived through another attempt to do this --- the SP/k series of layered
> languages based on PL/1. It wasn't generally regarded as a success; when
> a Pascal compiler that generated readable error messages came along, SP/k
> was abandoned almost immediately. No disrespect to Mathias and his
> colleagues, but I think that that if they have to shield learners from
> part of the language in order to make it learnable, they ought to
> re-design their language...
>
> Thanks,
> Greg
[Brian Harvey is the author of "Computer Science Logo Style", and a
long-time Logophile and educator]
---------- Forwarded message ----------
Date: Sun, 6 Feb 2000 17:21:44 -0800 (PST)
From: Brian Harvey <bh(a)CS.Berkeley.EDU>
To: gvwilson(a)nevex.com
Subject: Re: [Python-Dev] Re: [Edu-sig] Rational Division
Hi. There were some early Logo versions in which 2/3 was 0, and 2.0/3.0
was 0.6666, but sure enough, everyone was confused. These days 2/3 is
0.6666, and there's an INT operation that truncates to integer.
Oh, there was a later time when 2/3 was 0.6666 but QUOTIENT 2 3 was 0.
That confused people too. I think some dialects have an INTQUOTIENT
operation that's the same as INT QUOTIENT. :-)