Re: Guessing the encoding from a BOM
On 01/17/2014 08:46 AM, Pete Forman wrote: Chris Angelico ros...@gmail.com writes: On Fri, Jan 17, 2014 at 8:10 PM, Mark Lawrence breamore...@yahoo.co.uk wrote: Slight aside, any chance of changing the subject of this thread, or even ending the thread completely? Why? Every time I see it I picture Inspector Clouseau, A BOM!!! :) Special delivery, a berm! Were you expecting one? Endian detection: Does my BOM look big in this? LOL! -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: question about input() and/or raw_input()
On 01/19/2014 12:26 AM, Rustom Mody wrote: On Sunday, January 19, 2014 10:29:58 AM UTC+5:30, Chris Angelico wrote: On Sun, Jan 19, 2014 at 3:43 PM, Rustom Mody wrote: As do these pieces of code: -- def quux1(x): return str(x+1) -- def quux2(x): return hex(x+1)[2:] They do? -- quux1(2.3) '3.3' -- quux2(2.3) Traceback (most recent call last): File stdin, line 1, in module File stdin, line 1, in quux2 TypeError: hex() argument can't be converted to hex (Will be) fixed in 3.5 [1] :) -- ~Ethan~ [1] Which is to say, both will raise an exception. -- https://mail.python.org/mailman/listinfo/python-list
Re: question about input() and/or raw_input()
On 01/19/2014 08:38 AM, Chris Angelico wrote: On Mon, Jan 20, 2014 at 3:14 AM, Ethan Furman et...@stoneleaf.us wrote: -- def quux1(x): return str(x+1) -- quux1(2.3) '3.3' (Will be) fixed in 3.5 [1] :) [1] Which is to say, both will raise an exception. Why would that raise? Sorry, should have read that closer. It will not raise. The difference I was thinking of is: %h % 3.14 # this works vs. hex(3.14) # this raises In 3.5 both will raise. Apologies for the noise. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: question about input() and/or raw_input()
On 01/19/2014 10:41 AM, Chris Angelico wrote: On Mon, Jan 20, 2014 at 4:50 AM, Ethan Furman et...@stoneleaf.us wrote: The difference I was thinking of is: %h % 3.14 # this works vs. hex(3.14) # this raises In 3.5 both will raise. Now you have me *thoroughly* intrigued. It's not %h (incomplete format - h is a modifier), nor %H (unsupported format character). Do you mean %x? As of 3.4.0b2, that happily truncates a float: %x % 3.14 '3' Is that changing in 3.5? Seems a relatively insignificant point, tbh! Argh. Yes, %x or %X. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Add followers at time of import
On 01/21/2014 10:03 AM, Chris Angelico wrote: On Wed, Jan 22, 2014 at 4:52 AM, emile wrote: Ask if that's not clear. I'm not entirely sure, but I think this might have been meant for somewhere other than python-list. Welcome to the club. And it's an elite club, too! Very few members. ;) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Diving in to Python - Best resources?
On 01/21/2014 08:00 AM, Rustom Mody wrote: Most people -- even those using spreadsheets -- dont seem to think of the spreadsheet macro language/VBA as a programming language Ack, are you trying to put him off programming again?!? ;) Python us fun and a pleasure to use. VBA is not. (IMNSHO YMMV) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: awesome slugify and unicode
On 01/22/2014 11:23 AM, Mark Lawrence wrote: I thought this blog might interest some of you http://pydanny.com/awesome-slugify-human-readable-url-slugs-from-any-string.html Thanks! -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Case insensitive exists()?
On 01/22/2014 04:58 PM, Larry Martell wrote: I have the need to check for a files existence against a string, but I need to do case-insensitively. This should get you going. As it is, it will check the /entire/ string you send in even if it has path parts to it, and there are probably other idiosyncrasies that you may want to change to match your needs. --- def exists(filename, ci=False): from glob import glob search = filename if ci: new_search = [] for ch in filename: new_search.append('[%s%s]' % (ch.lower(), ch.upper())) search = ''.join(new_search) found = glob(search) return bool(found) --- -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: buggy python interpretter or am I missing something here?
On 01/26/2014 10:42 PM, me wrote: My point of contention isn't so much about what specific syntax I should be using as much as it is about being allowed to use a syntax that gives erroneous results without triggering a syntax violation. If the bare except: clause is syntactically legal then it should yield deterministic results based on a well defined language specification, right? It's looking very much like except: is undefined behaviour. There is nothing undefined about it. `except:` catches everything. Occasionally there is a good reason to do it that way, but under typical circumstances you tell 'except' which exceptions you are prepared to deal with. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: buggy python interpretter or am I missing something here?
On 01/26/2014 10:46 PM, me wrote: [...] I'm satisfied that the except: syntax yields undefined behavior, and in my mind it shouldn't be syntactically allowed then. Two points: 1) Python is not C++ 2) You asked for help; you received it. Coming back with an attitude of Python must be broken, I'll work around it is going to quickly lose you the support of those willing to help again. -- https://mail.python.org/mailman/listinfo/python-list
Re: Highlighting program variables instead of keywords?
On 01/26/2014 06:54 PM, Roy Smith wrote: Chris Angelico wrote: That said, though, I grew up without syntax highlighting of any sort, and didn't think it particularly important; but now that I have editors with all those sorts of features, I do find them handy. Same here, except I'd replace find them handy with totally addicted to. +1000 -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: UTC timezone causing brain explosions
On 01/29/2014 01:52 PM, Skip Montanaro wrote: Following up on my earlier note about UTC v. GMT, I am having some trouble grokking attempts to convert a datetime into UTC. Okay, let's see what GMT does for us: GMT = pytz.timezone(GMT) u = GMT.normalize(s) u datetime.datetime(2014, 1, 29, 21, 39, 35, 263666, tzinfo=StaticTzInfo 'GMT') u.hour 21 That looks correct, but I don't understand why I don't get hour==21 out of the UTC.normalize call. It's like it's a no-op. Having not examined the code, I can't tell you why UTC is different. I can say that .astimezone seems to work in all cases: -- GMT StaticTzInfo 'GMT' -- UTC UTC -- LOCAL_TZ = pytz.timezone(America/Los_Angeles) -- now = datetime.datetime.now() -- s = LOCAL_TZ.localize(now) -- s datetime.datetime(2014, 1, 29, 14, 9, 56, 494967, tzinfo=DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD) -- s.astimezone(UTC) datetime.datetime(2014, 1, 29, 22, 9, 56, 494967, tzinfo=UTC) -- s.astimezone(GMT) datetime.datetime(2014, 1, 29, 22, 9, 56, 494967, tzinfo=StaticTzInfo 'GMT') -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Try-except-finally paradox
On 01/30/2014 10:12 AM, Rotwang wrote: On 30/01/2014 06:33, Andrew Berg wrote: On 2014.01.29 23:56, Jessica Ross wrote: I found something like this in a StackOverflow discussion. -- def paradox(): ... try: ... raise Exception(Exception raised during try) ... except: ... print Except after try ... return True ... finally: ... print Finally ... return False ... return None ... -- return_val = paradox() Except after try Finally -- return_val False I understand most of this. What I don't understand is why this returns False rather than True. Does the finally short-circuit the return in the except block? My guess would be that the interpreter doesn't let the finally block get skipped under any circumstances, so the return value gets set to True, but then it forces the finally block to be run before returning, which changes the return value to False. Mine too. We can check that the interpreter gets as far as evaluating the return value in the except block: -- def paradox2(): try: raise Exception(Raise) except: print(Except) return [print(Return), True][1] finally: print(Finally) return False return None -- ret = paradox2() Except Return Finally -- ret False And just to be thorough, if the finally block doesn't have a return: -- def paradox3(): try: raise Exception(Raise) except: print(Except) return [print(Return), True][1] finally: print(Finally) return None -- print(paradox3()) Except Return Finally True -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: 1 0 == True - False
On 01/30/2014 11:03 AM, Chris Angelico wrote: On Fri, Jan 31, 2014 at 5:56 AM, Roy Smith wrote: Yes, that's probably how I would write that, although, this is even simpler: (x -1) and (y = 5) Be careful; that's not the same thing. How so? -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 11:33 AM, Mark Lawrence wrote: From http://docs.python.org/3/reference/datamodel.html#object.__init__ which states:- Called when the instance is created. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class’s __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: BaseClass.__init__(self, [args...]). As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime. Should the wording of the above be changed to clearly reflect that we have an initialiser here and that __new__ is the constructor? I would say yes. Go ahead and create an issue if one doesn't already exist. Thanks. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 11:52 AM, Ned Batchelder wrote: On 1/31/14 2:33 PM, Mark Lawrence wrote: From http://docs.python.org/3/reference/datamodel.html#object.__init__ which states:- Called when the instance is created. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class’s __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: BaseClass.__init__(self, [args...]). As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime. Should the wording of the above be changed to clearly reflect that we have an initialiser here and that __new__ is the constructor? I'm torn about that. The fact is, that for 95% of the reasons you want to say constructor, the thing you're describing is __init__. Most classes have __init__, only very very few have __new__. My problem is with the first sentence, as it makes it sound like there is no __new__ and everything you need is in __init__. Figuring out how __new__ and __init__ were tied together took a long time because of that. Why can't we call __init__ the constructor and __new__ the allocator? I'm not so much concerned about the names (although I like those names ;) as I am about the prose. If that first line was something like: Called after the instance has been created but before it is returned. I think that would be much clearer. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 12:48 PM, MRAB wrote: On 2014-01-31 19:52, Ned Batchelder wrote: Why can't we call __init__ the constructor and __new__ the allocator? The advantage of calling it the initialiser is that it explains why it's called __init__. Hm, yes, good point. Also, __init__ initializes so it is a good choice. Ignore the names comment in my previous post. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 03:43 PM, Ned Batchelder wrote: On 1/31/14 6:05 PM, Ben Finney wrote: Ned Batchelder writes: I'm not hoping to change any official terminology. I just think that calling __init__ anything other than a constructor is confusing pedantry. It is a constructor, and Python constructors work differently than those in C++ and Java. And I would say the opposite. __init__ is not creating anything, which is what I think of when speaking of a constructor. I'd be willing to yield the point that Python has a pair of methods that make up the constructor (an allocator and an initializer), but I found calling __init__ the constructor very confusing. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 03:47 PM, Ben Finney wrote: I would prefer it to be clear that “__init__” is called automatically, *during* the constructor's operation. So, instead of: Called when the instance is created. I suggest: Called automatically by the constructor “__new__” during instance creation, to initialise the new instance. But __new__ does not call __init__, type does [1]. -- ~Ethan~ [1] And I seem to think pickle does, too, but I'm not sure. -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 05:10 PM, Roy Smith wrote: In article mailman.6233.1391214984.18130.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: I found calling __init__ the constructor very confusing. I've heard many people say this, and it's always sort of befuddled me. I have never learned C++, so I don't know its screwy semantics. ;) Nor Java, for that matter. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 07:16 PM, Terry Reedy wrote: On 1/31/2014 7:13 PM, Ethan Furman wrote: On 01/31/2014 03:43 PM, Ned Batchelder wrote: On 1/31/14 6:05 PM, Ben Finney wrote: Ned Batchelder writes: I'm not hoping to change any official terminology. I just think that calling __init__ anything other than a constructor is confusing pedantry. It is a constructor, and Python constructors work differently than those in C++ and Java. And I would say the opposite. __init__ is not creating anything, As you pointed out in a different response, Python has one default, two-phase constructor. type.__call__. Typically, .__new__ allocates a generic object (with one customization as to class). .__init__ creates, from that mostly generic object, a customized instance of class C with the minimal attributes needed to be an instance of C, with value specific to the instance. Creating a painting on canvas has two similar phases. Prepare a generic blank canvas stretched on a frame and coated with a white undercoat. Paint a particular picture. Would you say that the second step is not creating anything? Very nicely put. Considering the discussion that this topic has engendered, you will hopefully agree that the current docs could use a little improvement. :) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 06:28 PM, Terry Reedy wrote: Construct a house: Clear and grade house site. Bring in power and water. Built temporary structures. Built foundation. Built house on foundation. For most classes, __new__ stops with the foundation -- the bare object object (with the class name slapped onto it). A *house* is not constructed until the house is constructed on top of the foundation. On the ground programming has the dividing line at: immutable objects -- everything done in __new__ mutable objects -- everything done in __init__ Typically, immutable objects are not created in Python code because, well, it's really dang hard (__slots__, anyone?), but one still needs to understand how __new__ and __init__ go together to do the more interesting stuff (such as having __new__ return a dynamically selected subclass, which still needs to be (or not be) __init__ed). -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 08:35 PM, Chris Angelico wrote: On Sat, Feb 1, 2014 at 2:42 PM, Steven D'Aprano wrote: Thus, two methods. __new__ constructs (creates, allocates) a new object; __init__ initialises it after the event. Yes, but if you think in terms of abstractions, they're both just steps in the conceptual process of creating the object. So maybe it's best to talk about the two methods collectively as the constructor, and then let people call the two parts whatever they will. I do like the idea of calling __init__ the initializer. The downside of calling __new__ the constructor is that it'll encourage C++ and Java programmers to override it and get themselves confused Why do we worry so about other languages? If and when I go to learn C++ or Lisp, I do not expect their devs to be worrying about making their terminology match Python's. Part of the effort is in learning what the terms mean, what the ideology is, the differences, the similarities, etc., etc.. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 01/31/2014 09:51 PM, Steven D'Aprano wrote: On Sat, 01 Feb 2014 15:35:17 +1100, Chris Angelico wrote: The two methods could have been done as a single method, __construct__, in which you get passed a cls instead of a self, and you call self=super().__construct__() and then initialize stuff. That would be called __new__ in Python. There's no *need* to use __init__ for anything (except old-style classic classes in Python 2). While there may not be a /need/ for two, having two is quite handy. Having __new__ take care of the nuts and bolts (or foundation, as Terry put it), and being able to further customize with __init__ (where the kitchen goes, how many bedrooms, to follow along with Terry) is quite useful. One of my favorite Enum recipes uses that pattern to have some basic behavior, with some other behavior that is easily overridable/extendable [1]. -- ~Ethan~ [1] http://stackoverflow.com/q/19330460/208880 -- https://mail.python.org/mailman/listinfo/python-list
Re: __init__ is the initialiser
On 02/02/2014 09:12 PM, Roy Smith wrote: In article mailman.6325.1391403799.18130.python-l...@python.org, Dave Angel da...@davea.name wrote: Skip Montanaro s...@pobox.com Wrote in message: On Sun, Feb 2, 2014 at 9:14 PM, Dave Angel da...@davea.name wrote: And when the q-bits get entangled up, we won't know the question till after the answer has collapsed. Won't looking at the answer change it? No, looking at it is what collapses it. Before that it was just another Schroedinger's cat So, what you're saying is when I delete an object, __del__() has both been called and not been called? That would certainly explain the problems with __del__! -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Latest Python 3.4 in the source repo is broken?
On 02/04/2014 07:45 AM, Steven D'Aprano wrote: Before I bother Python-Dev with this, can anyone else confirm that building Python 3.4 from source using the latest version in the source repository fails? This is the check-out I'm using: ethan@media:~/source/python/cpython$ hg parent rev:88961:7d0a4f89c6ce branch: default tag:tip user: Vinay Sajip vinay_sa...@yahoo.co.uk date: 2014-02-04 16:42 + desc: Closes #20509: Merged documentation update from 3.3. These are the settings I always use to make sure I have no weird problems between check-outs: ethan@media:~/source/python/cpython$ make distclean ./configure --with-pydebug make -j3 .. .. .. Python build finished successfully! The necessary bits to build these optional modules were not found: _gdbm _lzma To find the necessary bits, look in setup.py in detect_modules() for the module's name. running build_scripts creating build/scripts-3.4 copying and adjusting /home/ethan/source/python/cpython/Tools/scripts/pydoc3 - build/scripts-3.4 copying and adjusting /home/ethan/source/python/cpython/Tools/scripts/idle3 - build/scripts-3.4 copying and adjusting /home/ethan/source/python/cpython/Tools/scripts/2to3 - build/scripts-3.4 copying and adjusting /home/ethan/source/python/cpython/Tools/scripts/pyvenv - build/scripts-3.4 changing mode of build/scripts-3.4/pydoc3 from 664 to 775 changing mode of build/scripts-3.4/idle3 from 664 to 775 changing mode of build/scripts-3.4/2to3 from 664 to 775 changing mode of build/scripts-3.4/pyvenv from 664 to 775 renaming build/scripts-3.4/pydoc3 to build/scripts-3.4/pydoc3.4 renaming build/scripts-3.4/idle3 to build/scripts-3.4/idle3.4 renaming build/scripts-3.4/2to3 to build/scripts-3.4/2to3-3.4 renaming build/scripts-3.4/pyvenv to build/scripts-3.4/pyvenv-3.4 Hope this helps. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: how to reduce bugs due to incorrect indentation
On 02/06/2014 12:36 PM, Larry Martell wrote: On Thu, Feb 6, 2014 at 3:29 PM, Roel Schroeven wrote: msus...@gmail.com schreef: While editing this file I accidentally pushed TAB on the line with 'y = z + y'. My suggestion: configure your editor to insert the appropriate amount of spaces instead of a tab when you press the tab key. +1 - tabs are evil. Tabs are not evil, and an argument can be made that tabs are better (a decent editor can be configured to show x many spaces per tab, then users could decide how much indentation they preferred to see... but I digress). Using spaces instead of tabs would also have not prevented the error that Msustik encountered, and for that matter we don't know whether he was using tabs or spaces in his source file, only that he hit the Tab key -- surely you are not suggesting everyone rip out their tab key and just hit the space bar four times for each level of indentation? ;) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Finding size of Variable
On 02/07/2014 06:48 PM, Steven D'Aprano wrote: That is not a trade-off that the core developers have chosen to make, and I agree with them. Even though you haven't broken all the build-bots yet, you can still stop saying them. ;) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: imperative mood in docstrings
On 02/09/2014 08:52 AM, Roy Smith wrote: In article mailman.6584.1391950328.18130.python-l...@python.org, bagrat lazaryan bagra...@live.com wrote: pep 257 -- docstring conventions, as well as a myriad of books and other resources, recommend documenting a function's or method's effect as a command (do this, return that), not as a description (does this, returns that). what's the logic behind this recommendation? bagratte Methods are verbs, and should be described as such. If I had: class Sheep: def fly(self): Plummet to the ground. I'm defining the action the verb performs. If, on the other hand, I had: Shouldn't that be: class Pig: def fly(self): Soar gracefully through the air if a hot place is very cold. if hell is frozen: self.sprout_wings() self.altitude += 10 self.velocity += 25 else: self.splat() ;) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Fun with function argument counts
On 02/11/2014 05:05 PM, Chris Angelico wrote: On Wed, Feb 12, 2014 at 11:34 AM, Travis Griggs wrote: 6) Who writes a function with 19 mandatory arguments anyway subprocess._execute_child() and distutils.cygwincompiler._execute_child() Hmm. Those are internal functions (leading underscore). Might be fairer to remove those from consideration. Not at all. Even private routines get used by somebody! ;) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: singleton ... again
On 02/13/2014 03:50 AM, Ned Batchelder wrote: On 2/13/14 4:00 AM, Piet van Oostrum wrote: Ben Finney ben+pyt...@benfinney.id.au writes: Gregory Ewing greg.ew...@canterbury.ac.nz writes: Roy Smith wrote: It looks to me like he's trying to implement a classic Gang of Four singleton pattern. Which I've never really seen the point of in Python, or any other language for that matter. Just create one instance of the class during initialisation, put it in a global somewhere, and use it thereafter. Make that “somewhere” a module namespace, and you effectively have a Singleton for all practical purposes. So yes, I see the point of it; but we already have it built in :-) There is a use case for a singleton class: when creating the singleton object takes considerable resources and you don't need it always in your program. I still don't see it. To convince me that a singleton class makes sense, you'd have to explain why by virtue of the class's very nature, it never makes sense for there ever to be more than one of them. Say you have a database with a column that can only have a handful of values (like an enumeration, for instance) and this database can have hundreds of thousands of rows. When you're working with all those rows at once having just one object for the third enum value is a useful optimization. Say you have a class that represents serial ports or your computer. You should get the same object every time you ask for SerialPort(2). -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: singleton ... again
On 02/13/2014 09:57 AM, Roy Smith wrote: In article mailman.6850.1392313443.18130.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: Say you have a class that represents serial ports or your computer. You should get the same object every time you ask for SerialPort(2). Why? Certainly, you should get objects which refer to the same physical port. So: port_a = SerialPort(2) port_b = SerialPort(2) port_a.enable() assert port_b.is_shutdown() == False port_a.shutdown() assert port_b.is_shutdown() == True But, why do they have to be the same object? Why should I care if port_a is port_b is False, as long as all operations I perform on either are reflected in correct state changes on the other one? You mean use the Borg pattern instead of the Singleton pattern? As far as I can tell they are two shades of the same thing. Are there any drastic differences between the two? Besides one having many instances that share one __dict__ and the other just having one instance and one __dict__? -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 10:37 AM, forman.si...@gmail.com wrote: I ran across this and I thought there must be a better way of doing it, but then after further consideration I wasn't so sure. if key[:1] + key[-1:] == '': ... Some possibilities that occurred to me: if key.startswith('') and key.endswith(''): ... and: if (key[:1], key[-1:]) == ('', ''): ... I haven't run these through a profiler yet, but it seems like the original might be the fastest after all? Unless that line of code is a bottleneck, don't worry about speed, go for readability. In which case I'd go with the second option, then the first, and definitely avoid the third. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 11:09 AM, Mark Lawrence wrote: All I can say is that if you're worried about the speed of a single line of code like the above then you've got problems. Having said that, I suspect that using an index to extract a single character has to be faster than using a slice, but I haven't run these through a profiler yet :) The problem with using indices in the code sample is that if the string is 0 or 1 characters long you'll get an exception instead of a False. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 11:20 AM, Ethan Furman wrote: On 02/13/2014 11:09 AM, Mark Lawrence wrote: All I can say is that if you're worried about the speed of a single line of code like the above then you've got problems. Having said that, I suspect that using an index to extract a single character has to be faster than using a slice, but I haven't run these through a profiler yet :) The problem with using indices in the code sample is that if the string is 0 or 1 characters long you'll get an exception instead of a False. Oops, make that zero characters. ;) -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 11:17 AM, Neil Cerutti wrote: On 2014-02-13, forman.si...@gmail.com forman.si...@gmail.com wrote: I ran across this and I thought there must be a better way of doing it, but then after further consideration I wasn't so sure. if key[:1] + key[-1:] == '': ... Some possibilities that occurred to me: if key.startswith('') and key.endswith(''): ... and: if (key[:1], key[-1:]) == ('', ''): ... I haven't run these through a profiler yet, but it seems like the original might be the fastest after all? I think the following would occur to someone first: if key[0] == '' and key[-1] == '': ... It is wrong to avoid the obvious. Needlessly ornate or clever code will only irritate the person who has to read it later; most likely yourself. Not whet the obvious is wrong: - key = '' -- if key[0] == '' and key[-1] == '': ... print good key! ... else: ... print bad key ... Traceback (most recent call last): File stdin, line 1, in module IndexError: string index out of range -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 11:43 AM, Peter Otten wrote: forman.si...@gmail.com wrote: I ran across this and I thought there must be a better way of doing it, but then after further consideration I wasn't so sure. if key[:1] + key[-1:] == '': ... Some possibilities that occurred to me: if key.startswith('') and key.endswith(''): ... and: if (key[:1], key[-1:]) == ('', ''): ... I haven't run these through a profiler yet, but it seems like the original might be the fastest after all? $ python -m timeit -s 's = alpha' 's[:1]+s[-1:] == ' 100 loops, best of 3: 0.37 usec per loop $ python -m timeit -s 's = alpha' 's[:1] == and s[-1:] == ' 100 loops, best of 3: 0.329 usec per loop $ python -m timeit -s 's = alpha' 's.startswith() and s.endswith()' 100 loops, best of 3: 0.713 usec per loop The first is too clever for my taste. The second is fast and easy to understand. It might attract improvements replacing the slice with an index, but I trust you will catch that with your unit tests ;) Personally, I'm willing to spend the few extra milliseconds and use the foolproof third. For completeness: # the slowest method from Peter $ python -m timeit -s 's = alpha' 's.startswith() and s.endswith()' 100 loops, best of 3: 0.309 usec per loop # the re method from Roy $ python -m timeit -s import re;pattern=re.compile(r'^.*$');s = 'alpha' pattern.match(s) 100 loops, best of 3: 0.466 usec per loop -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 01:01 PM, Chris Angelico wrote: On Fri, Feb 14, 2014 at 7:55 AM, Emile van Sebille em...@fenx.com wrote: On 2/13/2014 11:59 AM, Zachary Ware wrote: In a fit of curiosity, I did some timings: Snip of lots of TMTOWTDT/TIMTOWTDI/whatever... timed examples :) But I didn't see this one: s[::len(s)-1] AAARGG! Really, I actually did pause, double-take, and then scream under my breath, when I saw that. Yes, it works. But please, if you EVER do this, save me the trouble and just submit your code to thedailywtf.com straight away! Oh, it's not that bad! All you have to do is handle the edge case of an empty string: s[::len(s)-1 if s else True] *ducks and runs* -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 02:13 PM, Chris Angelico wrote: On Fri, Feb 14, 2014 at 8:33 AM, Ethan Furman et...@stoneleaf.us wrote: Oh, it's not that bad! All you have to do is handle the edge case of an empty string: s[::len(s)-1 if s else True] And the edge case of the one-character string. Oops, my description should have said edge case of a one-character string. The empty string needs no extra handling. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: A curious bit of code...
On 02/13/2014 01:24 PM, Roy Smith wrote: Emile van Sebille wrote: But I didn't see this one: s[::len(s)-1] I love it. I need to add this to my list of Python trivia questions. Great interview question: What does this do? What is its weakness? How would you fix it? -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Best practices to overcome python's dynamic data type nature
On 02/14/2014 08:10 AM, Sam wrote: Dynamic data type has pros and cons. It is easier to program but also easier to create bugs. What are the best practices to reduce bugs caused by Python's dynamic data-type characteristic? Can the experienced Python programmers here advise? Unit tests. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Best practices to overcome python's dynamic data type nature
On 02/14/2014 08:54 AM, Marko Rauhamaa wrote: Here's some advice from a very experienced programmer: become a very experienced programmer. +1 QOTW -- https://mail.python.org/mailman/listinfo/python-list
Re: unittest: assertRaises() with an instance instead of a type
Steven D'Aprano wrote: On Wed, 28 Mar 2012 14:28:08 +0200, Ulrich Eckhardt wrote: Hi! I'm currently writing some tests for the error handling of some code. In this scenario, I must make sure that both the correct exception is raised and that the contained error code is correct: try: foo() self.fail('exception not raised') catch MyException as e: self.assertEqual(e.errorcode, SOME_FOO_ERROR) catch Exception: self.fail('unexpected exception raised') Secondly, that is not the right way to do this unit test. You are testing two distinct things, so you should write it as two separate tests: I have to disagree -- I do not see the advantage of writing a second test that *will* fail if the first test fails as opposed to bundling both tests together, and having one failure. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: unittest: assertRaises() with an instance instead of a type
Steven D'Aprano wrote: To the degree that the decision of how finely to slice tests is a matter of personal judgement and/or taste, I was wrong to say that is not the right way. I should have said that is not how I would do that test. I believe that a single test is too coarse, and three or more tests is too fine, but two tests is just right. Let me explain how I come to that judgement. If you take a test-driven development approach, the right way to test this is to write testFooWillFail once you decide that foo() should raise MyException but before foo() actually does so. You would write the test, the test would fail, and you would fix foo() to ensure it raises the exception. Then you leave the now passing test in place to detect regressions. Then you do the same for the errorcode. Hence two tests. [snip] So: never remove tests just because they are redundant. Only remove them when they are obsolete due to changes in the code being tested. Very persuasive argument -- I now find myself disposed to writing two tests (not three, nor five ;). ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Number of languages known [was Re: Python is readable] - somewhat OT
Tim Rowe wrote: On 22 March 2012 19:14, Chris Angelico ros...@gmail.com wrote: In any case, though, I agree that there's a lot of people professionally writing code who would know about the 3-4 that you say. I'm just not sure that they're any good at coding, even in those few languages. All the best people I've ever known have had experience with quite a lot of languages. I know 10 languages. But I'm not telling you what base that number is :) There are 10 types of people in the world: those who know binary and those who don't. ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
remainder of dividing by zero
Okay, so I haven't asked a stupid question in a long time and I'm suffering withdrawal symptoms... ;) 5 % 0 = ? It seems to me that the answer should be 5: no matter how many times we add 0 to itself, the remainder of the intermediate step will be 5. Is there a postulate or by definition answer as to why this should not be so? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: remainder of dividing by zero
Ethan Furman wrote: Okay, so I haven't asked a stupid question in a long time and I'm suffering withdrawal symptoms... ;) 5 % 0 = ? Thanks for your replies, much appreciated. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: with statement
Ian Kelly wrote: On Thu, Apr 19, 2012 at 3:33 PM, Terry Reedy tjre...@udel.edu wrote: On 4/19/2012 1:15 PM, Kiuhnm wrote: A with statement is not at the module level only if it appears inside a function definition or a class definition. This is true, I believe, of all statements. Am I forgetting something? Comprehensions (in Py3) and lambda expressions also introduce new local scopes -- because they are abbreviated def statements. But they cannot contain statements, only expressions, in that new scope. Syntactically, that's true. However, lambdas and comprehensions are just functions and generator functions under the hood, so in principle there is nothing preventing with blocks from being injected into their byte code. Which would still not be at the module level. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Kiuhnm wrote: I'd like to change the syntax of my module 'codeblocks' to make it more pythonic. Current Syntax: with res func(arg1) 'x, y': print(x, y) with res func(arg1) block_name 'x, y': print(x, y) New Syntax: with res == func(arg1) .taking_block (x, y): print(x, y) with res == func(arg1) .taking_block (x, y) as block_name: print(x, y) The full form is equivalent to def anon_func(x, y): print(x, y) res = func(arg1, block_name = anon_func) Suggestions? I don't find either the current syntax nor the new syntax pythonic. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Arnaud Delobelle wrote: On May 1, 2012 6:42 PM, Jerry Hill wrote: On Tue, May 1, 2012 at 1:07 PM, Kiuhnm wrote: If you had read the module's docstring you would know that the public version uses Are you aware that you've never posted a link to your module, nor it's docstrings? Are you also aware that your module is essentially unfindable on google? Certainly nothing on the first two pages of google results for 'python codeblocks' jumps out at me as a python module of that name. Perhaps you would have better luck if you either post the actual code you want people to critique, or posted a link to that code. He did post a link to a blog post describing his module and also a link to the actual code, on bitbucket IIRC. Actually, it was Ian Kelly that posted the blog reference. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
__del__ and wisdom
Every time discussion about __del__ had come up I had thought to myself, yeah, but I'm being careful to not have reference loops -- /my/ classes are okay. and then... BITE! But hey, it wasn't a reference loop that got me, it was data being written back to disk after the disk portion had changed, thus clobbering new data with old. Yeah, I know, that's not really any better. *sigh* Okay, no more __del__ for me! ~Ethan~ Knowledge is knowing that tomatoes are a fruit. Wisdom is not putting them in a fruit salad. -- http://mail.python.org/mailman/listinfo/python-list
ANN: dbf version 0.92.002 released
Available at http://pypi.python.org/pypi/dbf Fixed issue with Memo fields not returning correct unicode data. Updated many docstrings. Nulls now fully supported. Getting closer to a 1.0 (non-beta!) release; working on PEP 8 compliance, index files, and actual documentation. Biggest change == records no longer auto-update back to disk; make sure and use record.write_record() if you want the on-disk version of the table updated, or use the new Write generator which calls .write_record() before returning the next record in the table/list/index/whatever. As always, comments and bug-reports appreciated! -- http://mail.python.org/mailman/listinfo/python-list
PyPI is being spammed
with Dr Sultan Spells of various natures. Can anybody put a stop to that? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
__all__, public API, private stuff, and leading _
Style question: Since __all__ (if defined) is the public API, if I am using that should I also still use a leading underscore on my private data/functions/etc? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: __all__, public API, private stuff, and leading _
Emile van Sebille wrote: On 5/11/2012 9:41 AM Ethan Furman said... Style question: Since __all__ (if defined) is the public API, if I am using that should I also still use a leading underscore on my private data/functions/etc? I would, even if only to alert any future maintainer of the internal vs exposed nature of things. I find that a persuasive argument, thanks. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie naive question ... int() throws ValueError
Devin Jeanpierre wrote: On Fri, May 11, 2012 at 11:21 PM, Chris Angelico ros...@gmail.com wrote: There are times when you want to catch all exceptions, though. Top-level code will often want to replace exception tracebacks with error messages appropriate to some external caller, or possibly log the exception and return to some primary loop. Otherwise, though, most code will just let unexpected exceptions through. I'm not talking about unexpected exceptions. I'm saying, if I expect invalid input for int, where should I go to find out how to deal with said invalid input properly? How do I know that int raises ValueError on failure, and not, for example, something like ArgumentError (something that Python doesn't have) or (like chr) TypeError? Apparently the answer is to read the documentation for ValueError. It's a bit like putting the documentation on the return type for `map` in the list documentation. Kinda hard to get there without already knowing the answer. Unit tests. :) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Dealing with the __str__ method in classes with lots of attributes
Karl Knechtel wrote: On Thu, May 10, 2012 at 9:33 AM, Andreas Tawn andreas.t...@ubisoft.com wrote: And there's also something like... return \n.join((: .join((str(k), str(self.__dict__[k]))) for k in self.__dict__)) which is a nice length, but I lose control of the order of the attributes and the formatting is fixed. It also looks a bit too much like Lisp ;o) Is there a better way? If you don't care about being able to change the attributes dynamically, define the `__slots__` of your class [...] Firstly, __slots__ is a tuple. Secondly, this is bad advice. __slots__ is there as a memory optimization for classes that will have thousands of instances and do not need the ability to have arbitrary attributes added after creation. __slots__ is an advanced feature, and as such is easier to get wrong. It is *not* there to make __str__ nor __repr__ easier to write. 8--- Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. class Test1(object): ... __slots__ = ('item', 'size') ... desc = 'class-only attribute' ... t1 = Test1() t1.desc = 'read-only attribute' # fails because 'desc' is # not in __slots__ Traceback (most recent call last): File stdin, line 1, in module AttributeError: 'Test1' object attribute 'desc' is read-only print t1.item# fails because 'item' was # not set Traceback (most recent call last): File stdin, line 1, in module AttributeError: item class Test2(Test1): ... def __init__(self, price): ... self.price = price ... t2 = Test2(7.99) # __slots__ not defined in # subclass, optimizations lost t2.oops = '__slots__ no longer active' print t2.oops __slots__ no longer active 8--- ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
cPython, IronPython, Jython, and PyPy (Oh my!)
Just hit a snag: In cPython the deterministic garbage collection allows me a particular optimization when retrieving records from a dbf file -- namely, by using weakrefs I can tell if the record is still in memory and active, and if so not hit the disk to get the data; with PyPy (and probably the others) this doesn't work because the record may still be around even when it is no longer active because it hasn't been garbage collected yet. For PyPy I can use `'PyPy' in sys.version` to set a constant (REFRESH_FROM_DISK in this case) to disable the cPython optimization; does anyone know what strings to look for for the other implementations? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: cPython, IronPython, Jython, and PyPy (Oh my!)
Ian Kelly wrote: On Wed, May 16, 2012 at 3:33 PM, Ethan Furman et...@stoneleaf.us wrote: Just hit a snag: In cPython the deterministic garbage collection allows me a particular optimization when retrieving records from a dbf file -- namely, by using weakrefs I can tell if the record is still in memory and active, and if so not hit the disk to get the data; with PyPy (and probably the others) this doesn't work because the record may still be around even when it is no longer active because it hasn't been garbage collected yet. For PyPy I can use `'PyPy' in sys.version` to set a constant (REFRESH_FROM_DISK in this case) to disable the cPython optimization; does anyone know what strings to look for for the other implementations? Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. import sys sys.subversion ('CPython', 'tags/r271', '86832') Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06) [Java HotSpot(TM) Client VM (Sun Microsystems Inc.)] on java1.6.0_31 Type help, copyright, credits or license for more information. import sys sys.subversion ('Jython', 'tags/Release_2_5_2', '7206') I don't know what IronPython or PyPy return, but it should be something other than 'CPython'. Thanks! That will do the trick. On CPython 2.4 .subversion does not exist, so I'll use: subversion = getattr(sys, 'subversion', None) if subversion is not None and subversion[0] != 'CPython': ... Hopefully all the others do have it defined (PyPy does, at least as of 1.8). ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: cPython, IronPython, Jython, and PyPy (Oh my!)
Tim Delaney wrote: On 17 May 2012 07:33, Ethan Furman wrote: Just hit a snag: In cPython the deterministic garbage collection allows me a particular optimization when retrieving records from a dbf file -- namely, by using weakrefs I can tell if the record is still in memory and active, and if so not hit the disk to get the data; with PyPy (and probably the others) this doesn't work because the record may still be around even when it is no longer active because it hasn't been garbage collected yet. What is the distinguishing feature of an active record? What is the problem if you get back a reference to an inactive record? And if there is indeed a problem, don't you already have a race condition on CPython? 1. Record is active; 2. Get reference to record through weak ref; 3. Record becomes inactive; 4. Start trying to use the (now inactive) record. A record is an interesting critter -- it is given life either from the user or from the disk-bound data; its fields can then change, but those changes are not reflected on disk until .write_record() is called; I do this because I am frequently moving data from one table to another, making changes to the old record contents before creating the new record with the changes -- since I do not call .write_record() on the old record those changes do not get backed up to disk. With CPython as soon as a record goes out of scope it dies, and the next time I try to access that record I will get the disk version, without the temporary changes I had made earlier (this is good). However, with PyPy (and others) not all records are destroyed before I try to access them again, and I end up seeing the temp data instead of the disk data. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: cPython, IronPython, Jython, and PyPy (Oh my!)
Chris Angelico wrote: On Thu, May 17, 2012 at 9:01 AM, Ethan Furman et...@stoneleaf.us wrote: A record is an interesting critter -- it is given life either from the user or from the disk-bound data; its fields can then change, but those changes are not reflected on disk until .write_record() is called; I do this because I am frequently moving data from one table to another, making changes to the old record contents before creating the new record with the changes -- since I do not call .write_record() on the old record those changes do not get backed up to disk. I strongly recommend being more explicit about usage and when it gets written and re-read, rather than relying on garbage collection. Databasing should not be tied to a language's garbage collection. Imagine you were to reimplement the equivalent logic in some other language - could you describe it clearly? If so, then that's your algorithm. If not, you have a problem. Yeah, I've been thinking about this for a couple hours now; initially (way back when) I didn't want to keep hitting the disk unnecessarily -- but all my other supporting data structures go to great lengths to not keep records in memory unless the user has them explicitly named or contained... I think I've been fighting against myself! Good news is I'm winning. ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: A better contextlib.contextmanager
Michele Simionato wrote: but I am asking a question instead: should I add this feature to the next release of the decorator module? I think it would be an excellent addition to your module. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Scoping Issues
Andrew Berg wrote: On 5/24/2012 8:59 PM, Dave Angel wrote: so I fixed that, and got inconsistent use of tabs and spaces in indentation because you mistakenly used tabs for indentation. Not to start another tabs-vs.-spaces discussion, but tabs are perfectly legal indentation in Python. That exception is raised when the interpreter can't determine how much a line is indented because tabs and spaces are both used. To be clear: each entire suite must be consistent with its use of either tabs /or/ spaces -- attempting to use both, even on seperate lines, raises `TabError: inconsistent use of tabs and spaces in indentation`. (Python 3, of course. ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
DBF records API
I'm getting towards an actual non-beta release, which means even more tests, polishings, cleaning up of various things, and actual documentation. :) However, I am wondering about my current record API: Currently, one does things like: record.scatter_fields() or record.has_been_deleted or record.record_number The reason those method names are so long is that field names are limited to 10 characters, and long method names means no possibility of name clashes. Unfortunately, Version 7 tables can have much longer field names. So, do I not ever support version 7, do I not worry about it until I get there (which could easily be a long time from now), or do I move all the methods out of the record class and make them module level functions instead? That would like: dbf.scatter_fields(record) dbf.has_been_deleted(record) dbf.record_number(record) although probably with shorter names. Thoughts? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: DBF records API
MRAB wrote: On 01/06/2012 18:50, Ethan Furman wrote: I'm getting towards an actual non-beta release, which means even more tests, polishings, cleaning up of various things, and actual documentation. :) However, I am wondering about my current record API: Currently, one does things like: record.scatter_fields() or record.has_been_deleted or record.record_number The reason those method names are so long is that field names are limited to 10 characters, and long method names means no possibility of name clashes. Unfortunately, Version 7 tables can have much longer field names. So, do I not ever support version 7, do I not worry about it until I get there (which could easily be a long time from now), or do I move all the methods out of the record class and make them module level functions instead? That would like: dbf.scatter_fields(record) dbf.has_been_deleted(record) dbf.record_number(record) although probably with shorter names. Thoughts? I'd probably think of a record as being more like a dict (or an OrderedDict) with the fields accessed by key: record[name] but: record.deleted Record fields are accessible both by key and by attribute -- by key primarily for those cases when the field name is in a variable: for field in ('full_name','nick_name','pet_name'): print record[field] and since dbf record names cannot start with _ and are at most 10 characters long I've used longer than that method names... but if I want to support dbf version 7 that won't work. I would like to, not sure I will (it's not a need for me at work), but prudence suggests I make the easy preparations now. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: DBF records API
Tim Chase wrote: On 06/01/12 19:05, Jon Clements wrote: On 01/06/12 23:13, Tim Chase wrote: dbf.scatter_fields *always* trump and refer to the method. I did think about *trumping* one way or the other, but both *ugh*. For the record, it sounded like the OP wanted to be able to use the dot-notation for accessing fields by name, and I think it's a pretty non-pythonic way to do it. I'd much rather just stick to purely using __getitem__ for the fields and attributes/methods for non-fields. It can't be *that* non-Pythonic -- we now have namedtuples which pretty much behave just like my record class (although its indexes are only numbers, not strings as well). ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Import semantics?
Dan Stromberg wrote: Did the import semantics change in cpython 3.3a4? I used to be able to import treap.py even though I had a treap directory in my cwd. With 3.3a4, I have to rename the treap directory to see treap.py. Check out PEP 420 -- Implicit Namespace Packages [http://www.python.org/dev/peps/pep-0420/] ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: [Python-Dev] Import semantics?
Eric V. Smith wrote: On 6/8/2012 6:41 PM, Ethan Furman wrote: Dan Stromberg wrote: On Fri, Jun 8, 2012 at 3:16 PM, Ethan Furman wrote: Dan Stromberg wrote: Did the import semantics change in cpython 3.3a4? I used to be able to import treap.py even though I had a treap directory in my cwd. With 3.3a4, I have to rename the treap directory to see treap.py. Check out PEP 420 -- Implicit Namespace Packages [http://www.python.org/dev/peps/pep-0420/] Am I misinterpreting this? It seems like according to the PEP, I should have still been able to import treap.py despite having a treap/. But I couldn't; I had to rename treap/ to treap-dir/ first. During import processing, the import machinery will continue to iterate over each directory in the parent path as it does in Python 3.2. While looking for a module or package named foo, for each directory in the parent path: * If directory/foo/__init__.py is found, a regular package is imported and returned. * If not, but directory/foo.{py,pyc,so,pyd} is found, a module is imported and returned. The exact list of extension varies by platform and whether the -O flag is specified. The list here is representative. * If not, but directory/foo is found and is a directory, it is recorded and the scan continues with the next directory in the parent path. * Otherwise the scan continues with the next directory in the parent path. I do not understand PEP 420 well enough to say if this is intentional or a bug -- thoughts? I missed the beginning of this discussion and I need some more details. What directories are on sys.path, where do treap.py and treap/ appear in them, and is there an __init__.py in treap? At first blush it sounds like it should continue working. If you (Dan?) could re-create this in a small example and open a bug, that would be great. Eric. -- http://mail.python.org/mailman/listinfo/python-list
Re: using identifiers before they are defined
Julio Sergio wrote: Jose H. Martinez josehmartinezz at gmail.com writes: You should define the function first and then call it. def something(i): return i a = something(5) If you want a reference to the function somewhere else you can do this: I know that. That was what I meant by changing the order of the definitions will work in my original message. And I insist in the issue, which is not trivial... In my message I mentioned crossed recursion, and I delve into it here: Suppose I have to define two functions, aa, and, bb that are designed to call each other: def aa(): ... ... a call of bb() somewhere in the body of aa ... def bb(): ... ... a call of aa() somewhere in the body of bb ... Whatever the order of definition of aa and bb the problem remains No. The reply from MRAB explains this. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: using identifiers before they are defined
Julio Sergio wrote: Ethan Furman ethan at stoneleaf.us writes: No. The reply from MRAB explains this. ~Ethan~ Thanks, you're right! I was confusing statemens with declarations. Yeah, it took me a while to get that straight as well. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Academic citation of Python
Ben Finney wrote: Curt cu...@free.fr writes: On 2012-06-16, Christian Heimes li...@cheimes.de wrote: Actually it's van Rossum, Guido, not Rossum, Guido van. The van is part of the family name, not a middle name. It's like da Vinci, Leonardo or von Sydow, Max. On one occasion Guido complained that Americans always get his name wrong. I've read that now he prefers Guido V. Rossum, Jr. Citation needed. But what format should it take? ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: exception problem
Charles Hixson wrote: On 06/25/2012 12:48 AM, Steven D'Aprano wrote: Catch any exception is almost certainly the wrong thing to do, almost always. This time it was the right thing No, it wasn't. If you hadn't caught it, Python would have printed it out for you, along with the full trace-back, giving you most if not all the information you needed to track down the bug. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: I can't send images to this mail-list
Ben Finney wrote: Chris Angelico writes: 梦幻草 wrote: why can't I send images to python-list@python.org?? It's a text-only list. I'll take this opportunity to give heartfelt thanks to the administrators for that policy; please keep this a text-only forum. +1000 -- http://mail.python.org/mailman/listinfo/python-list
Re: Question about weakref
Ian Kelly wrote: def del_b(self, b): for i, x in enumerate(self.array): if b is x: del self.array[i] break Nice work, Ian. -- http://mail.python.org/mailman/listinfo/python-list
API design question for dbf.py
I'm looking for some free advice. ;) My dbf module has three basic containers, all of which support list-like access: Table, List, and Index, each of which is filled with _DbfRecords. The fun part is that a _DbfRecord can compare equal to another _DbfRecord, a _DbfRecordTemplate, a tuple with the same values in the same locations, or a dict with the same keys/fields and values. The really fun part is __contains__: should the __contains__ method return True when a _DbfRecordTemplate, tuple, or dict is looked up in the Table, List, or Index and there is a matching record? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: API design question for dbf.py
MRAB wrote: On 06/07/2012 22:34, Ethan Furman wrote: I'm looking for some free advice. ;) My dbf module has three basic containers, all of which support list-like access: Table, List, and Index, each of which is filled with _DbfRecords. The fun part is that a _DbfRecord can compare equal to another _DbfRecord, a _DbfRecordTemplate, a tuple with the same values in the same locations, or a dict with the same keys/fields and values. The really fun part is __contains__: should the __contains__ method return True when a _DbfRecordTemplate, tuple, or dict is looked up in the Table, List, or Index and there is a matching record? Well, if x is in c and x == y, then y is in c. Does that help? ;-) Heh, that's pretty much the conclusion I was coming to. As a more concrete example: -- x = 4.0 -- x in [1, 4, 7, 4, 9, 3, 4] True It's checking for equality, not identity. Thinks for helping me think that through. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: API design question for dbf.py
Devin Jeanpierre wrote: On Fri, Jul 6, 2012 at 6:46 PM, Ethan Furman et...@stoneleaf.us wrote: It's checking for equality, not identity. x = float('nan') x in [x] True It's checking for equality OR identity. Good point. In my case, checking for equality will cover both cases. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Python Interview Questions
Jean-Michel Pichavant wrote: Why would you want to hire someone that knows something pointless as the version where feature X has been introduced ? As an example from today, if someone claimed to have 5+ years of Python experience, but didn't know that 'with' was standard in 2.6 (or at least the end of the 2.x cycle) I would be suspicious that they actually had the experience they claimed. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Python Interview Questions
Chris Angelico wrote: On Wed, Jul 11, 2012 at 2:34 AM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Of course, if they try to sell themselves as having five years experience with Python 3.2... ... then they've been borrowing Guido's time machine for personal purposes. Reminds me of a job posting a few years ago where the prospective employer wanted three plus years experience in some language, and that language had only been created a year and a half before. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Python professional certification
Mark Lawrence wrote: Google tells me that various certifications are available but I'd like to know if any of these are approved by the PSF or whoever would be responsible? If there's anything out there I've missed it :-( There is an O'Reilly Python Certification class offered in conjunction with the Illinois Institute of Technology (or something like that) which was created by Steve Holden, and taught by him and a couple others. It's a great course of four classes. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Implicit conversion to boolean in if and while statements
Steven D'Aprano wrote: On Sun, 15 Jul 2012 10:19:16 -0600, Ian Kelly wrote: On Sun, Jul 15, 2012 at 4:56 AM, Steven D'Aprano wrote: (For the record, I can only think of one trap for the unwary: time objects are false at *exactly* midnight.) Ugh, that's irritating. I can't think of any scenario where I would ever want the semantics if timeval (is not midnight):. Yes, it is a genuine gotcha. Time values are numbers, and zero is falsey, so midnight is falsey even though it shouldn't be. There's no good solution here, since we have a conflict between treating time values as time values (midnight is nothing special) and as numbers (midnight == 0 which is falsey). -- import datetime -- mn = datetime.time(0) -- mn datetime.time(0, 0) -- mn == 0 False Apparently, midnight does not equal zero. Possibly because it should be truthy. ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Implicit conversion to boolean in if and while statements
Andrew Berg wrote: On 7/15/2012 9:38 PM, Steven D'Aprano wrote: I would expect None to mean doesn't exist or unknown or something like that - e.g., a value of 0 means 0 jelly beans in the jar and None means there isn't a jar. How you interpret some_variable = None depends on what some_variable represents. If some_variable represents number of jelly beans in a jar, then that should be 0 if there is no jar. What is None supposed to mean then, and what should I do when I have to make a distinction between doesn't exist and empty? Sure, if I need to count the total number of jelly beans in all my stores, the distinction is meaningless, but if I need to find out which stores sell jelly beans so I know which stores need to be restocked, the distinction is quite important. I'm not sure what Steven was trying to say there, but for me: jar with no jellybeans == 0 no jar == None ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Implicit conversion to boolean in if and while statements
Andrew Berg wrote: To put it in duck-typing terms, why should everything have to quack like True or False? Sure, I can see why 1 quacks like True or [] quacks like False, but I don't see why say, a Logger or function should quack like either. Should a Thread object be True if it's been started and False otherwise? True and False are red herrings. It is more appropriate to think that True quacks like something and False like nothing than the other way 'round. Maybe some examples from my own code will help: DbfTable-- True if any records in table, False otherwise DbfIndex-- True if any records in index, False otherwise DbfList -- True if any records in list, False otherwise DbfDate -- True if a date, False otherwise (could be eight spaces instead of a real date) DbfDateTime -- True if a datetime, False otherwise DbfRecord -- True always DbfRecordTemplate -- True always DbfRecordVaporware -- False always While I could have DbfRecord be False if, for example, it had no data stored in it, I have no use case for that scenario so haven't bothered. Also, at this point I am using the distinction of True/False with regards to records to determine if I have a real record (True means a record/template I can read/write, False means I don't). If it truly is about something vs. nothing, why is a NameError (or AttributeError) raised when testing with an undefined variable? Being undefined quacks like nothing, doesn't it? It's about /representing/ something vs. nothing. An undefined name isn't representing anything (except a bug, of course ;). ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation, inheritance and polymorphism
Terry Reedy wrote: On 7/17/2012 10:23 AM, Lipska the Kat wrote: Well 'type-bondage' is a strange way of thinking about compile time type checking and making code easier to read (and therefor debug 'type-bondage' is the requirement to restrict function inputs and output to one declared type, where the type declaration mechanisms are usually quite limited. def max(a, b): if a = b: return a return b Surely you meant 'if a = b: . . .' No worries, I'm sure your unittests would have caught it. ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation, inheritance and polymorphism
Mark Lawrence wrote: On 17/07/2012 18:29, Ethan Furman wrote: Terry Reedy wrote: On 7/17/2012 10:23 AM, Lipska the Kat wrote: Well 'type-bondage' is a strange way of thinking about compile time type checking and making code easier to read (and therefor debug 'type-bondage' is the requirement to restrict function inputs and output to one declared type, where the type declaration mechanisms are usually quite limited. def max(a, b): if a = b: return a return b Surely you meant 'if a = b: . . .' No worries, I'm sure your unittests would have caught it. ;) ~Ethan~ Wouldn't the compiler have caught it before the unittests? :-) Silly me, the word processor would have caught it! ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Foxpro goto command and deleted records
In Foxpro if you do a GOTO 7 with deleted off and record 7 is deleted, the record pointer doesn't move (at least in version 6). I don't like that. I see four other options: 0) don't move the pointer (listed for completeness) 1) go to that record anyway 2) go to the next undeleted record 3) go to the seventh undeleted record (possibly the least practical) 4) raise an exception Any opinions? ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Foxpro goto command and deleted records
Ian Kelly wrote: On Tue, Jul 17, 2012 at 4:57 PM, Ethan Furman et...@stoneleaf.us wrote: In Foxpro if you do a GOTO 7 with deleted off and record 7 is deleted, the record pointer doesn't move (at least in version 6). I don't like that. I see four other options: 0) don't move the pointer (listed for completeness) 1) go to that record anyway 2) go to the next undeleted record 3) go to the seventh undeleted record (possibly the least practical) 4) raise an exception Any opinions? Relevance to Python? I'm deciding how my python dbf module will handle this situation. http://python.org/pypi/dbf for the curious. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Foxpro goto command and deleted records
MRAB wrote: On 17/07/2012 23:57, Ethan Furman wrote: In Foxpro if you do a GOTO 7 with deleted off and record 7 is deleted, the record pointer doesn't move (at least in version 6). I don't like that. I see four other options: 0) don't move the pointer (listed for completeness) 1) go to that record anyway 2) go to the next undeleted record 3) go to the seventh undeleted record (possibly the least practical) 4) raise an exception Any opinions? What happens when you 'delete' a record? Does it disappear immediately, or is it merely marked for deletion? Marked for deletion. If it is marked for deletion, can it be unmarked? Will a marked record be removed when the file is closed, or does the file need to be explicitly purged/compacted? Yes, it can be unmarked. No, the table must be explicitly packed. If it is merely marked, then I think the best option is 1, or possibly 4 if the file is compacted when closed. There is a use_deleted setting that controls whether deleted records are accessed or skipped. Skipping is fine when looping, not so fine when going directly to a particular record. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Foxpro goto command and deleted records
MRAB wrote: On 18/07/2012 03:19, Ethan Furman wrote: MRAB wrote: On 17/07/2012 23:57, Ethan Furman wrote: In Foxpro if you do a GOTO 7 with deleted off and record 7 is deleted, the record pointer doesn't move (at least in version 6). I don't like that. I see four other options: 0) don't move the pointer (listed for completeness) 1) go to that record anyway 2) go to the next undeleted record 3) go to the seventh undeleted record (possibly the least practical) 4) raise an exception Any opinions? What happens when you 'delete' a record? Does it disappear immediately, or is it merely marked for deletion? Marked for deletion. If it is marked for deletion, can it be unmarked? Will a marked record be removed when the file is closed, or does the file need to be explicitly purged/compacted? Yes, it can be unmarked. No, the table must be explicitly packed. If it is merely marked, then I think the best option is 1, or possibly 4 if the file is compacted when closed. There is a use_deleted setting that controls whether deleted records are accessed or skipped. Skipping is fine when looping, not so fine when going directly to a particular record. If use_deleted is false, does that mean that deleted records are hidden, or just that when iterating through the records the deleted ones aren't yielded? Definitely the latter, but I'm starting to wonder if the former should also be the case. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation, inheritance and polymorphism
Lipska the Kat wrote: On 18/07/12 14:05, Steven D'Aprano wrote: Even with a break, why bother continuing through the body of the function when you already have the result? When your calculation is done, it's done, just return for goodness sake. You wouldn't write a search that keeps going after you've found the value that you want, out of some misplaced sense that you have to look at every value. Why write code with unnecessary guard values and temporary variables out of a misplaced sense that functions must only have one exit? Object Oriented programming is all about encapsulating human concepts in a way that makes sense to human beings. Make no mistake, it is NEVER the case that a software system is written for any other reason than to serve human beings. OO is more than just the mechanics of writing code, it's a state of mind. I must admit I have no idea how we went from discussing Single Exit functions to the One True Purpose of Object Oriented Programming; are you saying that SE is one of the basic tenets of OO? OO was 'invented' to address the many problems that beset increasingly complex software systems. The main problem was maintainability. Encapsulating a concept in a clear and concise way makes the code easier to understand. Sometimes this means writing code that is not 'optimal' for the machine. Good code should be readable as well as efficient but I contend that it is better to write something that is clear, concise and well encapsulated than always go for the 'meanest dog in the scrapyard' approach where a developer is determined to write unreadable code that shows how jolly clever he is. More often than not he is forced to admit six months down the line that he has no idea what his code does as he 'forgot' to comment it. And one of the many reasons I love Python is that it is so easy to write clear, readable, and sometimes concise code (nested list comps are still a challenge for me). . . . Python looks like an interesting language and I will certainly spend time getting to know it but at the moment it seems to me that calling it an Object Oriented language is just plain misleading. Since *everything* in Python is an object, how can you /not/ call it an OO language? Sure, you don't have to use everything as an object -- plain functions exist -- kinda ;) Even functions live in some namespace: len() lives in __builtin__, any top level function lives in its module, etc. Oh, and namespaces are objects. It seems to me that Python is more about providing tools, and then staying out of your way. That works for me. Maybe it will work for you, too. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Foxpro goto command and deleted records
Ed Leafe wrote: On Jul 17, 2012, at 5:57 PM, Ethan Furman wrote: In Foxpro if you do a GOTO 7 with deleted off and record 7 is deleted, the record pointer doesn't move (at least in version 6). I don't like that. I see four other options: 0) don't move the pointer (listed for completeness) 1) go to that record anyway 2) go to the next undeleted record 3) go to the seventh undeleted record (possibly the least practical) 4) raise an exception Any opinions? It's been many years since I fired up VFP, but the above doesn't sound correct. If you have SET DELETED OFF and the GOTO 7, the pointer should move to the 7th record, whether it is marked deleted or not. With SET DELETED ON, the pointer should not move, since 7 is not a valid record. Your memory is good! I typed it in wrong. I still don't like it. Any opinion on the other four choices? I'm leaning towards 1, possibly with 4 as an option: def goto(self, recno, raise_if_deleted=True): if is_deleted(self[recno)) and raise_if_deleted: raise DbfError( Record %d is deleted and use_deleted is False % recno) self._index = recno Part of the reason I feel this is reasonable is that with my dbf module it is possible to create an index that does /not/ include certain records: def ignore_deleted(record): if dbf.deleted(record): return dbf.DoNotIndex return dbf.recno(record) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
ANN: dbf.py 0.94
Getting closer to a stable release. Latest version has a simpler, cleaner API, and works on PyPy (and hopefully the other implementations as well ;), as well as CPython. Get your copy at http://python.org/pypi/dbf. Bug reports, comments, and kudos welcome! ;) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Steven D'Aprano wrote: On Fri, 20 Jul 2012 16:59:21 -0700, Ethan Furman wrote: Getting closer to a stable release. Excellent! That's fantastic news! I've been waiting for a stable release of dbf for months! I just have one question. What is dbf? :) dbf (also known as python dbase) is a module for reading/writing dBase III, FP, VFP, and soon Clipper, .dbf database files. It's an ancient format that still finds lots of use. It even reads and writes memo fields -- something which none of the other modules do (which is why I wrote this one -- I needed that! ;). It supports unicode, and returns all fields as native Python types: Character -- unicode Date -- datetime.date Logical -- bool/None Memo -- unicode Numeric -- int/float depending on field definition If a field is uninitialized (Date, Logical, Numeric) then None is returned for the value. Tables are accessible as lists; Records are accessible as lists, dicts, and objects ( attribute access ). Enjoy your weekend! -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Steven D'Aprano wrote: This mailing list is about helping our fellow Python developers improve their skills and solve problems. That doesn't just mean *coding* problems, it also means helping them to write better documentation and promote their software better. Indeed it is, and your reminder is appreciated. Hopefully my followup-post was more explanatory. Unless the software is so well-known that everybody knows what it is, failure to mention what the software does gives the impression that: 1) the software is so niche, or so ill-thought out, that the developer *can't* describe it succinctly; Nah -- just the end of a long week, needed to go get my daughter, and wanted it out there for those few who actually need the bug fixes (which I neglected to mention). 2) the developer has such poor communication skills that trying to get support will be a nightmare; My support is pretty good. :) 3) that he just doesn't give a monkey's toss for anyone else's time See point one. or all three. Ethan is a good, helpful member of this community, and so I'm pretty sure that neither 2) nor 3) are true, but others may get the wrong impression. Thank you. The project is kinda niche, but very useful if you happen to be in that niche. Here are a few randomly selected examples of good release announcements: http://mail.python.org/pipermail/python-announce-list/2012-June/009528.html http://mail.python.org/pipermail/python-announce-list/2012-June/009509.html http://mail.python.org/pipermail/python-announce-list/2012-June/009524.html Those are good. My announcement will be better next time. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Simon Cropper wrote: Question 1 - What version of VFP will dbf work with? Is VFP9 OK? As long as you don't use auto-incrementing fields nor varchar fields you'll be fine. Question 2 - You statement of compatibility is unclear. Works with CPython 2.4 - 2.7. (Tested) Works with PyPy 1.8. (Tested) Should work with the others. (Not tested) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Chris Angelico wrote: On Sat, Jul 21, 2012 at 6:02 PM, Ethan Furman et...@stoneleaf.us wrote: Works with CPython 2.4 - 2.7. (Tested) Have you considered supporting 3.2/3.3 at all? It's often not difficult to make your code compatible with both. Or is there some dependency that is locked to 2.X? I'll support 3.3+, but not with the same code base: I want to use all the cool features that 3.3 has! :) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Alex Strickland wrote: Hi Getting closer to a stable release. Latest version has a simpler, cleaner API, and works on PyPy (and hopefully the other implementations as well ;), as well as CPython. Get your copy at http://python.org/pypi/dbf. Bug reports, comments, and kudos welcome! ;) Not supported: index files: I have been using http://sourceforge.net/projects/harbour-project/ for years where a guy called Przemyslaw Czerpak has written an absolutely bullet proof implementation of NTX and CDX for DBF. Maybe it will interest you. I'll check it out, thanks! PS : bareable is spelt bearable. I wondered about that. :/ ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Ethan Furman wrote: Alex Strickland wrote: Not supported: index files: I have been using http://sourceforge.net/projects/harbour-project/ for years where a guy called Przemyslaw Czerpak has written an absolutely bullet proof implementation of NTX and CDX for DBF. Maybe it will interest you. I'll check it out, thanks! Unfortunately his code is GPL'ed, so I can't use it. :( ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: ANN: dbf.py 0.94
Chris Angelico wrote: On Sun, Jul 22, 2012 at 4:15 AM, Ethan Furman et...@stoneleaf.us wrote: I'll support 3.3+, but not with the same code base: I want to use all the cool features that 3.3 has! :) The trouble with double-codebasing is that you have double maintenance. But sure. So long as your time isn't under great pressure, it can be quite effective. Once I get dbf.py to 1.0 release, it will enter maintenance/bug-fix-only mode, and I'll start on the 3.3+ version. The 1.0 release will have the final API, support for Clipper tables, hopefully support for auto-incrementing fields, maybe support for .idx files, plus everything there now. .cdx files (and maybe .idx files) will have to wait for the 3.3+ version. There, now I have a roadmap to follow! :) ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Gender, Representativeness and Reputation in StackOverflow
Terry Reedy wrote: Leaving aside the point that this is not directly related to Python, my opinion is that if the authors will not make past and future papers freely available, not even an abstract, they should not ask for valuable free data from freely donated time. Thanks, Terry! Save me some valuable time. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list