Re: Seems like I want a pre-processor, but...

2006-03-29 Thread Carl Banks

Russell Warren wrote:
  the collections module was added in 2.4

 Ah... sorry about that.  I should have checked my example more closely.
 What I'm actually doing is rebinding some Queue.Queue behaviour in a
 safe location like this:

 def _get(self):
   ret = self.queue.popleft()
   DoSomethingSimple()
   return ret

What you should have done is call the base class's _get method, like
this:

def _get(self):
ret = Queue._get(self)
DoSomethingSimple()
return ret

This'll work in 2.3, 2.4, and if they were to change the type of the
queue again in 2.5, it would still work without any changes.  Don't
redo the work the base class does if you don't have to.


Carl Banks

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-29 Thread Cameron Laird
In article [EMAIL PROTECTED],
Russell Warren [EMAIL PROTECTED] wrote:
.
.
.
Anyway - it worked... you've answered my question perfectly, thanks.  I
hadn't considered that the module loading phase could basically used
for preprocessing.  You even helped by subtly providing a better
version checker... I didn't even know you could use  with a tuple like
that.  I'll have to look into the logic rules there.
.
.
.
I'm working on an article on this topic, as it happens.
Yes, in general pre-processors are strictly inferior for
all realistic use-cases.  Any time you think you need a
pre-processor in Python, you should ask for help to learn
of the better way that Python affords.

Even while writing this, I realize that some people have
implemented pre-processors for their Python, and expressed
satisfaction with the result.  The cases familiar to me
had to do syntactic style--folks who don't like significant
white space, and so on.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-29 Thread Russell Warren
Yes, I definitely should have done that for that case.  I'm not
entirely sure why I didn't.  If I had, though, I may not have been
prompted to ask the question and get all the other great little
tidbits!

-- 
http://mail.python.org/mailman/listinfo/python-list


Seems like I want a pre-processor, but...

2006-03-28 Thread Russell Warren
After some digging it seems that python does not have any equivalent to
C's #if directives, and I don't get it...

For example, I've got a bit of python 2.3 code that uses
collections.deque.pop(0) in order to pop the leftmost item.  In python
2.4 this is no longer valid - there is no argument on pop (rightmost
only now) and you call .popleft() instead.

I would like my code to work in both versions for now and simply want
to add code like:

if sys.version[:3] == 2.3:
  return self.myDeque.pop(0)
else:
  return self.myDeque.popleft()

but am recoiling a bit at the unnecessary conditional in there that I
think will be run on every execution - unless the compiler has some
magic detection of things like sys.version to compile out the
conditional as if it were a preprocessor directive (seems highly
unlikely!)?.

What is the pythonic thing to do?  This is in a generally usable file,
not a package, so I don't want to make a version for each (which seems
to be what every package out there does).  It seems to be begging for a
pre-processor directive set.

Thanks,
Russ

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-28 Thread Fredrik Lundh
Russell Warren wrote:

 For example, I've got a bit of python 2.3 code that uses
 collections.deque.pop(0) in order to pop the leftmost item.  In python
 2.4 this is no longer valid - there is no argument on pop (rightmost
 only now) and you call .popleft() instead.

the collections module was added in 2.4, so it's not clear what code you're
really using under 2.3.  but since it's not a standard module, maybe you could
add the missing method yourself ?

 I would like my code to work in both versions for now and simply want
 to add code like:

 if sys.version[:3] == 2.3:
   return self.myDeque.pop(0)
 else:
   return self.myDeque.popleft()

 but am recoiling a bit at the unnecessary conditional in there that I
 think will be run on every execution - unless the compiler has some
 magic detection of things like sys.version to compile out the
 conditional as if it were a preprocessor directive (seems highly
 unlikely!)?.

 What is the pythonic thing to do?

fork the function/method:

if sys.version_info  (2, 4):
def myfunc(self):
# using deque emulation
return self.myDeque.pop(0)
else:
def myfunc(self):
return self.myDeque.popleft()

or wrap the non-standard deque class in a compatibility wrapper:

if sys.version_info  (2, 4):
class mydequeclass(deque):
def popleft(self):
return self.pop(0)

...

return self.myDeque.popleft()

