Re: Seems like I want a pre-processor, but...
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...
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...
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...
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...
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...
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...
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...
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...
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