/F



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-28 Thread Kent Johnson
Russell Warren wrote:
 After some digging it seems that python does not have any equivalent to
 C's #if directives, and I don't get it...
 
 For example, I've got a bit of python 2.3 code that uses
 collections.deque.pop(0) in order to pop the leftmost item.  In python
 2.4 this is no longer valid - there is no argument on pop (rightmost
 only now) and you call .popleft() instead.
 
 I would like my code to work in both versions for now and simply want
 to add code like:
 
 if sys.version[:3] == 2.3:
   return self.myDeque.pop(0)
 else:
   return self.myDeque.popleft()

Often you can make these tests one-time by defining an appropriate 
object whose value depends on the test, then using that object instead 
of repeatedly making the test. In this case, I assume the code above is 
inside a class method. You could have the class conditionally define a 
myPopLeft() method like this (not tested):

class MyClass(object):
   ...
   if sys.version[:3] == 2.3:
 def myPopLeft(self):
   return self.myDeque.pop(0)
   else:
 def myPopLeft(self):
   return self.myDeque.popleft()

Now the class has a myPopLeft() method that does the right thing, and 
sys.version is only tested once, at class declaration time.

You might want to make the condition explicitly on the deque class, 
also, using has_attr(deque, 'popleft').

Another example is the common code used to define 'set' portably across 
Python 2.3 and 2.4:

try:
   set
except NameError:
   from sets import Set as set


In general the idea is to move the test from 'every time I need to do 
something' to 'once when some name is defined'.

Kent

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-28 Thread Peter Otten
Russell Warren wrote:

 After some digging it seems that python does not have any equivalent to
 C's #if directives, and I don't get it...
 
 For example, I've got a bit of python 2.3 code that uses
 collections.deque.pop(0) in order to pop the leftmost item.  In python
 2.4 this is no longer valid - there is no argument on pop (rightmost
 only now) and you call .popleft() instead.

collections is new in 2.4 -- I assume you mean list.pop(0) versus
collections.deque.popleft().

 I would like my code to work in both versions for now and simply want
 to add code like:
 
 if sys.version[:3] == 2.3:
   return self.myDeque.pop(0)
 else:
   return self.myDeque.popleft()
 
 but am recoiling a bit at the unnecessary conditional in there that I
 think will be run on every execution - unless the compiler has some
 magic detection of things like sys.version to compile out the
 conditional as if it were a preprocessor directive (seems highly
 unlikely!)?.
 
 What is the pythonic thing to do?  This is in a generally usable file,
 not a package, so I don't want to make a version for each (which seems
 to be what every package out there does).  It seems to be begging for a
 pre-processor directive set.

Here's how I would rewrite your example:

try:
from collections import deque
except ImportError:
class deque(list):
def popleft(self):
return self.pop(0)

# in your method:
return self.myDeque.popleft()

That way the performance impact almost vanishes for the newer python and
your code is less cluttered with if ... else statements that are only there
to pick the version specific code.

Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-28 Thread Russell Warren
 the collections module was added in 2.4

Ah... sorry about that.  I should have checked my example more closely.
What I'm actually doing is rebinding some Queue.Queue behaviour in a
safe location like this:

def _get(self):
  ret = self.queue.popleft()
  DoSomethingSimple()
  return ret

And self.queue.popleft() used to be self.queue.pop(0).  self.queue is a
deque object in 2.4 so I just used transferred that unluckily to the
post in a poor attempt to simplify it - I had no clue that it was new.
Should have made one up from scratch.

Anyway - it worked... you've answered my question perfectly, thanks.  I
hadn't considered that the module loading phase could basically used
for preprocessing.  You even helped by subtly providing a better
version checker... I didn't even know you could use  with a tuple like
that.  I'll have to look into the logic rules there.

Russ

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Seems like I want a pre-processor, but...

2006-03-28 Thread Russell Warren
Thanks guys - all great responses that answered my question in a few
different ways with the addition of some other useful tidbits!

This is a nice summary:
 In general the idea is to move the test from 'every time I need to do
 something' to 'once when some name is defined'.

Gotta love the response time of this newsgroup...

Russ

-- 
http://mail.python.org/mailman/listinfo/python-list