From brett at python.org Mon May 1 02:31:49 2006 From: brett at python.org (Brett Cannon) Date: Sun, 30 Apr 2006 17:31:49 -0700 Subject: [Python-Dev] Adding functools.decorator In-Reply-To: References: <4454C203.2060707@iinet.net.au> Message-ID: On 4/30/06, Guido van Rossum wrote: > On 4/30/06, Georg Brandl wrote: > > Nick Coghlan wrote: > > > Collin Winters has done the work necessary to rename PEP 309's functional > > > module to functools and posted the details to SF [1]. > > > > > > I'd like to take that patch, tweak it so the C module is built as _functools > > > rather than functools, and then add a functools.py consisting of: > > > > I'm all for it. (You could integrate the C version of "decorator" from my SF > > patch, but I think Python-only is enough). > > Stronger -- this should *not* be implemented in C. There's no > performance need, and the C code is much harder to understand, check, > and modify. > > I expect that at some point people will want to tweak what gets copied > by _update_wrapper() -- e.g. some attributes may need to be > deep-copied, or personalized, or skipped, etc. (Doesn't this already > apply to __decorator__ and __decorates__? I can't prove to myself that > these get set to the right things when several decorators are stacked > on top of each other.) > > I'm curious if @decorator is the right name and the right API for this > though? The name is overly wide (many things are decorators but should > not be decorated with @decorator) and I wonder of a manual call to > _update_wrapper() wouldn't be just as useful. I am +0 on the manual call. Just seems like I would like to happen explicitly instead of through a decorator. > (Perhaps with a simpler > API -- I'm tempted to call YAGNI on the __decorator__ and > __decorates__ attributes.) > This should also be redundant once I get the signature PEP cleaned up (and probably email py3k or python-dev on the subject) since I plan to store a reference to the function the object represents. That would mean if update_wrapper() copies the signature object over then you have a reference to the original function that way. -Brett > I think there are too many design options here to check this in > without more discussion. > > -- > --Guido van Rossum (home page: http://www.python.org/~guido/) > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/brett%40python.org > From brett at python.org Mon May 1 02:36:35 2006 From: brett at python.org (Brett Cannon) Date: Sun, 30 Apr 2006 17:36:35 -0700 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: References: <4454BA62.5080704@iinet.net.au> Message-ID: On 4/30/06, Guido van Rossum wrote: > On 4/30/06, Nick Coghlan wrote: > > A few things from the pre-alpha2 context management terminology review have > > had a chance to run around in the back of my head for a while now, and I'd > > like to return to a topic Paul Moore brought up during that discussion. > > I believe the context API design has gotten totally out of hand. > Regardless of the merits of the "with" approach to HTML generation > (which I personally believe to be an abomination), I don't see why the > standard library should support every possible use case with a > custom-made decorator. Let the author of that tag library provide the > decorator. > > I have a counter-proposal: let's drop __context__. Nearly all use > cases have __context__ return self. In the remaining cases, would it > really be such a big deal to let the user make an explicit call to > some appropriately named method? The only example that I know of where > __context__ doesn't return self is the decimal module. So the decimal > users would have to type > +1. -Brett > with mycontext.some_method() as ctx: # ctx is a clone of mycontext > ctx.prec += 2 > > > The implementation of some_method() could be exactly what we currently > have as the __context__ method on the decimal.Context object. Its > return value is a decimal.WithStatementContext() instance, whose > __enter__() method returns a clone of the original context object > which is assigned to the variable in the with-statement (here 'ctx'). > > This even has an additional advantage -- some_method() could have > keyword parameters to set the precision and various other context > parameters, so we could write this: > > with mycontext.some_method(prec=mycontext.prec+2): > > > Note that we can drop the variable too now (unless we have another > need to reference it). An API tweak for certain attributes that are > often incremented or decremented could reduce writing: > > with mycontext.some_method(prec_incr=2): > > > -- > --Guido van Rossum (home page: http://www.python.org/~guido/) > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/brett%40python.org > From tjreedy at udel.edu Mon May 1 02:45:24 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 30 Apr 2006 20:45:24 -0400 Subject: [Python-Dev] PEP 3101: Advanced String Formatting References: <4453AF51.6050605@acm.org> Message-ID: "Talin" wrote in message news:4453AF51.6050605 at acm.org... > Compound names are a sequence of simple names seperated by separated > The string and unicode classes will have a class method called > 'cformat' that does all the actual work of formatting; The > format() method is just a wrapper that calls cformat. > > The parameters to the cformat function are: > > -- The format string (or unicode; the same function handles > both.) A class method gets the class as its first argument. If the format string in the first argument, then it is a normal instance method. tjr From tjreedy at udel.edu Mon May 1 03:08:57 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 30 Apr 2006 21:08:57 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <44549922.7020109@gmail.com> Message-ID: "Nick Coghlan" wrote in message news:44549922.7020109 at gmail.com... > Terry Reedy wrote: >> "Talin" wrote in message >> news:4453B025.3080100 at acm.org... >>> Now, suppose you wanted to have 'key' be a keyword-only argument. >> >> Why? Why not let the user type the additional argument(s) without the >> parameter name? Like Martin, you clipped most of the essential context of my question: Talin's second proposal. >>> The second syntactical change is to allow the argument name to >>> be omitted for a varargs argument: >>> def compare(a, b, *, key=None): >>> The reasoning behind this change is as follows. Imagine for a >>> moment a function which takes several positional arguments, as >>> well as a keyword argument: >>> def compare(a, b, key=None): Again I ask, why would one want that? And, is the need for that so strong as to justify introducing '*' as a pseudoparameter? > Because for some functions (e.g. min()/max()) you want to use *args, but > support some additional keyword arguments to tweak a few aspects of the > operation (like providing a "key=x" option). This and the rest of your 'explanation' is about Talin's first proposal, to which I already had said "The rationale for this is pretty obvious". Terry Jan Reedy From john at integralsource.com Mon May 1 03:59:32 2006 From: john at integralsource.com (John Keyes) Date: Mon, 1 May 2006 02:59:32 +0100 Subject: [Python-Dev] unittest argv Message-ID: Hi, main() in unittest has an optional parameter called argv. If it is not present in the invocation, it defaults to None. Later in the function a check is made to see if argv is None and if so sets it to sys.argv. I think the default should be changed to sys.argv[1:] (i.e. the command line arguments minus the name of the python file being executed). The parseArgs() function then uses getopt to parse argv. It currently ignores the first item in the argv list, but this causes a problem when it is called from another python function and not from the command line. So using the current code if I call: python mytest.py -v then argv in parseArgs is ['mytest.py', '-v'] But, if I call: unittest.main(module=None, argv=['-v','mytest']) then argv in parseArgs is ['mytest'], as you can see the verbosity option is now gone and cannot be used. Here's a diff to show the code changes I have made: 744c744 < argv=None, testRunner=None, testLoader=defaultTestLoader): --- > argv=sys.argv[1:], testRunner=None, testLoader=defaultTestLoader): 751,752d750 < if argv is None: < argv = sys.argv 757c755 < self.progName = os.path.basename(argv[0]) --- > # self.progName = os.path.basename(argv[0]) 769c767 < options, args = getopt.getopt(argv[1:], 'hHvq', --- > options, args = getopt.getopt(argv, 'hHvq', You may notice I have commented out the self.progName line. This variable is not used anywhere in the module so I guess it could be removed. To keep it then conditional check on argv would have to remain and be moved after the self.progName line. I hope this makes sense, and it's my first post so go easy on me ;) Thanks, -John K From ncoghlan at gmail.com Mon May 1 04:05:15 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 12:05:15 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: References: <4454BA62.5080704@iinet.net.au> Message-ID: <44556CDB.1070604@gmail.com> Guido van Rossum wrote: > On 4/30/06, Nick Coghlan wrote: >> A few things from the pre-alpha2 context management terminology review >> have >> had a chance to run around in the back of my head for a while now, and >> I'd >> like to return to a topic Paul Moore brought up during that discussion. > > I believe the context API design has gotten totally out of hand. > Regardless of the merits of the "with" approach to HTML generation > (which I personally believe to be an abomination), The example is tempting because it's easy to follow. I agree actually doing it in real code would almost certainly be nuts :) > I don't see why the > standard library should support every possible use case with a > custom-made decorator. Let the author of that tag library provide the > decorator. The HTML tag was just an example. The underlying idea is being able to easily create a re-usable object that can be passed to multiple with statements (potentially nested within each other or within distinct threads). Without the __context__ method, the naive version of such an object looks like: class reusable(object): def __init__(self, factory): self.factory = factory factory() # Check the factory works at definition time def __enter__(self): current = self.current = factory() return current.__enter__() def __exit__(self, *exc_info): return self.current.__exit__(*exc_info) The downside of this over the __context__ method is that it is neither nesting nor thread-safe. Because the storage is on the object rather than in the execution frame, sharing such objects between threads or using one for nested with statements will break (as self.current gets overwritten). > I have a counter-proposal: let's drop __context__. Nearly all use > cases have __context__ return self. In the remaining cases, would it > really be such a big deal to let the user make an explicit call to > some appropriately named method? The only example that I know of where > __context__ doesn't return self is the decimal module. It would also prevent threading.Condition from using its underlying lock object as the managed context. The real problem I have with removing __context__() is that it pushes the burden of handling thread-safety and nesting-safety issues onto the developers of context managers without giving them any additional tools beyond threading.locals(). This was the problem Jason brought up for decimal.Context that lead to the introduction of __context__ in the first place. Without the __context__() method, *users* of the with statement will be forced to create a new object with __enter__()/__exit__() methods every time, either by invoking a method (whose name will vary from object to object, depending on the whim of the designer) or by calling a factory function (which is likely to be created either as a zero-argument lambda returning an object with enter/exit methods, or else by using PEP 309's partial function). So if you see a with statement with a bare variable name as the context expression, it will probably be wrong, unless: a) the implementor of that type provided thread-safety and nesting-safety; or b) the object is known to be neither thread-safe nor nesting-safe The synchronisation objects in threading being examples of category a, file objects being examples of category b. In this scenario, generator contexts defined using @contextfactory should always be invoked directly in the context expression, as attempting to cache them in order to be reused won't work (you would need to put them in a zero-argument lambda and call it in the context expression, so that you get a new generator object each time). Documenting all of the thread-safety and nesting-safety issues and how to deal with them would be a serious pain. I consider it much easier to provide the __context__() method and explain how to use that as the one obvious way to deal with such problems. Then only implementors need to care about it - from a user's point of view, you just provide a context expression that resolves to a context manager, and everything works as intended, including being able to cache that expression in a local variable and use it multiple times. (That last point obviously not applying to context managers like files that leave themselves in an unusable state after __exit__, and don't restore themselves to a usable state in __enter__). Essentially, I don't think dropping __context__ would gain us anything - the complexity associated with it is real, and including that method in the API let's us deal with that complexity in one place, once and for all. Removing the method from the statement definition just pushes the documentation burden out to all of the context managers where it matters (like decimal.Context, the documentation for which would get stuck with trying to explain why you have to call a method in order to get a usable context manager). Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From guido at python.org Mon May 1 04:10:46 2006 From: guido at python.org (Guido van Rossum) Date: Sun, 30 Apr 2006 19:10:46 -0700 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <5.1.1.6.0.20060430144919.01e6bb18@mail.telecommunity.com> References: <4454BA62.5080704@iinet.net.au> <5.1.1.6.0.20060430144919.01e6bb18@mail.telecommunity.com> Message-ID: > At 09:53 AM 4/30/2006 -0700, Guido van Rossum wrote: > >I have a counter-proposal: let's drop __context__. [...] > > with mycontext.some_method(prec_incr=2): > > On 4/30/06, Phillip J. Eby wrote: > But what's an appropriate name for some_method? Let's leave that up to the decimal lovers. You could call it push() or stack() or establish() or some other non-descript word. Or manage() or manager(). The method name can't involve the word "context" since the object is already called a context. But that still leaves an infinite number of possible names. :-) > If you can solve the naming issue for these use cases (and I notice you > punted on that issue by calling it "some_method"), then +1 on removing > __context__. Otherwise, I'm -0; we're just fixing one > documentation/explanation problem (that only people writing contexts will > care about) by creating others (that will affect the people *using* > contexts too). To the contrary. Even if we never come up with a perfect name for decimal.Context.some_method(), then we've still solved a documentation problem for 9 out of 10 cases where __context__ is just empty ballast. But I'm sure that if we require that folks come up with a name, they will. Things should be as simple as possible but no simpler. It's pretty clear to me that dropping __context__ approaches this ideal. I'm sorry I didn't push back harder when __context__ was first proposed -- in retrospect, the first 5 months of PEP 343's life, before __context__ (or __with__, as it was originally called) was invented, were by far its happiest times. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From edloper at gradient.cis.upenn.edu Mon May 1 04:50:49 2006 From: edloper at gradient.cis.upenn.edu (Edward Loper) Date: Sun, 30 Apr 2006 22:50:49 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> Message-ID: <44557789.5020107@gradient.cis.upenn.edu> Terry Reedy wrote: > There are two subproposals: first, keyword-only args after a variable > number of positional args, which requires allowing keyword parameter > specifications after the *args parameter, and second, keyword-only args > after a fixed number number of positional args, implemented with a naked > '*'. To the first, I said "The rationale for this is pretty obvious.". To > the second, I asked, and still ask, "Why?". I see two possible reasons: - A function's author believes that calls to the function will be easier to read if certain parameters are passed by name, rather than positionally; and they want to enforce that calling convention on their users. This seems to me to go against the "consenting adults" principle. - A function's author believes they might change the signature in the future to accept new positional arguments, and they will want to put them before the args that they declare keyword-only. Both of these motivations seem fairly weak. Certainly, neither seems to warrant a significant change to function definition syntax. But perhaps there are other use cases that I'm failing to consider. Anyone know of any? -Edward From guido at python.org Mon May 1 05:08:17 2006 From: guido at python.org (Guido van Rossum) Date: Sun, 30 Apr 2006 20:08:17 -0700 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <44556CDB.1070604@gmail.com> References: <4454BA62.5080704@iinet.net.au> <44556CDB.1070604@gmail.com> Message-ID: [I'm cutting straight to the chase here] On 4/30/06, Nick Coghlan wrote: > The downside of this over the __context__ method is that it is neither nesting > nor thread-safe. This argument is bogus. We currently have two types of objects involved in with-statements: those whose __context__ returns self and those whose __context__ returns some other object. In all of the latter cases, the original object doesn't have __enter__ or __exit__ methods, so using it in the "reduced-with-statement" will be an immediate run-time error. Writing a method that returns the correct type of object with the correct behavior (thread-safe, or nesting, or whatever is required by that specific object) is no harder whether the method name is __context__ or not. > The real problem I have with removing __context__() is that it pushes the > burden of handling thread-safety and nesting-safety issues onto the developers > of context managers without giving them any additional tools beyond > threading.locals(). This was the problem Jason brought up for decimal.Context > that lead to the introduction of __context__ in the first place. Again, I don't see how writing the thread-safe version is easier when the method is called __context__. > Without the __context__() method, *users* of the with statement will be forced > to create a new object with __enter__()/__exit__() methods every time, You seem to be missing the evidence that 9 out of 10 objects currently have a __context__ that returns self. In all those cases the user of the with-statement won't have to make any changes at all compared to code that works with 2.5a2. > either > by invoking a method (whose name will vary from object to object, depending on > the whim of the designer) or by calling a factory function (which is likely to > be created either as a zero-argument lambda returning an object with > enter/exit methods, or else by using PEP 309's partial function). Having the name being different in each situation may actually be an advantage -- it will give an additional clue as to what is happening, and it will let us design different APIs for use in a with-statement (just like dicts have iterkeys() and iteritems()). > So if you see a with statement with a bare variable name as the context > expression, it will probably be wrong, unless: > a) the implementor of that type provided thread-safety and nesting-safety; or > b) the object is known to be neither thread-safe nor nesting-safe > > The synchronisation objects in threading being examples of category a, file > objects being examples of category b. In this scenario, generator contexts > defined using @contextfactory should always be invoked directly in the context > expression, as attempting to cache them in order to be reused won't work (you > would need to put them in a zero-argument lambda and call it in the context > expression, so that you get a new generator object each time). Now we get to the crux of the matter. When I recommend that people write with foo.some_method(): you are worried that if they need two separate blocks like that, they are tempted to write x = foo.some_method() with x: with x: But there's an obvious solution for that: make sure that the object returned by foo.some_method() can only be used once. The second "with x" will raise an exception explaining what went wrong. (We could even rig it so that nesting the second "with x" inside the first one will produce a different error message.) So the "with foo.some_method()" idiom is the only one that works, and that is just as thread-safe and nesting-resilient as is writing __context__() today. If you object against the extra typing, we'll first laugh at you (proposals that *only* shave a few characters of a common idiom aren't all that popular in these parts), and then suggest that you can spell foo.some_method() as foo(). > Essentially, I don't think dropping __context__ would gain us anything - the > complexity associated with it is real, and including that method in the API > let's us deal with that complexity in one place, once and for all. It's not real in 9 out of 10 current cases. (And the Condition variable could easily be restored to its previous case where it had its own __enter__ and __exit__ methods that called the corresponding methods of the underlying lock. The code currently in svn is merely an optimization.) -- --Guido van Rossum (home page: http://www.python.org/~guido/) From pje at telecommunity.com Mon May 1 06:17:18 2006 From: pje at telecommunity.com (Phillip J. Eby) Date: Mon, 01 May 2006 00:17:18 -0400 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: References: <44556CDB.1070604@gmail.com> <4454BA62.5080704@iinet.net.au> <44556CDB.1070604@gmail.com> Message-ID: <5.1.1.6.0.20060501001028.01e6a460@mail.telecommunity.com> At 08:08 PM 4/30/2006 -0700, Guido van Rossum wrote: >If you object against the extra typing, we'll first laugh at you >(proposals that *only* shave a few characters of a common idiom aren't >all that popular in these parts), and then suggest that you can spell >foo.some_method() as foo(). Okay, you've moved me to at least +0 for dropping __context__. I have only one object myself that has a non-self __context__, and it doesn't have a __call__, so none of my code breaks beyond the need to add parentheses in a few places. ;) As for decimal contexts, I'm thinking maybe we should have a decimal.using(ctx=None, **kw) function, where ctx defaults to the current decimal context, and the keyword arguments are used to make a modified copy, seems like a reasonable best way to implement the behavior that __context__ was added for. And then all of the existing special machinery can go away and be replaced with a single @contextfactory. (I think we should stick with @contextfactory as the decorator name, btw, even if we go back to calling __enter__/__exit__ things context managers.) From jcarlson at uci.edu Mon May 1 06:19:04 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Sun, 30 Apr 2006 21:19:04 -0700 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <44550752.1050907@v.loewis.de> References: <20060430111344.673E.JCARLSON@uci.edu> <44550752.1050907@v.loewis.de> Message-ID: <20060430191152.6741.JCARLSON@uci.edu> "Martin v. L?wis" wrote: > > Josiah Carlson wrote: > >> I think what you are missing is that algorithms that currently operate > >> on byte strings should be reformulated to operate on character strings, > >> not reformulated to operate on bytes objects. > > > > By "character strings" can I assume you mean unicode strings which > > contain data, and not some new "character string" type? > > I mean unicode strings, period. I can't imagine what "unicode strings > which do not contain data" could be. Binary data as opposed to text. Input to a array.fromstring(), struct.unpack(), etc. > > I know I must > > have missed some conversation. I was under the impression that in Py3k: > > > > Python 1.x and 2.x str -> mutable bytes object > > No. Python 1.x and 2.x str -> str, Python 2.x unicode -> str > In addition, a bytes type is added, so that > Python 1.x and 2.x str -> bytes > > The problem is that the current string type is used both to represent > bytes and characters. Current applications of str need to be studied, > and converted appropriately, depending on whether they use > "str-as-bytes" or "str-as-characters". The "default", in some > sense of that word, is that str applications are assumed to operate > on character strings; this is achieved by making string literals > objects of the character string type. Certainly it is the case that right now strings are used to contain 'text' and 'bytes' (binary data, encodings of text, etc.). The problem is in the ambiguity of Python 2.x str containing text where it should only contain bytes. But in 3.x, there will continue to be an ambiguity, as strings will still contain bytes and text (parsing literals, see the somewhat recent argument over bytes.encode('base64'), etc.). We've not removed the problem, only changed it from being contained in non-unicode strings to be contained in unicode strings (which are 2 or 4 times larger than their non-unicode counterparts). Within the remainder of this email, there are two things I'm trying to accomplish: 1. preserve the Python 2.x string type 2. make the bytes object more pallatable regardless of #1 The current plan (from what I understand) is to make all string literals equivalent to their Python 2.x u-prefixed equivalents, and to leave u-prefixed literals alone (unless the u prefix is being removed?). I won't argue because I think it is a great idea. I do, however, believe that the Python 2.x string type is very useful from a data parsing/processing perspective. Look how successful and effective it has been so far in the history of Python. In order to make the bytes object be as effective in 3.x, one would need to add basically all of the Python 2.x string methods to it (having some mechanism to use slices of bytes objects as dictionary keys (if data[:4] in handler: ... -> if tuple(data[:4]) in handler: ... ?) would also be nice). Of course, these implementations, ultimately, already exist with Python 2.x immutable strings. So, what to do? Rename Python 2.x str to bytes. The name of the type now confers the idea that it should contain bytes, not strings. If bytes literals are deemed necessary (I think they would be nice, but not required), have b"..." as the bytes literal. Not having a literal, I think, will generally reduce the number of people who try to put text into bytes. Ahh, but what about the originally thought-about bytes object? That mutable, file-like, string-like thing which is essentially array.array ('B', ...) with some other useful stuff? Those are certainly still useful, but not so much from a data parsing/processing perspective, as much as a mutable in-memory buffer (not the Python built-in buffer object, but a C-equivalent char* = (char*)malloc(...); ). I currently use mmaps and array objects for that (to limited success), but a new type in the collections module (perhaps mutablebytes?) which offers such functionality would be perfectly reasonable (as would moving the immutable bytes object if it lacked a literal; or even switch to bytes/frozenbytes). If we were to go to the mutable/immutable bytes object pair, we could still give mutable bytes .read()/.write(), slice assignment, etc., and even offer an integer view mechanism (for iteration, assignment, etc.). Heck, we could do the same thing for the immutable type (except for .write(), assignment, etc.), and essentially replace cStringIO(initializer) (of course mutable bytes effectively replace cStringIO()). > > and that there would be some magical argument > > to pass to the file or open open(fn, 'rb', magical_parameter).read() -> > > bytes. > > I think the precise details of that are still unclear. But yes, > the plan is to have two file modes: one that returns character > strings (type 'str') and one that returns type 'bytes'. Here's a thought; require 'b' or 't' as arguments to open/file, the 't' also having an optional encoding argument (which defaults to the current default encoding). If one attempts to write bytes to a text file or if one attempts to write text to a bytes file; IOError, "Cannot write bytes to a text file" or "Cannot write text to a bytes file". Passing an encoding to the 'b' file could either raise an exception, or provide an encoding for text writing (removing the "Cannot write text to a bytes file"), though I wouldn't want to do any encoding by default for this case. If there are mutable/immutable bytes as I describe above, reads on such could produce either, but only one of the two (immutable seems reasonable, at least from a consistancy perspective), but writes could take either (or even buffer()s). > > I mention this because I do binary data handling, some ''.join(...) for > > IO buffers as Guido mentioned (because it is the fastest string > > concatenation available in Python 2.x), and from this particular > > conversation, it seems as though Python 3.x is going to lose > > some expressiveness and power. > > You certainly need a "concatenate list of bytes into a single > bytes". Apparently, Guido assumes that this can be done through > bytes().join(...); I personally feel that this is over-generalization: > if the only practical application of .join is the empty bytes > object as separator, I think the method should be omitted. > > bytes(...) > bytes.join(...) I don't know if the only use-case for bytes would be ''.join() (all of mine happen to be; non-''.join() cases are text), but I don't see the motivator for _only_ allowing that particular use. The difference is an increment in the implementation; type checking and data copying should be more significant. - Josiah From martin at v.loewis.de Mon May 1 07:38:59 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 07:38:59 +0200 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <20060430191152.6741.JCARLSON@uci.edu> References: <20060430111344.673E.JCARLSON@uci.edu> <44550752.1050907@v.loewis.de> <20060430191152.6741.JCARLSON@uci.edu> Message-ID: <44559EF3.3050605@v.loewis.de> Josiah Carlson wrote: >> I mean unicode strings, period. I can't imagine what "unicode strings >> which do not contain data" could be. > > Binary data as opposed to text. Input to a array.fromstring(), > struct.unpack(), etc. You can't/shouldn't put such data into character strings: you need an encoding first. Neither array.fromstring nor struct.unpack will produce/consume type 'str' in Python 3; both will operate on the bytes type. So fromstring should probably be renamed frombytes. > Certainly it is the case that right now strings are used to contain > 'text' and 'bytes' (binary data, encodings of text, etc.). The problem > is in the ambiguity of Python 2.x str containing text where it should > only contain bytes. But in 3.x, there will continue to be an ambiguity, > as strings will still contain bytes and text (parsing literals, see the > somewhat recent argument over bytes.encode('base64'), etc.). No. In Python 3, type 'str' cannot be interpreted to contain bytes. Operations that expect bytes and are given type 'str', and no encoding, should raise TypeError. > We've not removed the problem, only changed it from being contained > in non-unicode > strings to be contained in unicode strings (which are 2 or 4 times larger > than their non-unicode counterparts). We have removed the problem. > Within the remainder of this email, there are two things I'm trying to > accomplish: > 1. preserve the Python 2.x string type I would expect that people try that. I'm -1. > 2. make the bytes object more pallatable regardless of #1 This might be good, but we have to be careful to not create a type that people would casually use to represent text. > I do, however, believe that the Python 2.x string type is very useful > from a data parsing/processing perspective. You have to explain your terminology somewhat better here: What applications do you have in mind when you are talking about "parsing/processing"? To me, "parsing" always means "text", never "raw bytes". I'm thinking of the Chomsky classification of grammars, EBNF, etc. when I hear "parsing". > Look how successful and > effective it has been so far in the history of Python. In order to make > the bytes object be as effective in 3.x, one would need to add basically > all of the Python 2.x string methods to it The precondition of this clause is misguided: the bytes type doesn't need to be as effective, since the string type is as effective in 2.3, so you can do all parsing based on strings. > (having some mechanism to use > slices of bytes objects as dictionary keys (if data[:4] in handler: ... > -> if tuple(data[:4]) in handler: ... ?) would also be nice). You can't use the bytes type as a dictionary key because it is immutable. Use the string type instead. > So, what to do? Rename Python 2.x str to bytes. The name of the type > now confers the idea that it should contain bytes, not strings. It seems that you want an immutable version of the bytes type. As I don't understand what "parsing" is, I cannot see the need for it; I think having two different bytes types is confusing. Regards, Martin From martin at v.loewis.de Mon May 1 07:46:55 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 07:46:55 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> Message-ID: <4455A0CF.3080008@v.loewis.de> Terry Reedy wrote: >> Are you asking why that feature (keyword-only arguments) is desirable? >> That's the whole point of the PEP. Or are you asking why the user >> shouldn't be allowed to pass keyword-only arguments by omitting the >> keyword? Because they wouldn't be keyword-only arguments then, anymore. > > There are two subproposals: first, keyword-only args after a variable > number of positional args, which requires allowing keyword parameter > specifications after the *args parameter, and second, keyword-only args > after a fixed number number of positional args, implemented with a naked > '*'. To the first, I said "The rationale for this is pretty obvious.". To > the second, I asked, and still ask, "Why?". One reason I see is to have keyword-only functions, i.e. with no positional arguments at all: def make_person(*, name, age, phone, location): pass which also works for methods: def make_person(self, *, name, age, phone, location): pass In these cases, you don't *want* name, age to be passed in a positional way. How else would you formulate that if this syntax wasn't available? (I know it is possible to formulate it elsehow, I'm asking what notation you would use) > Again: if a function has a fixed number n of params, why say that the first > k can be passed by position, while the remaining n-k *must* be passed by > name? I see an important use case for k=0 functions, and k=1 methods (where the only positional argument is self). Regards, Martin From martin at v.loewis.de Mon May 1 07:50:09 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 07:50:09 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <44549922.7020109@gmail.com> Message-ID: <4455A191.5000404@v.loewis.de> Terry Reedy wrote: >>>> Now, suppose you wanted to have 'key' be a keyword-only argument. >>> Why? Why not let the user type the additional argument(s) without the >>> parameter name? > > Like Martin, you clipped most of the essential context of my question: > Talin's second proposal. I clipped it because I couldn't understand your question: "Why" what? (the second question only gives "Why not") I then assumed that the question must have applied to the text that immediately preceded the question - hence that's the text that I left. Now I understand, though. Regards, Martin From martin at v.loewis.de Mon May 1 08:31:51 2006 From: martin at v.loewis.de (=?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?=) Date: Mon, 01 May 2006 08:31:51 +0200 Subject: [Python-Dev] Tkinter lockups. In-Reply-To: <9e804ac0604231436q491d7289m97bb165dc42a5de@mail.gmail.com> References: <9e804ac0604231436q491d7289m97bb165dc42a5de@mail.gmail.com> Message-ID: <4455AB57.4020200@v.loewis.de> Thomas Wouters wrote: > It seems that, on my platform at least, Tk_Init() doesn't like being > called twice even when the first call resulted in an error. That's Tcl > and Tk 8.4.12. Tkapp_Init() (which is the Tkinter part that calls > Tk_Init()) does its best to guard against calling Tk_Init() twice when > the first call was succesful, but it doesn't remember failure cases. I > don't know enough about Tcl/Tk or Tkinter how this is best handled, but > it would be mightily convenient if it were. ;-) I've created a bugreport > on it, and I hope someone with Tkinter knowledge can step in and fix it. > (It looks like SF auto-assigned it to Martin already, hmm.) I have now reported the underlying Tk bug at http://sourceforge.net/tracker/index.php?func=detail&aid=1479587&group_id=12997&atid=112997 and worked around it in _tkinter.c. Regards, Martin From nnorwitz at gmail.com Mon May 1 09:04:51 2006 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 1 May 2006 00:04:51 -0700 Subject: [Python-Dev] speeding up function calls Message-ID: Results: 2.86% for 1 arg (len), 11.8% for 2 args (min), and 1.6% for pybench. ./python.exe -m timeit 'for x in xrange(10000): len([])' ./python.exe -m timeit 'for x in xrange(10000): min(1,2)' One part of it is a little dangerous though. http://python.org/sf/1479611 The general idea is to preallocate arg tuples and never dealloc. This saves a fair amount of work. I'm not sure it's entirely safe though. I noticed in doing this patch that PyTuple_Pack() calls _New() which initializes each item to NULL, then in _Pack() each item is set to the appropriate value. If we could get rid of duplicate work like that (or checking values in both callers and callees), we could get more speed. In order to try and find functions where this is more important, you can use Walter's coverage results: http://coverage.livinglogic.de n From jcarlson at uci.edu Mon May 1 10:07:55 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Mon, 01 May 2006 01:07:55 -0700 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <44559EF3.3050605@v.loewis.de> References: <20060430191152.6741.JCARLSON@uci.edu> <44559EF3.3050605@v.loewis.de> Message-ID: <20060430231024.674A.JCARLSON@uci.edu> "Martin v. L?wis" wrote: > > Josiah Carlson wrote: > >> I mean unicode strings, period. I can't imagine what "unicode strings > >> which do not contain data" could be. > > > > Binary data as opposed to text. Input to a array.fromstring(), > > struct.unpack(), etc. > > You can't/shouldn't put such data into character strings: you need > an encoding first. Certainly that is the case. But how would you propose embedded bytes data be represented? (I talk more extensively about this particular issue later). > Neither array.fromstring nor struct.unpack will > produce/consume type 'str' in Python 3; both will operate on the > bytes type. So fromstring should probably be renamed frombytes. Um...struct.unpack() already works on unicode... >>> struct.unpack('>L', u'work') (2003792491L,) As does array.fromstring... >>> a = array.array('B') >>> a.fromstring(u'work') >>> a array('B', [119, 111, 114, 107]) ... assuming that all characters are in the 0...127 range. But that's a different discussion. > > Certainly it is the case that right now strings are used to contain > > 'text' and 'bytes' (binary data, encodings of text, etc.). The problem > > is in the ambiguity of Python 2.x str containing text where it should > > only contain bytes. But in 3.x, there will continue to be an ambiguity, > > as strings will still contain bytes and text (parsing literals, see the > > somewhat recent argument over bytes.encode('base64'), etc.). > > No. In Python 3, type 'str' cannot be interpreted to contain bytes. > Operations that expect bytes and are given type 'str', and no encoding, > should raise TypeError. I am apparently not communicating this particular idea effectively enough. How would you propose that I store parsing literals for non-textual data, and how would you propose that I set up a dictionary to hold some non-trivial number of these parsing literals? I don't want a vague "you can't do X", I want a "here's the code you would use". From what I understand, it would seem that you would suggest that I use something like the following... handler = {bytes('...', encoding=...).encode('latin-1'): ..., #or '\uXXXX\uXXXX...': ..., #or even without bytes/str (0xXX, 0xXX, ...): ..., } Note how two of those examples have non-textual data inside of a Python 3.x string? Yeah. > > We've not removed the problem, only changed it from being contained > > in non-unicode > > strings to be contained in unicode strings (which are 2 or 4 times larger > > than their non-unicode counterparts). > > We have removed the problem. Excuse me? People are going to use '...' to represent literals of all different kinds. Whether these are text literals, binary data literals, encoded binary data blobs (see the output of img2py.py from wxPython), whatever. We haven't removed the problem, we've only forced all string literals to be unicode; foolish consistancy and all that. > > Within the remainder of this email, there are two things I'm trying to > > accomplish: > > 1. preserve the Python 2.x string type > > I would expect that people try that. I'm -1. I also expect that people will try to make it happen; I am (and I'm certainly not a visionary when it comes to programming language features). I would also hope that others are able to see that immutable unicode and mutable bytes aren't necessarily sufficient, especially when the standard line will be something like "if you are putting binary data inside of a unicode string, you are doing it wrong". Especially considering that unless one jumps through hoops of defining their bytes data as a bytes(list/tuple), and not bytes('...', encoding=...), that technically, they are still going to be storing bytes data as unicode strings. > > 2. make the bytes object more palatable regardless of #1 > > This might be good, but we have to be careful to not create a type > that people would casually use to represent text. Certainly. But by lacking #1, we will run into a situation where Python 3.x strings will be used to represent bytes. Understand that I'm also trying to differentiate the two cases (and thinking further, a bytes literal would allow users to differentiate them without needing to use bytes('...', ...) ). In the realm of palatability, giving bytes objects most of the current string methods, (with perhaps .read(), .seek(), (and .write() for mutable bytes) ), I think, would go a long ways (if not all the way) towards being more than satisfactory. > > I do, however, believe that the Python 2.x string type is very useful > > from a data parsing/processing perspective. > > You have to explain your terminology somewhat better here: What > applications do you have in mind when you are talking about > "parsing/processing"? To me, "parsing" always means "text", never > "raw bytes". I'm thinking of the Chomsky classification of grammars, > EBNF, etc. when I hear "parsing". What does pickle.load(...) do to the files that are passed into it? It reads the (possibly binary) data it reads in from a file (or file-like object), performing a particular operation based based on a dictionary of expected tokens in the file, producing a Python object. I would say that pickle 'parses' the content of a file, which I presume isn't necessary text. Replace pickle with a structured data storage format of your choice. It's still parsing (at least according to my grasp of English, which could certainly be flawed (my wife says as much on a daily basis)). > > Look how successful and > > effective it has been so far in the history of Python. In order to make > > the bytes object be as effective in 3.x, one would need to add basically > > all of the Python 2.x string methods to it > > The precondition of this clause is misguided: the bytes type doesn't > need to be as effective, since the string type is as effective in 2.3, > so you can do all parsing based on strings. Not if those strings contain binary data. I thought we were disambiguating what Python 3.x strings are supposed to contain? If they contain binary data, then there isn't a disambiguation as to their content, and we end up with the same situation we have now (only worse because now your data takes up twice as much memory and takes twice as much time to process). > > (having some mechanism to use > > slices of bytes objects as dictionary keys (if data[:4] in handler: ... > > -> if tuple(data[:4]) in handler: ... ?) would also be nice). > > You can't use the bytes type as a dictionary key because it is > immutable. Use the string type instead. I meant that currently, if I have data as a Python 2.x string, and I were to perhaps handle the current portion of the string via... if data[:4] in handler: ...that when my data becomes bytes in 3.x (because it isn't text, and non-text shouldn't be in the 3.x string, if I understand our discussions about it correctly), then I would need to use... if tuple(data[:4]) in handler: or even if data[:4].decode('latin-1') in handler: ...because data is mutable. I was expressing that being able to leave out the tuple() (or .decode()) would be convenient, though not necessary. If given an immutable bytes type, data to be parsed would likely be immutable, so data[:4] could be hashable (I personally rarely mutate input data that is being parsed, and I would suggest, if there is a choice between mutable/immutable file reads, etc., that it be immutable). > > So, what to do? Rename Python 2.x str to bytes. The name of the type > > now confers the idea that it should contain bytes, not strings. > > It seems that you want an immutable version of the bytes type. As I > don't understand what "parsing" is, I cannot see the need for it; I hope I've made what I consider parsing sufficiently clear. > I think having two different bytes types is confusing. I think that the difference between an immutable and mutable bytes types will be clear, especially because they are given different names, and because attempting to assign to read-only bytes would raise an AttributeError, "'[immutable]bytes' object has no attribute '...'" (if one wanted to be clever, one could even have it raise TypeError, "'[immutable]bytes' object is not writable'". There are at least two other situations in which there are mutable and immutable simple variants of the same structure: set/frozenset and list/tuple (though the latter instance doesn't support the same API in both objects, due to their significantly different use-cases). One of the reasons I think that a bytes/mutablebytes should have a very similar API, is because their use-cases may very well overlap, in a similar fashion to how set/frozenset and list/tuple sometimes overlap (I remember a discussion about giving tuples a list.index-like method, and even another about giving one or the other a str.find-like method). I would also point out that duplication of very similar functionality in Python types is not that uncommon (beyond set/frozenset and list/tuple). See the 4 (soon 3) different kinds of numbers in Python 2.4, and the 5 different ways of representing dates and times. - Josiah From fredrik at pythonware.com Mon May 1 10:48:44 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 10:48:44 +0200 Subject: [Python-Dev] More on contextlib - adding back a contextmanagerdecorator References: <4454BA62.5080704@iinet.net.au><5.1.1.6.0.20060430144919.01e6bb18@mail.telecommunity.com> Message-ID: Guido van Rossum wrote: > Things should be as simple as possible but no simpler. It's pretty > clear to me that dropping __context__ approaches this ideal. I'm sorry > I didn't push back harder when __context__ was first proposed -- in > retrospect, the first 5 months of PEP 343's life, before __context__ > (or __with__, as it was originally called) was invented, were by far > its happiest times. I've posted two versions of the "with" page from the language reference: http://pyref.infogami.com/with (current) http://pyref.infogami.com/with-alt (simplified) (the original is a slightly tweaked version of the current development docs) From martin at v.loewis.de Mon May 1 10:55:52 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 10:55:52 +0200 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <20060430231024.674A.JCARLSON@uci.edu> References: <20060430191152.6741.JCARLSON@uci.edu> <44559EF3.3050605@v.loewis.de> <20060430231024.674A.JCARLSON@uci.edu> Message-ID: <4455CD18.8030200@v.loewis.de> Josiah Carlson wrote: > Certainly that is the case. But how would you propose embedded bytes > data be represented? (I talk more extensively about this particular > issue later). Can't answer: I don't know what "embedded bytes data" are. > Um...struct.unpack() already works on unicode... > >>> struct.unpack('>L', u'work') > (2003792491L,) > As does array.fromstring... > >>> a = array.array('B') > >>> a.fromstring(u'work') > >>> a > array('B', [119, 111, 114, 107]) > > ... assuming that all characters are in the 0...127 range. But that's a > different discussion. Yes, it applies the default encoding. This is unfortunate: it shouldn't have worked in the first place. I hope this gives a type error in Python 3, with the default encoding gone. > I am apparently not communicating this particular idea effectively > enough. How would you propose that I store parsing literals for > non-textual data, and how would you propose that I set up a dictionary > to hold some non-trivial number of these parsing literals? I can't answer that question: I don't know what a "parsing literal for non-textual data" is. If you are asking how you represent bytes object in source code: I would encode them as a list of integers, then use, say, parsing_literal = bytes([3,5,30,99]) > From what I understand, it would seem that you would suggest that I use > something like the following... > > handler = {bytes('...', encoding=...).encode('latin-1'): ..., > #or > '\uXXXX\uXXXX...': ..., > #or even without bytes/str > (0xXX, 0xXX, ...): ..., } > > Note how two of those examples have non-textual data inside of a Python > 3.x string? Yeah. Unfortunately, I don't notice. I assume you don't mean a literal '...'; if this is what you represent, I would write handler = { '...': "some text" } But I cannot guess what you want to put into '...' instead. >>> We've not removed the problem, only changed it from being contained >>> in non-unicode >>> strings to be contained in unicode strings (which are 2 or 4 times larger >>> than their non-unicode counterparts). >> We have removed the problem. > > Excuse me? People are going to use '...' to represent literals of all > different kinds. In Python 3, '...' will be a character string. You can't use it to represent anything else but characters. Can you give examples of actual source code where people use '...' something other than text? > What does pickle.load(...) do to the files that are passed into it? It > reads the (possibly binary) data it reads in from a file (or file-like > object), performing a particular operation based based on a dictionary > of expected tokens in the file, producing a Python object. I would say > that pickle 'parses' the content of a file, which I presume isn't > necessary text. Right. I think pickle can be implemented with just the bytes type. There is a textual and a binary version of the pickle format. The textual should be read as text; the binary version using bytes. (I *thinK* the encoding of the textual version is ASCII, but one would have to check). > Replace pickle with a structured data storage format of your choice. > It's still parsing (at least according to my grasp of English, which > could certainly be flawed (my wife says as much on a daily basis)). Well, I have no "native language" intuition with respect to these words - I only use them in the way I see them used elsewhere. I see "parsing" typically associated with textual data, and "unmarshalling" with binary data. >>> Look how successful and >>> effective it has been so far in the history of Python. In order to make >>> the bytes object be as effective in 3.x, one would need to add basically >>> all of the Python 2.x string methods to it >> The precondition of this clause is misguided: the bytes type doesn't >> need to be as effective, since the string type is as effective in 2.3, >> so you can do all parsing based on strings. > > Not if those strings contain binary data. I couldn't (until right now) understand what you mean by "parsing binary data". I still doubt that you typically need the same operations for unmarshalling that you need for parsing. In parsing, you need to look (scan) for separators, follow a possibly recursive grammar, and so on. For unmarshalling, you typically have a TLV (tag-length-value) structure, where you read a tag (of fixed size), then the length, then the value (of the size indicated in the length). There are variations, of course, but you typically don't need .find, .startswith, etc. Regards, Martni From fredrik at pythonware.com Mon May 1 11:33:03 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 11:33:03 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> Message-ID: Terry Reedy wrote: > My "Why?" was and is exactly a request for that further discussion. > > Again: if a function has a fixed number n of params, why say that the first > k can be passed by position, while the remaining n-k *must* be passed by > name? have you designed API:s for others than yourself, and followed up how they are used ? From greg.ewing at canterbury.ac.nz Mon May 1 11:34:17 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Mon, 01 May 2006 21:34:17 +1200 Subject: [Python-Dev] elimination of scope bleeding of iteration variables In-Reply-To: <4454C87A.7020701@gmail.com> References: <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> Message-ID: <4455D619.9030002@canterbury.ac.nz> Nick Coghlan wrote: > However, the scoping of for loop > variables won't change, as the current behaviour is essential for search loops > that use a break statement to terminate the loop when the item is found. It occurs to me that there's a middle ground here: leave the loop variable scope alone, but make it an error to use the same variable in two different loops at the same time. e.g. for x in stuff: if its_what_were_looking_for(x): break snarfle(x) for x in otherstuff: dosomethingelse(x) would be fine, but for x in stuff: for x in otherstuff: dosomethingelse(x) would be a SyntaxError because the inner loop is trying to use x while it's still in use by the outer loop. -- Greg From ncoghlan at gmail.com Mon May 1 11:49:46 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 19:49:46 +1000 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <44549922.7020109@gmail.com> Message-ID: <4455D9BA.9070804@gmail.com> Terry Reedy wrote: > "Nick Coghlan" wrote in message >> Because for some functions (e.g. min()/max()) you want to use *args, but >> support some additional keyword arguments to tweak a few aspects of the >> operation (like providing a "key=x" option). > > This and the rest of your 'explanation' is about Talin's first proposal, to > which I already had said "The rationale for this is pretty obvious". Actually, I misread Talin's PEP moreso than your question - I thought the first syntax change was about the earlier Py3k discussion of permitting '*args' before keyword arguments in a functional call. It seems that one is actually non-controversial enough to not really need a PEP at all :) Reading the PEP again, I realise what you were actually asking, and have to say I agree the only use case that has been identified for keyword-only arguments is functions which accept an arbitrary number of positional arguments. So +1 for the first change, -1 for the second. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From ncoghlan at gmail.com Mon May 1 12:29:12 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 20:29:12 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <5.1.1.6.0.20060501001028.01e6a460@mail.telecommunity.com> References: <44556CDB.1070604@gmail.com> <4454BA62.5080704@iinet.net.au> <44556CDB.1070604@gmail.com> <5.1.1.6.0.20060501001028.01e6a460@mail.telecommunity.com> Message-ID: <4455E2F8.5020206@gmail.com> Phillip J. Eby wrote: > At 08:08 PM 4/30/2006 -0700, Guido van Rossum wrote: >> If you object against the extra typing, we'll first laugh at you >> (proposals that *only* shave a few characters of a common idiom aren't >> all that popular in these parts), and then suggest that you can spell >> foo.some_method() as foo(). > > Okay, you've moved me to at least +0 for dropping __context__. I have > only one object myself that has a non-self __context__, and it doesn't > have a __call__, so none of my code breaks beyond the need to add > parentheses in a few places. ;) At least +0 here, too. I've just been so deep in this lately that it is taking a while to wind my thinking back a year or so. Still, far better to be having this discussion now than in 6 months time :) It sure has been a long and winding road back to Guido's original version of PEP 343, though! > As for decimal contexts, I'm thinking maybe we should have a > decimal.using(ctx=None, **kw) function, where ctx defaults to the > current decimal context, and the keyword arguments are used to make a > modified copy, seems like a reasonable best way to implement the > behavior that __context__ was added for. And then all of the existing > special machinery can go away and be replaced with a single > @contextfactory. 'localcontext' would probably work as at least an interim name for such a function. with decimal.localcontext() as ctx: # use the new context here This is really an all-round improvement over the current SVN approach, where the fact that a new decimal context object is being created by the existing decimal context object is thoroughly implicit and unobvious. > (I think we should stick with @contextfactory as the decorator name, > btw, even if we go back to calling __enter__/__exit__ things context > managers.) Agreed. And that decorator will still be useful for defining methods as well as functions. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From greg.ewing at canterbury.ac.nz Mon May 1 13:03:48 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Mon, 01 May 2006 23:03:48 +1200 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: References: <4454BA62.5080704@iinet.net.au> Message-ID: <4455EB14.6000709@canterbury.ac.nz> Guido van Rossum wrote: > I believe the context API design has gotten totally out of hand. My thoughts exactly! > I have a counter-proposal: let's drop __context__... would it > really be such a big deal to let the user make an explicit call to > some appropriately named method? Another possibility I thought of, for the case where an object is needed to keep track of the state of each invocation of a context, is to have the __enter__ method return the state object, which the with-statement tucks away and later passes to the __exit__ method. Also a thought on terminology. Even though it seems I may have been the person who thought it up originally, I'm not sure I like the term "manager". It seems rather wooly, and it's not clear whether a "context manager" is supposed to manage just one context or multiple contexts. I've been thinking about the terms "guarded context" and "context guard". We could say that the with-statement executes its body in a guarded context (an abstract notion, not a concrete object). To do this, it creates a context guard (a concrete object) with __enter__ and __exit__ methods that set up and tear down the guarded context. This seems clearer to me, since I can more readily visualise a "guard" object being specially commissioned to deal with one particular job (guarding a particular invocation of a context). With only one object, there wouldn't be a need for any more terms. But if another term is needed for an object with a __context__ method or equivalent, I rather liked Nick's "context specifier". -- Greg From ben at 666.com Mon May 1 05:47:07 2006 From: ben at 666.com (Ben Wing) Date: Sun, 30 Apr 2006 22:47:07 -0500 Subject: [Python-Dev] global variable modification in functions [Re: elimination of scope bleeding of iteration variables] In-Reply-To: <4454C87A.7020701@gmail.com> References: <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> Message-ID: <445584BB.8090708@666.com> Nick Coghlan wrote: > Ben Wing wrote: > >> apologies if this has been brought up on python-dev already. >> >> a suggestion i have, perhaps for python 3.0 since it may break some >> code (but imo it could go into 2.6 or 2.7 because the likely breakage >> would be very small, see below), is the elimination of the misfeature >> whereby the iteration variable used in for-loops, list >> comprehensions, etc. bleeds out into the surrounding scope. >> >> [i'm aware that there is a similar proposal for python 3.0 for list >> comprehensions specifically, but that's not enough.] > > > List comprehensions will be fixed in Py3k. However, the scoping of for > loop variables won't change, as the current behaviour is essential for > search loops that use a break statement to terminate the loop when the > item is found. Accordingly, there is plenty of code in the wild that > *would* break if the for loop variables were constrained to the for > loop, even if your own code wouldn't have such a problem. > > Outside pure scripts, significant control flow logic (like for loops) > should be avoided at module level. You are typically much better off > moving the logic inside a _main() function and invoking it at the end > of the module. This avoids the 'accidental global' problem for all of > the script-only variables, not only the ones that happen to be used as > for loop variables. i did in fact end up doing that. however, in the process i ran into another python annoyance i've tripped over repeatedly: you can't assign to a global variable without explicitly declaring it as `global'. instead, you "magically" get a shadowing local variable. this behavior is extremely hostile to newcomers: e.g. foo = 1 def set_foo(): foo = 2 print foo --> 1 the worst part is, not a single warning from Python about this. in a large program, such a bug can be very tricky to track down. now i can see how an argument against changing this behavior might hinge upon global names like `hash' and `list'; you certainly wouldn't want an intended local variable called `hash' or `list' to trounce upon these. but this argument confuses lexical and dynamic scope: global variables declared inside a module are (or can be viewed as) globally lexically scoped in the module, whereas `hash' and `list' are dynamically scoped. so i'd suggest: [1] ideally, change this behavior, either for 2.6 or 3.0. maybe have a `local' keyword if you really want a new scope. [2] until this change, python should always print a warning in this situation. [3] the current 'UnboundLocal' exception should probably be more helpful, e.g. suggesting that you might need to use a `global foo' declaration. ben From ben at 666.com Mon May 1 06:42:13 2006 From: ben at 666.com (Ben Wing) Date: Sun, 30 Apr 2006 23:42:13 -0500 Subject: [Python-Dev] python syntax additions to support indentation insensitivity/generated code Message-ID: <445591A5.8050808@666.com> recently i've been writing code that generates a python program from a source file containing intermixed python code and non-python constructs, which get converted into python. similar things have been done in many other languages -- consider, for example, the way php is embedded into web pages. unfortunately, doing this is really hard in python because of its whitespace sensitivity. i suggest the following simple change: in addition to constructs like this: block: within-block statement within-block statement ... out-of-block statement python should support block:: within-block statement within-block statement ... end out-of-block statement the syntax is similar, but has an extra colon, and is terminated by an `end'. indentation of immediate-level statements within the block is unimportant. mixed-mode code should be possible, e.g.: block-1:: within-block-1 statement within-block-1 statement block-2: within-block-2 statement within-block-2 statement within-block-1 statement ... end in other words, code within block-2 is indentation-sensitive; block-2 is terminated by the first immediate-level statement at or below the indentation of the `block-2' statement. similarly, in this: [A] block-1:: [B] within-block-1 statement [C] within-block-1 statement [D] block-2: [E] within-block-2 statement [F] within-block-2 statement [G] block-3:: [H] within-block-3 statement [I] within-block-3 statement [J] end [K] within-block-2 statement [L] within-block-1 statement [M] ... [N] end the indentation of lines [D], [E], [F], [G], [K] and [L] is significant, but not any others. that is, [E], [F], [G], and [K] must be at the same level, which is greater than the level of line [D], and line [L] must be at a level less than or equal to line [D]. all other lines, including [H], [I] and [J], can be at any indentation level. also, line [D] can be at any level with respect to line [C]. the idea is that a python code generator could easily mix generated and hand-written code. hand-written code written in normal python style could be wrapped by generated code using the indentation-insensitive style; if the generated code had no indentation, everything would work as expected without the generator having to worry about indentation. i don't see too many problems with backward-compatibility here. the double-colon shouldn't cause any problems, since that syntax isn't legal currently. `end' could be recognized as a keyword only following a double-colon block; elsewhere, it could still be a variable. ben From fredrik at pythonware.com Mon May 1 13:39:26 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 13:39:26 +0200 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> Message-ID: Greg Ewing wrote: > I've been thinking about the terms "guarded context" > and "context guard". We could say that the with-statement > executes its body in a guarded context (an abstract > notion, not a concrete object). To do this, it creates > a context guard (a concrete object) with __enter__ > and __exit__ methods that set up and tear down the > guarded context. This seems clearer to me, since I > can more readily visualise a "guard" object being > specially commissioned to deal with one particular > job (guarding a particular invocation of a context). > > With only one object, there wouldn't be a need for any more > terms. contrast and compare: http://pyref.infogami.com/with http://pyref.infogami.com/with-alt http://pyref.infogami.com/with-guard a distinct term for "whatever the __enter__ method returns" (i.e. the thing assigned to the target list) would still be nice. From ncoghlan at gmail.com Mon May 1 13:42:13 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 21:42:13 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455EB14.6000709@canterbury.ac.nz> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> Message-ID: <4455F415.3040104@gmail.com> Greg Ewing wrote: > Also a thought on terminology. Even though it seems I > may have been the person who thought it up originally, > I'm not sure I like the term "manager". It seems rather > wooly, and it's not clear whether a "context manager" > is supposed to manage just one context or multiple > contexts. I think getting rid of __context__ should clear up most of this confusion (which is further evidence that Guido is making the right call). Once that change is made, the context expression in the with statement produces a context manager with __enter__ and __exit__ methods which set up and tear down a managed context for the body of the with statement. This is very similar to your later suggestion of context guard and guarded context. I believe this is actually going back to using the terminology as you originally suggested it (one concrete object, one abstract concept). We really only got into trouble once we tried to add a second kind of concrete object into the mix (objects with only a __context__ method). Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From greg.ewing at canterbury.ac.nz Mon May 1 14:02:45 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 02 May 2006 00:02:45 +1200 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455F415.3040104@gmail.com> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> Message-ID: <4455F8E5.7070203@canterbury.ac.nz> Nick Coghlan wrote: > the context expression in the with > statement produces a context manager with __enter__ and __exit__ methods > which set up and tear down a managed context for the body of the with > statement. This is very similar to your later suggestion of context > guard and guarded context. Currently I think I still prefer the term "guard", since it does a better job of conjuring up the same sort of idea as a try-finally. There's also one other issue, what to call the decorator. I don't like @contextfactory, because it sounds like something that produces contexts, yet we have no such object. With only one object, it should probably be named after that object, i.e. @contextmanager or @contextguard. That's if we think it's really worth making it easy to abuse a generator in this way -- which I'm not convinced about. It's not as if people are going to be implementing context managers/guards every day. -- Greg From ncoghlan at gmail.com Mon May 1 14:15:59 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 22:15:59 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455F415.3040104@gmail.com> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> Message-ID: <4455FBFF.3080301@gmail.com> Nick Coghlan wrote: > Greg Ewing wrote: >> Also a thought on terminology. Even though it seems I >> may have been the person who thought it up originally, >> I'm not sure I like the term "manager". It seems rather >> wooly, and it's not clear whether a "context manager" >> is supposed to manage just one context or multiple >> contexts. > > I think getting rid of __context__ should clear up most of this confusion > (which is further evidence that Guido is making the right call). Once that > change is made, the context expression in the with statement produces a > context manager with __enter__ and __exit__ methods which set up and tear down > a managed context for the body of the with statement. This is very similar to > your later suggestion of context guard and guarded context. Thinking about it a bit further. . . 1. PEP 343, 2.5 alpha 1, 2.5 alpha 2 and the discussions here have no doubt seriously confused the meaning of the term 'context manager' for a lot of people (you can certainly put me down as one such person). Anyone not already confused is likely to *become* confused if we subtly change the meaning in alpha 3. 2. The phrase "managed context" is unfortunately close to .NET's term "managed code", and would likely lead to confusion for IronPython folks (and other programmers with .NET experience) 3. "manager" is an extremely generic term that is already used in a lot of different ways in various programming contexts Switching to Greg's suggestion of "context guard" and "guarded context" as the terms would allow us to hit the reset button and start the documentation afresh without terminology confusion resulting from the evolution of PEP 343 and its implementation and documentation. I think context guard also works better in terms of guarding entry to and exit from the guarded context, whereas I always wanted to call those operations "set up" and "tear down" for context managers. The current @contextfactory decorator could be renamed to @guardfactory to make it explicit that it results in a factory function for context guards. Cheers, Nick. P.S. I think I can hear anguished howls coming from the offices of various book publishers around the world ;) -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From jepler at unpythonic.net Mon May 1 14:16:16 2006 From: jepler at unpythonic.net (Jeff Epler) Date: Mon, 1 May 2006 07:16:16 -0500 Subject: [Python-Dev] Tkinter lockups. In-Reply-To: <4455AB57.4020200@v.loewis.de> References: <9e804ac0604231436q491d7289m97bb165dc42a5de@mail.gmail.com> <4455AB57.4020200@v.loewis.de> Message-ID: <20060501121616.GD2603@unpythonic.net> Thanks Martin! Jeff From ncoghlan at gmail.com Mon May 1 14:24:58 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 22:24:58 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455F8E5.7070203@canterbury.ac.nz> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> <4455F8E5.7070203@canterbury.ac.nz> Message-ID: <4455FE1A.2010506@gmail.com> Greg Ewing wrote: > Nick Coghlan wrote: >> the context expression in the with statement produces a context >> manager with __enter__ and __exit__ methods which set up and tear down >> a managed context for the body of the with statement. This is very >> similar to your later suggestion of context guard and guarded context. > > Currently I think I still prefer the term "guard", > since it does a better job of conjuring up the same > sort of idea as a try-finally. See the other message I wrote while you were writing this one for the various reasons I now agree with you :) > There's also one other issue, what to call the > decorator. I don't like @contextfactory, because it > sounds like something that produces contexts, > yet we have no such object. Agreed. > With only one object, it should probably be named > after that object, i.e. @contextmanager or > @contextguard. That's if we think it's really > worth making it easy to abuse a generator in this > way -- which I'm not convinced about. It's not > as if people are going to be implementing context > managers/guards every day. I suggested renaming it to "guardfactory" in my other message. Keeping the term 'factory' in the name emphasises that the decorator results in a callable that returns a context guard, rather than producing a context guard directly. As for whether or not we should provide this ability, I think we definitely should. It allows try/finally boilerplate code to be replaced with a guarded context almost mechanically, whereas converting the same code to a manually written context guard could involve significant effort in changing from local variable based storage to instance attribute based storage. IOW, the feature is provided for the same reason that generator functions are provided: it is typically *much* easier to write a generator function than it is to write the same iterator manually. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From ncoghlan at gmail.com Mon May 1 14:32:06 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 01 May 2006 22:32:06 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> Message-ID: <4455FFC6.8010901@gmail.com> Fredrik Lundh wrote: > a distinct term for "whatever the __enter__ method returns" (i.e. > the thing assigned to the target list) would still be nice. I've called that the "context entry value" in a few places (I don't think any of them were in the actual documentation though). A sample modification to the reference page: ------------------------------ Here's a more detailed description: 1. The context expression is evaluated, to obtain a context guard. 2. The guard object's __enter__ method is invoked to obtain the context entry value. 3. If a target list was included in the with statement, the context entry value is assigned to it. 4. The suite is executed. 5. The guard object's __exit__ method is invoked. If an exception caused the suite to be exited, its type, value, and traceback are passed as arguments to __exit__. Otherwise, three None arguments are supplied. ------------------------------ Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From phd at mail2.phd.pp.ru Mon May 1 14:32:35 2006 From: phd at mail2.phd.pp.ru (Oleg Broytmann) Date: Mon, 1 May 2006 16:32:35 +0400 Subject: [Python-Dev] global variable modification in functions [Re: elimination of scope bleeding of iteration variables] In-Reply-To: <445584BB.8090708@666.com> References: <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> <445584BB.8090708@666.com> Message-ID: <20060501123235.GF6556@phd.pp.ru> On Sun, Apr 30, 2006 at 10:47:07PM -0500, Ben Wing wrote: > foo = 1 > > def set_foo(): > foo = 2 PyLint gives a warning here "local foo shadows global variable". Oleg. -- Oleg Broytmann http://phd.pp.ru/ phd at phd.pp.ru Programmers don't die, they just GOSUB without RETURN. From edloper at gradient.cis.upenn.edu Mon May 1 14:36:03 2006 From: edloper at gradient.cis.upenn.edu (Edward Loper) Date: Mon, 01 May 2006 08:36:03 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <4455A0CF.3080008@v.loewis.de> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> Message-ID: <445600B3.7040903@gradient.cis.upenn.edu> Martin v. L?wis wrote: > One reason I see is to have keyword-only functions, i.e. with no > positional arguments at all: > > def make_person(*, name, age, phone, location): > pass > > which also works for methods: > > def make_person(self, *, name, age, phone, location): > pass > > In these cases, you don't *want* name, age to be passed in a positional > way. How else would you formulate that if this syntax wasn't available? But is it necessary to syntactically *enforce* that the arguments be used as keywords? I.e., why not just document that the arguments should be used as keyword arguments, and leave it at that. If users insist on using them positionally, then their code will be less readable, and might break if you decide to change the order of the parameters, but we're all consenting adults. (And if you *do* believe that the parameters should all be passed as keywords, then I don't see any reason why you'd ever be motivated to change their order.) -Edward From fredrik at pythonware.com Mon May 1 15:04:01 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 15:04:01 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445600B3.7040903@gradient.cis.upenn.edu> Message-ID: Edward Loper wrote: > > One reason I see is to have keyword-only functions, i.e. with no > > positional arguments at all: > > > > def make_person(*, name, age, phone, location): > > pass > > > > which also works for methods: > > > > def make_person(self, *, name, age, phone, location): > > pass > > > > In these cases, you don't *want* name, age to be passed in a positional > > way. How else would you formulate that if this syntax wasn't available? > > But is it necessary to syntactically *enforce* that the arguments be > used as keywords? I.e., why not just document that the arguments should > be used as keyword arguments, and leave it at that. and how do you best do that, in a way that automatic introspection tools understand, unless you invent some kind of standard syntax for it? and if you have a standard syntax for it, why not support it at the interpreter level ? From fredrik at pythonware.com Mon May 1 15:05:24 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 15:05:24 +0200 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455FFC6.8010901@gmail.com> Message-ID: Nick Coghlan wrote: > I've called that the "context entry value" in a few places (I don't think any > of them were in the actual documentation though). that doesn't really give me the right associations (I want something that makes it clear that this is an "emphemeral" object). > A sample modification to the reference page: except for the exact term, that's a definite improvement. thanks! From jason.orendorff at gmail.com Mon May 1 15:14:38 2006 From: jason.orendorff at gmail.com (Jason Orendorff) Date: Mon, 1 May 2006 09:14:38 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <44557789.5020107@gradient.cis.upenn.edu> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <44557789.5020107@gradient.cis.upenn.edu> Message-ID: On 4/30/06, Edward Loper wrote (referring to keyword-only arguments): > I see two possible reasons: > > - A function's author believes that calls to the function will be > easier to read if certain parameters are passed by name, rather > than positionally; and they want to enforce that calling > convention on their users. This seems to me to go against the > "consenting adults" principle. > > - A function's author believes they might change the signature in the > future to accept new positional arguments, and they will want to put > them before the args that they declare keyword-only. > > Both of these motivations seem fairly weak. Certainly, neither seems to > warrant a significant change to function definition syntax. I disagree. I think the use cases are more significant than you suggest, and the proposed change less significant. Readability and future-compatibility are key factors in API design. How well a language supports them determines how sweet its libraries can be. Even relatively simple high-level functions often have lots of clearly inessential "options". When I design this kind of function, I often wish for keyword-only arguments. path.py's write_lines() is an example. In fact... it feels as though I've seen "keyword-only" arguments in a few places in the stdlib. Am I imagining this? Btw, I don't think the term "consenting adults" applies. To me, that refers to the agreeable state of affairs where you, the programmer about to do something dangerous, know it's dangerous and indicate your consent somehow in your source code, e.g. by typing an underscore. That underscore sends a warning. It tells you to think twice. It tells you the blame is all yours if this doesn't work. It makes consent explicit (both mentally and syntactically). I'm +1 on the use cases but -0 on the PEP. The proposed syntax isn't clear; I think I want a new 'explicit' keyword or something. (Like that'll happen. Pfft.) -j From fdrake at acm.org Mon May 1 15:30:22 2006 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 1 May 2006 09:30:22 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <44557789.5020107@gradient.cis.upenn.edu> References: <4453B025.3080100@acm.org> <44557789.5020107@gradient.cis.upenn.edu> Message-ID: <200605010930.23198.fdrake@acm.org> On Sunday 30 April 2006 22:50, Edward Loper wrote: > I see two possible reasons: Another use case, observed in the wild: - An library function is written to take an arbitrary number of positional arguments using *args syntax. The library is released, presumably creating dependencies on the specific signature of the function. In a subsequent version of the function, the function is determined to need additional information. The only way to add an argument is to use a keyword for which there is no positional equivalent. -Fred -- Fred L. Drake, Jr. From edloper at gradient.cis.upenn.edu Mon May 1 15:39:00 2006 From: edloper at gradient.cis.upenn.edu (Edward Loper) Date: Mon, 01 May 2006 09:39:00 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <200605010930.23198.fdrake@acm.org> References: <4453B025.3080100@acm.org> <44557789.5020107@gradient.cis.upenn.edu> <200605010930.23198.fdrake@acm.org> Message-ID: <44560F74.5000600@gradient.cis.upenn.edu> Fred L. Drake, Jr. wrote: > On Sunday 30 April 2006 22:50, Edward Loper wrote: > > I see two possible reasons: > > Another use case, observed in the wild: > > - An library function is written to take an arbitrary number of > positional arguments using *args syntax. The library is released, > presumably creating dependencies on the specific signature of the > function. In a subsequent version of the function, the function is > determined to need additional information. The only way to add an > argument is to use a keyword for which there is no positional > equivalent. This falls under the "first subproposal" from Terry's email: > There are two subproposals: first, keyword-only args after a variable > number of positional args, which requires allowing keyword parameter > specifications after the *args parameter, and second, keyword-only args > after a fixed number number of positional args, implemented with a naked > '*'. To the first, I said "The rationale for this is pretty obvious.". To > the second, I asked, and still ask, "Why?". I was trying to come up with use cases for the "second subproposal." -Edward From foom at fuhm.net Mon May 1 15:55:23 2006 From: foom at fuhm.net (James Y Knight) Date: Mon, 1 May 2006 09:55:23 -0400 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455FBFF.3080301@gmail.com> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> <4455FBFF.3080301@gmail.com> Message-ID: <8D9580FC-95C5-4A15-994C-6F91E31E3F45@fuhm.net> On May 1, 2006, at 8:15 AM, Nick Coghlan wrote: > 1. PEP 343, 2.5 alpha 1, 2.5 alpha 2 and the discussions here have > no doubt > seriously confused the meaning of the term 'context manager' for a > lot of > people (you can certainly put me down as one such person). Anyone > not already > confused is likely to *become* confused if we subtly change the > meaning in > alpha 3. Don't forget that the majority of users will never have heard any of these discussions nor have used 2.5a1 or 2.5a2. Choose the best term for them, not for the readers of python-dev. James From guido at python.org Mon May 1 16:18:54 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 07:18:54 -0700 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <8D9580FC-95C5-4A15-994C-6F91E31E3F45@fuhm.net> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> <4455FBFF.3080301@gmail.com> <8D9580FC-95C5-4A15-994C-6F91E31E3F45@fuhm.net> Message-ID: On 5/1/06, James Y Knight wrote: > Don't forget that the majority of users will never have heard any of > these discussions nor have used 2.5a1 or 2.5a2. Choose the best term > for them, not for the readers of python-dev. I couldn't agree more! (Another thought, occasionally useful,is to consider that surely the number of Python programs yet to be written, and the number of Python programmers who yet have to learn the language, must surely exceed the current count. At least, one would hope so -- if that's not true, we might as well stop now. :-) Nick, do you have it in you to fix PEP 343? Or at least come up with a draft patch? We can take this off-linel with all the +0's and +1's coming in I'm pretty comfortable with this change now, although we should probably wait until later today to commit. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 16:28:59 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 07:28:59 -0700 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <44560F74.5000600@gradient.cis.upenn.edu> References: <4453B025.3080100@acm.org> <44557789.5020107@gradient.cis.upenn.edu> <200605010930.23198.fdrake@acm.org> <44560F74.5000600@gradient.cis.upenn.edu> Message-ID: On 5/1/06, Edward Loper wrote: > > There are two subproposals: first, keyword-only args after a variable > > number of positional args, which requires allowing keyword parameter > > specifications after the *args parameter, and second, keyword-only args > > after a fixed number number of positional args, implemented with a naked > > '*'. To the first, I said "The rationale for this is pretty obvious.". To > > the second, I asked, and still ask, "Why?". > > I was trying to come up with use cases for the "second subproposal." A function/method could have one argument that is obviously needed and a whole slew of options that few people care about. For most people, the signature they know is foo(arg). It would be nice if all the options were required to be written as keyword arguments, so the reader will not have to guess what foo(arg, True) means. This signature style could perhaps be used for the join() builtin that some folks are demanding: join(iterable, sep=" ", auto_str=False). For the record, I'm +1 on Talin's PEP, -1 on join. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 16:32:40 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 07:32:40 -0700 Subject: [Python-Dev] global variable modification in functions [Re: elimination of scope bleeding of iteration variables] In-Reply-To: <445584BB.8090708@666.com> References: <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> <445584BB.8090708@666.com> Message-ID: On 4/30/06, Ben Wing wrote: > [1] ideally, change this behavior, either for 2.6 or 3.0. maybe have a > `local' keyword if you really want a new scope. > [2] until this change, python should always print a warning in this > situation. > [3] the current 'UnboundLocal' exception should probably be more > helpful, e.g. suggesting that you might need to use a `global foo' > declaration. You're joking right? -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 16:48:04 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 07:48:04 -0700 Subject: [Python-Dev] unittest argv In-Reply-To: References: Message-ID: Wouldn't this be an incompatible change? That would make it a no-no. Providing a dummy argv[0] isn't so hard is it? On 4/30/06, John Keyes wrote: > Hi, > > main() in unittest has an optional parameter called argv. If it is not > present in the invocation, it defaults to None. Later in the function > a check is made to see if argv is None and if so sets it to sys.argv. > I think the default should be changed to sys.argv[1:] (i.e. the > command line arguments minus the name of the python file > being executed). > > The parseArgs() function then uses getopt to parse argv. It currently > ignores the first item in the argv list, but this causes a problem when > it is called from another python function and not from the command > line. So using the current code if I call: > > python mytest.py -v > > then argv in parseArgs is ['mytest.py', '-v'] > > But, if I call: > > unittest.main(module=None, argv=['-v','mytest']) > > then argv in parseArgs is ['mytest'], as you can see the verbosity option is > now gone and cannot be used. > > Here's a diff to show the code changes I have made: > > 744c744 > < argv=None, testRunner=None, testLoader=defaultTestLoader): > --- > > argv=sys.argv[1:], testRunner=None, testLoader=defaultTestLoader): > 751,752d750 > < if argv is None: > < argv = sys.argv > 757c755 > < self.progName = os.path.basename(argv[0]) > --- > > # self.progName = os.path.basename(argv[0]) > 769c767 > < options, args = getopt.getopt(argv[1:], 'hHvq', > --- > > options, args = getopt.getopt(argv, 'hHvq', > > You may notice I have commented out the self.progName line. This variable > is not used anywhere in the module so I guess it could be removed. To > keep it then conditional check on argv would have to remain and be moved after > the self.progName line. > > I hope this makes sense, and it's my first post so go easy on me ;) > > Thanks, > -John K > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 16:51:35 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 07:51:35 -0700 Subject: [Python-Dev] Adding functools.decorator In-Reply-To: References: <4454C203.2060707@iinet.net.au> Message-ID: On 4/30/06, Georg Brandl wrote: > Guido van Rossum wrote: > > I expect that at some point people will want to tweak what gets copied > > by _update_wrapper() -- e.g. some attributes may need to be > > deep-copied, or personalized, or skipped, etc. > > What exactly do you have in mind there? If someone wants to achieve this, > she can write his own version of @decorator. I meant that the provided version should make writing your own easier than copying the source and editing it. Some form of subclassing might make sense, or a bunch of smaller functions that can be called for various actions. You'll probably have to discover some real use cases before you'll be able to design the right API for this. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 16:54:55 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 07:54:55 -0700 Subject: [Python-Dev] socket module recvmsg/sendmsg In-Reply-To: <200604302133.15205.me+python-dev@modelnine.org> References: <200604302133.15205.me+python-dev@modelnine.org> Message-ID: Is there a question or a request in here somewhere? If not, c.l.py.ann would be more appropriate. If you want that code integrated into core Python, read python.org/dev and prepare a patch for SF! --Guido On 4/30/06, Heiko Wundram wrote: > Hi all! > > I've implemented recvmsg and sendmsg for the socket module in my private > Python tree for communication between two forked processes, which are > essentially wrappers for proper handling of SCM_RIGHTS and SCM_CREDENTIALS > Unix-Domain-Socket messages (which are the two types of messages that are > defined on Linux). > > The main reason I need these two primitives is that I require (more or less > transparent) file/socket descriptor exchange between two forked processes, > where one process accepts a socket, and delegates processing of the socket > connection to another process of a set of processes; this is much like a > ForkingTCPServer, but with the Handler-process prestarted. > > As connection to the Unix-Domain-Socket is openly available, the receiving > process needs to check the identity of the first process; this is done using > a getsockopt(SO_PEERCRED) call, which is also handled more specifically by my > socket extension to return a socket._ucred-type structure, which wraps the > pid/uid/gid-structure returned by the corresponding getsockopt call, and also > the socket message (SCM_CREDENTIALS) which passes or sets this information > for the remote process. > > I'd love to see these two socket message primitives (of which the first, > SCM_RIGHTS, is available on pretty much any Unix derivative) included in a > Python distribution at some point in time, and as I've not got the time to > push for an inclusion in the tree (and even less time to work on other Python > patches myself) at the moment, I thought that I might just post here so that > someone interested might pick up the work I've done so far and check the > implementation for bugs, and at some stage these two functions might actually > find their way into the Python core. > > Anyway, my private Python tree (which has some other patches which aren't of > general interest, I'd think) is available at: > > http://dev.modelnine.org/hg/python > > and I can, if anyone is interested, post a current diff of socketmodule.* > against 2.4.3 to the Python bug tracker at sourceforge. I did that some time > ago (about half a year) when socket-passing code wasn't completely > functioning yet, but at least at that point there didn't seem much interest > in the patch. The patch should apply pretty cleanly against the current HEAD > too, at least it did the last time I checked. > > I'll add a small testsuite for both functions to my tree some time tomorrow. > > --- Heiko. > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 17:05:46 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 08:05:46 -0700 Subject: [Python-Dev] methods on the bytes object (was: Crazy idea for str.join) In-Reply-To: <20060430023808.673B.JCARLSON@uci.edu> References: <20060429055551.672C.JCARLSON@uci.edu> <20060430023808.673B.JCARLSON@uci.edu> Message-ID: Please take this to the py3k list. It's still open which methods to add; it'll depend on the needs we discover while using bytes to write the I/O library. I don't believe we should add everything we can; rather, I'd like to keep the API small until we have a clear need for a particular method. For the record, I'm holding off adding join() for now; I'd rather speed up the += operation. --Guido On 4/30/06, Josiah Carlson wrote: > > "Guido van Rossum" wrote: > > On 4/29/06, Josiah Carlson wrote: > > > I understand the underlying implementation of str.join can be a bit > > > convoluted (with the auto-promotion to unicode and all), but I don't > > > suppose there is any chance to get str.join to support objects which > > > implement the buffer interface as one of the items in the sequence? > > > > In Py3k, buffers won't be compatible with strings -- buffers will be > > about bytes, while strings will be about characters. Given that future > > I don't think we should mess with the semantics in 2.x; one change in > > the near(ish) future is enough of a transition. > > This brings up something I hadn't thought of previously. While unicode > will obviously keep its .join() method when it becomes str in 3.x, will > bytes objects get a .join() method? Checking the bytes PEP, very little > is described about the type other than it basically being an array of 8 > bit integers. That's fine and all, but it kills many of the parsing > and modification use-cases that are performed on strings via the non > __xxx__ methods. > > > Specifically in the case of bytes.join(), the current common use-case of > .join(...) would become something similar to > bytes().join(...), unless bytes objects got a syntax... Or > maybe I'm missing something? > > > Anyways, when the bytes type was first being discussed, I had hoped that > it would basically become array.array("B", ...) + non-unicode str. > Allowing for bytes to do everything that str was doing before, plus a > few new tricks (almost like an mmap...), minus those operations which > require immutability. > > > - Josiah > > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From aahz at pythoncraft.com Mon May 1 17:19:22 2006 From: aahz at pythoncraft.com (Aahz) Date: Mon, 1 May 2006 08:19:22 -0700 Subject: [Python-Dev] python syntax additions to support indentation insensitivity/generated code In-Reply-To: <445591A5.8050808@666.com> References: <445591A5.8050808@666.com> Message-ID: <20060501151922.GA6886@panix.com> On Sun, Apr 30, 2006, Ben Wing wrote: > > recently i've been writing code that generates a python program from a > source file containing intermixed python code and non-python constructs, > which get converted into python. Please take this to comp.lang.python (this is not in-and-of-itself inappropriate for python-dev, but experience indicates that this discussion will probably not be productive and therefore belongs on the general newsgroup). -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From pje at telecommunity.com Mon May 1 17:34:28 2006 From: pje at telecommunity.com (Phillip J. Eby) Date: Mon, 01 May 2006 11:34:28 -0400 Subject: [Python-Dev] global variable modification in functions [Re: elimination of scope bleeding of iteration variables] In-Reply-To: References: <445584BB.8090708@666.com> <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> <445584BB.8090708@666.com> Message-ID: <5.1.1.6.0.20060501112424.03760840@mail.telecommunity.com> At 07:32 AM 5/1/2006 -0700, Guido van Rossum wrote: >On 4/30/06, Ben Wing wrote: > > [1] ideally, change this behavior, either for 2.6 or 3.0. maybe have a > > `local' keyword if you really want a new scope. > > [2] until this change, python should always print a warning in this > > situation. > > [3] the current 'UnboundLocal' exception should probably be more > > helpful, e.g. suggesting that you might need to use a `global foo' > > declaration. > >You're joking right? While I agree that item #1 is a non-starter, it seems to me that in the case where the compiler statically knows a name is being bound in the module's globals, and there is a *non-argument* local variable being bound in a function body, the odds are quite high that the programmer forgot to use "global". I could almost see issuing a warning, or having a way to enable such a warning. And for the case where the compiler can tell the variable is accessed before it's defined, there's definitely something wrong. This code, for example, is definitely missing a "global" and the compiler could in principle tell: foo = 1 def bar(): foo+=1 So I see no problem (in principle, as opposed to implementation) with issuing a warning or even a compilation error for that code. (And it's wrong even if the snippet I showed is in a nested function definition, although the error would be different.) If I recall correctly, the new compiler uses a control-flow graph that could possibly be used to determine whether there is a path on which a local could be read before it's stored. From pje at telecommunity.com Mon May 1 17:28:58 2006 From: pje at telecommunity.com (Phillip J. Eby) Date: Mon, 01 May 2006 11:28:58 -0400 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455E2F8.5020206@gmail.com> References: <5.1.1.6.0.20060501001028.01e6a460@mail.telecommunity.com> <44556CDB.1070604@gmail.com> <4454BA62.5080704@iinet.net.au> <44556CDB.1070604@gmail.com> <5.1.1.6.0.20060501001028.01e6a460@mail.telecommunity.com> Message-ID: <5.1.1.6.0.20060501111752.01e6d258@mail.telecommunity.com> At 08:29 PM 5/1/2006 +1000, Nick Coghlan wrote: >'localcontext' would probably work as at least an interim name for such a >function. > > with decimal.localcontext() as ctx: > # use the new context here And the "as ctx" should be unnecessary for most use cases, if localcontext has an appropriately designed API. From martin at v.loewis.de Mon May 1 17:33:33 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 17:33:33 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <445600B3.7040903@gradient.cis.upenn.edu> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445600B3.7040903@gradient.cis.upenn.edu> Message-ID: <44562A4D.30102@v.loewis.de> Edward Loper wrote: > Martin v. L?wis wrote: >> One reason I see is to have keyword-only functions, i.e. with no >> positional arguments at all: >> >> def make_person(*, name, age, phone, location): >> pass > > But is it necessary to syntactically *enforce* that the arguments be > used as keywords? This really challenges the whole point of the PEP: keyword-only arguments (at least, it challenges the title of the PEP, although probably not the specified rationale). > I.e., why not just document that the arguments should > be used as keyword arguments, and leave it at that. Because they wouldn't be keyword-only arguments, then. Regards, Martin From guido at python.org Mon May 1 17:38:13 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 08:38:13 -0700 Subject: [Python-Dev] global variable modification in functions [Re: elimination of scope bleeding of iteration variables] In-Reply-To: <5.1.1.6.0.20060501112424.03760840@mail.telecommunity.com> References: <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> <445584BB.8090708@666.com> <5.1.1.6.0.20060501112424.03760840@mail.telecommunity.com> Message-ID: On 5/1/06, Phillip J. Eby wrote: > While I agree that item #1 is a non-starter, it seems to me that in the > case where the compiler statically knows a name is being bound in the > module's globals, and there is a *non-argument* local variable being bound > in a function body, the odds are quite high that the programmer forgot to > use "global". I could almost see issuing a warning, or having a way to > enable such a warning. > > And for the case where the compiler can tell the variable is accessed > before it's defined, there's definitely something wrong. This code, for > example, is definitely missing a "global" and the compiler could in > principle tell: > > foo = 1 > > def bar(): > foo+=1 > > So I see no problem (in principle, as opposed to implementation) with > issuing a warning or even a compilation error for that code. (And it's > wrong even if the snippet I showed is in a nested function definition, > although the error would be different.) > > If I recall correctly, the new compiler uses a control-flow graph that > could possibly be used to determine whether there is a path on which a > local could be read before it's stored. Sure. This is a quality of implementation issue. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From fredrik at pythonware.com Mon May 1 17:40:08 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 17:40:08 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de><445600B3.7040903@gradient.cis.upenn.edu> <44562A4D.30102@v.loewis.de> Message-ID: Martin v. Löwis wrote: > > I.e., why not just document that the arguments should > > be used as keyword arguments, and leave it at that. > > Because they wouldn't be keyword-only arguments, then. which reminds me of the following little absurdity gem from the language reference: The following identifiers are used as keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: /.../ (maybe it's just me). btw, talking about idioms used in the language reference, can any of the native speakers on this list explain if "A is a nicer way of spelling B" means that "A is preferred over B", "B is preferred over A", "A and B are the same word and whoever wrote this is just being absurd", or anything else ? From p.f.moore at gmail.com Mon May 1 17:56:49 2006 From: p.f.moore at gmail.com (Paul Moore) Date: Mon, 1 May 2006 16:56:49 +0100 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445600B3.7040903@gradient.cis.upenn.edu> <44562A4D.30102@v.loewis.de> Message-ID: <79990c6b0605010856p12d2083cl2fe2858a1cf2c7d8@mail.gmail.com> On 5/1/06, Fredrik Lundh wrote: > btw, talking about idioms used in the language reference, can any of the > native speakers on this list explain if "A is a nicer way of spelling B" means > that "A is preferred over B", "B is preferred over A", "A and B are the same > word and whoever wrote this is just being absurd", or anything else ? Without any context, I'd read it as "A is preferred over B". Paul From tjreedy at udel.edu Mon May 1 18:43:48 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 1 May 2006 12:43:48 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> Message-ID: ""Martin v. Löwis"" wrote in message news:4455A0CF.3080008 at v.loewis.de... > Terry Reedy wrote: >> There are two subproposals: first, keyword-only args after a variable >> number of positional args, which requires allowing keyword parameter >> specifications after the *args parameter, and second, keyword-only args >> after a fixed number number of positional args, implemented with a naked >> '*'. To the first, I said "The rationale for this is pretty obvious.". >> To >> the second, I asked, and still ask, "Why?". > > One reason I see is to have keyword-only functions, i.e. with no > positional arguments at all: This is not a reason for subproposal two, but a special case, as you yourself note below, and hence does say why you want to have such. > def make_person(*, name, age, phone, location): > pass And again, why would you *make* me, the user-programmer, type make_person(name=namex, age=agex, phone=phonex, location = locationx) #instead of make_person(namex,agex,phonex,locationx) ? Ditto for methods. > In these cases, you don't *want* name, age to be passed in a positional > way. I sure you know what I am going to ask, that you did not answer ;-) Terry Jan Reedy PS. I see that Guido finally gave a (different) use case for bare * that does make sense to me. From aahz at pythoncraft.com Mon May 1 18:45:40 2006 From: aahz at pythoncraft.com (Aahz) Date: Mon, 1 May 2006 09:45:40 -0700 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <445600B3.7040903@gradient.cis.upenn.edu> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445600B3.7040903@gradient.cis.upenn.edu> Message-ID: <20060501164540.GA4961@panix.com> On Mon, May 01, 2006, Edward Loper wrote: > > But is it necessary to syntactically *enforce* that the arguments be > used as keywords? I.e., why not just document that the arguments should > be used as keyword arguments, and leave it at that. If users insist on > using them positionally, then their code will be less readable, and > might break if you decide to change the order of the parameters, but > we're all consenting adults. (And if you *do* believe that the > parameters should all be passed as keywords, then I don't see any reason > why you'd ever be motivated to change their order.) IIRC, part of the motivation for this is to make it easier for super() to work correctly. -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From fredrik at pythonware.com Mon May 1 18:49:00 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 18:49:00 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de><4455A0CF.3080008@v.loewis.de> Message-ID: Terry Reedy wrote: > And again, why would you *make* me, the user-programmer, type > > make_person(name=namex, age=agex, phone=phonex, location = locationx) > #instead of > make_person(namex,agex,phonex,locationx) > ? because a good API designer needs to consider more than just the current release. I repeat my question: have you done API design for others, and have you studied how your API:s are used (and how they evolve) over a longer period of time ? From tjreedy at udel.edu Mon May 1 18:47:34 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 1 May 2006 12:47:34 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <44549922.7020109@gmail.com> <4455A191.5000404@v.loewis.de> Message-ID: ""Martin v. Löwis"" wrote in message > I clipped it because I couldn't understand your question: "Why" what? > (the second question only gives "Why not") I then assumed that the > question must have applied to the text that immediately preceded the > question - hence that's the text that I left. > > Now I understand, though. For future reference, when I respond to a post, I usually try to help readers by snipping away inessentials, leaving only the essential context of my responses. Terry From john at integralsource.com Mon May 1 19:11:50 2006 From: john at integralsource.com (John Keyes) Date: Mon, 1 May 2006 18:11:50 +0100 Subject: [Python-Dev] unittest argv In-Reply-To: References: Message-ID: On 5/1/06, Guido van Rossum wrote: > Wouldn't this be an incompatible change? That would make it a no-no. > Providing a dummy argv[0] isn't so hard is it? It would be incompatible with existing code, but that code is already broken (IMO) by passing a dummy argv[0]. I don't think fixing it would affect much code, because normally people don't specify the '-q' or '-v' in code, it is almost exclusively used on the command line. The only reason I came across it was that I was modifying an ant task (py-test) so it could handle all of the named arguments that TestProgram.__init__ supports. If the list index code can't change, at a minimum the default value for argv should change from None to sys.argv. Are the tests for unittest.py? Thanks, -John K > > On 4/30/06, John Keyes wrote: > > Hi, > > > > main() in unittest has an optional parameter called argv. If it is not > > present in the invocation, it defaults to None. Later in the function > > a check is made to see if argv is None and if so sets it to sys.argv. > > I think the default should be changed to sys.argv[1:] (i.e. the > > command line arguments minus the name of the python file > > being executed). > > > > The parseArgs() function then uses getopt to parse argv. It currently > > ignores the first item in the argv list, but this causes a problem when > > it is called from another python function and not from the command > > line. So using the current code if I call: > > > > python mytest.py -v > > > > then argv in parseArgs is ['mytest.py', '-v'] > > > > But, if I call: > > > > unittest.main(module=None, argv=['-v','mytest']) > > > > then argv in parseArgs is ['mytest'], as you can see the verbosity option is > > now gone and cannot be used. > > > > Here's a diff to show the code changes I have made: > > > > 744c744 > > < argv=None, testRunner=None, testLoader=defaultTestLoader): > > --- > > > argv=sys.argv[1:], testRunner=None, testLoader=defaultTestLoader): > > 751,752d750 > > < if argv is None: > > < argv = sys.argv > > 757c755 > > < self.progName = os.path.basename(argv[0]) > > --- > > > # self.progName = os.path.basename(argv[0]) > > 769c767 > > < options, args = getopt.getopt(argv[1:], 'hHvq', > > --- > > > options, args = getopt.getopt(argv, 'hHvq', > > > > You may notice I have commented out the self.progName line. This variable > > is not used anywhere in the module so I guess it could be removed. To > > keep it then conditional check on argv would have to remain and be moved after > > the self.progName line. > > > > I hope this makes sense, and it's my first post so go easy on me ;) > > > > Thanks, > > -John K > > _______________________________________________ > > Python-Dev mailing list > > Python-Dev at python.org > > http://mail.python.org/mailman/listinfo/python-dev > > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > > > > > -- > --Guido van Rossum (home page: http://www.python.org/~guido/) > From edloper at gradient.cis.upenn.edu Mon May 1 19:11:54 2006 From: edloper at gradient.cis.upenn.edu (Edward Loper) Date: Mon, 01 May 2006 13:11:54 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de><4455A0CF.3080008@v.loewis.de> Message-ID: <4456415A.6040406@gradient.cis.upenn.edu> Fredrik Lundh wrote: >> And again, why would you *make* me, the user-programmer, type >> >> make_person(name=namex, age=agex, phone=phonex, location = locationx) >> #instead of >> make_person(namex,agex,phonex,locationx) >> ? > > because a good API designer needs to consider more than just the current > release. I believe that it's quite possible that you're right, but I think more concrete answers would be helpful. I.e., how does having parameters that are syntactically keyword-only (as opposed to being simply documented as keyword-only) help you develop an API over time? I gave some thought to it, and can come up with a few answers. In all cases, assume a user BadUser, who decided to use positional arguments for arguments that you documented as keyword-only. - You would like to deprecate, and eventually remove, an argument to a function. For people who read your documentation, and use keyword args for the keyword-only arguments, their code will break in a clean, easy-to-understand way. But BadUser's code may break in strange hard-to-understand ways, since their positional arguments will get mapped to the wrong function arguments. - You would like to add a new parameter to a function, and would like to make that new parameter available for positional argument use. So you'd like to add it before all the keyword arguments. But this will break BadUser's code. - You have a function that takes one argument and a bunch of keyword options, and would like to change it to accept *varargs instead of just one argument. But this will break BadUser's code. I think that this kind of *concrete* use-case provides a better justification for the feature than just saying "it will help API design." As someone who has had a fair amount of experience designing & maintaining APIs over time, perhaps you'd care to contribute some more use cases where you think having syntactically keyword-only arguments would help? -Edward From guido at python.org Mon May 1 19:23:43 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 10:23:43 -0700 Subject: [Python-Dev] unittest argv In-Reply-To: References: Message-ID: On 5/1/06, John Keyes wrote: > On 5/1/06, Guido van Rossum wrote: > > Wouldn't this be an incompatible change? That would make it a no-no. > > Providing a dummy argv[0] isn't so hard is it? > > It would be incompatible with existing code, but that code is > already broken (IMO) by passing a dummy argv[0]. That's a new meaning of "broken", one that I haven't heard before. It's broken because it follows the API?!?! >I don't > think fixing it would affect much code, because normally > people don't specify the '-q' or '-v' in code, it is almost > exclusively used on the command line. Famous last words. > The only reason I came across it was that I was modifying > an ant task (py-test) so it could handle all of the named > arguments that TestProgram.__init__ supports. > > If the list index code can't change, at a minimum the default value > for argv should change from None to sys.argv. No. Late binding of sys.argv is very important. There are plenty of uses where sys.argv is dynamically modified. > Are the tests for unittest.py? Assuming you meant "Are there tests", yes: test_unittest.py. But it needs work. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From pje at telecommunity.com Mon May 1 19:26:42 2006 From: pje at telecommunity.com (Phillip J. Eby) Date: Mon, 01 May 2006 13:26:42 -0400 Subject: [Python-Dev] unittest argv In-Reply-To: References: Message-ID: <5.1.1.6.0.20060501132427.01f27d58@mail.telecommunity.com> At 06:11 PM 5/1/2006 +0100, John Keyes wrote: >On 5/1/06, Guido van Rossum wrote: > > Wouldn't this be an incompatible change? That would make it a no-no. > > Providing a dummy argv[0] isn't so hard is it? > >It would be incompatible with existing code, but that code is >already broken (IMO) by passing a dummy argv[0]. I don't >think fixing it would affect much code, because normally >people don't specify the '-q' or '-v' in code, it is almost >exclusively used on the command line. Speak for yourself - I have at least two tools that would have to change for this, at least one of which would have to grow version testing code, since it's distributed for Python 2.3 and up. That's far more wasteful than providing an argv[0], which is already a common requirement for main program functions in Python. From tjreedy at udel.edu Mon May 1 19:25:16 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 1 May 2006 13:25:16 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de><445600B3.7040903@gradient.cis.upenn.edu><44562A4D.30102@v.loewis.de> Message-ID: "Fredrik Lundh" wrote in message news:e35a4q$c23$1 at sea.gmane.org... > which reminds me of the following little absurdity gem from the language > reference: > > The following identifiers are used as keywords of the language, and > cannot be used as ordinary identifiers. They must be spelled exactly > as written here: /.../ > > (maybe it's just me). I am not sure of what you see as absurdity, as opposed to clumbsiness. Keywords are syntacticly indentifiers, but are reserved for predefined uses, and thus sematically are not identifiers. Perhaps 'ordinary indentifiers' should be replaced by 'names'. The second sentence is referring to case variations, and that could be more explicit. Before the elevation of None to reserved word status, one could have just added ", in lower case letters" > btw, talking about idioms used in the language reference, can any of the > native speakers on this list explain if "A is a nicer way of spelling B" > means > that "A is preferred over B", [alternatives snipped] Yes. Terry Jan Reedy From martin at v.loewis.de Mon May 1 19:26:41 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 19:26:41 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> Message-ID: <445644D1.3050200@v.loewis.de> Terry Reedy wrote: > This is not a reason for subproposal two, but a special case, as you > yourself note below, and hence does say why you want to have such. > >> def make_person(*, name, age, phone, location): >> pass You weren't asking for a reason, you were asking for an example: this is one. > And again, why would you *make* me, the user-programmer, type > > make_person(name=namex, age=agex, phone=phonex, location = locationx) > #instead of > make_person(namex,agex,phonex,locationx) > ? Because there should be preferably only one obvious way to call that function. Readers of the code should not need to remember the order of parameters, instead, the meaning of the parameters should be obvious in the call. This is the only sane way of doing functions with many arguments. > PS. I see that Guido finally gave a (different) use case for bare * that > does make sense to me. It's actually the same use case: I don't *want* callers to pass these parameters positionally, to improve readability. Regards, Martin From brett at python.org Mon May 1 19:42:44 2006 From: brett at python.org (Brett Cannon) Date: Mon, 1 May 2006 10:42:44 -0700 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) Message-ID: Signature objects (which has been lightly discussed on python-3000, but I realize should be retargeted to 2.6 since there is no incompatibility problems) are the idea of having an object that represents the parameters of a function for easy introspection. But there are two things that I can't quite decide upon. One is whether a signature object should be automatically created for every function. As of right now the PEP I am drafting has it on a per-need basis and have it assigned to __signature__ through a built-in function or putting it 'inspect'. Now automatically creating the object would possibly make it more useful, but it could also be considered overkill. Also not doing it automatically allows signature objects to possibly make more sense for classes (to represent __init__) and instances (to represent __call__). But having that same support automatically feels off for some reason to me. The second question is whether it is worth providing a function that will either figure out if a tuple and dict representing arguments would work in calling the function. Some have even suggested a function that returns the actual bindings if the call were to occur. Personally I don't see a huge use for either, but even less for the latter version. If people have a legit use case for either please speak up, otherwise I am tempted to keep the object simple. Now, I probably won't be participating in this discussion for the rest of the week. I am driving down to the Bay Area from Seattle for the next few days and have no idea what my Internet access will be like. But I wanted to get this discussion going since it kept me up last night thinking about it and I would like to sleep by knowing python-dev, in its infinite wisdom , is considering the issues. =) -Brett From fredrik at pythonware.com Mon May 1 19:43:03 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 19:43:03 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de><4455A0CF.3080008@v.loewis.de> <4456415A.6040406@gradient.cis.upenn.edu> Message-ID: Edward Loper wrote: > >> And again, why would you *make* me, the user-programmer, type > >> > >> make_person(name=namex, age=agex, phone=phonex, location = locationx) > >> #instead of > >> make_person(namex,agex,phonex,locationx) > >> ? > > > > because a good API designer needs to consider more than just the current > > release. > > I believe that it's quite possible that you're right, but I think more > concrete answers would be helpful. I.e., how does having parameters > that are syntactically keyword-only (as opposed to being simply > documented as keyword-only) help you develop an API over time? As you've figured out, the main advantage is that by forcing people to do what you intended, you can change things around without breaking existing code. And others can implement your API:s without having to emulate every possible implementation artifact. (I guess this is something that distinguish me from most other Pythoneers; I don't consider an API design good enough until it has at least two semi-independent implementations...) > I gave some thought to it, and can come up with a few answers. In all > cases, assume a user BadUser, who decided to use positional arguments > for arguments that you documented as keyword-only. > > - You would like to deprecate, and eventually remove, an argument to > a function. For people who read your documentation, and use > keyword args for the keyword-only arguments, their code will break > in a clean, easy-to-understand way. But BadUser's code may break in > strange hard-to-understand ways, since their positional arguments will > get mapped to the wrong function arguments. > > - You would like to add a new parameter to a function, and would like > to make that new parameter available for positional argument use. > So you'd like to add it before all the keyword arguments. But this > will break BadUser's code. > > - You have a function that takes one argument and a bunch of keyword > options, and would like to change it to accept *varargs instead of > just one argument. But this will break BadUser's code. > > I think that this kind of *concrete* use-case provides a better > justification for the feature than just saying "it will help API > design." As someone who has had a fair amount of experience designing & > maintaining APIs over time, perhaps you'd care to contribute some more > use cases where you think having syntactically keyword-only arguments > would help? In addition to your cases, the major remaining use case is the "one or more standard arguments, and one or more options"-style interface. ET's write method is a typical example. The documented interface is tree.write(out, **options) where 'out' is either a filename or something that has a 'write' method, and the available options are implementation dependent. An implementer that wants to support an "encoding" option could implement this as def write(self, out, encoding="us-ascii"): even if he only documents the write(out, **options) form, but developers using e.g. introspection-based "intellisense" tools or pydoc or help() will in- variably end up calling this as tree.write(out, "utf-8") which causes problems for reimplementors, and limits how the interface can be modified in the future (once enough people do this, you cannot even go back to a stricter "def write(self, out, **options)" approach without breaking stuff). I've suffered from enough "specification by reverse engineering" incidents during my career to ignore things like this... From amk at amk.ca Mon May 1 19:47:11 2006 From: amk at amk.ca (A.M. Kuchling) Date: Mon, 1 May 2006 13:47:11 -0400 Subject: [Python-Dev] introducing the experimental pyref wiki In-Reply-To: References: Message-ID: <20060501174711.GA12953@localhost.localdomain> On Sat, Apr 29, 2006 at 08:54:00PM +0200, Fredrik Lundh wrote: > http://pyref.infogami.com/ I find this work very exciting. Time hasn't been kind to the reference guide -- as language features were added to 2.x, not everything has been applied to the RefGuide, and users will probably have been forced to read a mixture of the RefGuide and various PEPs. The Reference Guide tries to provide a formal specification of the language. A while ago I wondered if we needed a "User's Guide" that explains all the keywords, lists special methods, and that sort of thing, in a style that isn't as formal and as complete as the Reference Guide. Now maybe we don't -- maybe the RefGuide can be tidied bit by bit into something more readable. (Or are the two goals -- completeness and readability -- incompossible, unable to be met at the same time by one document?) --amk From john at integralsource.com Mon May 1 19:51:37 2006 From: john at integralsource.com (John Keyes) Date: Mon, 1 May 2006 18:51:37 +0100 Subject: [Python-Dev] unittest argv In-Reply-To: References: Message-ID: On 5/1/06, Guido van Rossum wrote: > On 5/1/06, John Keyes wrote: > > On 5/1/06, Guido van Rossum wrote: > > > Wouldn't this be an incompatible change? That would make it a no-no. > > > Providing a dummy argv[0] isn't so hard is it? > > > > It would be incompatible with existing code, but that code is > > already broken (IMO) by passing a dummy argv[0]. > > That's a new meaning of "broken", one that I haven't heard before. > It's broken because it follows the API?!?! Fair enough, a bad use of language on my part. > >I don't > > think fixing it would affect much code, because normally > > people don't specify the '-q' or '-v' in code, it is almost > > exclusively used on the command line. > > Famous last words. Probably ;) > > The only reason I came across it was that I was modifying > > an ant task (py-test) so it could handle all of the named > > arguments that TestProgram.__init__ supports. > > > > If the list index code can't change, at a minimum the default value > > for argv should change from None to sys.argv. > > No. Late binding of sys.argv is very important. There are plenty of > uses where sys.argv is dynamically modified. Can you explain this some more? If it all happens in the same function call so how can it be late binding? > > Are the tests for unittest.py? > > Assuming you meant "Are there tests", yes: test_unittest.py. But it needs work. Ok thanks, -John K From aahz at pythoncraft.com Mon May 1 20:00:49 2006 From: aahz at pythoncraft.com (Aahz) Date: Mon, 1 May 2006 11:00:49 -0700 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <4455F8E5.7070203@canterbury.ac.nz> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> <4455F8E5.7070203@canterbury.ac.nz> Message-ID: <20060501180049.GA16007@panix.com> On Tue, May 02, 2006, Greg Ewing wrote: > Nick Coghlan wrote: >> >> the context expression in the with statement produces a context >> manager with __enter__ and __exit__ methods which set up and tear >> down a managed context for the body of the with statement. This is >> very similar to your later suggestion of context guard and guarded >> context. > > Currently I think I still prefer the term "guard", since it does a > better job of conjuring up the same sort of idea as a try-finally. "Guard" really doesn't work for me. It seems clear (especially in light of Fredrik's docs) that "wrapper" comes much closer to what's going on. -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From dinov at exchange.microsoft.com Mon May 1 17:31:40 2006 From: dinov at exchange.microsoft.com (Dino Viehland) Date: Mon, 1 May 2006 08:31:40 -0700 Subject: [Python-Dev] __getslice__ usage in sre_parse In-Reply-To: Message-ID: <4039D552ADAB094BB1EA670F3E96214E02ADE24F@df-foxhound-msg.exchange.corp.microsoft.com> I've also opened a bug for supporting __getslice__ in IronPython. Do you want to help develop Dynamic languages on CLR? (http://members.microsoft.com/careers/search/details.aspx?JobID=6D4754DE-11F0-45DF-8B78-DC1B43134038) -----Original Message----- From: python-dev-bounces+dinov=microsoft.com at python.org [mailto:python-dev-bounces+dinov=microsoft.com at python.org] On Behalf Of Guido van Rossum Sent: Sunday, April 30, 2006 8:31 AM To: Sanghyeon Seo Cc: Discussion of IronPython; python-dev at python.org Subject: Re: [Python-Dev] __getslice__ usage in sre_parse On 4/28/06, Sanghyeon Seo wrote: > Hello, > > Python language reference 3.3.6 deprecates __getslice__. I think it's > okay that UserList.py has it, but sre_parse shouldn't use it, no? Well, as long as the deprecated code isn't removed, there's no reason why other library code shouldn't use it. So I disagree that technically there's a reason why sre_parse shouldn't use it. > __getslice__ is not implemented in IronPython and this breaks usage of > _sre.py, a pure-Python implementation of _sre, on IronPython: > http://ubique.ch/code/_sre/ > > _sre.py is needed for me because IronPython's own regex implementation > using underlying .NET implementation is not compatible enough for my > applications. I will write a separate bug report for this. > > It should be a matter of removing __getslice__ and adding > isinstance(index, slice) check in __getitem__. I would very much > appreciate it if this is fixed before Python 2.5. You can influence the fix yourself -- please write a patch (relative to Python 2.5a2 that was just released), submit it to Python's patch tracker on SourceForge (read python.org/dev first), and then sending an email here to alert the developers. This ought to be done well before the planned 2.5b1 release (see PEP 256 for the 2.5 release timeline). You should make sure that the patched Python 2.5 passes all unit tests before submitting your test. Good luck! -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-Dev mailing list Python-Dev at python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/dinov%40microsoft.com From tjreedy at udel.edu Mon May 1 20:07:16 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 1 May 2006 14:07:16 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <44557789.5020107@gradient.cis.upenn.edu><200605010930.23198.fdrake@acm.org><44560F74.5000600@gradient.cis.upenn.edu> Message-ID: "Guido van Rossum" wrote in message news:ca471dc20605010728g2742bd01m4b4b284c15eabb18 at mail.gmail.com... > A function/method could have one argument that is obviously needed and > a whole slew of options that few people care about. For most people, > the signature they know is foo(arg). It would be nice if all the > options were required to be written as keyword arguments, so the > reader will not have to guess what foo(arg, True) means. Ok, this stimulates an old memory of written IBM JCL statements something like DD FILENAME,,,,,2,,HOP where you had to carefully count commas to correctly write and later read which defaulted options were being overridden. dd(filename, unit=2, meth = 'hop') is much nicer. So it seems to me now that '*, name1 = def1, name2=def2, ...' in the signature is a really a substitute for and usually an improvement upon (easier to write, read, and programmaticly extract) '**names' in the signature followed by name1 = names.get('name1', def1) name2 = names.get('name2', def2) ... (with the semantic difference being when defs are calculated) (But I still don't quite see why one would require that args for required, non-defaulted param be passed by name instead of position ;-). As something of an aside, the use of 'keyword' to describe arguments passed by name instead of position conflicts with and even contradicts the Ref Man definition of keyword as an identifier, with a reserved use, that cannot be used as a normal identifier. The parameter names used to pass an argument by name are normal identifiers and cannot be keywords in the other sense of the word. (Yes, I understand that this is usual CS usage, but Python docs can be more careful.) So I would like to see the name of this PEP changed to 'Name-only arguments' Terry Jan Reedy From tjreedy at udel.edu Mon May 1 20:09:26 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 1 May 2006 14:09:26 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de><445600B3.7040903@gradient.cis.upenn.edu><44562A4D.30102@v.loewis.de> Message-ID: "Terry Reedy" wrote in message news:e35g9r$275$1 at sea.gmane.org... > > "Fredrik Lundh" wrote in message > news:e35a4q$c23$1 at sea.gmane.org... >> which reminds me of the following little absurdity gem from the language >> reference: > I am not sure of what you see as absurdity, Perhaps I do. Were you referring to what I wrote in the last paragraph of my response to Guido? tjr From fredrik at pythonware.com Mon May 1 20:11:08 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 20:11:08 +0200 Subject: [Python-Dev] more pyref: continue in finally statements Message-ID: the language reference says: continue may only occur syntactically nested in a for or while loop, but not nested in a function or class definition or finally statement within that loop. /.../ It may occur within an except or else clause. The restriction on occurring in the try clause is implementor's laziness and will eventually be lifted. and it looks like the new compiler still has the same issue: $ python test.py File "test.py", line 5: continue SyntaxError: 'continue' not supported inside 'finally' clause how hard would it be to fix this ? (shouldn't the "try clause" in the note read "finally clause", btw? "continue" within the "try" suite seem to work just fine...) From guido at python.org Mon May 1 20:24:19 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 11:24:19 -0700 Subject: [Python-Dev] more pyref: continue in finally statements In-Reply-To: References: Message-ID: Strange. I thought this was supposed to be fixed? (But I can confirm that it isn't.) BTW there's another bug in the compiler: it doesn't diagnose this inside "while 0". --Guido On 5/1/06, Fredrik Lundh wrote: > the language reference says: > > continue may only occur syntactically nested in a for or while loop, > but not nested in a function or class definition or finally statement > within that loop. /.../ > > It may occur within an except or else clause. The restriction on occurring > in the try clause is implementor's laziness and will eventually be lifted. > > and it looks like the new compiler still has the same issue: > > $ python test.py > File "test.py", line 5: > continue > SyntaxError: 'continue' not supported inside 'finally' clause > > how hard would it be to fix this ? > > (shouldn't the "try clause" in the note read "finally clause", btw? "continue" > within the "try" suite seem to work just fine...) > > > > > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 20:31:00 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 11:31:00 -0700 Subject: [Python-Dev] unittest argv In-Reply-To: References: Message-ID: On 5/1/06, John Keyes wrote: > > No. Late binding of sys.argv is very important. There are plenty of > > uses where sys.argv is dynamically modified. > > Can you explain this some more? If it all happens in the same > function call so how can it be late binding? You seem to be unaware of the fact that defaults are computed once, when the 'def' is executed (typically when the module is imported). Consider module A containing this code: import sys def foo(argv=sys.argv): print argv and module B doing import sys import A sys.argv = ["a", "b", "c"] A.foo() This will print the initial value for sys.argv, not ["a", "b", "c"]. With the late binding version it will print ["a", "b", "c"]: def foo(argv=None): if argv is None: argv = sys.argv print argv -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Mon May 1 20:37:37 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 11:37:37 -0700 Subject: [Python-Dev] introducing the experimental pyref wiki In-Reply-To: <20060501174711.GA12953@localhost.localdomain> References: <20060501174711.GA12953@localhost.localdomain> Message-ID: Agreed. Is it too late to also attempt to bring Doc/ref/*.tex completely up to date and remove confusing language from it? Ideally that's the authoritative Language Reference -- admittedly it's been horribly out of date but needn't stay so forever. --Guido On 5/1/06, A.M. Kuchling wrote: > On Sat, Apr 29, 2006 at 08:54:00PM +0200, Fredrik Lundh wrote: > > http://pyref.infogami.com/ > > I find this work very exciting. Time hasn't been kind to the > reference guide -- as language features were added to 2.x, not > everything has been applied to the RefGuide, and users will probably > have been forced to read a mixture of the RefGuide and various PEPs. > > The Reference Guide tries to provide a formal specification of the > language. A while ago I wondered if we needed a "User's Guide" that > explains all the keywords, lists special methods, and that sort of > thing, in a style that isn't as formal and as complete as the > Reference Guide. Now maybe we don't -- maybe the RefGuide can be > tidied bit by bit into something more readable. > > (Or are the two goals -- completeness and readability -- > incompossible, unable to be met at the same time by one document?) > > --amk > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From pje at telecommunity.com Mon May 1 20:44:52 2006 From: pje at telecommunity.com (Phillip J. Eby) Date: Mon, 01 May 2006 14:44:52 -0400 Subject: [Python-Dev] introducing the experimental pyref wiki In-Reply-To: References: <20060501174711.GA12953@localhost.localdomain> <20060501174711.GA12953@localhost.localdomain> Message-ID: <5.1.1.6.0.20060501144339.01e6f6c8@mail.telecommunity.com> At 11:37 AM 5/1/2006 -0700, Guido van Rossum wrote: >Agreed. Is it too late to also attempt to bring Doc/ref/*.tex >completely up to date and remove confusing language from it? Ideally >that's the authoritative Language Reference -- admittedly it's been >horribly out of date but needn't stay so forever. Well, I added stuff for PEP 343, but PEP 342 (yield expression plus generator-iterator methods) hasn't really been added yet, mostly because I was unsure of how to fit it in without one of those "first let's explain it how it was, then how we changed it" sort of things. :( From edloper at gradient.cis.upenn.edu Mon May 1 20:40:31 2006 From: edloper at gradient.cis.upenn.edu (Edward Loper) Date: Mon, 01 May 2006 14:40:31 -0400 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: References: Message-ID: <4456561F.5090804@gradient.cis.upenn.edu> Brett Cannon wrote: > The second question is whether it is worth providing a function that > will either figure out if a tuple and dict representing arguments > would work in calling the function. Some have even suggested a > function that returns the actual bindings if the call were to occur. > Personally I don't see a huge use for either, but even less for the > latter version. If people have a legit use case for either please > speak up, otherwise I am tempted to keep the object simple. One use case that comes to mind is a type-checking decorator (or precondition-checking decorator, etc): @precondition(lambda x,y: x>y) @precondition(lambda y,z: y>z) def foo(x, y, z): ... where precondition is something like: def precondition(test): def add_precondition(func): def f(*args, **kwargs): bindings = func.__signature__.bindings(args, kwargs) if not test(**bindings): raise ValueError, 'Precontition not met' func(*args, **kwargs) return f return add_precondition -Edward From fuzzyman at voidspace.org.uk Mon May 1 20:47:39 2006 From: fuzzyman at voidspace.org.uk (Michael Foord) Date: Mon, 01 May 2006 19:47:39 +0100 Subject: [Python-Dev] introducing the experimental pyref wiki In-Reply-To: <20060501174711.GA12953@localhost.localdomain> References: <20060501174711.GA12953@localhost.localdomain> Message-ID: <445657CB.2040603@voidspace.org.uk> A.M. Kuchling wrote: > On Sat, Apr 29, 2006 at 08:54:00PM +0200, Fredrik Lundh wrote: > >> http://pyref.infogami.com/ >> > > I find this work very exciting. Time hasn't been kind to the > reference guide -- as language features were added to 2.x, not > everything has been applied to the RefGuide, and users will probably > have been forced to read a mixture of the RefGuide and various PEPs. > > The Reference Guide tries to provide a formal specification of the > language. A while ago I wondered if we needed a "User's Guide" that > explains all the keywords, lists special methods, and that sort of > thing, in a style that isn't as formal and as complete as the > Reference Guide. Now maybe we don't -- maybe the RefGuide can be > tidied bit by bit into something more readable. > At my company we recently got badly bitten because the language syntax as defined in the 'language reference' varies wildly from the grammar in SVN. We had to implement it twice ! When we tried to check syntax usage (as distinct from the BNF type specification in the grammar) we found that things like keyword arguments (etc) are not documented anywhere, except possibly in the tutorial. Currently the language reference seems to neither reflect the language definition in the grammar, nor be a good reference for users (except parts that are excellent). A users guide which straddles the middle would be very useful, and with some shepherding can probably be mainly done by community input. I also find that when trying to implement objects with 'the magic methods', I have to search in several places in the documentation. For example, to implement a mapping type I will probably need to refer to the following pages : http://docs.python.org/ref/sequence-types.html http://docs.python.org/lib/typesmapping.html http://docs.python.org/ref/customization.html Michael Foord > (Or are the two goals -- completeness and readability -- > incompossible, unable to be met at the same time by one document?) > > --amk > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk > > From martin at v.loewis.de Mon May 1 20:52:44 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 20:52:44 +0200 Subject: [Python-Dev] introducing the experimental pyref wiki In-Reply-To: References: <20060501174711.GA12953@localhost.localdomain> Message-ID: <445658FC.70806@v.loewis.de> Guido van Rossum wrote: > Agreed. Is it too late to also attempt to bring Doc/ref/*.tex > completely up to date and remove confusing language from it? Ideally > that's the authoritative Language Reference -- admittedly it's been > horribly out of date but needn't stay so forever. It's never too late to update the specification. I really think there should be a specification, and I really think it should be as precise as possible - where "possible" takes both of these into account: - it may get out of date due to lack of contributors. This is free software, and you don't always get what you want unless you do it yourself (and even then, sometimes not). - it might be deliberately vague to allow for different implementation strategies. Ideally, it would be precise in pointing out where it is deliberately vague. So I think the PEPs all should be merged into the documentation, at least their specification parts (rationale, history, examples might stay in the PEPs). To some degree, delivery of documentation can be enforced by making acceptance of the PEP conditional upon creation of documentation patches. Once the feature is committed, we can only hope for (other) volunteers to provide the documentation, or keep nagging the author of the code to produce it. Regards, Martin From jcarlson at uci.edu Mon May 1 21:02:21 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Mon, 01 May 2006 12:02:21 -0700 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <4455CD18.8030200@v.loewis.de> References: <20060430231024.674A.JCARLSON@uci.edu> <4455CD18.8030200@v.loewis.de> Message-ID: <20060501092208.6756.JCARLSON@uci.edu> Before I get into my reply, I'm going to start out by defining a new term: operationX - the operation of interpreting information differently than how it is presented, generally by constructing a data structure based on the input information. eg; programming language source file -> parse tree, natual language -> parse tree or otherwise, structured data file -> data structure (tree, dictionary, etc.), etc. synonyms: parsing, unmarshalling, interpreting, ... Any time I would previously describe something as some variant of 'parse', replace that with 'operationX'. I will do that in all of my further replies. "Martin v. L?wis" wrote: > Josiah Carlson wrote: > > Certainly that is the case. But how would you propose embedded bytes > > data be represented? (I talk more extensively about this particular > > issue later). > > Can't answer: I don't know what "embedded bytes data" are. I described this before as the output of img2py from wxPython. Here's a sample which includes the py.ico from Python 2.3 . #---------------------------------------------------------------------- # This file was generated by C:\Python23\Scripts\img2py # from wx import ImageFromStream, BitmapFromImage import cStringIO, zlib def getData(): return zlib.decompress( 'x\xda\x01\x14\x02\xeb\xfd\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \ \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08\ |\x08d\x88\x00\x00\x01\xcbIDATX\x85\xb5W\xd1\xb6\x84 \x08\x1ct\xff;\xf6\xc3\ \x93\xfb`\x18\x92f\xb6^:\x9e\xd4\x94\x19\x04\xd4\x88BDO$\xed\x02\x00\x14"i]\ \xdb\xddI\x93B=\x02\x92va\xceu\xe6\\T\x98\xd7\x91h\x12\xb0\xd6z\xb1\xa4V\x90\ \xf8\xf4>\xc8A\x81\xe8\xack\xdb\xae\xc6\xbf\x11\xc8`\x02\x80L\x1d\xa5\xbdJ\ \xc2Rm\xab\t\x88PU\xb7m\xe0>V^\x13(\xa9G\xa7\xbf\xb5n\xfd\xafoI\xbbhyC\xa0\ \xc4\x80*h\x05\xd8]\xd0\xd5\xe9y\xee\x1bO\t\x10\x85X\xe5\xfc\x8c\xf0\x06\xa0\ \x91\x153)\x1af\xc1y\xab\xdf\x906\x81\xa7.)1\xe0w\xba\x1e\xb0\xaf\xff*C\x02\ \x17`\xc2\xa3\xad\xe0\xe9*\x04U\xec\x97\xb6i\xb1\x02\x0b\xc0_\xd3\xf7C2\xe6\ \xe9#\x05\xc6bfG\xc8\xcc-\xa4\xcc\xd8Q0\x06\n\x91\x14@\x15To;\xdd\x125s<\xf0\ \x8c\x94\xd3\xd0\xfa\xab\xb5\xeb{\xcb\xcb\x1d\xe1\xd7\x15\xf0\x1d\x1e\x9c9wz\ p\x0f\xfa\x06\x1cp\xa7a\x01?\x82\x8c7\x80\xf5\xe3\xa1J\x95\xaa\xf5\xdc\x00\ \x9f\x91\xe2\x82\xa4g\x80\x0f\xc8\x06p9\x0f\xb66\xf8\xccNH\x14\xe2\t\xde\x1a\ `\x14\x8d|>\x0b\x0e\x00\x9f\x94v\t!RJ\xbb\xf4&VV/\x04\x97\xb4K\xe5\x82\xe0&\ \x97\xcc\x18X\xfd\x16\x1cxx+\x06\xfa\xfeVp+\x17\xb7\xb9~\xd5\xcd<\xb8\x13V\ \xdb\xf1\r\xf8\xf54\xcc\xee\xbc\x18\xc1\xd7;G\x93\x80\x0f\xb6.\xc1\x06\xf8\ \xd9\x7f=\xe6[c\xbb\xff\x05O\x97\xff\xadh\xcct]\xb0\xf2\xcc/\xc6\x98mV\xe3\ \xe1\xf1\xb5\xbcGhDT--\x87\x9e\xdb\xca\xa7\xb2\xe0"\xe6~\xd0\xfb6LM\n\xb1[\ \x90\xef\n\xe5a>j\x19R\xaaq\xae\xdc\xe9\xad\xca\xdd\xef\xb9\xaeD\x83\xf4\xb2\ \xff\xb3?\x1c\xcd1U-7%\x96\x00\x00\x00\x00IEND\xaeB`\x82\xdf\x98\xf1\x8f' ) def getBitmap(): return BitmapFromImage(getImage()) def getImage(): stream = cStringIO.StringIO(getData()) return ImageFromStream(stream) That data is non-textual. It is bytes within a string literal. And it is embedded (within a .py file). > > I am apparently not communicating this particular idea effectively > > enough. How would you propose that I store parsing literals for > > non-textual data, and how would you propose that I set up a dictionary > > to hold some non-trivial number of these parsing literals? > > I can't answer that question: I don't know what a "parsing literal > for non-textual data" is. If you are asking how you represent bytes > object in source code: I would encode them as a list of integers, > then use, say, > > parsing_literal = bytes([3,5,30,99]) An operationX literal is a symbol that describes how to interpret the subsequent or previous data. For an example of this, see the pickle module (portions of which I include below). > > From what I understand, it would seem that you would suggest that I use > > something like the following... > > > > handler = {bytes('...', encoding=...).encode('latin-1'): ..., > > #or > > '\uXXXX\uXXXX...': ..., > > #or even without bytes/str > > (0xXX, 0xXX, ...): ..., } > > > > Note how two of those examples have non-textual data inside of a Python > > 3.x string? Yeah. > > Unfortunately, I don't notice. I assume you don't mean a literal '...'; > if this is what you represent, I would write > > handler = { '...': "some text" } > > But I cannot guess what you want to put into '...' instead. I described before how you would use this kind of thing to perform operationX on structured information. It turns out that pickle (in Python) uses a dictionary of operationX symbols/literals -> unbound instance methods to perform operationX on the pickled representation of Python objects (literals where XXXX = '...' are defined, and symbols using the XXXX names). The relevant code for unpickling is the while 1: section of the following. def load(self): """Read a pickled object representation from the open file. Return the reconstituted object hierarchy specified in the file. """ self.mark = object() # any new unique object self.stack = [] self.append = self.stack.append read = self.read dispatch = self.dispatch try: while 1: key = read(1) dispatch[key](self) except _Stop, stopinst: return stopinst.value > >>> We've not removed the problem, only changed it from being contained > >>> in non-unicode > >>> strings to be contained in unicode strings (which are 2 or 4 times larger > >>> than their non-unicode counterparts). > >> We have removed the problem. > > > > Excuse me? People are going to use '...' to represent literals of all > > different kinds. > > In Python 3, '...' will be a character string. You can't use it to > represent anything else but characters. > > Can you give examples of actual source code where people use '...' > something other than text? For an example of where people use '...' to represent non-textual information in a literal, see the '# Protocol 2' section of pickle.py ... # Protocol 2 PROTO = '\x80' # identify pickle protocol NEWOBJ = '\x81' # build object by applying cls.__new__ to argtuple EXT1 = '\x82' # push object from extension registry; 1-byte index EXT2 = '\x83' # ditto, but 2-byte index EXT4 = '\x84' # ditto, but 4-byte index TUPLE1 = '\x85' # build 1-tuple from stack top TUPLE2 = '\x86' # build 2-tuple from two topmost stack items TUPLE3 = '\x87' # build 3-tuple from three topmost stack items NEWTRUE = '\x88' # push True NEWFALSE = '\x89' # push False LONG1 = '\x8a' # push long from < 256 bytes LONG4 = '\x8b' # push really big long Also look at the getData() function I defined earlier in this post for non-text string literals. > > What does pickle.load(...) do to the files that are passed into it? It > > reads the (possibly binary) data it reads in from a file (or file-like > > object), performing a particular operation based based on a dictionary > > of expected tokens in the file, producing a Python object. I would say > > that pickle 'parses' the content of a file, which I presume isn't > > necessary text. > > Right. I think pickle can be implemented with just the bytes type. > There is a textual and a binary version of the pickle format. The > textual should be read as text; the binary version using bytes. > (I *thinK* the encoding of the textual version is ASCII, but one > would have to check). The point of this example was to show that operationX isn't necessarily the processing of text, but may in fact be the interpretation of binary data. It was also supposed to show how one may need to define symbols for such interpretation via literals of some kind. In the pickle module, this is done in two parts: XXX = ; dispatch[XXX] = fcn. I've also seen it as dispatch = {: fcn} In regards to the text pickles using text as input, and binary pickles using bytes as input, I would remind you that bytes are mutable. This isn't quite as big a deal with pickle, but one would need to either add both the '...' and int literals to the dictionary: dispatch[SYMBOL] = fcn dispatch[SYMBOL.encode('latin-1')[0]] = fcn Or always use text _or_ integers in in the decoding: #decoding bytes when only str in dispatch... dispatch[bytesX.decode('latin-1')](self) #encoding str when only int in dispatch... dispatch[strX.encode('latin-1')[0]](self) > > Replace pickle with a structured data storage format of your choice. > > It's still parsing (at least according to my grasp of English, which > > could certainly be flawed (my wife says as much on a daily basis)). > > Well, I have no "native language" intuition with respect to these > words - I only use them in the way I see them used elsewhere. I see > "parsing" typically associated with textual data, and "unmarshalling" > with binary data. Before Python, I hadn't heard of 'marshal' in relation to the storage or retrieval of data structures as data, and at least in my discussion about such topics with my friends and colleagues, unmarshalling is an example of parsing. In any case, you can replace many of my uses of 'parsing' with 'unmarshalling', or even 'operationX', which I defined at the beginning of this email. > >>> Look how successful and > >>> effective it has been so far in the history of Python. In order to make > >>> the bytes object be as effective in 3.x, one would need to add basically > >>> all of the Python 2.x string methods to it > >> The precondition of this clause is misguided: the bytes type doesn't > >> need to be as effective, since the string type is as effective in 2.3, > >> so you can do all parsing based on strings. > > > > Not if those strings contain binary data. > > I couldn't (until right now) understand what you mean by "parsing binary > data". I still doubt that you typically need the same operations for > unmarshalling that you need for parsing. > > In parsing, you need to look (scan) for separators, follow a possibly > recursive grammar, and so on. For unmarshalling, you typically have > a TLV (tag-length-value) structure, where you read a tag (of fixed > size), then the length, then the value (of the size indicated in the > length). There are variations, of course, but you typically don't > need .find, .startswith, etc. See any line-based socket protocol for where .find() is useful. We'll take telnet, for example. A telnet line is terminated by a CRLF pair, and being able to interpret incoming information on a line-by-line basis is sufficient to support all of the required portions of the RFC. In addition, telnet lines may contain non-text information as escapes (ascii 0-8, 11-12, 14-31, 128-255), regardless of line buffering. - Josiah From martin at v.loewis.de Mon May 1 21:01:32 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 21:01:32 +0200 Subject: [Python-Dev] more pyref: continue in finally statements In-Reply-To: References: Message-ID: <44565B0C.6010207@v.loewis.de> Guido van Rossum wrote: > Strange. I thought this was supposed to be fixed? (But I can confirm > that it isn't.) Perhaps you were confusing it with this HISTORY entry? - A 'continue' statement can now appear in a try block within the body of a loop. It is still not possible to use continue in a finally clause. This was added as ------------------------------------------------------------------------ r19261 | jhylton | 2001-02-01 23:53:15 +0100 (Do, 01 Feb 2001) | 2 lines Ge?nderte Pfade: M /python/trunk/Misc/NEWS continue now allowed in try block ------------------------------------------------------------------------ r19260 | jhylton | 2001-02-01 23:48:12 +0100 (Do, 01 Feb 2001) | 3 lines Ge?nderte Pfade: M /python/trunk/Doc/ref/ref7.tex M /python/trunk/Include/opcode.h M /python/trunk/Lib/dis.py M /python/trunk/Lib/test/output/test_exceptions M /python/trunk/Lib/test/output/test_grammar M /python/trunk/Lib/test/test_exceptions.py M /python/trunk/Lib/test/test_grammar.py M /python/trunk/Python/ceval.c M /python/trunk/Python/compile.c Allow 'continue' inside 'try' clause SF patch 102989 by Thomas Wouters ------------------------------------------------------------------------ Regards, Martin From fredrik at pythonware.com Mon May 1 21:02:38 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 21:02:38 +0200 Subject: [Python-Dev] introducing the experimental pyref wiki References: <20060501174711.GA12953@localhost.localdomain> Message-ID: A.M. Kuchling wrote: > I find this work very exciting. Time hasn't been kind to the > reference guide -- as language features were added to 2.x, not > everything has been applied to the RefGuide, and users will probably > have been forced to read a mixture of the RefGuide and various PEPs. or as likely, mailing list archives. > The Reference Guide tries to provide a formal specification of the > language. A while ago I wondered if we needed a "User's Guide" that > explains all the keywords, lists special methods, and that sort of > thing, in a style that isn't as formal and as complete as the > Reference Guide. Now maybe we don't -- maybe the RefGuide can be > tidied bit by bit into something more readable. > > (Or are the two goals -- completeness and readability -- > incompossible, unable to be met at the same time by one document?) well, I'm biased, but I'm convinced that the pyref material (which consists of the entire language reference plus portions of the library reference) can be both complete and readable. I don't think it can be complete, readable, and quite as concise as before, though ;-) (see the "a bit more inviting" part on the front-page for the guidelines I've been using this far). From fredrik at pythonware.com Mon May 1 21:08:07 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 21:08:07 +0200 Subject: [Python-Dev] introducing the experimental pyref wiki References: <20060501174711.GA12953@localhost.localdomain> Message-ID: Guido van Rossum wrote: > Agreed. Is it too late to also attempt to bring Doc/ref/*.tex > completely up to date and remove confusing language from it? Ideally > that's the authoritative Language Reference -- admittedly it's been > horribly out of date but needn't stay so forever. it's perfectly possible to generate a list of changes from the wiki which some volunteer could apply to the existing document. or we could generate a complete new set of Latex documents from the wiki contents. it's just a small matter of programming... I'm not sure I would bother, though -- despite Fred's heroic efforts, the toolchain is nearly as dated as the language reference itself. XHTML and ODT should be good enough, really. From martin at v.loewis.de Mon May 1 21:09:36 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 21:09:36 +0200 Subject: [Python-Dev] more pyref: continue in finally statements In-Reply-To: References: Message-ID: <44565CF0.4000207@v.loewis.de> Fredrik Lundh wrote: > the language reference says: > > continue may only occur syntactically nested in a for or while loop, > but not nested in a function or class definition or finally statement > within that loop. /.../ > > It may occur within an except or else clause. The restriction on occurring > in the try clause is implementor's laziness and will eventually be lifted. > > and it looks like the new compiler still has the same issue: > > $ python test.py > File "test.py", line 5: > continue > SyntaxError: 'continue' not supported inside 'finally' clause > > how hard would it be to fix this ? > > (shouldn't the "try clause" in the note read "finally clause", btw? "continue" > within the "try" suite seem to work just fine...) For the latter: the documentation apparently wasn't fully updated in r19260: it only changed ref7.tex, but not ref6.tex. IOW, it really means to say "in the try clause", and it is out-of-date in saying so. As for "continue in the 'finally' clause: What would that mean? Given def f(): raise Exception while 1: try: f() finally: g() continue then what should be the meaning of "continue" here? The finally block *eventually* needs to re-raise the exception. When should that happen? So I would say: It's very easy to fix, just change the message to SyntaxError: 'continue' not allowed inside 'finally' clause :-) Regards, Martin From martin at v.loewis.de Mon May 1 21:24:30 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 21:24:30 +0200 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <20060501092208.6756.JCARLSON@uci.edu> References: <20060430231024.674A.JCARLSON@uci.edu> <4455CD18.8030200@v.loewis.de> <20060501092208.6756.JCARLSON@uci.edu> Message-ID: <4456606E.2030100@v.loewis.de> Josiah Carlson wrote: >>> Certainly that is the case. But how would you propose embedded bytes >>> data be represented? (I talk more extensively about this particular >>> issue later). >> Can't answer: I don't know what "embedded bytes data" are. Ok. I think I would use base64, of possibly compressed content. It's more compact than your representation, as it only uses 1.3 characters per byte, instead of the up-to-four bytes that the img2py uses. If ease-of-porting is an issue, img2py should just put an .encode("latin-1") at the end of the string. > return zlib.decompress( > 'x\xda\x01\x14\x02\xeb\xfd\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \ [...] > That data is non-textual. It is bytes within a string literal. And it > is embedded (within a .py file). In Python 2.x, it is that, yes. In Python 3, it is a (meaningless) text. >>> I am apparently not communicating this particular idea effectively >>> enough. How would you propose that I store parsing literals for >>> non-textual data, and how would you propose that I set up a dictionary >>> to hold some non-trivial number of these parsing literals? > > An operationX literal is a symbol that describes how to interpret the > subsequent or previous data. For an example of this, see the pickle > module (portions of which I include below). I don't think there can be, or should be, a general solution for all operationX literals, because the different applications of operationX all have different requirements wrt. their literals. In binary data, integers are the most obvious choice for operationX literals. In text data, string literals are. > I described before how you would use this kind of thing to perform > operationX on structured information. It turns out that pickle (in > Python) uses a dictionary of operationX symbols/literals -> unbound > instance methods to perform operationX on the pickled representation of > Python objects (literals where XXXX = '...' are defined, and symbols > using the XXXX names). The relevant code for unpickling is the while 1: > section of the following. Right. I would convert the top of pickle.py to read MARK = ord('(') STOP = ord('.') ... > > def load(self): > """Read a pickled object representation from the open file. > > Return the reconstituted object hierarchy specified in the file. > """ > self.mark = object() # any new unique object > self.stack = [] > self.append = self.stack.append > read = self.read > dispatch = self.dispatch > try: > while 1: > key = read(1) and then this to key = ord(read(1)) > dispatch[key](self) > except _Stop, stopinst: > return stopinst.value > For an example of where people use '...' to represent non-textual > information in a literal, see the '# Protocol 2' section of pickle.py ... Right. > # Protocol 2 > > PROTO = '\x80' # identify pickle protocol This should be changed to PROTO = 0x80 # identify pickle protocol etc. > The point of this example was to show that operationX isn't necessarily > the processing of text, but may in fact be the interpretation of binary > data. It was also supposed to show how one may need to define symbols > for such interpretation via literals of some kind. In the pickle module, > this is done in two parts: XXX = ; dispatch[XXX] = fcn. I've > also seen it as dispatch = {: fcn} Yes. For pickle, the ordinals of the type code make good operationX literals. > See any line-based socket protocol for where .find() is useful. Any line-based protocol is textual, usually based on ASCII. Regards, Martin From aahz at pythoncraft.com Mon May 1 21:25:27 2006 From: aahz at pythoncraft.com (Aahz) Date: Mon, 1 May 2006 12:25:27 -0700 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: References: Message-ID: <20060501192527.GA11018@panix.com> On Mon, May 01, 2006, Brett Cannon wrote: > > But there are two things that I can't quite decide upon. > > One is whether a signature object should be automatically created > for every function. As of right now the PEP I am drafting has it > on a per-need basis and have it assigned to __signature__ through > a built-in function or putting it 'inspect'. Now automatically > creating the object would possibly make it more useful, but it > could also be considered overkill. Also not doing it automatically > allows signature objects to possibly make more sense for classes (to > represent __init__) and instances (to represent __call__). But having > that same support automatically feels off for some reason to me. My take is that we should do it automatically and provide a helper function that does additional work. The class case is already complicated by __new__(); we probably don't want to automatically sort out __init__() vs __new__(), but I think we do want regular functions and methods to automatically have a __signature__ attribute. Aside from the issue with classes, are there any other drawbacks to automatically creating __signature__? -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From tim.peters at gmail.com Mon May 1 21:27:48 2006 From: tim.peters at gmail.com (Tim Peters) Date: Mon, 1 May 2006 15:27:48 -0400 Subject: [Python-Dev] introducing the experimental pyref wiki In-Reply-To: <20060501174711.GA12953@localhost.localdomain> References: <20060501174711.GA12953@localhost.localdomain> Message-ID: <1f7befae0605011227o4b8873d4sf35e0951a4ecdd3e@mail.gmail.com> [A.M. Kuchling] > ... > (Or are the two goals -- completeness and readability -- > incompossible, unable to be met at the same time by one document?) No, but it's not easy, and it's not necessarily succinct. For an existence proof, see Guy Steele's "Common Lisp the Language". I don't think it's a coincidence that Steele worked on the readable "The Java Language Specification" either, or on the original Scheme spec. Google should hire him to work on Python docs now ;-) From fredrik at pythonware.com Mon May 1 21:38:42 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 21:38:42 +0200 Subject: [Python-Dev] introducing the experimental pyref wiki References: <20060501174711.GA12953@localhost.localdomain> <1f7befae0605011227o4b8873d4sf35e0951a4ecdd3e@mail.gmail.com> Message-ID: Tim Peters wrote: > > (Or are the two goals -- completeness and readability -- > > incompossible, unable to be met at the same time by one document?) > > No, but it's not easy, and it's not necessarily succinct. For an > existence proof, see Guy Steele's "Common Lisp the Language". I > don't think it's a coincidence that Steele worked on the readable "The > Java Language Specification" either, or on the original Scheme spec. > Google should hire him to work on Python docs now ;-) on the other hand, it's important to realize that the Python audience have changed a lot since Guido wrote the first (carefully crafted, and mostly excellent) version of the language reference. I'm sure Guy could create a document that even a martian could read [1], and I'm pretty sure that we could untangle the huge pile of peep- hole tweaks that the reference has accumulated and get back to some- thing close to Guido's original, but I'm not sure that is what the Python community needs. (my goal is to turn pyref into more of a random-access encyclopedia, and less of an ISO-style "it's all there; just keep reading it over and over again until you get it" specification. it should be possible to link from the tutorial to a reference page without causing brain implosions) 1) see http://pyref.infogami.com/introduction From fredrik at pythonware.com Mon May 1 21:50:30 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 21:50:30 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de><445600B3.7040903@gradient.cis.upenn.edu><44562A4D.30102@v.loewis.de> Message-ID: Terry Reedy wrote: > >> which reminds me of the following little absurdity gem from the language > >> reference: > > > I am not sure of what you see as absurdity, > > Perhaps I do. Were you referring to what I wrote in the last paragraph of > my response to Guido? I don't know; I've lost track of all the subthreads in this subthread. it wasn't quite obvious to me that "be spelled exactly" meant "use the same case" rather than "must have the same letters in the same order". if you use the latter interpretation, the paragraph looks a bit... odd. From fdrake at acm.org Mon May 1 22:14:28 2006 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 1 May 2006 16:14:28 -0400 Subject: [Python-Dev] New methods for weakref.Weak*Dictionary types Message-ID: <200605011614.30613.fdrake@acm.org> I'd like to commit this for Python 2.5: http://www.python.org/sf/1479988 The WeakKeyDictionary and WeakValueDictionary don't provide any API to get just the weakrefs out, instead of the usual mapping API. This can be desirable when you want to get a list of everything without creating new references to the underlying objects at that moment. This patch adds methods to make the references themselves accessible using the API, avoiding requiring client code to have to depend on the implementation. The WeakKeyDictionary gains the .iterkeyrefs() and .keyrefs() methods, and the WeakValueDictionary gains the .itervaluerefs() and .valuerefs() methods. The patch includes tests and docs. -Fred -- Fred L. Drake, Jr. From sluggoster at gmail.com Mon May 1 22:16:10 2006 From: sluggoster at gmail.com (Mike Orr) Date: Mon, 1 May 2006 13:16:10 -0700 Subject: [Python-Dev] More Path comments (PEP 355) Message-ID: <6e9196d20605011316w749afa07u9594169b39ae46b5@mail.gmail.com> I just read over the changes to the proposed Path class since the discussion last summer. A big thanks to Bjorn Lindqvist for writing a PEP, Jason Orendorff for the original path.py and his suggestions on how the Path class should be different, and the writers of the Python-Dev Summary for bringing the discussion to my attention. I've been testing/using the interim Path class in the Python subversion (/sandbox/trunk/path, last modified in September), and have a few comments about PEP 355: - .walk*() return a list rather than an iterator. Was this an intentional change or a typo? Most typical uses yield thousands of paths which do not need to be in memory simultaneously. - An equivalent to os.listdir() is frequently useful in applications. This would return a list of filenames (strings) without the parent info. Path.listdir() calls os.listdir() and wraps all the items into Paths, and then I have to unwrap them again, which seems like a waste. I end up calling os.listdir(my_path) instead. If we decide not to subsume many os.* functions into Path, that's fine, but if we deprecate os.listdir(), it's not. - -1 on removing .joinpath(), whatever it's called. Path(basepath, *args) is good but not the same. (1) it's less intuitive: I expect this to be a method on a directory. (2) the class name is hardcoded: do I really have to do self.__class__(self, *args) to make my code forward compatible with whatever nifty subclasses might appear? - +1 on renaming .directory back to .parent. - -1 on losing a 1-liner to read/iterate a file's contents. This is a frequent operation, and having to write a 2-liner or a custom function is a pain. - +1 on consolidating mkdir/makedirs and rmdir/rmdirs. I'd also suggest not raising an error if the operation is already done, and a .purge() method that deletes recursively no matter what it is. This was suggested last summer as a rename for my .delete_dammit() proposal. Unsure what to do if permission errors prevent the operation; I guess propagating the exception is best. This would make .rmtree() redundant, which chokes if the item is a file. - +1 for rationalizing .copy*(). - +1 for .chdir(). This is a frequent operation, and it makes no sense not to include it. -- Mike Orr (mso at oz.net address is semi-reliable) From fredrik at pythonware.com Mon May 1 22:21:30 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 22:21:30 +0200 Subject: [Python-Dev] more pyref: a better term for "string conversion" Message-ID: for some reason, the language reference uses the term "string con- version" for the backtick form of "repr": http://docs.python.org/ref/string-conversions.html any suggestions for a better term ? should backticks be deprecated, and documented in terms of repr (rather than the other way around) ? From fuzzyman at voidspace.org.uk Mon May 1 22:31:53 2006 From: fuzzyman at voidspace.org.uk (Michael Foord) Date: Mon, 01 May 2006 21:31:53 +0100 Subject: [Python-Dev] more pyref: a better term for "string conversion" In-Reply-To: References: Message-ID: <44567039.7040408@voidspace.org.uk> Fredrik Lundh wrote: > for some reason, the language reference uses the term "string con- > version" for the backtick form of "repr": > The language reference also says that trailing commas for expressions work with backticks. This is incorrect. I think this is necessary to allow nested 'string conversions', so it is a doc error rather than an implementation error. I can't think of a better term than string conversion. At least it is distinct from 'string formatting'. Personally I think that backticks in code look like an ugly hack and ``repr(expression)`` is clearer. If backticks were documented as a hackish shortcut for repr then great. :-) Michael Foord > http://docs.python.org/ref/string-conversions.html > > any suggestions for a better term ? should backticks be deprecated, > and documented in terms of repr (rather than the other way around) ? > > > > > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/fuzzyman%40voidspace.org.uk > > From guido at python.org Mon May 1 22:54:01 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 13:54:01 -0700 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <4456606E.2030100@v.loewis.de> References: <20060430231024.674A.JCARLSON@uci.edu> <4455CD18.8030200@v.loewis.de> <20060501092208.6756.JCARLSON@uci.edu> <4456606E.2030100@v.loewis.de> Message-ID: This discussion seems to have gotten a bit out of hand. I believe it belongs on the python-3000 list. As a quick commentary, I see good points made by both sides. My personal view is that we should *definitely* not introduce a third type, and that *most* text-based activities should be done in the (Unicode) string domain. That said, I expect a certain amount of parsing to happen on bytes objects -- for example, I would say that CPython's current parser is parsing bytes since its input is UTF-8. There are also plenty of text-based socket protocols that are explicitly defined in terms of octets (mostly containing ASCII bytes only); I can see why some people would want to write handlers that parse the bytes directly. But instead of analyzing or arguing the situation to death, I'd like to wait until we have a Py3k implementation that implements something approximating the proposed end goal, where 'str' represents unicode characters, and 'bytes' represents bytes, and we have separate I/O APIs for binary (bytes) and character (str) data. I'm hoping to make some progress towards this goal in the p3yk (sic) branch. It appears that before we can switch the meaning of 'str' we will first have to implement the new I/O library, which is what I'm focusing on right now. I already have a fairly minimal but functional bytes type, which I'll modify as I go along and understand more of the requirements. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From sluggoster at gmail.com Mon May 1 22:54:21 2006 From: sluggoster at gmail.com (Mike Orr) Date: Mon, 1 May 2006 13:54:21 -0700 Subject: [Python-Dev] Path.ancestor() Message-ID: <6e9196d20605011354x429d0a56k48d9eb527f99061c@mail.gmail.com> This is a potentially long discussion so I'm putting it in a separate thread. When finding one file relative to another, it's difficult to read multiple ".parent" attributes stacked together. Worse, if you have the wrong number, you end up at the wrong directory level, potentially causing destructive damage. Doubly worse, the number of ".parent" is non-intuitive for those used to the near-universal "." and ".." conventions. Say I'm in apps/myapp/bin/myprogram.py and want to add apps/myapp/lib and apps/shared/lib to sys.path in a portable way. app_root = Path(__file__).realpath().abspath().parent.parent assert app_root.parent.name == 'apps' sys.path.insert(0, app_root.parent / 'shared/lib') sys.path.insert(0, app_root / 'lib') Yikes! At least it's better than: lib = os.path.join(os.path.dirname(os.path.dirname(x)), "lib") which is completely unreadable. (Silence to those who say __path__ is obsolete now that setuptools has a function for finding a file in an egg. (1) I don't understand that part of the setuptools docs. (2) It will be many months before most Python programmers are ready to switch to it.) The tricky thing with "." and ".." is they have a different meaning depending on whether the original path is a file or directory. With a directory there's one less ".parent". I've played a bit with the argument and come up with this: # N is number of ".."; None (default arg) is special case for ".". .ancestor() => "." => p.parent or d .ancestor(0) => ValueError .ancestor(1) => ".." => p.parent.parent or d.parent .ancestor(2) => "../.." => p.parent.parent.parent or d.parent.parent The simplest alternative is making N the number of ".parent". This has some merit, and would solve the original problem of too many ".parent" stacking up. But it means Path wouldn't have any equivalent to "." and ".." behavior. Another alternative is to make .ancestor(0) mean ".". I don't like this because "." is a special case, and this should be shown in the syntax. Another alternative is to move every number down by 1, so .ancestor(0) is equivalent to "..". The tidiness of this is outweighed by the difficulty of remembering that N is not the number of "..". -- Mike Orr (mso at oz.net address is semi-reliable) From martin at v.loewis.de Mon May 1 22:54:43 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Mon, 01 May 2006 22:54:43 +0200 Subject: [Python-Dev] more pyref: a better term for "string conversion" In-Reply-To: References: Message-ID: <44567593.2010103@v.loewis.de> Fredrik Lundh wrote: > for some reason, the language reference uses the term "string con- > version" for the backtick form of "repr": > > http://docs.python.org/ref/string-conversions.html > > any suggestions for a better term ? should backticks be deprecated, > and documented in terms of repr (rather than the other way around) ? I vaguely recall that they are deprecated, but I can't remember the details. The one obvious way to invoke that functionality is the repr() builtin. Regards, Martin From tim.peters at gmail.com Mon May 1 22:57:06 2006 From: tim.peters at gmail.com (Tim Peters) Date: Mon, 1 May 2006 16:57:06 -0400 Subject: [Python-Dev] New methods for weakref.Weak*Dictionary types In-Reply-To: <200605011614.30613.fdrake@acm.org> References: <200605011614.30613.fdrake@acm.org> Message-ID: <1f7befae0605011357s6427602cnc6ca6a8bfa442ec8@mail.gmail.com> [Fred L. Drake, Jr.] > I'd like to commit this for Python 2.5: > > http://www.python.org/sf/1479988 > > The WeakKeyDictionary and WeakValueDictionary don't > provide any API to get just the weakrefs out, instead > of the usual mapping API. This can be desirable when > you want to get a list of everything without creating > new references to the underlying objects at that moment. > > This patch adds methods to make the references > themselves accessible using the API, avoiding requiring > client code to have to depend on the implementation. > The WeakKeyDictionary gains the .iterkeyrefs() and > .keyrefs() methods, and the WeakValueDictionary gains > the .itervaluerefs() and .valuerefs() methods. > > The patch includes tests and docs. +1. A real need for this is explained in ZODB's ZODB/util.py's WeakSet class, which contains a WeakValueDictionary: """ # Return a list of weakrefs to all the objects in the collection. # Because a weak dict is used internally, iteration is dicey (the # underlying dict may change size during iteration, due to gc or # activity from other threads). as_weakref_list() is safe. # # Something like this should really be a method of Python's weak dicts. # If we invoke self.data.values() instead, we get back a list of live # objects instead of weakrefs. If gc occurs while this list is alive, # all the objects move to an older generation (because they're strongly # referenced by the list!). They can't get collected then, until a # less frequent collection of the older generation. Before then, if we # invoke self.data.values() again, they're still alive, and if gc occurs # while that list is alive they're all moved to yet an older generation. # And so on. Stress tests showed that it was easy to get into a state # where a WeakSet grows without bounds, despite that almost all its # elements are actually trash. By returning a list of weakrefs instead, # we avoid that, although the decision to use weakrefs is now very # visible to our clients. def as_weakref_list(self): # We're cheating by breaking into the internals of Python's # WeakValueDictionary here (accessing its .data attribute). return self.data.data.values() """ As that implementation suggests, though, I'm not sure there's real payback for the extra time taken in the patch's `valuerefs` implementation to weed out weakrefs whose referents are already gone: the caller has to make this check anyway when it iterates over the returned list of weakrefs. Iterating inside the implementation, to build the list via itervalues(), also creates that much more vulnerability to "dict changed size during iteration" multi-threading surprises. For that last reason, if the patch went in as-is, I expect ZODB would still need to "cheat"; obtaining the list of weakrefs directly via plain .data.values() is atomic, and so immune to these multi-threading surprises. From guido at python.org Mon May 1 23:05:43 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 14:05:43 -0700 Subject: [Python-Dev] more pyref: a better term for "string conversion" In-Reply-To: <44567593.2010103@v.loewis.de> References: <44567593.2010103@v.loewis.de> Message-ID: Backticks certainly are deprecated -- Py3k won't have them (nor will they become available for other syntax; they are undesirable characters due to font issues and the tendency of word processing tools to generate backticks in certain cases where you type forward ticks). So it would be a good idea to document them as a deprecated syntax for spelling repr(). --Guido On 5/1/06, "Martin v. L?wis" wrote: > Fredrik Lundh wrote: > > for some reason, the language reference uses the term "string con- > > version" for the backtick form of "repr": > > > > http://docs.python.org/ref/string-conversions.html > > > > any suggestions for a better term ? should backticks be deprecated, > > and documented in terms of repr (rather than the other way around) ? > > I vaguely recall that they are deprecated, but I can't remember the > details. The one obvious way to invoke that functionality is the repr() > builtin. > > Regards, > Martin > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From fdrake at acm.org Mon May 1 23:26:34 2006 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Mon, 1 May 2006 17:26:34 -0400 Subject: [Python-Dev] New methods for weakref.Weak*Dictionary types In-Reply-To: <1f7befae0605011357s6427602cnc6ca6a8bfa442ec8@mail.gmail.com> References: <200605011614.30613.fdrake@acm.org> <1f7befae0605011357s6427602cnc6ca6a8bfa442ec8@mail.gmail.com> Message-ID: <200605011726.34659.fdrake@acm.org> On Monday 01 May 2006 16:57, Tim Peters wrote: > +1. A real need for this is explained in ZODB's ZODB/util.py's > WeakSet class, which contains a WeakValueDictionary: ... > As that implementation suggests, though, I'm not sure there's real > payback for the extra time taken in the patch's `valuerefs` > implementation to weed out weakrefs whose referents are already gone: > the caller has to make this check anyway when it iterates over the Good point; I've updated the patch accordingly. -Fred -- Fred L. Drake, Jr. From fredrik at pythonware.com Mon May 1 23:41:54 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 23:41:54 +0200 Subject: [Python-Dev] more pyref: comparison precedence Message-ID: one last one for tonight; the operator precedence summary says that "in" and "not in" has lower precedence than "is" and "is not", which has lower precedence than "<, <=, >, >=, <>, !=, ==": http://docs.python.org/ref/summary.html but the comparisions chapter http://docs.python.org/ref/comparisons.html says that they all have the same priority. which one is right ? From guido at python.org Mon May 1 23:43:43 2006 From: guido at python.org (Guido van Rossum) Date: Mon, 1 May 2006 14:43:43 -0700 Subject: [Python-Dev] more pyref: comparison precedence In-Reply-To: References: Message-ID: They're all the same priority. On 5/1/06, Fredrik Lundh wrote: > one last one for tonight; the operator precedence summary says that > "in" and "not in" has lower precedence than "is" and "is not", which > has lower precedence than "<, <=, >, >=, <>, !=, ==": > > http://docs.python.org/ref/summary.html > > but the comparisions chapter > > http://docs.python.org/ref/comparisons.html > > says that they all have the same priority. which one is right ? > > > > > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From jcarlson at uci.edu Mon May 1 23:50:10 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Mon, 01 May 2006 14:50:10 -0700 Subject: [Python-Dev] methods on the bytes object In-Reply-To: <4456606E.2030100@v.loewis.de> References: <20060501092208.6756.JCARLSON@uci.edu> <4456606E.2030100@v.loewis.de> Message-ID: <20060501144214.6765.JCARLSON@uci.edu> "Martin v. L?wis" wrote: > > Josiah Carlson wrote: > >>> Certainly that is the case. But how would you propose embedded bytes > >>> data be represented? (I talk more extensively about this particular > >>> issue later). > >> Can't answer: I don't know what "embedded bytes data" are. > > Ok. I think I would use base64, of possibly compressed content. It's > more compact than your representation, as it only uses 1.3 characters > per byte, instead of the up-to-four bytes that the img2py uses. I never said it was the most efficient representation, just one that was being used (and one in which I had no control over previously defining). What I provided was automatically generated by a script provided with wxPython. > If ease-of-porting is an issue, img2py should just put an > .encode("latin-1") at the end of the string. Ultimately, this is still the storage of bytes in a textual string. It may be /encoded/ as text, but it is still conceptually bytes in text, which is at least as confusing as text in bytes. > > return zlib.decompress( > > 'x\xda\x01\x14\x02\xeb\xfd\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \ > [...] > > > That data is non-textual. It is bytes within a string literal. And it > > is embedded (within a .py file). > > In Python 2.x, it is that, yes. In Python 3, it is a (meaningless) > text. Toss an .encode('latin-1'), and it isn't meaningless. >>> type(x) >>> zlib.decompress(x.encode('latin-1'))[:4] '\x89PNG' > >>> I am apparently not communicating this particular idea effectively > >>> enough. How would you propose that I store parsing literals for > >>> non-textual data, and how would you propose that I set up a dictionary > >>> to hold some non-trivial number of these parsing literals? > > > > An operationX literal is a symbol that describes how to interpret the > > subsequent or previous data. For an example of this, see the pickle > > module (portions of which I include below). > > I don't think there can be, or should be, a general solution for > all operationX literals, because the different applications of > operationX all have different requirements wrt. their literals. > > In binary data, integers are the most obvious choice for > operationX literals. In text data, string literals are. [snip] > Yes. For pickle, the ordinals of the type code make good operationX > literals. But, as I brought up before, while single integers are sufficient for some operationX literals, that may not be the case for others. Say, for example, a tool which discovers the various blobs from quicktime .mov files (movie portions, audio portions, images, etc.). I don't remember all of the precise names to parse, but I do remember that they were all 4 bytes long. This means that we would generally use the following... dispatch = {(ord(ch), ord(ch), ord(ch), ord(ch)): ..., #or tuple(ord(i) for i in '...'): ..., } And in the actual operationX process... #if we are reading bytes... key = tuple(read(4)) #if we are reading str... key = tuple(bytes(read(4), 'latin-1')) #or tuple(read(4).encode('latin-1')) #or tuple(ord(i) for i in read(4)) There are, of course, other options which could use struct and 8, 16, 32, and/or 64 bit integers (with masks and/or shifts), for the dispatch = ... or key = ... cases, but those, again, would rely on using Python 3.x strings as a container for non-text data. > > I described before how you would use this kind of thing to perform > > operationX on structured information. It turns out that pickle (in > > Python) uses a dictionary of operationX symbols/literals -> unbound > > instance methods to perform operationX on the pickled representation of > > Python objects (literals where XXXX = '...' are defined, and symbols > > using the XXXX names). The relevant code for unpickling is the while 1: > > section of the following. > > Right. I would convert the top of pickle.py to read > > MARK = ord('(') > STOP = ord('.') > ... > > > For an example of where people use '...' to represent non-textual > > information in a literal, see the '# Protocol 2' section of pickle.py ... > > Right. > > > # Protocol 2 > > > > PROTO = '\x80' # identify pickle protocol > > This should be changed to > > PROTO = 0x80 # identify pickle protocol > etc. I see that you don't see ord(...) as a case where strings are being used to hold bytes data. I would disagree, in much the same way that I would disagree with the idea that bytes.encode('base64') only holds text. But then again, I also see that the majority of this "rethink your data structures and dispatching" would be unnecessary if there were an immutable bytes literal in Python 3.x. People could then use... MARK = b'(' STOP = b'.' ... PROTO = b'\x80' ... dispatch = {b'...': fcn} key = read(X) dispatch[X](self) #regardless of X ... etc., as they have already been doing (only without the 'b' or other prefix). > > key = read(1) > > and then this to > key = ord(read(1)) This, of course, presumes that read() will return Python 3.x strings, which may be ambiguous and/or an error in the binary pickle case (especially if people don't pass 'latin-1' as the encoding to the open() call). > > See any line-based socket protocol for where .find() is useful. > > Any line-based protocol is textual, usually based on ASCII. Not all of ASCII 0...127 is text, and the RFC for telnet describes how ASCII 128...255 can be used as optional extensions. Further, the FTP protocol defines a mechanism where by in STREAM or BLOCK modes, data can be terminated by an EOR, EOF, or even a different specified marker (could be multiple contiguous bytes). It is also the case that some filesystems, among other things, define file names as a null-terminated string in a variable-lengthed record, or even pad the remaining portion of the field with nulls (which one would presumably .rstrip('\0') in Python 2.x). (On occasion, I have found the need to write a filesystem explorer which opens volumes raw, especially on platforms without drivers for that particular filesystem). - Josiah From jcarlson at uci.edu Mon May 1 23:52:31 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Mon, 01 May 2006 14:52:31 -0700 Subject: [Python-Dev] methods on the bytes object In-Reply-To: References: <4456606E.2030100@v.loewis.de> Message-ID: <20060501145130.6768.JCARLSON@uci.edu> "Guido van Rossum" wrote: > This discussion seems to have gotten a bit out of hand. I believe it > belongs on the python-3000 list. I accidentally jumped the gun on hitting 'send' on my most recent reply, I'll repost it in the Py3k list and expect further discussion to proceed there. - Josiah From fredrik at pythonware.com Mon May 1 23:55:01 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon, 1 May 2006 23:55:01 +0200 Subject: [Python-Dev] methods on the bytes object References: <20060430231024.674A.JCARLSON@uci.edu> <4455CD18.8030200@v.loewis.de><20060501092208.6756.JCARLSON@uci.edu> <4456606E.2030100@v.loewis.de> Message-ID: Martin v. Löwis wrote: > Ok. I think I would use base64, of possibly compressed content. It's > more compact than your representation, as it only uses 1.3 characters > per byte, instead of the up-to-four bytes that the img2py uses. only if you're shipping your code as PY files. in PYC format (ZIP, PY2EXE, etc), the img2py format is more efficient. From fredrik at pythonware.com Tue May 2 00:01:52 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Tue, 2 May 2006 00:01:52 +0200 Subject: [Python-Dev] more pyref: comparison precedence References: Message-ID: Guido van Rossum wrote: > They're all the same priority. yet another description that is obvious only if you already know what it says, in other words: Operators in the same box have the same precedence. /.../ Operators in the same box group left to right (except for com- parisons, including tests, which all have the same precedence and chain from left to right /.../ I think I'll do something about this one too ;-) From jjl at pobox.com Tue May 2 00:25:57 2006 From: jjl at pobox.com (John J Lee) Date: Mon, 1 May 2006 22:25:57 +0000 (UTC) Subject: [Python-Dev] Assigning "Group" on SF tracker? Message-ID: When opening patches on the SF tracker for bugs that affect Python 2.5, but may be candidates for backporting (to 2.4 ATM), should I leave "Group" as "None", or set it to "Python 2.5" to indicate it affects 2.5? If it's known to be a candidate for backporting, should I set it to "Python 2.4" to indicate that? I'm guessing I should always select "Python 2.5" if it affects 2.5, but I've been using "None" up till now, I think... John From tdelaney at avaya.com Tue May 2 00:52:01 2006 From: tdelaney at avaya.com (Delaney, Timothy (Tim)) Date: Tue, 2 May 2006 08:52:01 +1000 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables Message-ID: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> Greg Ewing wrote: > for x in stuff: > for x in otherstuff: > dosomethingelse(x) > > would be a SyntaxError because the inner loop > is trying to use x while it's still in use by the > outer loop. So would this also be a SyntaxError? for x in stuff: x = somethingelse Tim Delaney From tim.peters at gmail.com Tue May 2 02:41:14 2006 From: tim.peters at gmail.com (Tim Peters) Date: Mon, 1 May 2006 20:41:14 -0400 Subject: [Python-Dev] Assigning "Group" on SF tracker? In-Reply-To: References: Message-ID: <1f7befae0605011741i4541397btf60a1a78c33497b5@mail.gmail.com> [John J Lee] > When opening patches on the SF tracker for bugs that affect Python 2.5, > but may be candidates for backporting (to 2.4 ATM), should I leave "Group" > as "None", or set it to "Python 2.5" to indicate it affects 2.5? > > If it's known to be a candidate for backporting, should I set it to > "Python 2.4" to indicate that? > > I'm guessing I should always select "Python 2.5" if it affects 2.5, but > I've been using "None" up till now, I think... I think it's best to set it to the earliest still-maintained Python version to which it applies. So that would be 2.4 now. The body of the report should say that the problem still exists in 2.5 (assuming it does). Or ;-) you could set it to 2.5, and note in the body that it's also a bug in 2.4. The _helpful_ part is that it be clear the bug exists in both 2.4 and 2.5 (when you know that), so that the next helpful elf doesn't have to figure that out again. From tjreedy at udel.edu Tue May 2 04:12:31 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 1 May 2006 22:12:31 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> Message-ID: ""Martin v. Löwis"" wrote in message news:445644D1.3050200 at v.loewis.de... > You weren't asking for a reason, you were asking for an example: No wonder we weren't connecting very well. You somehow have it backwards. 'Why' means "for what reason". But to continue with examples: my way to call your example (given the data in separate variables): make_person(name, age, phone, location) your way: make_person(name=name, age=age, phone=phone, location = location) my way (given the data in one sequence): make_person(*person_data) your way: make_person(name=person_data[0], age=person_data[2], phone=person_data[3], location=person_data[3]) > Because there should be preferably only one obvious way to call that > function. It is a feature of Python that arguments can usually be matched to parameters either by position or name, as the *caller* chooses. But if you want to (ab)use (my opinion) the 'one obvious way' mantra to disable that , then 'my way' above is obviously the more obvious way to do so ;-). It is to me anyway. Try typing the 'your way' version of the second pair without making and having to correct typos, >Readers of the code should not need to remember the > order of parameters, And they need not; it is right there in front of them. As for writers, modern IDEs should try to list the parameter signature upon typing 'func('. > instead, the meaning of the parameters should > be obvious in the call. With good naming of variables in the calling code, I think it is. > I don't *want* callers to pass these > parameters positionally, to improve readability. The code I write is my code, not yours, and I consider your version to be less readable, as well as harder to type without mistake. Do you think Python should be changed to prohited more that one, or maybe two named positional parameters? Terry Jan Reedy From brett at python.org Tue May 2 04:39:41 2006 From: brett at python.org (Brett Cannon) Date: Mon, 1 May 2006 19:39:41 -0700 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: <20060501192527.GA11018@panix.com> References: <20060501192527.GA11018@panix.com> Message-ID: On 5/1/06, Aahz wrote: > On Mon, May 01, 2006, Brett Cannon wrote: > > > > But there are two things that I can't quite decide upon. > > > > One is whether a signature object should be automatically created > > for every function. As of right now the PEP I am drafting has it > > on a per-need basis and have it assigned to __signature__ through > > a built-in function or putting it 'inspect'. Now automatically > > creating the object would possibly make it more useful, but it > > could also be considered overkill. Also not doing it automatically > > allows signature objects to possibly make more sense for classes (to > > represent __init__) and instances (to represent __call__). But having > > that same support automatically feels off for some reason to me. > > My take is that we should do it automatically and provide a helper > function that does additional work. The class case is already > complicated by __new__(); we probably don't want to automatically sort > out __init__() vs __new__(), but I think we do want regular functions and > methods to automatically have a __signature__ attribute. Aside from the > issue with classes, are there any other drawbacks to automatically > creating __signature__? Well, one issue is the dichotomy between Python and C functions not both providing a signature object. There is no good way to provide a signature object automatically for C functions (at least at the moment; could add the signature string for PyArg_ParseTuple() to the PyMethodDef and have it passed in to the wrapped C function so that initialization of the class can get to the parameters string). So you can't fully rely on the object being available for all functions and methods unless a worthless signature object is placed for C functions. -Brett From aahz at pythoncraft.com Tue May 2 05:49:34 2006 From: aahz at pythoncraft.com (Aahz) Date: Mon, 1 May 2006 20:49:34 -0700 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: References: <20060501192527.GA11018@panix.com> Message-ID: <20060502034934.GA10329@panix.com> On Mon, May 01, 2006, Brett Cannon wrote: > On 5/1/06, Aahz wrote: >>On Mon, May 01, 2006, Brett Cannon wrote: >>> >>> But there are two things that I can't quite decide upon. >>> >>> One is whether a signature object should be automatically created >>> for every function. As of right now the PEP I am drafting has it >>> on a per-need basis and have it assigned to __signature__ through >>> a built-in function or putting it 'inspect'. Now automatically >>> creating the object would possibly make it more useful, but it >>> could also be considered overkill. Also not doing it automatically >>> allows signature objects to possibly make more sense for classes (to >>> represent __init__) and instances (to represent __call__). But having >>> that same support automatically feels off for some reason to me. >> >>My take is that we should do it automatically and provide a helper >>function that does additional work. The class case is already >>complicated by __new__(); we probably don't want to automatically sort >>out __init__() vs __new__(), but I think we do want regular functions and >>methods to automatically have a __signature__ attribute. Aside from the >>issue with classes, are there any other drawbacks to automatically >>creating __signature__? > > Well, one issue is the dichotomy between Python and C functions not > both providing a signature object. There is no good way to provide a > signature object automatically for C functions (at least at the > moment; could add the signature string for PyArg_ParseTuple() to the > PyMethodDef and have it passed in to the wrapped C function so that > initialization of the class can get to the parameters string). So you > can't fully rely on the object being available for all functions and > methods unless a worthless signature object is placed for C functions. >From my POV, that suggests changing the C API rather than not having automatic signatures. That probably requires Py3K, though. -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From tim.peters at gmail.com Tue May 2 07:52:57 2006 From: tim.peters at gmail.com (Tim Peters) Date: Tue, 2 May 2006 01:52:57 -0400 Subject: [Python-Dev] [Python-checkins] r45850 - in python/trunk: Doc/lib/libfuncs.tex Lib/test/test_subprocess.py Misc/NEWS Objects/fileobject.c Python/bltinmodule.c In-Reply-To: <20060502044316.408951E4010@bag.python.org> References: <20060502044316.408951E4010@bag.python.org> Message-ID: <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> > Author: neal.norwitz > Date: Tue May 2 06:43:14 2006 > New Revision: 45850 > > Modified: > python/trunk/Doc/lib/libfuncs.tex > python/trunk/Lib/test/test_subprocess.py > python/trunk/Misc/NEWS > python/trunk/Objects/fileobject.c > python/trunk/Python/bltinmodule.c > Log: > SF #1479181: split open() and file() from being aliases for each other. Umm ... why? I suppose I wouldn't care, except it left test_subprocess failing on all the Windows buildbots, and I don't feel like figuring out why. To a first approximation, test_universal_newlines_communicate() now takes the # Interpreter without universal newline support branch on Windows, but shouldn't. From greg.ewing at canterbury.ac.nz Tue May 2 08:19:33 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 02 May 2006 18:19:33 +1200 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables In-Reply-To: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> Message-ID: <4456F9F5.1050701@canterbury.ac.nz> Delaney, Timothy (Tim) wrote: > So would this also be a SyntaxError? > > for x in stuff: > x = somethingelse That would be something to be debated. I don't really mind much one way or the other. -- Greg From nnorwitz at gmail.com Tue May 2 08:25:47 2006 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 1 May 2006 23:25:47 -0700 Subject: [Python-Dev] [Python-checkins] r45850 - in python/trunk: Doc/lib/libfuncs.tex Lib/test/test_subprocess.py Misc/NEWS Objects/fileobject.c Python/bltinmodule.c In-Reply-To: <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> References: <20060502044316.408951E4010@bag.python.org> <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> Message-ID: On 5/1/06, Tim Peters wrote: > > Author: neal.norwitz > > Date: Tue May 2 06:43:14 2006 > > New Revision: 45850 > > > > Modified: > > python/trunk/Doc/lib/libfuncs.tex > > python/trunk/Lib/test/test_subprocess.py > > python/trunk/Misc/NEWS > > python/trunk/Objects/fileobject.c > > python/trunk/Python/bltinmodule.c > > Log: > > SF #1479181: split open() and file() from being aliases for each other. > > Umm ... why? I suppose I wouldn't care, except it left I'll let Aahz answer that, it's his patch. > test_subprocess failing on all the Windows buildbots, and I don't feel > like figuring out why. To a first approximation, > test_universal_newlines_communicate() now takes the > > # Interpreter without universal newline support > > branch on Windows, but shouldn't. I tried to fix that breakage. n From tim.peters at gmail.com Tue May 2 08:51:13 2006 From: tim.peters at gmail.com (Tim Peters) Date: Tue, 2 May 2006 02:51:13 -0400 Subject: [Python-Dev] [Python-checkins] r45850 - in python/trunk: Doc/lib/libfuncs.tex Lib/test/test_subprocess.py Misc/NEWS Objects/fileobject.c Python/bltinmodule.c In-Reply-To: References: <20060502044316.408951E4010@bag.python.org> <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> Message-ID: <1f7befae0605012351k4655e6ebr1840d4661df3c01e@mail.gmail.com> [Tim] > ... >> test_subprocess failing on all the Windows buildbots [Neal] > I tried to fix that breakage. You succeeded! Thanks. From tim.peters at gmail.com Tue May 2 09:47:42 2006 From: tim.peters at gmail.com (Tim Peters) Date: Tue, 2 May 2006 03:47:42 -0400 Subject: [Python-Dev] [Python-checkins] r45850 - in python/trunk:Doc/lib/libfuncs.tex Lib/test/test_subprocess.py Misc/NEWSObjects/fileobject.c Python/bltinmodule.c In-Reply-To: References: <20060502044316.408951E4010@bag.python.org> <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> Message-ID: <1f7befae0605020047o4c138450vd4dbc1385fa422a9@mail.gmail.com> >>> SF #1479181: split open() and file() from being aliases for each other. >> Umm ... why? [/F] > so that introspection tools can support GvR's pronouncement that "open" > should be used to open files, and "file" should be used as a type representing > standard (current stdio-based) file handles. Maybe some of the intended changes are missing? The post-patch docstrings don't draw this distinction, and I'm lost about what else introspection tools could be looking at to make the distinction (special-casing the names? but they could have done that before): """ >>> print open.__doc__ open(name[, mode[, buffering]]) -> file object Open a file using the file() type, returns a file object. >>> print file.__doc__ file(name[, mode[, buffering]]) -> file object Open a file. The mode can be 'r', 'w' or 'a' for reading (default), writing or appending. The file will be created if it doesn't exist when opened for writing or appending; it will be truncated when opened for writing. Add a 'b' to the mode for binary files. Add a '+' to the mode to allow simultaneous reading and writing. If the buffering argument is given, 0 means unbuffered, 1 means line buffered, and larger numbers specify the buffer size. Add a 'U' to mode to open the file for input with universal newline support. Any line ending in the input file will be seen as a '\n' in Python. Also, a file so opened gains the attribute 'newlines'; the value for this attribute is one of None (no newline read yet), '\r', '\n', '\r\n' or a tuple containing all the newline types seen. 'U' cannot be combined with 'w' or '+' mode. >>> """ In Python 2.4, the docstrings were of course the same (the current trunk's file.__doc__ except for a line at the end). Since all useful info about how to open a file has been purged from open()'s docstring, if you've got the intent right, looks like the implementation got it backwards ;-) OK, maybe this is what you have in mind: >>> type(open) >>> type(file) Fine, if that's all there really is to this, but I think it's a net loss if open()'s docstring regression stands -- someone should finish this job, or it should be reverted. From jcarlson at uci.edu Tue May 2 10:09:40 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Tue, 02 May 2006 01:09:40 -0700 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables In-Reply-To: <4456F9F5.1050701@canterbury.ac.nz> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> <4456F9F5.1050701@canterbury.ac.nz> Message-ID: <20060502010809.677B.JCARLSON@uci.edu> Greg Ewing wrote: > > Delaney, Timothy (Tim) wrote: > > > So would this also be a SyntaxError? > > > > for x in stuff: > > x = somethingelse > > That would be something to be debated. I don't > really mind much one way or the other. for line in lines: line = line.rstrip() ... I'm generally -0 on the "raise a SyntaxError" in this particular case, and am +0 on the double use below: for x in y: for x in z: - Josiah From pedronis at strakt.com Tue May 2 10:25:36 2006 From: pedronis at strakt.com (Samuele Pedroni) Date: Tue, 02 May 2006 10:25:36 +0200 Subject: [Python-Dev] Reminder: call for proposals "Python Language and Libraries Track" for Europython 2006 Message-ID: <44571780.8080808@strakt.com> """ Python Language and Libraries A track about Python the Language, all batteries included. Talks about the language, language evolution, patterns and idioms, implementations (CPython, IronPython, Jython, PyPy ...) and implementation issues belong to the track. So do talks about the standard library or interesting 3rd-party libraries (and frameworks), unless the gravitational pull of other tracks is stronger. """ Of course talks to detail new features in the upcoming 2.5 release are more than welcome. Deadline is 31th of May. The full call and submission links are at: http://www.europython.org/sections/tracks_and_talks/call-for-proposals Thanks, Samuele Pedroni From fredrik at pythonware.com Tue May 2 10:47:08 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Tue, 2 May 2006 10:47:08 +0200 Subject: [Python-Dev] [Python-checkins] r45850 - inpython/trunk:Doc/lib/libfuncs.tex Lib/test/test_subprocess.pyMisc/NEWSObjects/fileobject.c Python/bltinmodule.c References: <20060502044316.408951E4010@bag.python.org><1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> <1f7befae0605020047o4c138450vd4dbc1385fa422a9@mail.gmail.com> Message-ID: Tim Peters wrote: >>>> SF #1479181: split open() and file() from being aliases for each other. > >>> Umm ... why? > > [/F] >> so that introspection tools can support GvR's pronouncement that "open" >> should be used to open files, and "file" should be used as a type representing >> standard (current stdio-based) file handles. > > Maybe some of the intended changes are missing? The post-patch > docstrings don't draw this distinction, and I'm lost about what else > introspection tools could be looking at to make the distinction > (special-casing the names? but they could have done that before): > > """ >>>> print open.__doc__ > open(name[, mode[, buffering]]) -> file object > > Open a file using the file() type, returns a file object. > >>>> print file.__doc__ > file(name[, mode[, buffering]]) -> file object > > Open a file. The mode can be 'r', 'w' or 'a' for reading (default), > writing or appending. The file will be created if it doesn't exist > when opened for writing or appending; it will be truncated when > opened for writing. Add a 'b' to the mode for binary files. > Add a '+' to the mode to allow simultaneous reading and writing. > If the buffering argument is given, 0 means unbuffered, 1 means line > buffered, and larger numbers specify the buffer size. > Add a 'U' to mode to open the file for input with universal newline > support. Any line ending in the input file will be seen as a '\n' > in Python. Also, a file so opened gains the attribute 'newlines'; > the value for this attribute is one of None (no newline read yet), > '\r', '\n', '\r\n' or a tuple containing all the newline types seen. > > 'U' cannot be combined with 'w' or '+' mode. > >>>> > """ > > In Python 2.4, the docstrings were of course the same (the current > trunk's file.__doc__ except for a line at the end). Since all useful > info about how to open a file has been purged from open()'s docstring, > if you've got the intent right, looks like the implementation got it > backwards ;-) agreed. imho, the detailed description should be moved to open, and the file docstring should refer to open for a full description of how the arguments are used. and the open docstring could say something like "returns a file object. in the current version, this is always an instance of the file() type." unless I'm missing something here, of course. (I was asked to review this patch, but those mails arrived around 2 am, so I didn't see them until now...) From ncoghlan at gmail.com Tue May 2 12:13:16 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 02 May 2006 20:13:16 +1000 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> <4455FBFF.3080301@gmail.com> <8D9580FC-95C5-4A15-994C-6F91E31E3F45@fuhm.net> Message-ID: <445730BC.9030708@gmail.com> Guido van Rossum wrote: > On 5/1/06, James Y Knight wrote: >> Don't forget that the majority of users will never have heard any of >> these discussions nor have used 2.5a1 or 2.5a2. Choose the best term >> for them, not for the readers of python-dev. > > I couldn't agree more! (Another thought, occasionally useful,is to > consider that surely the number of Python programs yet to be written, > and the number of Python programmers who yet have to learn the > language, must surely exceed the current count. At least, one would > hope so -- if that's not true, we might as well stop now. :-) If reason 1 had been my only reason for agreeing with Greg, I wouldn't have said anything :) The conflict with 'managed code' and thinking about the number of objects named 'manager' I've seen in different programs were enough to give me pause, though. I've got no real idea as to how we can get a better feel for which terminology would be clearer to people that haven't already been exposed to this topic for months, though :( > Nick, do you have it in you to fix PEP 343? Or at least come up with a > draft patch? We can take this off-linel with all the +0's and +1's > coming in I'm pretty comfortable with this change now, although we > should probably wait until later today to commit. I can handle the PEP (just getting rid of __context__ for now). I'll willingly cede the joy of actually fixing SVN to someone else, though :) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From ncoghlan at gmail.com Tue May 2 12:36:42 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 02 May 2006 20:36:42 +1000 Subject: [Python-Dev] Adding functools.decorator In-Reply-To: References: <4454C203.2060707@iinet.net.au> Message-ID: <4457363A.8050802@gmail.com> Guido van Rossum wrote: > On 4/30/06, Georg Brandl wrote: >> Guido van Rossum wrote: >>> I expect that at some point people will want to tweak what gets copied >>> by _update_wrapper() -- e.g. some attributes may need to be >>> deep-copied, or personalized, or skipped, etc. >> What exactly do you have in mind there? If someone wants to achieve this, >> she can write his own version of @decorator. > > I meant that the provided version should make writing your own easier > than copying the source and editing it. Some form of subclassing might > make sense, or a bunch of smaller functions that can be called for > various actions. You'll probably have to discover some real use cases > before you'll be able to design the right API for this. Maybe we should just expose a basic interface to replace the four lines of boilerplate (the docstring makes this look more complicated than it really is!): WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') WRAPPER_UPDATES = ('__dict__') def update_wrapper(wrapper, wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): """Update a wrapper function to look like the wrapped function Attributes of the wrapped function named in the assigned argument are assigned directly to the corresponding attributes of the wrapper function. The update() method of wrapper function attributes named in the updated argument are called with the corresponding attribute of the wrapped function as their sole argument. """ for attr in assigned: setattr(wrapper, attr, getattr(wrapped, attr)) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr)) The two global constants provide clear documentation of the default behaviour and the keyword arguments make it easy to copy or update a couple of extra arguments if you need to, or to prevent the standard copying. Including the return statement allows this to be used as a decorator if you prefer: from functools import partial, update_wrapper @partial(update_wrapper, func) def wrapper(*args, **kwds): # wrap func here. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From ncoghlan at gmail.com Tue May 2 13:04:06 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 02 May 2006 21:04:06 +1000 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: References: Message-ID: <44573CA6.5010608@gmail.com> Brett Cannon wrote: > One is whether a signature object should be automatically created for > every function. As of right now the PEP I am drafting has it on a > per-need basis and have it assigned to __signature__ through a > built-in function or putting it 'inspect'. Now automatically creating > the object would possibly make it more useful, but it could also be > considered overkill. Also not doing it automatically allows signature > objects to possibly make more sense for classes (to represent > __init__) and instances (to represent __call__). But having that same > support automatically feels off for some reason to me. My current impulse is to put the signature object in the inspect module to start with, and don't give it a special attribute at all. All of the use cases I can think of (introspection for documentation purposes or argument checking purposes) don't really suffer either way regardless of whether the signature retrieval is spelt "obj.__signature__" or "inspect.getsignature(obj)". Since it doesn't make much difference from a usability point of view, let's start with the object in the library module first. > The second question is whether it is worth providing a function that > will either figure out if a tuple and dict representing arguments > would work in calling the function. Some have even suggested a > function that returns the actual bindings if the call were to occur. > Personally I don't see a huge use for either, but even less for the > latter version. If people have a legit use case for either please > speak up, otherwise I am tempted to keep the object simple. A "bind" method on the signature objects is pretty much essential for any kind of argument checking usage. In addition to Aahz's precondition checking example, Talin gave a good example on the Py3k list of a function decorator for logging all calls to a function, and including the argument bindings in the log message. And just in case you think the operation would be easy to implement if you need it, I've included below the bind method from the signature object I wrote to play around with the ideas posted to the Py3k list. It took a fair bit of work to get it to spit out the right answers :) Cheers, Nick. def bind(*args, **kwds): """Return a dict mapping parameter names to bound arguments""" self = args[0] args = args[1:] bound_params = {} num_args = len(args) missing_args = set(self.required_args) arg_names = self.required_args + self.optional_args num_names = len(arg_names) # Handle excess positional arguments if self.extra_args: bound_params[self.extra_args] = tuple(args[num_names:]) elif num_args > num_names: self._raise_args_error(num_args) # Bind positional arguments for name, value in zip(arg_names, args): bound_params[name] = value missing_args -= set((name,)) # Bind keyword arguments (and handle excess) if self.extra_kwds: extra_kwds = dict() bound_params[self.extra_kwds] = extra_kwds else: extra_kwds = None for name, value in kwds.items(): if name in bound_params: raise TypeError( "Got multiple values for argument '%s'" % name) elif name in arg_names: missing_args -= set((name,)) bound_params[name] = value elif extra_kwds is not None: extra_kwds[name] = value else: raise TypeError( "Got unexpected keyword argument '%s'" % name) if missing_args: self._raise_args_error(num_args) # All done return bound_params -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From greg.ewing at canterbury.ac.nz Tue May 2 13:07:33 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 02 May 2006 23:07:33 +1200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> Message-ID: <44573D75.40007@canterbury.ac.nz> Terry Reedy wrote: > my way to call your example (given the data in separate variables): > make_person(name, age, phone, location) > your way: > make_person(name=name, age=age, phone=phone, location = location) For situations like that, I've sometimes thought it would be useful to be able to say something like make_person(=name, =age, =phone, =location) > It is a feature of Python that arguments can usually be matched to > parameters either by position or name, as the *caller* chooses. Except that the caller doesn't always get that option even now, if the callee has chosen to use *args or **kwds. So I wouldn't consider that a very strong argument. > And they need not; it is right there in front of them. As for writers, > modern IDEs should try to list the parameter signature upon typing 'func('. Which is extremely difficult for an IDE to do without static type information. -- Greg From greg.ewing at canterbury.ac.nz Tue May 2 13:13:56 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 02 May 2006 23:13:56 +1200 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables In-Reply-To: <20060502010809.677B.JCARLSON@uci.edu> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> <4456F9F5.1050701@canterbury.ac.nz> <20060502010809.677B.JCARLSON@uci.edu> Message-ID: <44573EF4.9080306@canterbury.ac.nz> Josiah Carlson wrote: > for line in lines: > line = line.rstrip() > ... > > I'm generally -0 on the "raise a SyntaxError" in this particular case, That's a good point. I'm inclined to agree. I think I might have even done something like that recently, but I can't remember the details. > and am +0 on the double use below: > > for x in y: > for x in z: Can anyone think of a plausible use case for that? -- Greg From ncoghlan at gmail.com Tue May 2 13:28:49 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 02 May 2006 21:28:49 +1000 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables In-Reply-To: <44573EF4.9080306@canterbury.ac.nz> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> <4456F9F5.1050701@canterbury.ac.nz> <20060502010809.677B.JCARLSON@uci.edu> <44573EF4.9080306@canterbury.ac.nz> Message-ID: <44574271.7050408@gmail.com> Greg Ewing wrote: > Josiah Carlson wrote: >> and am +0 on the double use below: >> >> for x in y: >> for x in z: > > Can anyone think of a plausible use case for that? This really seems more like the domain of pychecker/pylint rather than the compiler. The code may be a bad idea, but I don't see any reason to make it a syntax error. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From ncoghlan at gmail.com Tue May 2 13:32:15 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 02 May 2006 21:32:15 +1000 Subject: [Python-Dev] global variable modification in functions [Re: elimination of scope bleeding of iteration variables] In-Reply-To: <5.1.1.6.0.20060501112424.03760840@mail.telecommunity.com> References: <445584BB.8090708@666.com> <44532F0B.5050804@666.com> <4454C87A.7020701@gmail.com> <445584BB.8090708@666.com> <5.1.1.6.0.20060501112424.03760840@mail.telecommunity.com> Message-ID: <4457433F.8080306@gmail.com> Phillip J. Eby wrote: > And for the case where the compiler can tell the variable is accessed > before it's defined, there's definitely something wrong. This code, for > example, is definitely missing a "global" and the compiler could in > principle tell: > > foo = 1 > > def bar(): > foo+=1 > > So I see no problem (in principle, as opposed to implementation) with > issuing a warning or even a compilation error for that code. (And it's > wrong even if the snippet I showed is in a nested function definition, > although the error would be different.) > > If I recall correctly, the new compiler uses a control-flow graph that > could possibly be used to determine whether there is a path on which a > local could be read before it's stored. I think symtable.c could wander back up the lexical block stack checking that target names are defined for augmented assignment statements. That said, while I'd be happy to review a patch, I'm not going to try to write one :) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From aahz at pythoncraft.com Tue May 2 16:02:37 2006 From: aahz at pythoncraft.com (Aahz) Date: Tue, 2 May 2006 07:02:37 -0700 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables In-Reply-To: <44574271.7050408@gmail.com> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6AB@au3010avexu1.global.avaya.com> <4456F9F5.1050701@canterbury.ac.nz> <20060502010809.677B.JCARLSON@uci.edu> <44573EF4.9080306@canterbury.ac.nz> <44574271.7050408@gmail.com> Message-ID: <20060502140237.GA8154@panix.com> On Tue, May 02, 2006, Nick Coghlan wrote: > Greg Ewing wrote: >> Josiah Carlson wrote: >>> >>> and am +0 on the double use below: >>> >>> for x in y: >>> for x in z: >> >> Can anyone think of a plausible use case for that? > > This really seems more like the domain of pychecker/pylint rather than > the compiler. The code may be a bad idea, but I don't see any reason > to make it a syntax error. My sentiments precisely. Unless someone can come up with a good reason for changing the current semantics, I'm -1. Side note: if people do want to continue discussing this, I think it should go to python-3000. There is absolutely no reason to break currently-running code that happens to use this pattern. -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From amk at amk.ca Tue May 2 17:32:21 2006 From: amk at amk.ca (A.M. Kuchling) Date: Tue, 2 May 2006 11:32:21 -0400 Subject: [Python-Dev] Date for DC-area Python sprint? Message-ID: <20060502153221.GA29734@rogue.amk.ca> I'm working on setting up a sprint in the Washington DC area; currently I have a lead that would be in Arlington. I'd like to discuss the date on python-dev in order to coordinate with other events. The sprint has no particular goal, so people might just hack on their core-related projects. It certainly doesn't need to be limited to core Python; if space is available, people could certainly come to work on other projects. I'm thinking May 27th might be a good date. The Need For Speed sprint is May 21-28 (Sunday to Sunday), so the DC-area people can coordinate with the other sprinters via IRC. On the 21st the Need For Speed sprinters might be scattered, with people still arriving; on the 28th people will be leaving. The 27th seems like a good compromise (though maybe everyone in Iceland will be burnt out by that point). Also, does someone want to organize a bug day for the same date, or a sprint on the West Coast or in the Midwest? --amk From aahz at pythoncraft.com Tue May 2 16:34:28 2006 From: aahz at pythoncraft.com (Aahz) Date: Tue, 2 May 2006 07:34:28 -0700 Subject: [Python-Dev] [Python-checkins] r45850 - in python/trunk: Doc/lib/libfuncs.tex Lib/test/test_subprocess.py Misc/NEWS Objects/fileobject.c Python/bltinmodule.c In-Reply-To: <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> References: <20060502044316.408951E4010@bag.python.org> <1f7befae0605012252s1c563b04o8ed6a797d2861f87@mail.gmail.com> Message-ID: <20060502143428.GA4605@panix.com> On Tue, May 02, 2006, Tim Peters wrote: > >> Author: neal.norwitz >> Date: Tue May 2 06:43:14 2006 >> New Revision: 45850 >> >> Modified: >> python/trunk/Lib/test/test_subprocess.py >> python/trunk/Objects/fileobject.c >> python/trunk/Python/bltinmodule.c >> Log: >> SF #1479181: split open() and file() from being aliases for each other. > > Umm ... why? I suppose I wouldn't care, except it left > test_subprocess failing on all the Windows buildbots, and I don't feel > like figuring out why. To a first approximation, > test_universal_newlines_communicate() now takes the > > # Interpreter without universal newline support > > branch on Windows, but shouldn't. That's a bug in the Windows implementation or in the docs. test_subprocess failed because open() was no longer an alias for file(); I originally planned to just s/open/file/ but when I read the docs, the docs said that newlines attribute was supposed to go on file objects, not the file type. Neal's decision to use my original idea is probably fine, but I'm not sure. http://docs.python.org/dev/lib/bltin-file-objects.html I'll answer your other post later when I have more time, but you might check http://mail.python.org/pipermail/python-dev/2005-December/thread.html#59073 for the basic history. -- Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ "Argue for your limitations, and sure enough they're yours." --Richard Bach From guido at python.org Tue May 2 16:41:25 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 07:41:25 -0700 Subject: [Python-Dev] More on contextlib - adding back a contextmanager decorator In-Reply-To: <445730BC.9030708@gmail.com> References: <4454BA62.5080704@iinet.net.au> <4455EB14.6000709@canterbury.ac.nz> <4455F415.3040104@gmail.com> <4455FBFF.3080301@gmail.com> <8D9580FC-95C5-4A15-994C-6F91E31E3F45@fuhm.net> <445730BC.9030708@gmail.com> Message-ID: On 5/2/06, Nick Coghlan wrote: > > Nick, do you have it in you to fix PEP 343? Or at least come up with a > > draft patch? We can take this off-linel with all the +0's and +1's > > coming in I'm pretty comfortable with this change now, although we > > should probably wait until later today to commit. > > I can handle the PEP (just getting rid of __context__ for now). I'll willingly > cede the joy of actually fixing SVN to someone else, though :) OK, if you fix the PEP, I'll fix the code to match; I added most of those __context__ methods so I can delete them. Unless someone else beats me to it. :-) -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Tue May 2 16:42:07 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 07:42:07 -0700 Subject: [Python-Dev] Adding functools.decorator In-Reply-To: <4457363A.8050802@gmail.com> References: <4454C203.2060707@iinet.net.au> <4457363A.8050802@gmail.com> Message-ID: On 5/2/06, Nick Coghlan wrote: > Maybe we should just expose a basic interface to replace the four lines of > boilerplate (the docstring makes this look more complicated than it really is!): +1 -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Tue May 2 16:44:00 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 07:44:00 -0700 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <44573D75.40007@canterbury.ac.nz> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> Message-ID: On 5/2/06, Greg Ewing wrote: > Terry Reedy wrote: > > > my way to call your example (given the data in separate variables): > > make_person(name, age, phone, location) > > your way: > > make_person(name=name, age=age, phone=phone, location = location) > > For situations like that, I've sometimes thought > it would be useful to be able to say something like > > make_person(=name, =age, =phone, =location) And even with Terry's use case quoted I can't make out what you meant that to do. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From g.brandl at gmx.net Tue May 2 19:10:36 2006 From: g.brandl at gmx.net (Georg Brandl) Date: Tue, 02 May 2006 19:10:36 +0200 Subject: [Python-Dev] more pyref: a better term for "string conversion" In-Reply-To: References: <44567593.2010103@v.loewis.de> Message-ID: Guido van Rossum wrote: > Backticks certainly are deprecated -- Py3k won't have them (nor will > they become available for other syntax; they are undesirable > characters due to font issues and the tendency of word processing > tools to generate backticks in certain cases where you type forward > ticks). And would it be acceptable for 2.5 to issue a DeprecationWarning for backticks? Georg From rhettinger at ewtllc.com Tue May 2 19:24:33 2006 From: rhettinger at ewtllc.com (Raymond Hettinger) Date: Tue, 02 May 2006 10:24:33 -0700 Subject: [Python-Dev] more pyref: a better term for "string conversion" In-Reply-To: References: <44567593.2010103@v.loewis.de> Message-ID: <445795D1.8050403@ewtllc.com> Georg Brandl wrote: >Guido van Rossum wrote: > > >>Backticks certainly are deprecated -- Py3k won't have them (nor will >>they become available for other syntax; they are undesirable >>characters due to font issues and the tendency of word processing >>tools to generate backticks in certain cases where you type forward >>ticks). >> >> > >And would it be acceptable for 2.5 to issue a DeprecationWarning for >backticks? > > > No. Backticks do not disappear until Py3.0 and we're not going to muck-up the 2.x series with warnings and deprecations for everything that is going to change in Py3.0. Raymond From guido at python.org Tue May 2 19:29:07 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 10:29:07 -0700 Subject: [Python-Dev] test failures in test_ctypes (HEAD) Message-ID: I see test failures in current HEAD on my Google Red Hat Linux desktop that the buildbots don't seem to have: ./python -E -tt ../Lib/test/regrtest.py test_ctypes test_ctypes test test_ctypes failed -- errors occurred; run in verbose mode for details More details from running this manually: $ ./python ../Lib/test/test_ctypes.py . . (lots of passing tests; then:) . test_gl (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR test_glu (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR test_glut (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR ====================================================================== ERROR: test_gl (ctypes.test.test_find.Test_OpenGL_libs) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/guido/projects/python/trunk/Lib/ctypes/test/test_find.py", line 42, in setUp self.glut = CDLL(lib_glut) File "/home/guido/projects/python/trunk/Lib/ctypes/__init__.py", line 288, in __init__ self._handle = _dlopen(self._name, mode) OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion ====================================================================== ERROR: test_glu (ctypes.test.test_find.Test_OpenGL_libs) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/guido/projects/python/trunk/Lib/ctypes/test/test_find.py", line 42, in setUp self.glut = CDLL(lib_glut) File "/home/guido/projects/python/trunk/Lib/ctypes/__init__.py", line 288, in __init__ self._handle = _dlopen(self._name, mode) OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion ====================================================================== ERROR: test_glut (ctypes.test.test_find.Test_OpenGL_libs) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/guido/projects/python/trunk/Lib/ctypes/test/test_find.py", line 42, in setUp self.glut = CDLL(lib_glut) File "/home/guido/projects/python/trunk/Lib/ctypes/__init__.py", line 288, in __init__ self._handle = _dlopen(self._name, mode) OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion ---------------------------------------------------------------------- This seems libglut related -- I don't know what that is but find /lib /usr/lib -name \*glut\* produces this output: /usr/lib/libglut.so.3 /usr/lib/libglut.so.3.7 -- --Guido van Rossum (home page: http://www.python.org/~guido/) From benji at zope.com Tue May 2 19:34:52 2006 From: benji at zope.com (Benji York) Date: Tue, 02 May 2006 13:34:52 -0400 Subject: [Python-Dev] Positional-only Arguments Message-ID: <4457983C.5080109@zope.com> I've not followed the PEP 3102 (keyword-only arguments) discussion closely enough to know if this has been mentioned, but we were discussing a need at work today for the ability to enforce position-only arguments. The specific instance was an argument that was intended to be used as a positional argument which a group had began using as a keyword argument instead. There was no way for the users to know it was intended for positional use only. And it makes refactoring the signature difficult. Of course you could use *args from the get-go, but ugly signatures as default isn't nice. Is there any reason to pursue the idea, or this mostly a misguided desire for symmetry? -- Benji York From g.brandl at gmx.net Tue May 2 19:46:56 2006 From: g.brandl at gmx.net (Georg Brandl) Date: Tue, 02 May 2006 19:46:56 +0200 Subject: [Python-Dev] test failures in test_ctypes (HEAD) In-Reply-To: References: Message-ID: Guido van Rossum wrote: > I see test failures in current HEAD on my Google Red Hat Linux desktop > that the buildbots don't seem to have: > > ./python -E -tt ../Lib/test/regrtest.py test_ctypes > test_ctypes > test test_ctypes failed -- errors occurred; run in verbose mode for details > > More details from running this manually: > $ ./python ../Lib/test/test_ctypes.py > . > . (lots of passing tests; then:) > . > test_gl (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > test_glu (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > test_glut (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > > ====================================================================== > ERROR: test_gl (ctypes.test.test_find.Test_OpenGL_libs) > ---------------------------------------------------------------------- > Traceback (most recent call last): > File "/home/guido/projects/python/trunk/Lib/ctypes/test/test_find.py", > line 42, in setUp > self.glut = CDLL(lib_glut) > File "/home/guido/projects/python/trunk/Lib/ctypes/__init__.py", > line 288, in __init__ > self._handle = _dlopen(self._name, mode) > OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion You might be interested in https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1478253&group_id=5470 Georg From ark at acm.org Tue May 2 19:55:03 2006 From: ark at acm.org (Andrew Koenig) Date: Tue, 2 May 2006 13:55:03 -0400 Subject: [Python-Dev] Any reason that any()/all() do not takea predicateargument? In-Reply-To: <4440B49C.7040902@sweetapp.com> Message-ID: <002401c66e11$8d352e90$6402a8c0@arkdesktop> > > How about this? > > > > if any(x==5 for x in seq): > > Aren't all of these equivalent to: > > if 5 in seq: > ... Of course. However, the original example was pretty clearly intended to be an illustrative instance of a more general problem. Rewriting the example as any(x==5 for x in seq) preserves the generality; rewriting it as 5 in seq doesn't. From theller at python.net Tue May 2 19:57:32 2006 From: theller at python.net (Thomas Heller) Date: Tue, 02 May 2006 19:57:32 +0200 Subject: [Python-Dev] test failures in test_ctypes (HEAD) In-Reply-To: References: Message-ID: <44579D8C.6080808@python.net> Guido van Rossum wrote: > I see test failures in current HEAD on my Google Red Hat Linux desktop > that the buildbots don't seem to have: > > ./python -E -tt ../Lib/test/regrtest.py test_ctypes > test_ctypes > test test_ctypes failed -- errors occurred; run in verbose mode for details > > More details from running this manually: > $ ./python ../Lib/test/test_ctypes.py > . > . (lots of passing tests; then:) > . > test_gl (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > test_glu (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > test_glut (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR Can you try this patch for Lib/ctypes/test/test_find, please? Index: test_find.py =================================================================== --- test_find.py (Revision 45791) +++ test_find.py (Arbeitskopie) @@ -39,9 +39,9 @@ if lib_glu: self.glu = CDLL(lib_glu, RTLD_GLOBAL) if lib_glut: - self.glut = CDLL(lib_glut) + self.glut = CDLL(lib_glut, RTLD_GLOBAL) if lib_gle: - self.gle = CDLL(lib_gle) + self.gle = CDLL(lib_gle, RTLD_GLOBAL) if lib_gl: def test_gl(self): The test should try to test the RTLD_GLOBAL flag for loading shared libs. (The patch is pure guesswork, inspired by a recent thread on the ctypes-users list. It would be great if someone could provide some insight into this, or suggest a better test). Thomas From brett at python.org Tue May 2 20:43:56 2006 From: brett at python.org (Brett Cannon) Date: Tue, 2 May 2006 11:43:56 -0700 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: <44573CA6.5010608@gmail.com> References: <44573CA6.5010608@gmail.com> Message-ID: On 5/2/06, Nick Coghlan wrote: > Brett Cannon wrote: > > One is whether a signature object should be automatically created for > > every function. As of right now the PEP I am drafting has it on a > > per-need basis and have it assigned to __signature__ through a > > built-in function or putting it 'inspect'. Now automatically creating > > the object would possibly make it more useful, but it could also be > > considered overkill. Also not doing it automatically allows signature > > objects to possibly make more sense for classes (to represent > > __init__) and instances (to represent __call__). But having that same > > support automatically feels off for some reason to me. > > My current impulse is to put the signature object in the inspect module to > start with, and don't give it a special attribute at all. > > All of the use cases I can think of (introspection for documentation purposes > or argument checking purposes) don't really suffer either way regardless of > whether the signature retrieval is spelt "obj.__signature__" or > "inspect.getsignature(obj)". > It does for decorators. How do you make sure that a decorator uses the signature object of the wrapped function instead of the decorator? Or are you saying to just not worry about that right now? > Since it doesn't make much difference from a usability point of view, let's > start with the object in the library module first. > > > The second question is whether it is worth providing a function that > > will either figure out if a tuple and dict representing arguments > > would work in calling the function. Some have even suggested a > > function that returns the actual bindings if the call were to occur. > > Personally I don't see a huge use for either, but even less for the > > latter version. If people have a legit use case for either please > > speak up, otherwise I am tempted to keep the object simple. > > A "bind" method on the signature objects is pretty much essential for any kind > of argument checking usage. > > In addition to Aahz's precondition checking example, Talin gave a good example > on the Py3k list of a function decorator for logging all calls to a function, > and including the argument bindings in the log message. > > And just in case you think the operation would be easy to implement if you > need it, I've included below the bind method from the signature object I wrote > to play around with the ideas posted to the Py3k list. It took a fair bit of > work to get it to spit out the right answers :) > Thanks, Nick! -Brett > Cheers, > Nick. > > def bind(*args, **kwds): > """Return a dict mapping parameter names to bound arguments""" > self = args[0] > args = args[1:] > bound_params = {} > num_args = len(args) > missing_args = set(self.required_args) > arg_names = self.required_args + self.optional_args > num_names = len(arg_names) > # Handle excess positional arguments > if self.extra_args: > bound_params[self.extra_args] = tuple(args[num_names:]) > elif num_args > num_names: > self._raise_args_error(num_args) > # Bind positional arguments > for name, value in zip(arg_names, args): > bound_params[name] = value > missing_args -= set((name,)) > # Bind keyword arguments (and handle excess) > if self.extra_kwds: > extra_kwds = dict() > bound_params[self.extra_kwds] = extra_kwds > else: > extra_kwds = None > for name, value in kwds.items(): > if name in bound_params: > raise TypeError( > "Got multiple values for argument '%s'" % name) > elif name in arg_names: > missing_args -= set((name,)) > bound_params[name] = value > elif extra_kwds is not None: > extra_kwds[name] = value > else: > raise TypeError( > "Got unexpected keyword argument '%s'" % name) > if missing_args: > self._raise_args_error(num_args) > # All done > return bound_params > > > -- > Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia > --------------------------------------------------------------- > http://www.boredomandlaziness.org > From tjreedy at udel.edu Tue May 2 21:46:56 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 2 May 2006 15:46:56 -0400 Subject: [Python-Dev] Positional-only Arguments References: <4457983C.5080109@zope.com> Message-ID: "Benji York" wrote in message news:4457983C.5080109 at zope.com... > I've not followed the PEP 3102 (keyword-only arguments) discussion > closely enough to know if this has been mentioned, but we were > discussing a need at work today for the ability to enforce position-only > arguments. You could discourage name use by not documenting the actual, internal name of the parameters. Something like def weather_guess(temp, pres): '''Guess weather from temperature in degrees Kelvin and pressure in millibars passed by position in that order.''' Terry Jan Reedy From guido at python.org Tue May 2 21:48:25 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 12:48:25 -0700 Subject: [Python-Dev] Positional-only Arguments In-Reply-To: References: <4457983C.5080109@zope.com> Message-ID: I've used a double leading underscore on the name. Works great for methods! On 5/2/06, Terry Reedy wrote: > > "Benji York" wrote in message > news:4457983C.5080109 at zope.com... > > I've not followed the PEP 3102 (keyword-only arguments) discussion > > closely enough to know if this has been mentioned, but we were > > discussing a need at work today for the ability to enforce position-only > > arguments. > > You could discourage name use by not documenting the actual, internal name > of the parameters. Something like > > def weather_guess(temp, pres): > '''Guess weather from temperature in degrees Kelvin and pressure > in millibars passed by position in that order.''' > > Terry Jan Reedy > > > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (home page: http://www.python.org/~guido/) From rowen at cesmail.net Tue May 2 22:22:45 2006 From: rowen at cesmail.net (Russell E. Owen) Date: Tue, 02 May 2006 13:22:45 -0700 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> Message-ID: In article , "Guido van Rossum" wrote: > On 5/2/06, Greg Ewing wrote: > > Terry Reedy wrote: > > > > > my way to call your example (given the data in separate variables): > > > make_person(name, age, phone, location) > > > your way: > > > make_person(name=name, age=age, phone=phone, location = location) > > > > For situations like that, I've sometimes thought > > it would be useful to be able to say something like > > > > make_person(=name, =age, =phone, =location) > > And even with Terry's use case quoted I can't make out what you meant > that to do. I'm pretty sure he wants it to mean: make_person(name=name, age=age, phone=phone, location=location). In other words it's a shortcut to avoid needless repetition. Personally I'd like some way to do that, but the initial "=" is pretty startling at first glance. Not that I have a better suggestion. As far as the rest of the thread goes (and I may be late to the party on this), I personally would *love* to be able to write: def func(arg0, arg1, *args, key1=def1) and force key1 to be specified by name. I've coded this before using **kargs for the keyword-only args, but I'd much rather be able to list them in the def (making it more self-documenting). But that's as far as I'd take it. I don't see the point to keyword-only arguments that do not have default values. And I don't think it's worth the potential confusion to allow keyword-only args after a fixed # of positional args. The proposed syntax reads like exactly the wrong thing to me; "|" as a separator might do if one is desperate enough for this feature, i.e.: def foo(arg0, arg1 | karg=None): -- Russell From benji at benjiyork.com Tue May 2 22:59:06 2006 From: benji at benjiyork.com (Benji York) Date: Tue, 02 May 2006 16:59:06 -0400 Subject: [Python-Dev] Positional-only Arguments In-Reply-To: References: <4457983C.5080109@zope.com> Message-ID: <4457C81A.3050104@benjiyork.com> Terry Reedy wrote: > You could discourage name use by not documenting the actual, internal name > of the parameters. The issue we had was that the name wasn't documented at all, the users simply looked at the code and began using the keyword name. This may well be an area where "we're all adults here" wins. OTOH there is a /slight/ possibility that it'd be better to disallow using an argument as a keyword unless explicitly flagged as such. Similar to how the C API works now. This has the same advantages of the keyword-only PEP (3102): tools will know which arguments are positional and which are keyword. Doing so would recast PEP 3102 from "how to get a keyword-only argument" into "how to get a keyword (non-positional) argument". A downside would be the need to specify when an argument can be positional *or* keyword. -- Benji York From benji at benjiyork.com Tue May 2 23:01:50 2006 From: benji at benjiyork.com (Benji York) Date: Tue, 02 May 2006 17:01:50 -0400 Subject: [Python-Dev] Positional-only Arguments In-Reply-To: References: <4457983C.5080109@zope.com> Message-ID: <4457C8BE.8030208@benjiyork.com> Guido van Rossum wrote: > I've used a double leading underscore on the name. Works great for methods! We discussed that. My main issue with that is that it's possible/likely that all arguments should be positional by default, should they all then begin with underscores? Makes for ugly function bodies (or lots of name rebinding). -- Benji York From guido at python.org Tue May 2 23:49:28 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 14:49:28 -0700 Subject: [Python-Dev] mail to talin is bouncing Message-ID: Sorry to bother the list -- talin, mail to you is bouncing: ----- The following addresses had permanent fatal errors ----- ----- Transcript of session follows ----- ... while talking to viridia.org >>> RCPT To: <<< 550 message to verify they are valid." -- --Guido van Rossum (home page: http://www.python.org/~guido/) From tdelaney at avaya.com Wed May 3 00:29:43 2006 From: tdelaney at avaya.com (Delaney, Timothy (Tim)) Date: Wed, 3 May 2006 08:29:43 +1000 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables Message-ID: <2773CAC687FD5F4689F526998C7E4E5FF1E6B3@au3010avexu1.global.avaya.com> Josiah Carlson wrote: > for line in lines: > line = line.rstrip() > ... Exactly the use case I was thinking of (and one I used yesterday BTW). I'm -1 on *dis*allowing reusing a name bound in a for loop in any construct i.e. +1 for the status quo. Tim Delaney From noamraph at gmail.com Wed May 3 01:02:14 2006 From: noamraph at gmail.com (Noam Raphael) Date: Wed, 3 May 2006 02:02:14 +0300 Subject: [Python-Dev] Alternative path suggestion Message-ID: Hello, I saw the discussion about including the path type in the standard library. As it turned out, I recently wrote a program which does quite a lot of path manipulation. This caused me to think that the proposed path module: * Makes path manipulation significantly easier * Can be improved. So I tried to write my version of it. My basic problem with the current proposed path module is that it's a bit... messy. It contains a lot of methods, collected from various modules, and for me it looks too crowded - there are too many methods and too many details for me to easily learn. So I tried to organize it all. I think that the result may make file and path manipulation really easier. Here are my ideas. It's a copy of what I posted a few minutes ago in the wiki - you can view it at http://wiki.python.org/moin/AlternativePathClass (it looks better there). You can find the implementation at http://wiki.python.org/moin/AlternativePathModule?action=raw (By the way, is there some "code wiki" available? It can simply be a public svn repository. I think it will be useful for those things.) All these are ideas - I would like to hear what you think about them. = Major Changes = == a tuple instead of a string == The biggest conceptual change is that my path object is a subclass of ''tuple'', not a subclass of str. For example, {{{ >>> tuple(path('a/b/c')) ('a', 'b', 'c') >>> tuple(path('/a/b/c')) (path.ROOT, 'a', 'b', 'c') }}} This means that path objects aren't the string representation of a path; they are a ''logical'' representation of a path. Remember why a filesystem path is called a path - because it's a way to get from one place on the filesystem to another. Paths can be relative, which means that they don't define from where to start the walk, and can be not relative, which means that they do. In the tuple representation, relative paths are simply tuples of strings, and not relative paths are tuples of strings with a first "root" element. The advantage of using a logical representation is that you can forget about the textual representation, which can be really complex. You don't have to call normpath when you're unsure about how a path looks, you don't have to search for seps and altseps, and... you don't need to remember a lot of names of functions or methods. To show that, take a look at those methods from the original path class and their equivalent in my path class: {{{ p.normpath() -> Isn't needed - done by the constructor p.basename() -> p[-1] p.splitpath() -> (p[:-1], p[-1]) p.splitunc() -> (p[0], p[1:]) (if isinstance(p[0], path.UNCRoot)) p.splitall() -> Isn't needed p.parent -> p[:-1] p.name -> p[-1] p.drive -> p[0] (if isinstance(p[0], path.Drive)) p.uncshare -> p[0] (if isinstance(p[0], path.UNCRoot)) and of course: p.join(q) [or anything like it] -> p + q }}} The only drawback I can see in using a logical representation is that giving a path object to functions which expect a path string won't work. The immediate solution is to simply use str(p) instead of p. The long-term solution is to make all related functions accept a path object. Having a logical representation of a path calls for a bit of term clearing-up. What's an absolute path? On POSIX, it's very simple: a path starting with a '/'. But what about Windows? Is "\temp\file" an absolute path? I claim that it isn't really. The reason is that if you change the current working directory, its meaning changes: It's now not "c:\temp\file", but "a:\temp\file". The same goes for "c:temp\file". So I decided on these two definitions: * A ''relative path'' is a path without a root element, so it can be concatenated to other paths. * An ''absolute path'' is a path whose meaning doesn't change when the current working directory changes. This means that paths starting with a drive letter alone (!UnrootedDrive instance, in my module) and paths starting with a backslash alone (the CURROOT object, in my module) are not relative and not absolute. I really think that it's a better way to handle paths. If you want an example, compare the current implementation of relpathto and my implementation. == Easier attributes for stat objects == The current path objects includes: * isdir, isfile, islink, and - * atime, mtime, ctime, size. The first line does file mode checking, and the second simply gives attributes from the stat object. I suggest that these should be added to the stat_result object. isdir, isfile and islink are true if a specific bit in st_mode is set, and atime, mtime, ctime and size are simply other names for st_atime, st_mtime, st_ctime and st_size. It means that instead of using the atime, mtime etc. methods, you will write {{{ p.stat().atime }}}, {{{ p.stat().size }}}, etc. This is good, because: * If you want to make only one system call, it's very easy to save the stat object and use it. * If you have to deal with symbolic links, you can simply use {{{ p.lstat().mtime }}}. Yes, symbolic links have a modification time. The alternative is to add three methods with ugly names (latime, lmtime, lctime) or to have an incomplete interface without a good reason. I think that isfile, isdir should be kept (along with lisfile, lisdir), since I think that doing what they do is quite common, and requires six lines: {{{ try: st = p.stat() except OSError: return False else: return st.isdir }}} I think that still, isdir, isfile and islink should be added to stat_result objects: They turned out pretty useful in writing some of the more complex path methods. == One Method for Finding Files == (They're actually two, but with exactly the same interface). The original path object has these methods for finding files: {{{ def listdir(self, pattern = None): ... def dirs(self, pattern = None): ... def files(self, pattern = None): ... def walk(self, pattern = None): ... def walkdirs(self, pattern = None): ... def walkfiles(self, pattern = None): ... def glob(self, pattern): }}} I suggest one method that replaces all those: {{{ def glob(self, pattern='*', topdown=True, onlydirs=False, onlyfiles=False): ... }}} pattern is the good old glob pattern, with one additional extension: "**" matches any number of subdirectories, including 0. This means that '**' means "all the files in a directory", '**/a' means "all the files in a directory called a", and '**/a*/**/b*' means "all the files in a directory whose name starts with 'b' and the name of one of their parent directories starts with 'a'". onlydirs and onlyfiles filter the results (they can't be combined, of course). topdown has the same meaning as in os.walk (it isn't supported by the original path class). So, let's show how these methods can be replaced: {{{ p.listdir() -> p.glob() p.dirs() -> p.glob(onlydirs=1) p.files() -> p.glob(onlyfiles=1) p.walk() -> p.glob('**') p.walkdirs() -> p.glob('**', onlydirs=1) p.walkfiles() -> p.glob('**', onlyfiles=1) p.glob(patt) -> p.glob(patt) }}} Now, for the promised additional method. The current implementation of glob doesn't follow symbolic links. In my implementation, there's "lglob", which does what the current glob does. However, the (default) glob does follow symbolic links. To avoid infinite recursion, it keeps the set of filesystem ids on the current path, and checks each dir to see if it was already encountered. (It does so only if there's '**' in the pattern, because otherwise a finite number of results is guaranteed.) Note that it doesn't keep the ids of all the files traversed, only those on the path from the base node to the current node. This means that as long as there're no cycles, everything will go fine - for example, 'a' and 'b' pointing at the same dir will just cause the same files to be reported twice, once under 'a' and once under 'b'. One last note: On windows there are no file ids, but there are no symbolic links, so everything is fine. Oh, and it returns an iterator, not a list. == Separation of Calculations and System Calls == I like to know when I'm using system calls and when I don't. It turns out that using tuples instead of strings makes it possible to define all operations which do not use system calls as properties or operators, and all operations which do use system calls as methods. The only exception currently is .match(). What can I do? == Reduce the Number of Methods == I think that the number of methods should be reduced. The most obvious example are the copy functions. In the current proposal: {{{ def copyfile(self, dst): ... def copymode(self, dst): ... def copystat(self, dst): ... def copy(self, dst): ... def copy2(self, dst): ... }}} In my proposal: {{{ def copy(self, dst, copystat=False): ... }}} It's just that I think that copyfile, copymode and copystat aren't usually useful, and there's no reason not to unite copy and copy2. = Other Changes = Here is a list of the smaller things I've changed in my proposal. The current normpath removes '..' with the name before them. I didn't do that, because it doesn't return an equivalent path if the path before the '..' is a symbolic link. I removed the methods associated with file extensions. I don't recall using them, and since they're purely textual and not OS-dependent, I think that you can always do p[-1].rsplit('.', 1). I removed renames. Why not use makedirs, rename, removedirs? I removed unlink. It's an alias to remove, as far as I know. I removed expand. There's no need to use normpath, so it's equivalent to .expanduser().expandvars(), and I think that the explicit form is better. removedirs - I added another argument, basedir, which won't be removed even if it's empty. I also allowed the first directory to be unempty (I required that it should be a directory). This version is useful for me. readlinkabs - The current path class returns abspath(readlink). This is meaningless - symbolic links are interpreted relative to the directory they are in, not relative the the current working directory of the program. Instead, I wrote readlinkpath, which returns the correct path object. However, I'm not sure if it's needed - why not use realpath()? copytree - I removed it. In shutil it's documented as being mostly a demonstration, and I'm not sure if it's really useful. symlink - Instead of a function like copy, with the destination as the second (actually, the only) argument, I wrote "writelink", which gets a string and creates a symbolic link with that value. The reason is that symbolic links can be any string, not necessarily a legal path. I added mknod and mkfifo, which from some reason weren't there. I added chdir, which I don't see why shouldn't be defined. relpathto - I used realpath() instead of abspath(). abspath() may be incorrect if some of the dirs are symlinks. I removed relpath. It doesn't seem useful to me, and I think that writing path.cwd().relpathto(p) is easy enough. join - I decided that p+q should only work if q is a relative path. In my first implementation, it returned q, which is consistent with the current os.path.join(). However, I think that in the spirit of "explicit is better than implicit", a code like {{{ if q.isrel: return p + q else: return q }}} is pretty easy and pretty clear. I think that many times you want q to be relative, so an exception if it isn't would be helpful. I also think that it's nice that {{{ len(p+q) == len(p) + len(q) }}}. match - The current implementation matches the base name of the path against a pattern. My implementation matches a relative path against a pattern, which is also a relative path (it's of the same form as the pattern of glob - may include '**') matchcase - I removed it. If you see a reason for keeping it, tell me. = Comparison to the Current Path Class = Here's a comparison of doing things using the current path class and doing things using my proposed path class. {{{ # Operations on path strings: p.cwd() -> p.cwd() p.abspath() -> p.abspath() p.normcase() -> p.normcase Also added p.normcasestr, to normalize path elements. p.normpath() -> Unneeded p.realpath() -> p.realpath() p.expanduser() -> p.expanduser() p.expandvars() -> p.expandvars() p.basename() -> p[-1] p.expand() -> p.expanduser().expandvars() p.splitpath() -> Unneeded p.stripext() -> p[-1].rsplit('.', 1)[0] p.splitunc() -> Unneeded p.splitall() -> Unneeded p.relpath() -> path.cwd().relpathto(p) p.relpathto(dst) -> p.relpathto(dst) # Properties about the path: p.parent -> p[:-1] p.name -> p[-1] p.ext -> ''.join(p[-1].rsplit('.', 1)[1:]) p.drive -> p[0] if p and isinstance(p[0], path.Drive) else None p.namebase -> p[-1].rsplit('.', 1)[0] p.uncshare -> p[0] if p and isinstance(p[0], path.UNCRoot) else None # Operations that return lists of paths: p.listdir() -> p.glob() p.listdir(patt)-> p.glob(patt) p.dirs() -> p.glob(onlydirs=1) p.dirs(patt) -> p.glob(patt, onlydirs=1) p.files() -> p.glob(onlyfiles=1) p.files(patt) -> p.glob(patt, onlyfiles=1) p.walk() -> p.glob('**') p.walk(patt) -> p.glob('**/patt') p.walkdirs() -> p.glob('**', onlydirs=1) p.walkdirs(patt) -> p.glob('**/patt', onlydirs=1) p.walkfiles() -> p.glob('**', onlyfiles=1) p.walkfiles(patt) -> p.glob('**/patt', onlyfiles=1) p.match(patt) -> p[-1:].match(patt) (The current match matches the base name. My matches a relative path) p.matchcase(patt) -> Removed p.glob(patt) -> p.glob(patt) # Methods for retrieving information about the filesystem # path: p.exists() -> p.exists() Added p.lexists() p.isabs() -> not p.isrel (That's the meaning of the current isabs().) Added p.isabs p.isdir() -> p.isdir() Added p.lisdir() p.isfile() -> p.isfile() Added p.lisfile() p.islink() -> p.islink() p.ismount() -> p.ismount() p.samefile(other) -> p.samefile(other) p.getatime() -> p.stat().atime p.getmtime() -> p.stat().mtime p.getctime() -> p.stat().ctime p.getsize() -> p.stat().size p.access(mode) -> p.access(mode) p.stat() -> p.stat() p.lstat() -> p.lstat() p.statvfs() -> p.statvfs() p.pathconf(name) -> p.pathconf(name) # Filesystem properties for path. atime, mtime, ctime, size - Removed # Methods for manipulating information about the filesystem # path. utime, chmod, chown, rename - unchanged p.renames(new) -> new[:-1].makedirs(); p.rename(new); p[:-1].removedirs() # Create/delete operations on directories mkdir, makedirs, rmdir, removedirs - unchanged (added an option to removedirs) # Modifying operations on files touch, remove - unchanged unlink - removed # Modifying operations on links p.link(newpath) -> p.link(newpath) p.symlink(newlink) -> newlink.writelink(p) p.readlink() -> p.readlink() p.readlinkabs() -> p.readlinkpath() # High-level functions from shutil copyfile, copymode, copystat, copytree - removed p.copy(dst) -> p.copy(dst) p.copy2(dst) -> p.copt(dst, copystat=1) move, rmtree - unchanged. # Special stuff from os chroot, startfile - unchanged. }}} = Open Issues = Unicode - I have no idea about unicode paths. My current implementation simply uses str. This should be changed, I guess. Slash-terminated paths - In my current implementation, paths ending with a slash are normalized to paths without a slash (this is also the behaviour of os.path.normpath). However, they aren't really the same: stat() on paths ending with a slash fails if they aren't directories, and lstat() treats them as directories even if they are symlinks. Perhaps a final empty string should be allowed. = Finally = Please say what you think, either here or on the wiki. Not every change that I suggested must be accepted, but I would be happy if they were considered. I hope it proves useful. Noam From guido at python.org Wed May 3 01:46:43 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 16:46:43 -0700 Subject: [Python-Dev] elimination of scope bleeding ofiteration variables In-Reply-To: <2773CAC687FD5F4689F526998C7E4E5FF1E6B3@au3010avexu1.global.avaya.com> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6B3@au3010avexu1.global.avaya.com> Message-ID: Don't worry. This isn't going to change. Someone please update PEP 3099. On 5/2/06, Delaney, Timothy (Tim) wrote: > Josiah Carlson wrote: > > > for line in lines: > > line = line.rstrip() > > ... > > Exactly the use case I was thinking of (and one I used yesterday BTW). > > I'm -1 on *dis*allowing reusing a name bound in a for loop in any > construct i.e. +1 for the status quo. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From greg.ewing at canterbury.ac.nz Wed May 3 03:22:50 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 03 May 2006 13:22:50 +1200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> Message-ID: <445805EA.7000501@canterbury.ac.nz> Guido van Rossum wrote: > On 5/2/06, Greg Ewing wrote: > > make_person(=name, =age, =phone, =location) > > And even with Terry's use case quoted I can't make out what you meant > that to do. I meant it to do the same thing as make_person(name=name, age=age, phone=phone, location=location) I come across use cases for this fairly frequently, usually when I have an __init__ method that supplies default values for a bunch of arguments, and then wants to pass them on to an inherited __init__ with the same names. It feels very wanky having to write out all those foo=foo expressions. -- Greg From guido at python.org Wed May 3 04:32:48 2006 From: guido at python.org (Guido van Rossum) Date: Tue, 2 May 2006 19:32:48 -0700 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <445805EA.7000501@canterbury.ac.nz> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> <445805EA.7000501@canterbury.ac.nz> Message-ID: On 5/2/06, Greg Ewing wrote: > Guido van Rossum wrote: > > On 5/2/06, Greg Ewing wrote: > > > > make_person(=name, =age, =phone, =location) > > > > And even with Terry's use case quoted I can't make out what you meant > > that to do. > > I meant it to do the same thing as > > make_person(name=name, age=age, phone=phone, location=location) > > I come across use cases for this fairly frequently, usually > when I have an __init__ method that supplies default values > for a bunch of arguments, and then wants to pass them on to > an inherited __init__ with the same names. It feels very > wanky having to write out all those foo=foo expressions. Sorry, but leading = signs feel even more wanky. (That's a technical term. ;-) It violates the guideline that Python's punctuation should preferably mimic English; or other mainstram languages (as with 'x.y' and '@deco'). -- --Guido van Rossum (home page: http://www.python.org/~guido/) From fdrake at acm.org Wed May 3 05:06:02 2006 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Tue, 2 May 2006 23:06:02 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445805EA.7000501@canterbury.ac.nz> Message-ID: <200605022306.03128.fdrake@acm.org> On Tuesday 02 May 2006 22:32, Guido van Rossum wrote: > and '@deco'). Pronounced "at-deck-oh", @deco is an art-deco variant favored in "r"-deprived regions. -Fred -- Fred L. Drake, Jr. From murman at gmail.com Wed May 3 05:49:33 2006 From: murman at gmail.com (Michael Urman) Date: Tue, 2 May 2006 22:49:33 -0500 Subject: [Python-Dev] more pyref: continue in finally statements In-Reply-To: <44565CF0.4000207@v.loewis.de> References: <44565CF0.4000207@v.loewis.de> Message-ID: On 5/1/06, "Martin v. L?wis" wrote: > then what should be the meaning of "continue" here? The finally > block *eventually* needs to re-raise the exception. When should > that happen? It should behave similarly to return and swallow the exception. In your example this would result in an infinite loop. Alternately the behavior of return should be changed, and the below code would no longer work as it does today. >>> def foo(): ... try: raise Exception ... finally: return 'Done' ... >>> foo() 'Done' Michael -- Michael Urman http://www.tortall.net/mu/blog From nnorwitz at gmail.com Wed May 3 09:15:33 2006 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 3 May 2006 00:15:33 -0700 Subject: [Python-Dev] Seeking students for the Summer of Code Message-ID: There is less than a week left before students must submit a final application. There are a bunch of ideas up on the wiki: http://wiki.python.org/moin/SummerOfCode/ The wiki has instructions for how to submit a proposal. There are many different areas including: core language features, libraries, and applications. This is a great opportunity to get real coding experience. Not to mention the chance to work with a nice and fun group of people. The earlier you submit an application, the more feedback you can get to improve it and increase your liklihood of getting accepted. Feel free to contact me if you have any questions. Cheers, n From jcarlson at uci.edu Wed May 3 10:25:35 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Wed, 03 May 2006 01:25:35 -0700 Subject: [Python-Dev] binary trees. Review obmalloc.c In-Reply-To: <44508866.60503@renet.ru> References: <20060426094148.66EE.JCARLSON@uci.edu> <44508866.60503@renet.ru> Message-ID: <20060502222033.678D.JCARLSON@uci.edu> "Vladimir 'Yu' Stepanov" wrote: > Comparison of functions of sorting and binary trees not absolutely > correctly. I think that function sort will lose considerably on > greater lists. Especially after an insert or removal of all one element. Generally speaking, people who understand at least some of Python's internals (list internals specifically), will not be *removing* entries from lists one at a time (at least not using list.pop(0) ), because that is slow. If they need to remove items one at a time from the smallest to the largest, they will usually use list.reverse(), then repeatedly list.pop(), as this is quite fast (in general). However, as I just said, people usually don't remove items from just-sorted lists, they tend to iterate over them via 'for i in list:' . - Josiah As an aside, I have personally implemented trees a few times for different reasons. One of the issues I have with most tree implementations is that it is generally difficult to do things like "give me the kth smallest/largest item". Of course the standard solution is what is generally called a "partial order" or "order statistic" tree, but then you end up with yet another field in your structure. One nice thing about Red-Black trees combined with order-statistic trees, is that you can usually use the uppermost bit of the order statistics for red/black information. Of course, this is really only interesting from an "implement this in C" perspective; because if one were implementing it in Python, one may as well be really lazy and not bother implementing guaranteed balanced trees and be satisfied with randomized-balancing via Treaps. Of course all of this discussion about trees in Python is fine, though there is one major problem. With minimal work, one can construct 3 values such that ((a < b < c) and (c < a)) is true. From ncoghlan at gmail.com Wed May 3 12:15:54 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Wed, 03 May 2006 20:15:54 +1000 Subject: [Python-Dev] signature object issues (to discuss while I am out of contact) In-Reply-To: References: <44573CA6.5010608@gmail.com> Message-ID: <445882DA.1020806@gmail.com> Brett Cannon wrote: > On 5/2/06, Nick Coghlan wrote: >> All of the use cases I can think of (introspection for documentation >> purposes >> or argument checking purposes) don't really suffer either way >> regardless of >> whether the signature retrieval is spelt "obj.__signature__" or >> "inspect.getsignature(obj)". >> > > It does for decorators. How do you make sure that a decorator uses > the signature object of the wrapped function instead of the decorator? > Or are you saying to just not worry about that right now? Ah, good point. In that case, I'd be in favour of including the attribute in the PEP, and having inspect.getsignature() check for that attribute before manually building a signature object from the function and its code object. The other nice thing about the attribute is that it allows otherwise uninspectable functions (like C functions) to choose to declare their API for introspection purposes. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From amk at amk.ca Wed May 3 18:08:07 2006 From: amk at amk.ca (A.M. Kuchling) Date: Wed, 3 May 2006 12:08:07 -0400 Subject: [Python-Dev] Date for DC-area Python sprint? Message-ID: <20060503160807.GB30707@rogue.amk.ca> I found out that May 27th is on Memorial Day weekend, and some people will doubtless have travel plans. Let's aim for the next Saturday, June 3rd. (No intersection with the Need for Speed sprint; oh well.) I'll post a detailed announcement and set up a wiki page when things are nailed down, but it looks like the sprint can be from 9 or 10AM to 4PM, or thereabouts. Wireless will be available. Does anyone else want to organize sprints for that day? --amk From coder_infidel at hotmail.com Wed May 3 17:11:17 2006 From: coder_infidel at hotmail.com (Luke Dunstan) Date: Wed, 3 May 2006 23:11:17 +0800 Subject: [Python-Dev] Python for Windows CE Message-ID: Hi, I would like to explore the possibility of submitting patches to allow Python to work on Windows CE out of the box. I have a few questions in preparation: 1. Is there any reason in principle why patches for Windows CE support would be rejected? 2. Should I submit unified diffs or context diffs? One page says: "Context diffs are preferred, so generate the patch using diff -c." http://www.python.org/dev/tools/ Another says: "We like unified diffs. We grudgingly accept contextual diffs..." http://www.python.org/dev/patches/ 3. The page http://www.python.org/dev/patches/style/ says that platform-specific code should use preprocessor symbols documented for the compiler, but existing Python code uses e.g. the invented MS_WIN32 symbol instead of the standard _WIN32. Should we create a symbol MS_WINCE for consistency or use the more common _WIN32_WCE? 4. The latest existing patch set uses os.name = "ce", and this can be used to distinguish Windows CE from other operating systems in Python code. The existing patches also set sys.platform = "Pocket PC", but I am not so keen on keeping this, mainly because Windows CE is equivalent to Win32 in many cases. Any comments? 5. Windows CE lacks some header files that are present on other platforms, e.g. . If we ignore the actual declarations in the header for a moment, there are a few ways to solve this problem: (a) The obvious solution is to wrap each #include inside #ifndef MS_WINCE...#endif (b) Instead we could use #ifdef HAVE_DIRECT_H, requiring patches to #define HAVE_DIRECT_H for other platforms (c) The existing patch set uses a simpler solution by creating a (possibly empty) direct.h in a Windows CE-specific subdirectory of the Python source tree, and adding that directory to the compiler include path. This means that the source files probably won't need to be patched and it may help when building C extension modules. Is there any objection to the method (c) of providing missing headers? What is the preferred solution? In later emails I will of course go into more detail about the patches required. Any general tips on how to submit good patches are welcome. Thanks, Luke Dunstan From theller at python.net Wed May 3 20:53:48 2006 From: theller at python.net (Thomas Heller) Date: Wed, 03 May 2006 20:53:48 +0200 Subject: [Python-Dev] Shared libs on Linux (Was: test failures in test_ctypes (HEAD)) In-Reply-To: References: Message-ID: <4458FC3C.1040407@python.net> [Crossposting to both python-dev and ctypes-users, please respond to the list that seems most appropriate] Guido van Rossum wrote: > I see test failures in current HEAD on my Google Red Hat Linux desktop > that the buildbots don't seem to have: > > ./python -E -tt ../Lib/test/regrtest.py test_ctypes > test_ctypes > test test_ctypes failed -- errors occurred; run in verbose mode for details > > More details from running this manually: > $ ./python ../Lib/test/test_ctypes.py > . > . (lots of passing tests; then:) > . > test_gl (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > test_glu (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > test_glut (ctypes.test.test_find.Test_OpenGL_libs) ... ERROR > > ====================================================================== > ERROR: test_gl (ctypes.test.test_find.Test_OpenGL_libs) > ---------------------------------------------------------------------- > Traceback (most recent call last): > File "/home/guido/projects/python/trunk/Lib/ctypes/test/test_find.py", > line 42, in setUp > self.glut = CDLL(lib_glut) > File "/home/guido/projects/python/trunk/Lib/ctypes/__init__.py", > line 288, in __init__ > self._handle = _dlopen(self._name, mode) > OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion I have now changed the test to ignore the case when the libglut.so library cannot be loaded because of missing symbols. I could not reproduce the failure on any of the systems I have access to. I've installed fedora 5, but the test succeeds on this system (I assume redhat desktop is different from fedora, though). Unfortunately I don't know enough about shared libs on linux to make the test more correct. I would appreciate explanations or pointers to explanations how shard library loading on linux works in detail. The most important questions now is: - When I load shared libs, sometimes it is required to use the RTLD_GLOBAL flag (RTLD_LOCAL is the default), although in most casesthis is not needed. I think I do understand what RTLD_GLOBAL does, I just do not know how to determine if it is required or not. The runtime loader seems to have access to this information - is there a way for me to find out? Thanks, Thomas From martin at v.loewis.de Wed May 3 23:03:27 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Wed, 03 May 2006 23:03:27 +0200 Subject: [Python-Dev] Python for Windows CE In-Reply-To: References: Message-ID: <44591A9F.1090304@v.loewis.de> Luke Dunstan wrote: > 1. Is there any reason in principle why patches for Windows CE support would > be rejected? No, not in principle. Of course, - the patch shouldn't break anything - you should state an explicit commitment to support the port for some years (or else it might get removed at the slightest problem) > 2. Should I submit unified diffs or context diffs? Yes, please :-) Actually, unified diffs are common these days, in particular as subversion generates them. > 3. The page http://www.python.org/dev/patches/style/ says that > platform-specific code should use preprocessor symbols documented for the > compiler, but existing Python code uses e.g. the invented MS_WIN32 symbol > instead of the standard _WIN32. Should we create a symbol MS_WINCE for > consistency or use the more common _WIN32_WCE? Depends on who defines it. If the compiler defines it on its own, it is best to use that. If some header file that gets unconditionally included defines it, that is just as well. If you explicitly define something, try to follow the conventions you like best. > 4. The latest existing patch set uses os.name = "ce", and this can be used > to distinguish Windows CE from other operating systems in Python code. The > existing patches also set sys.platform = "Pocket PC", but I am not so keen > on keeping this, mainly because Windows CE is equivalent to Win32 in many > cases. Any comments? I would guide the decision based on the number of API changes you need to make to the standard library (e.g. distutils). In any case, the platform module should be able to reliably report the specific system (including the specific processor architecture). > (b) Instead we could use #ifdef HAVE_DIRECT_H, requiring patches to #define > HAVE_DIRECT_H for other platforms That would be best. Python generally uses autoconf methodology, which implies that conditionally-existing headers should be detected using HAVE_*_H. Regards, Martin From bjourne at gmail.com Thu May 4 01:21:13 2006 From: bjourne at gmail.com (=?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=) Date: Thu, 4 May 2006 01:21:13 +0200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <445805EA.7000501@canterbury.ac.nz> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> <445805EA.7000501@canterbury.ac.nz> Message-ID: <740c3aec0605031621v48f33dd0g591cb12a131764e8@mail.gmail.com> > > > make_person(=name, =age, =phone, =location) > > > > And even with Terry's use case quoted I can't make out what you meant > > that to do. > > I meant it to do the same thing as > > make_person(name=name, age=age, phone=phone, location=location) > > I come across use cases for this fairly frequently, usually > when I have an __init__ method that supplies default values > for a bunch of arguments, and then wants to pass them on to Me too! I would have thought that the one obvious way to get rid of the wanky feeling would have been to write: def make_person(name, age, phone, location): ... make_person(name, age, phone, location) IMHO, keyword arguments are often overused like that. Many times they don't improve readability any more than naming your variables sensibly do. No, I have not studied how my API:s are used (and how they evolve) over a longer period of time. -- mvh Bj?rn From talin at acm.org Thu May 4 03:25:15 2006 From: talin at acm.org (Talin) Date: Thu, 4 May 2006 01:25:15 +0000 (UTC) Subject: [Python-Dev] mail to talin is bouncing References: Message-ID: Guido van Rossum python.org> writes: > Sorry to bother the list -- talin, mail to you is bouncing: Someone sent me mail? Cool! :) Sorry about that, I'm in the process of migrating hosting providers, and I forgot to add an email account for myself :) It should be better now, I'll do some more tests tonight. (This is all part of my mad scheme to get my TurboGears/AJAX-based online collaborative Thesaurus project available to the outside world.) -- Talin From xah at xahlee.org Thu May 4 04:09:06 2006 From: xah at xahlee.org (xahlee) Date: Wed, 3 May 2006 19:09:06 -0700 Subject: [Python-Dev] lambda in Python Message-ID: Today i ran into one of Guido van Rossum's blog article titled ?Language Design Is Not Just Solving Puzzles? at http://www.artima.com/weblogs/viewpost.jsp?thread=147358 The article reads very kooky. The bottom line is that Guido simply does not like the solution proposed for fixing the lambda construct in Python, and for whatever reasons thinks that no solution would satisfy him about this. But instead, he went thru sophistry on the ignorance and psychology of coder mass in the industry, with mentions of the mysterious Zen, the cool Google, the Right Brain, Rube Goldberg contraption irrelevancies. From his article, i noticed that there's largish thread of discussions on lambda. The following is a essay i wrote after reading another one of Guido blog, in which shows prejudice and ignorance about functional programing. I hope it can reduce the ignorance about lambda and functional programing. -------------------------- Lambda in Python 3000 Xah Lee, 20050930 On Guido van Rossum's website: http://www.artima.com/weblogs/viewpost.jsp?thread=98196 (local copy) dated 20050310, he muses with the idea that he would like to remove lambda, reduce(), filter() and map() constructs in a future version Python 3000. Guido wrote: ?filter(P, S) is almost always written clearer as [x for x in S if P(x)], and this has the huge advantage that the most common usages involve predicates that are comparisons, e.g. x==42, and defining a lambda for that just requires much more effort for the reader (plus the lambda is slower than the list comprehension)? The form ?[x for x in S if P(x)]? is certainly not more clear than ?filter(P, S)?. The latter is clearly a function, what is the former? A function every programer in any language can understand and appreciate its form and function. Why would anyone to expect everyone to appreciate a Python syntactical idiosyncrasy ?[x for ...]?? Also, the argument that the form ?filter(F,S)? being cumbersome because the first argument is a function and that mostly likely it would be a function that returns true/false thus most people will probably use the inline ?lambda? construct and that is quite cumbersome than if the whole thing is written with the syntactical idiosyncrasy ?[x for ...]?, is rather inane, as you can now see. The filter(decision_function,list) form is clean, concise, and helps thinking. Why it helps thinking? Because it condenses the whole operation into its mathematical essence with the most clarity. That is, it filters, of a list, and by a yes/no decision function. Nothing is more, and nothing can be less. It is unfortunate that we have the jargon Lambda and Predicate developed by the tech geekers of the functional programing community. The lambda could be renamed Pure Function and the Predicate could be called True/False function, but the world of things being the way they are already, it is unwise to rewrite every existing Perl program just because somebody invented another language. If the predicate P in filter(P,S) is cumbersome, so would exactly the same thing appear in the syntactical idiosyncrasy: ?[x for x in S if P(x)]?. Guido added this sting as a afterthought: ?(plus the lambda is slower than the list comprehension)? Which is faster is really the whim and capacity of Python compiler implementators. And, weren't we using clarity as the judgement a moment ago? The concept of a function every programer understands, but what the heck is a List Comprehension? Why don't you scrap list comprehension in Python 3000 and create a table() function that's simpler in syntax and more powerful in semantics? ( See http:// xahlee.org/perl-python/list_comprehension.html ) ?Why drop lambda? Most Python users are unfamiliar with Lisp or Scheme, so the name is confusing; also, there is a widespread misunderstanding that lambda can do things that a nested function can't -- I still recall Laura Creighton's Aha!-erlebnis after I showed her there was no difference! Even with a better name, I think having the two choices side-by-side just requires programmers to think about making a choice that's irrelevant for their program; not having the choice streamlines the thought process. Also, once map(), filter() and reduce() are gone, there aren't a whole lot of places where you really need to write very short local functions; Tkinter callbacks come to mind, but I find that more often than not the callbacks should be methods of some state-carrying object anyway (the exception being toy programs).? In the outset Guido here assumes a moronitude about the set of Python users and what they are familiar of. Python users 10 years ago are not the same Python users today, and will certainly not be the same 10 years later if you chop off lambda. Things change, math literacy advances, and what users you have changes with what you are. A function is the gist of a mathematical idea embodied in computer languages, not something from LISP or Scheme as tech geekers wont to think. ?... there is a widespread misunderstanding that lambda can do things that a nested function can't...? One is so insulted by a industrial big shot in quoting something so disparate then shot it down as if showing his perspicacity. A lambda is a syntax for function or a name for the concept of function. What does it mean that a lambda isn't as powerful as nested function?? The lambda in Python is really ill. It is designed with a built-in limitation in the first place, and regarded as some foreign substance in the Imperative Crowd such as the Pythoners. If there's any problem with lambda, it is with lambda in Python and Pythoner's attitude. ?Also, once map(), filter() and reduce() are gone, there aren't a whole lot of places where you really need to write very short local functions;? Of course, one begins to write things like Java: in three thousand words just to show you are a moron. The removing of elements in a language is in general not a good idea. Removing powerful features so that coding monkeys can use it is moronic. (e.g. Java) Removing ?redundant? constructs is not always smart (e.g. Scheme), because it pinches on practicality. Removing existing language features by a visionary upgrade is a waste. It forces unnecessary shakeup and can cause death. ?So now reduce(). This is actually the one I've always hated most, because, apart from a few examples involving + or *, almost every time I see a reduce() call with a non-trivial function argument, I need to grab pen and paper to diagram what's actually being fed into that function before I understand what the reduce() is supposed to do. So in my mind, the applicability of reduce() is pretty much limited to associative operators, and in all other cases it's better to write out the accumulation loop explicitly.? The existence of reduce() in Python is probably caused by tech geeking clowns of the computing industry. Basically, nobody really have a clear understanding of mathematics or computing semantics, but every elite tech geeker knew one bag of constructs of various languages. So, you add this, i want that, and the language becomes a incoherent soup of constructs, with the backlash of wanting to chop off things again, with that good things. reduce() in fact embodies a form of iteration/recursion on lists, very suitable in a functional language environment. If Python's lambda and other functional facilities are more powerful or complete, reduce() would be a good addition. For instance, in functional programing, it is a paradigm to nest or sequence functions. (most readers will be familiar in the form of unix shell's ?pipe?). When you sequence functions, you can't stop in the middle and do a loop construct. So, reduce() and other functional forms of iteration are convenient and necessary. Suggestions: lambda, reduce(), filter() and map() all should stay. I'm not sure exactly what's the ins and outs of Python 3000. If one wants to shake things up based on a vision: don't. There are already gazillion languages and visions; the world really don't need another bigshot's say for their personal advancement. As for improvement, lambda in Python should be expanded to remove its built-in limitation (and Imperative Programing Crowd such as Pythoners should cease and desist with their lambda attitude problem). The function map() could also be considered for expansion. (see ?What is Expressiveness in a Computer Language? at http://xahlee.org/perl-python/ what_is_expresiveness.html ) Function reduce() should stay because it's already there, even if it is not very useful and odd in Python. filter() should stay as it is as it is superb and proper. ... the rest of the article explaining the functions of the functions in question is at: http://xahlee.org/perl-python/python_3000.html Xah xah at xahlee.org ? http://xahlee.org/ ? From anthony at python.org Thu May 4 05:20:27 2006 From: anthony at python.org (Anthony Baxter) Date: Thu, 4 May 2006 13:20:27 +1000 Subject: [Python-Dev] lambda in Python In-Reply-To: References: Message-ID: <200605041320.31979.anthony@python.org> This is utterly irrelevant for python-dev. Please take it elsewhere. Thanks, Anthony From greg.ewing at canterbury.ac.nz Thu May 4 06:20:56 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 04 May 2006 16:20:56 +1200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <740c3aec0605031621v48f33dd0g591cb12a131764e8@mail.gmail.com> References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> <445805EA.7000501@canterbury.ac.nz> <740c3aec0605031621v48f33dd0g591cb12a131764e8@mail.gmail.com> Message-ID: <44598128.8060506@canterbury.ac.nz> BJ?rn Lindqvist wrote: > would have thought that the one obvious way to get rid of > the wanky feeling would have been to write: > > def make_person(name, age, phone, location): ... > > make_person(name, age, phone, location) This doesn't fly in something like PyGUI, where there are literally dozens of potential arguments to many of the constructors. The only sane way to deal with that is for them to be keyword-only, at least conceptually if not in actual implementation. -- Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | Carpe post meridiam! | Christchurch, New Zealand | (I'm not a morning person.) | greg.ewing at canterbury.ac.nz +--------------------------------------+ From me+python-dev at modelnine.org Thu May 4 08:29:52 2006 From: me+python-dev at modelnine.org (Heiko Wundram) Date: Thu, 4 May 2006 08:29:52 +0200 Subject: [Python-Dev] Python long command line options Message-ID: <200605040829.53140.me+python-dev@modelnine.org> Hi all! Martin von L?wis said that it'd be necessary to discuss a patch to Python's ability to parse command-line parameters to the interpreter here, and I thought I might start the ball rolling. The associated patch of mine is: http://sourceforge.net/tracker/index.php?func=detail&aid=1481112&group_id=5470&atid=305470 which refers to: http://groups.google.de/group/comp.lang.python/browse_thread/thread/e3db1619040d7c6c/3c119e09122c83ed?hl=de#3c119e09122c83ed (sorry for the long URLs, tinyurl isn't working for me at the moment...) The patch itself is an extension of the Python/getopt.c module to handle long command-line parameters (including option data passed as --=), which are specified in the optstring as: "[(longopt)][:]" for example: "V(version)" or "c(command):" The patch doesn't change behaviour on old optstrings, except where an old optstring relied on the fact that one of :, (, ) are valid parameter names (because of the unconditional strchr to find the option name). I've not found any reference to _PyOS_GetOpt besides the one in Modules/main.c, so I don't think this change in behaviour breaks any existing code. The patch relies only on usability of strchr (which the old getopt.c did too), removes a usage of strcmp which was completely unneccesary, fixes some checks which were unneccesarily broad (>= replaced by ==), and compilation doesn't show any warnings on gcc 3.4.6; as for Windows (and MSVC), I don't have the means to test there. The current patch offers prefix matching: when an option is only specified with a significant amount of prefix characters which doesn't match any other long option, the patch assumes that the user meant this option. For example: --ver would also be interpreted as command-line parameter --version just as would --v --ve --vers --versi --versio if there are no other long options that start with the corresponding prefix. This "trick" is easy enough to remove from the sources, though, so that only correctly spelled options are actually returned. Anyway, back on topic, I personally agree with the people who posted to comp.lang.python that --version (and possibly --help, possibly other long parameters too) would be useful additions to Pythons command-line parameters, as it's increasingly getting more common amongst GNU and BSD utilities to support these command-line options to get information about the utility at hand (very popular amongst system administrators) and to use long commandline options to be able to easily see what an option does when encountered in a shell script of some sort. And, as this doesn't break any old code (-V isn't going away by the patch), I personally find this to be a very useful change. Your thoughts? --- Heiko. From talin at acm.org Thu May 4 08:47:20 2006 From: talin at acm.org (Talin) Date: Thu, 4 May 2006 06:47:20 +0000 (UTC) Subject: [Python-Dev] lambda in Python References: Message-ID: xahlee xahlee.org> writes: > Today i ran into one of Guido van Rossum's blog article titled > ?Language Design Is Not Just Solving Puzzles? at > http://www.artima.com/weblogs/viewpost.jsp?thread=147358 The confrontational tone of this post makes it pretty much impossible to have a reasonable debate on the subject. I'd suggest that if you really want to be heard (instead of merely having that "I'm right" feeling) that you try a different approach. -- Talin From sluggoster at gmail.com Thu May 4 10:13:18 2006 From: sluggoster at gmail.com (Mike Orr) Date: Thu, 4 May 2006 01:13:18 -0700 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: References: Message-ID: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> On 5/2/06, Noam Raphael wrote: > Here are my ideas. It's a copy of what I posted a few minutes ago in > the wiki - you can view it at > http://wiki.python.org/moin/AlternativePathClass (it looks better > there). > > You can find the implementation at > http://wiki.python.org/moin/AlternativePathModule?action=raw > (By the way, is there some "code wiki" available? It can simply be a > public svn repository. I think it will be useful for those things.) Intriguing idea, Noam, and excellent thinking. I'd say it's worth a separate PEP. It's too different to fit into PEP 355, and too big to be summarized in the "Open Issues" section. Of course, one PEP will be rejected if the other is approved. The main difficulty with this approach is it's so radical. It would require a serious champion to convince people it's as good as our tried-and-true strings. > == a tuple instead of a string == > > The biggest conceptual change is that my path object is a subclass of > ''tuple'', not a subclass of str. For example, > {{{ > >>> tuple(path('a/b/c')) > ('a', 'b', 'c') > >>> tuple(path('/a/b/c')) > (path.ROOT, 'a', 'b', 'c') > }}} How about an .isabsolute attribute instead of prepending path.ROOT? I can see arguments both ways. An attribute is easy to query and easy for str() to use, but it wouldn't show up in a tuple-style repr(). > This means that path objects aren't the string representation of a > path; they are a ''logical'' representation of a path. Remember why a > filesystem path is called a path - because it's a way to get from one > place on the filesystem to another. Paths can be relative, which means > that they don't define from where to start the walk, and can be not > relative, which means that they do. In the tuple representation, > relative paths are simply tuples of strings, and not relative paths > are tuples of strings with a first "root" element. > > The advantage of using a logical representation is that you can forget > about the textual representation, which can be really complex. You > don't have to call normpath when you're unsure about how a path looks, > you don't have to search for seps and altseps, and... you don't need > to remember a lot of names of functions or methods. To show that, take > a look at those methods from the original path class and their > equivalent in my path class: > > {{{ > p.normpath() -> Isn't needed - done by the constructor > p.basename() -> p[-1] > p.splitpath() -> (p[:-1], p[-1]) > p.splitunc() -> (p[0], p[1:]) (if isinstance(p[0], path.UNCRoot)) > p.splitall() -> Isn't needed > p.parent -> p[:-1] > p.name -> p[-1] > p.drive -> p[0] (if isinstance(p[0], path.Drive)) > p.uncshare -> p[0] (if isinstance(p[0], path.UNCRoot)) > > and of course: > p.join(q) [or anything like it] -> p + q > }}} All that slicing is cool. > The only drawback I can see in using a logical representation is that > giving a path object to functions which expect a path string won't > work. The immediate solution is to simply use str(p) instead of p. The > long-term solution is to make all related functions accept a path > object. That's a big drawback. PEP 355 can choose between string and non-string, but this way is limited to non-string. That raises the minor issue of changing the open() functions etc in the standard library, and the major issue of changing them in third-party libraries. > Having a logical representation of a path calls for a bit of term > clearing-up. What's an absolute path? On POSIX, it's very simple: a > path starting with a '/'. But what about Windows? Is "\temp\file" an > absolute path? I claim that it isn't really. The reason is that if you > change the current working directory, its meaning changes: It's now > not "c:\temp\file", but "a:\temp\file". The same goes for > "c:temp\file". So I decided on these two definitions: > > * A ''relative path'' is a path without a root element, so it can be > concatenated to other paths. > * An ''absolute path'' is a path whose meaning doesn't change when > the current working directory changes. > > This means that paths starting with a drive letter alone > (!UnrootedDrive instance, in my module) and paths starting with a > backslash alone (the CURROOT object, in my module) are not relative > and not absolute. I guess that's plausable. We'll need feedback from Windows users. > I really think that it's a better way to handle paths. If you want an > example, compare the current implementation of relpathto and my > implementation. In my enhanced Path class (I posted the docstring last summer), I made a .relpathfrom() function because .relpathto() was so confusing. > == Easier attributes for stat objects == > > The current path objects includes: > * isdir, isfile, islink, and - > * atime, mtime, ctime, size. > The first line does file mode checking, and the second simply gives > attributes from the stat object. > > I suggest that these should be added to the stat_result object. isdir, > isfile and islink are true if a specific bit in st_mode is set, and > atime, mtime, ctime and size are simply other names for st_atime, > st_mtime, st_ctime and st_size. > > It means that instead of using the atime, mtime etc. methods, you will > write {{{ p.stat().atime }}}, {{{ p.stat().size }}}, etc. > > This is good, because: > * If you want to make only one system call, it's very easy to save > the stat object and use it. > * If you have to deal with symbolic links, you can simply use {{{ > p.lstat().mtime }}}. Yes, symbolic links have a modification time. The > alternative is to add three methods with ugly names (latime, lmtime, > lctime) or to have an incomplete interface without a good reason. > > I think that isfile, isdir should be kept (along with lisfile, > lisdir), since I think that doing what they do is quite common, and > requires six lines: > {{{ > try: > st = p.stat() > except OSError: > return False > else: > return st.isdir > }}} > > I think that still, isdir, isfile and islink should be added to > stat_result objects: They turned out pretty useful in writing some of > the more complex path methods. Not sure about this. I see the point in not duplicating .foo() vs .stat().foo. .foo() exists in os.path to avoid the ugliness of os.stat() in the middle of an expression. I think the current recommendation is to just do stats all the time because the overhead is minimal and it's not worth getting out of sync. The question is, does forcing people to use .stat() expose an implementation detail that should be hidden, and does it smell of Unixism? Most people think a file *is* a regular file or a directory. The fact that this is encoded in the file's permission bits -- which stat() examines -- is a quirk of Unix. > == One Method for Finding Files == > > (They're actually two, but with exactly the same interface). The > original path object has these methods for finding files: > > {{{ > def listdir(self, pattern = None): ... > def dirs(self, pattern = None): ... > def files(self, pattern = None): ... > def walk(self, pattern = None): ... > def walkdirs(self, pattern = None): ... > def walkfiles(self, pattern = None): ... > def glob(self, pattern): > }}} > > I suggest one method that replaces all those: > {{{ > def glob(self, pattern='*', topdown=True, onlydirs=False, onlyfiles=False): ... > }}} > > pattern is the good old glob pattern, with one additional extension: > "**" matches any number of subdirectories, including 0. This means > that '**' means "all the files in a directory", '**/a' means "all the > files in a directory called a", and '**/a*/**/b*' means "all the files > in a directory whose name starts with 'b' and the name of one of their > parent directories starts with 'a'". I like the separate methods, but OK. I hope it doesn't *really* call glob if the pattern is the default. How about 'dirs' and 'files' instead of 'onlydirs' and 'onlyfiles'? Or one could, gasp, pass a constant or the 'find' command's abbreviation ("d" directory, "f" file, "s" socket, "b" block special...). In my enhanced Path class, I used a boolean 'symlinks' arg meaning "follow symlinks" (default True). This allows the user to process symbolic links seperately if he wishes, or to ignore them if he doesn't care. Separate .symlinks() and .walklinks() methods handle the case that the user does want to treat them specially. This seems to be more intuitive and flexible than just your .symlinks() method below. Not sure I like "**/" over a 'recursive' argument because the syntax is so novel and nonstandard. You mean "ancestor" in the last paragraph, not "parent'. Parent is often read as immediate parent, and ancestor as any number of levels up. > == Reduce the Number of Methods == > > I think that the number of methods should be reduced. The most obvious > example are the copy functions. In the current proposal: > > {{{ > def copyfile(self, dst): ... > def copymode(self, dst): ... > def copystat(self, dst): ... > def copy(self, dst): ... > def copy2(self, dst): ... > }}} > > In my proposal: > > {{{ > def copy(self, dst, copystat=False): ... > }}} > > It's just that I think that copyfile, copymode and copystat aren't > usually useful, and there's no reason not to unite copy and copy2. Sounds good. > = Other Changes = > > Here is a list of the smaller things I've changed in my proposal. > > The current normpath removes '..' with the name before them. I didn't > do that, because it doesn't return an equivalent path if the path > before the '..' is a symbolic link. I was wondering what the fallout would be of normalizing "a/../b" and "a/./b" and "a//b", but it sounds like you're thinking about it. > I removed the methods associated with file extensions. I don't recall > using them, and since they're purely textual and not OS-dependent, I > think that you can always do p[-1].rsplit('.', 1). No, .ext and .namebase are important! I use them all the time; e.g., to force the extension to lowercase, to insert/update a suffix to the basename and re-add the extension, etc. I can see cutting the other properties but not these. .namebase is an obnoxious name though. I wish we could come up with something better. > I removed unlink. It's an alias to remove, as far as I know. It was added because .unlink() is cryptic to non-Unix users. Although I'd argue that .delete() is more universally understood than either. > I removed expand. There's no need to use normpath, so it's equivalent > to .expanduser().expandvars(), and I think that the explicit form is > better. Expand is useful though, so you don't forget one or the other. > copytree - I removed it. In shutil it's documented as being mostly a > demonstration, and I'm not sure if it's really useful. Er, not sure I've used it, but it seems useful. Why force people to reinvent the wheel with their own recursive loops that they may get wrong? > symlink - Instead of a function like copy, with the destination as the > second (actually, the only) argument, I wrote "writelink", which gets > a string and creates a symbolic link with that value. The reason is > that symbolic links can be any string, not necessarily a legal path. Does that mean you have to build a relative link yourself if you're going from one directory to another? > p.ext -> ''.join(p[-1].rsplit('.', 1)[1:]) People shouldn't have to do this. > Unicode - I have no idea about unicode paths. My current > implementation simply uses str. This should be changed, I guess. No idea about that either. You've got two issues here. One is to go to a tuple base and replace several properties with slicing. The other is all your other proposed changes. Ideally the PEP would be written in a way that these other changes can be propagated back and forth between the PEPs as consensus builds. -- Mike Orr (mso at oz.net address is semi-reliable) From fredrik at pythonware.com Thu May 4 14:32:26 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Thu, 4 May 2006 14:32:26 +0200 Subject: [Python-Dev] Alternative path suggestion References: Message-ID: Noam Raphael wrote: > You can find the implementation at > http://wiki.python.org/moin/AlternativePathModule?action=raw > (By the way, is there some "code wiki" available? It can simply be a > public svn repository. I think it will be useful for those things.) pastebin is quite popular: http://python.pastebin.com/ From ncoghlan at gmail.com Thu May 4 14:57:05 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 04 May 2006 22:57:05 +1000 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> Message-ID: <4459FA21.6030508@gmail.com> Mike Orr wrote: > Intriguing idea, Noam, and excellent thinking. I'd say it's worth a > separate PEP. It's too different to fit into PEP 355, and too big to > be summarized in the "Open Issues" section. Of course, one PEP will > be rejected if the other is approved. I agree that a competing PEP is probably the best way to track this idea. > The main difficulty with this approach is it's so radical. It would > require a serious champion to convince people it's as good as our > tried-and-true strings. Guido has indicated strong dissatisfaction with the idea of subclassing str/unicode with respect to PEP 355. And if you're not subclassing those types in order to be able to pass the object transparently to existing APIs, then it makes much more sense to choose a sensible internal representation like a tuple, so that issues like os.sep can be deferred until they matter. That's generally been my problem with PEP 355 - a string is an excellent format for describing and displaying paths, but its a *hopeless* format for manipulating them. A real data type that acts as a convenience API for the various string-accepting filesystem APIs would be a good thing. >> == a tuple instead of a string == >> >> The biggest conceptual change is that my path object is a subclass of >> ''tuple'', not a subclass of str. Why subclass anything? The path should internally represent the filesystem path as a list or tuple, but it shouldn't *be* a tuple. Also, was it a deliberate design decision to make the path objects immutable, or was that simply copied from the fact that strings are immutable? Given that immutability allows the string representation to be calculated once and then cached, I'll go with that interpretation. >>>>> tuple(path('/a/b/c')) >> (path.ROOT, 'a', 'b', 'c') >> }}} > > How about an .isabsolute attribute instead of prepending path.ROOT? > I can see arguments both ways. An attribute is easy to query and easy > for str() to use, but it wouldn't show up in a tuple-style repr(). You can have your cake and eat it too by storing most of the state in the internal tuple, but providing convenience attributes to perform certain queries. This would actually be the criterion for the property/method distinction. Properties can be determined solely by inspecting the internal data store, whereas methods would require accessing the filesystem. >> This means that path objects aren't the string representation of a >> path; they are a ''logical'' representation of a path. Remember why a >> filesystem path is called a path - because it's a way to get from one >> place on the filesystem to another. Paths can be relative, which means >> that they don't define from where to start the walk, and can be not >> relative, which means that they do. In the tuple representation, >> relative paths are simply tuples of strings, and not relative paths >> are tuples of strings with a first "root" element. I suggest storing the first element separately from the rest of the path. The reason for suggesting this is that you use 'os.sep' to separate elements in the normal path, but *not* to separate the first element from the rest. Possible values for the path's root element would then be: None ==> relative path path.ROOT ==> Unix absolute path path.DRIVECWD ==> Windows drive relative path path.DRIVEROOT ==> Windows drive absolute path path.UNCSHARE ==> UNC path path.URL ==> URL path The last four would have attributes (the two Windows ones to get at the drive letter, the UNC one to get at the share name, and the URL one to get at the text of the URL). Similarly, I would separate out the extension to a distinct attribute, as it too uses a different separator from the normal path elements ('.' most places, but '/' on RISC OS, for example) The string representation would then be: def __str__(self): return (str(self.root) + os.sep.join(self.path) + os.extsep + self.ext) >> The advantage of using a logical representation is that you can forget >> about the textual representation, which can be really complex. As noted earlier - text is a great format for path related I/O. It's a lousy format for path manipulation. >> {{{ >> p.normpath() -> Isn't needed - done by the constructor >> p.basename() -> p[-1] >> p.splitpath() -> (p[:-1], p[-1]) >> p.splitunc() -> (p[0], p[1:]) (if isinstance(p[0], path.UNCRoot)) >> p.splitall() -> Isn't needed >> p.parent -> p[:-1] >> p.name -> p[-1] >> p.drive -> p[0] (if isinstance(p[0], path.Drive)) >> p.uncshare -> p[0] (if isinstance(p[0], path.UNCRoot)) >> }}} These same operations using separate root and path attributes: p.basename() -> p[-1] p.splitpath() -> (p[:-1], p[-1]) p.splitunc() -> (p.root, p.path) p.splitall() -> Isn't needed p.parent -> p[:-1] p.name -> p[-1] p.drive -> p.root.drive (AttributeError if not drive based) p.uncshare -> p.root.share (AttributeError if not drive based) > That's a big drawback. PEP 355 can choose between string and > non-string, but this way is limited to non-string. That raises the > minor issue of changing the open() functions etc in the standard > library, and the major issue of changing them in third-party > libraries. It's not that big a drama, really. All you need to do is call str() on your path objects when you're done manipulating them. The third party libraries don't need to know how you created your paths, only what you ended up with. Alternatively, if the path elements are stored in separate attributes, there's nothing stopping the main object from inheriting from str or unicode the way the PEP 355 path object does. Either way, this object would still be far more convenient for manipulating paths than a string based representation that has to deal with OS-specific issues on every operation, rather than only during creation and conversion to a string. The path objects would also serve as an OS-independent representation of filesystem paths. In fact, I'd leave most of the low-level API's working only on strings - the only one I'd change to accept path objects directly is open() (which would be fairly easy, as that's a factory function now). >> This means that paths starting with a drive letter alone >> (!UnrootedDrive instance, in my module) and paths starting with a >> backslash alone (the CURROOT object, in my module) are not relative >> and not absolute. > > I guess that's plausable. We'll need feedback from Windows users. As suggested above, I think the root element should be stored separately from the rest of the path. Then adding a new kind of root element (such as a URL) becomes trivial. > The question is, does forcing people to use .stat() expose an > implementation detail that should be hidden, and does it smell of > Unixism? Most people think a file *is* a regular file or a directory. > The fact that this is encoded in the file's permission bits -- which > stat() examines -- is a quirk of Unix. I wouldn't expose stat() - as you say, it's a Unixism. Instead, I'd provide a subclass of Path that used lstat instead of stat for symbolic links. So if I want symbolic links followed, I use the normal Path class. This class just generally treat symbolic links as if they were the file pointed to (except for the whole not recursing into symlinked subdirectories thing). The SymbolicPath subclass would treat normal files as usual, but *wouldn't* follow symbolic links when stat'ting files (instead, it would stat the symlink). >> == One Method for Finding Files == >> >> (They're actually two, but with exactly the same interface). The >> original path object has these methods for finding files: >> >> {{{ >> def listdir(self, pattern = None): ... >> def dirs(self, pattern = None): ... >> def files(self, pattern = None): ... >> def walk(self, pattern = None): ... >> def walkdirs(self, pattern = None): ... >> def walkfiles(self, pattern = None): ... >> def glob(self, pattern): >> }}} >> >> I suggest one method that replaces all those: >> {{{ >> def glob(self, pattern='*', topdown=True, onlydirs=False, onlyfiles=False): ... >> }}} Swiss army methods are even more evil than wide APIs. And I consider the term 'glob' itself to be a Unixism - I've found the technique to be far more commonly known as wildcard matching in the Windows world. The path module has those methods for 7 distinct use cases: - list the contents of this directory - list the subdirectories of this directory - list the files in this directory - walk the directory tree rooted at this point, yielding both files and dirs - walk the directory tree rooted at this point, yielding only the dirs - walk the directory tree rooted at this point, yielding only the files - walk this pattern The first 3 operations are far more common than the last 4, so they need to stay. def entries(self, pattern=None): """Return list of all entries in directory""" _path = type(self) all_entries = os.listdir(str(self)) if pattern is not None: return [_path(x) for x in all_entries if x.matches(pattern)] return [_path(x) for x in all_entries] def subdirs(self, pattern=None) """Return list of all subdirectories in directory""" return [x for x in self.entries(pattern) if x.is_dir()] def files(self, pattern=None) """Return list of all files in directory""" return [x for x in self.entries(pattern) if x.is_dir()] # here's sample implementations of the test methods used above def matches(self, pattern): return fnmatch.fnmatch(str(self), pattern) def is_dir(self): return os.isdir(str(self)) def is_file(self): return os.isfile(str(self)) For the tree traversal operations, there are still multiple use cases: def walk(self, topdown=True, onerror=None) """ Walk directories and files just as os.walk does""" # Similar to os.walk, only yielding Path objects instead of strings # For each directory, effectively returns: # yield dirpath, dirpath.subdirs(), dirpath.files() def walkdirs(self, pattern=None, onerror=None) """Only walk directories matching pattern""" for dirpath, subdirs, files in self.walk(onerror=onerror): yield dirpath if pattern is not None: # Modify in-place so that walk() responds to the change subdirs[:] = [x for x in subdirs if x.matches(pattern)] def walkfiles(self, pattern=None, onerror=None) """Only walk file names matching pattern""" for dirpath, subdirs, files in self.walk(onerror=onerror): if pattern is not None: for f in files: if f.match(pattern): yield f else: for f in files: yield f def walkpattern(self, pattern=None) """Only walk paths matching glob pattern""" _factory = type(self) for pathname in glob.glob(pattern): yield _factory(pathname) >> pattern is the good old glob pattern, with one additional extension: >> "**" matches any number of subdirectories, including 0. This means >> that '**' means "all the files in a directory", '**/a' means "all the >> files in a directory called a", and '**/a*/**/b*' means "all the files >> in a directory whose name starts with 'b' and the name of one of their >> parent directories starts with 'a'". > > I like the separate methods, but OK. I hope it doesn't *really* call > glob if the pattern is the default. Keep the separate methods. Trying to squeeze too many disparate use cases through a single API is a bad idea. Directory listing and tree-traversal are not the same thing. Path matching and filename matching are not the same thing either. > Or one could, gasp, pass a constant or the 'find' command's > abbreviation ("d" directory, "f" file, "s" socket, "b" block > special...). Magic letters in an API are just as bad as magic numbers :) More importantly, these things don't port well between systems. >> In my proposal: >> >> {{{ >> def copy(self, dst, copystat=False): ... >> }}} >> >> It's just that I think that copyfile, copymode and copystat aren't >> usually useful, and there's no reason not to unite copy and copy2. > > Sounds good. OK, this is one case where a swiss army method may make sense. Specifically, something like: def copy_to(self, dest, copyfile=True, copymode=True, copytime=False) Whether or not to copy the file contents, the permission settings and the last access and modification time are then all independently selectable. The different method name also makes the direction of the copying clear (with a bare 'copy', it's slightly ambiguous as the 'cp src dest' parallel isn't as strong as it is with a function). > I was wondering what the fallout would be of normalizing "a/../b" and > "a/./b" and "a//b", but it sounds like you're thinking about it. The latter two are OK, but normalizing the first one can give you the wrong answer if 'a' is a symlink (since 'a/../b' is then not necessarily the same as 'b'). Better to just leave the '..' in and not treat it as something that can be normalised away. >> I removed the methods associated with file extensions. I don't recall >> using them, and since they're purely textual and not OS-dependent, I >> think that you can always do p[-1].rsplit('.', 1). Most modern OS's use '.' as the extension separator, true, but os.extsep still exists for a reason :) > .namebase is an obnoxious name though. I wish we could come up with > something better. p.path[-1] :) Then p.name can just do (p.path[-1] + os.extsep + p.ext) to rebuild the full filename including the extension (if p.ext was None, then p.name would be the same as p.path[-1]) >> I removed expand. There's no need to use normpath, so it's equivalent >> to .expanduser().expandvars(), and I think that the explicit form is >> better. > > Expand is useful though, so you don't forget one or the other. And as you'll usually want to do both, adding about 15 extra characters for no good reason seems like a bad idea. . . >> copytree - I removed it. In shutil it's documented as being mostly a >> demonstration, and I'm not sure if it's really useful. > > Er, not sure I've used it, but it seems useful. Why force people to > reinvent the wheel with their own recursive loops that they may get > wrong? Because the handling of exceptional cases is almost always going to be application specific. Note that even os.walk provides a callback hook for if the call to os.listdir() fails when attempting to descend into a directory. For copytree, the issues to be considered are significantly worse: - what to do if listdir fails in the source tree? - what to do if reading a file fails in the source tree? - what to do if a directory doesn't exist in the target tree? - what to do if a directory already exists in the target tree? - what to do if a file already exists in the target tree? - what to do if writing a file fails in the target tree? - should the file contents/mode/time be copied to the target tree? - what to do with symlinks in the source tree? Now, what might potentially be genuinely useful is paired walk methods that allowed the following: # Do path.walk over this directory, and also return the corresponding # information for a destination directory (so the dest dir information # probably *won't* match that file system for src_info, dest_info in src_path.pairedwalk(dest_path): src_dirpath, src_subdirs, src_files = src_info dest_dirpath, dest_subdirs, dest_files = dest_info # Do something useful # Ditto for path.walkdirs for src_dirpath, dest_dirpath in src_path.pairedwalkdirs(dest_path): # Do something useful # Ditto for path.walkfiles for src_path, dest_path in src_path.pairedwalkfiles(dest_path): src_path.copy_to(dest_path) > You've got two issues here. One is to go to a tuple base and replace > several properties with slicing. The other is all your other proposed > changes. Ideally the PEP would be written in a way that these other > changes can be propagated back and forth between the PEPs as consensus > builds. The main thing Jason's path object has going for it is that it brings together Python's disparate filesystem manipulation API's into one place. Using it is a definite improvement over using the standard lib directly. However, the choice to use a string as the internal storage instead a more appropriate format (such as the three-piece structure I suggest of root, path, extension), it doesn't do as much as it could to abstract away the hassles of os.sep and os.extsep. By focusing on the idea that strings are for path input and output operations, rather than for path manipulation, it should be possible to build something even more usable than path.py If it was done within the next several months and released on PyPI, it might even be a contender for 2.6. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From jparlar at cogeco.ca Thu May 4 15:21:57 2006 From: jparlar at cogeco.ca (Jay Parlar) Date: Thu, 4 May 2006 09:21:57 -0400 Subject: [Python-Dev] lambda in Python In-Reply-To: References: Message-ID: <7bf78738c8226235c5e4290d41a8922f@cogeco.ca> On May 4, 2006, at 6:00 AM, Talin wrote: > xahlee xahlee.org> writes: > >> Today i ran into one of Guido van Rossum's blog article titled >> ?Language Design Is Not Just Solving Puzzles? at >> http://www.artima.com/weblogs/viewpost.jsp?thread=147358 > > The confrontational tone of this post makes it pretty much impossible > to have a reasonable debate on the subject. I'd suggest that if you > really want to be heard (instead of merely having that "I'm right" > feeling) that you try a different approach. > > -- Talin Xah Lee is a well known troll, he does stuff like this on c.l.p. all the time. Best to just ignore him, he doesn't listen to reason. Jay P. From stefan.rank at ofai.at Thu May 4 15:28:29 2006 From: stefan.rank at ofai.at (Stefan Rank) Date: Thu, 04 May 2006 15:28:29 +0200 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <4459FA21.6030508@gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> Message-ID: <445A017D.4080207@ofai.at> on 04.05.2006 14:57 Nick Coghlan said the following: > Mike Orr wrote: >> Intriguing idea, Noam, and excellent thinking. I'd say it's worth a >> separate PEP. It's too different to fit into PEP 355, and too big to >> be summarized in the "Open Issues" section. Of course, one PEP will >> be rejected if the other is approved. > > I agree that a competing PEP is probably the best way to track this idea. >>> This means that path objects aren't the string representation of a >>> path; they are a ''logical'' representation of a path. Remember why a >>> filesystem path is called a path - because it's a way to get from one >>> place on the filesystem to another. Paths can be relative, which means >>> that they don't define from where to start the walk, and can be not >>> relative, which means that they do. In the tuple representation, >>> relative paths are simply tuples of strings, and not relative paths >>> are tuples of strings with a first "root" element. > > I suggest storing the first element separately from the rest of the path. The > reason for suggesting this is that you use 'os.sep' to separate elements in > the normal path, but *not* to separate the first element from the rest. I want to add that people might want to manipulate paths that are not for the currently running OS. Therefore I think the `sep` should be an attribute of the "root" element. For the same reason I'd like to add two values to the following list: > Possible values for the path's root element would then be: > > None ==> relative path (uses os.sep) + path.UNIXRELATIVE ==> uses '/' + path.WINDOWSRELATIVE ==> uses r'\' unconditionally > path.ROOT ==> Unix absolute path > path.DRIVECWD ==> Windows drive relative path > path.DRIVEROOT ==> Windows drive absolute path > path.UNCSHARE ==> UNC path > path.URL ==> URL path > > The last four would have attributes (the two Windows ones to get at the drive > letter, the UNC one to get at the share name, and the URL one to get at the > text of the URL). > > Similarly, I would separate out the extension to a distinct attribute, as it > too uses a different separator from the normal path elements ('.' most places, > but '/' on RISC OS, for example) > > The string representation would then be: > > def __str__(self): > return (str(self.root) > + os.sep.join(self.path) > + os.extsep + self.ext) > >>> The advantage of using a logical representation is that you can forget >>> about the textual representation, which can be really complex. > > As noted earlier - text is a great format for path related I/O. It's a lousy > format for path manipulation. > >>> {{{ >>> p.normpath() -> Isn't needed - done by the constructor >>> p.basename() -> p[-1] >>> p.splitpath() -> (p[:-1], p[-1]) >>> p.splitunc() -> (p[0], p[1:]) (if isinstance(p[0], path.UNCRoot)) >>> p.splitall() -> Isn't needed >>> p.parent -> p[:-1] >>> p.name -> p[-1] >>> p.drive -> p[0] (if isinstance(p[0], path.Drive)) >>> p.uncshare -> p[0] (if isinstance(p[0], path.UNCRoot)) >>> }}} > > These same operations using separate root and path attributes: > > p.basename() -> p[-1] > p.splitpath() -> (p[:-1], p[-1]) > p.splitunc() -> (p.root, p.path) > p.splitall() -> Isn't needed > p.parent -> p[:-1] > p.name -> p[-1] > p.drive -> p.root.drive (AttributeError if not drive based) > p.uncshare -> p.root.share (AttributeError if not drive based) > >> That's a big drawback. PEP 355 can choose between string and >> non-string, but this way is limited to non-string. That raises the >> minor issue of changing the open() functions etc in the standard >> library, and the major issue of changing them in third-party >> libraries. > > It's not that big a drama, really. All you need to do is call str() on your > path objects when you're done manipulating them. The third party libraries > don't need to know how you created your paths, only what you ended up with. > > Alternatively, if the path elements are stored in separate attributes, there's > nothing stopping the main object from inheriting from str or unicode the way > the PEP 355 path object does. > > Either way, this object would still be far more convenient for manipulating > paths than a string based representation that has to deal with OS-specific > issues on every operation, rather than only during creation and conversion to > a string. The path objects would also serve as an OS-independent > representation of filesystem paths. > > In fact, I'd leave most of the low-level API's working only on strings - the > only one I'd change to accept path objects directly is open() (which would be > fairly easy, as that's a factory function now). > >>> This means that paths starting with a drive letter alone >>> (!UnrootedDrive instance, in my module) and paths starting with a >>> backslash alone (the CURROOT object, in my module) are not relative >>> and not absolute. >> I guess that's plausable. We'll need feedback from Windows users. > > As suggested above, I think the root element should be stored separately from > the rest of the path. Then adding a new kind of root element (such as a URL) > becomes trivial. > >> The question is, does forcing people to use .stat() expose an >> implementation detail that should be hidden, and does it smell of >> Unixism? Most people think a file *is* a regular file or a directory. >> The fact that this is encoded in the file's permission bits -- which >> stat() examines -- is a quirk of Unix. > > I wouldn't expose stat() - as you say, it's a Unixism. Instead, I'd provide a > subclass of Path that used lstat instead of stat for symbolic links. > > So if I want symbolic links followed, I use the normal Path class. This class > just generally treat symbolic links as if they were the file pointed to > (except for the whole not recursing into symlinked subdirectories thing). > > The SymbolicPath subclass would treat normal files as usual, but *wouldn't* > follow symbolic links when stat'ting files (instead, it would stat the symlink). > >>> == One Method for Finding Files == >>> >>> (They're actually two, but with exactly the same interface). The >>> original path object has these methods for finding files: >>> >>> {{{ >>> def listdir(self, pattern = None): ... >>> def dirs(self, pattern = None): ... >>> def files(self, pattern = None): ... >>> def walk(self, pattern = None): ... >>> def walkdirs(self, pattern = None): ... >>> def walkfiles(self, pattern = None): ... >>> def glob(self, pattern): >>> }}} >>> >>> I suggest one method that replaces all those: >>> {{{ >>> def glob(self, pattern='*', topdown=True, onlydirs=False, onlyfiles=False): ... >>> }}} > > Swiss army methods are even more evil than wide APIs. And I consider the term > 'glob' itself to be a Unixism - I've found the technique to be far more > commonly known as wildcard matching in the Windows world. > > The path module has those methods for 7 distinct use cases: > - list the contents of this directory > - list the subdirectories of this directory > - list the files in this directory > - walk the directory tree rooted at this point, yielding both files and dirs > - walk the directory tree rooted at this point, yielding only the dirs > - walk the directory tree rooted at this point, yielding only the files > - walk this pattern > > The first 3 operations are far more common than the last 4, so they need to stay. > > def entries(self, pattern=None): > """Return list of all entries in directory""" > _path = type(self) > all_entries = os.listdir(str(self)) > if pattern is not None: > return [_path(x) for x in all_entries if x.matches(pattern)] > return [_path(x) for x in all_entries] > > def subdirs(self, pattern=None) > """Return list of all subdirectories in directory""" > return [x for x in self.entries(pattern) if x.is_dir()] > > def files(self, pattern=None) > """Return list of all files in directory""" > return [x for x in self.entries(pattern) if x.is_dir()] > > # here's sample implementations of the test methods used above > def matches(self, pattern): > return fnmatch.fnmatch(str(self), pattern) > def is_dir(self): > return os.isdir(str(self)) > def is_file(self): > return os.isfile(str(self)) > > For the tree traversal operations, there are still multiple use cases: > > def walk(self, topdown=True, onerror=None) > """ Walk directories and files just as os.walk does""" > # Similar to os.walk, only yielding Path objects instead of strings > # For each directory, effectively returns: > # yield dirpath, dirpath.subdirs(), dirpath.files() > > > def walkdirs(self, pattern=None, onerror=None) > """Only walk directories matching pattern""" > for dirpath, subdirs, files in self.walk(onerror=onerror): > yield dirpath > if pattern is not None: > # Modify in-place so that walk() responds to the change > subdirs[:] = [x for x in subdirs if x.matches(pattern)] > > def walkfiles(self, pattern=None, onerror=None) > """Only walk file names matching pattern""" > for dirpath, subdirs, files in self.walk(onerror=onerror): > if pattern is not None: > for f in files: > if f.match(pattern): > yield f > else: > for f in files: > yield f > > def walkpattern(self, pattern=None) > """Only walk paths matching glob pattern""" > _factory = type(self) > for pathname in glob.glob(pattern): > yield _factory(pathname) > > >>> pattern is the good old glob pattern, with one additional extension: >>> "**" matches any number of subdirectories, including 0. This means >>> that '**' means "all the files in a directory", '**/a' means "all the >>> files in a directory called a", and '**/a*/**/b*' means "all the files >>> in a directory whose name starts with 'b' and the name of one of their >>> parent directories starts with 'a'". >> I like the separate methods, but OK. I hope it doesn't *really* call >> glob if the pattern is the default. > > Keep the separate methods. Trying to squeeze too many disparate use cases > through a single API is a bad idea. Directory listing and tree-traversal are > not the same thing. Path matching and filename matching are not the same thing > either. > >> Or one could, gasp, pass a constant or the 'find' command's >> abbreviation ("d" directory, "f" file, "s" socket, "b" block >> special...). > > Magic letters in an API are just as bad as magic numbers :) > > More importantly, these things don't port well between systems. > >>> In my proposal: >>> >>> {{{ >>> def copy(self, dst, copystat=False): ... >>> }}} >>> >>> It's just that I think that copyfile, copymode and copystat aren't >>> usually useful, and there's no reason not to unite copy and copy2. >> Sounds good. > > OK, this is one case where a swiss army method may make sense. Specifically, > something like: > > def copy_to(self, dest, copyfile=True, copymode=True, copytime=False) > > Whether or not to copy the file contents, the permission settings and the last > access and modification time are then all independently selectable. > > The different method name also makes the direction of the copying clear (with > a bare 'copy', it's slightly ambiguous as the 'cp src dest' parallel isn't as > strong as it is with a function). > >> I was wondering what the fallout would be of normalizing "a/../b" and >> "a/./b" and "a//b", but it sounds like you're thinking about it. > > The latter two are OK, but normalizing the first one can give you the wrong > answer if 'a' is a symlink (since 'a/../b' is then not necessarily the same as > 'b'). > > Better to just leave the '..' in and not treat it as something that can be > normalised away. > >>> I removed the methods associated with file extensions. I don't recall >>> using them, and since they're purely textual and not OS-dependent, I >>> think that you can always do p[-1].rsplit('.', 1). > > Most modern OS's use '.' as the extension separator, true, but os.extsep still > exists for a reason :) > >> .namebase is an obnoxious name though. I wish we could come up with >> something better. > > p.path[-1] :) > > Then p.name can just do (p.path[-1] + os.extsep + p.ext) to rebuild the full > filename including the extension (if p.ext was None, then p.name would be the > same as p.path[-1]) > >>> I removed expand. There's no need to use normpath, so it's equivalent >>> to .expanduser().expandvars(), and I think that the explicit form is >>> better. >> Expand is useful though, so you don't forget one or the other. > > And as you'll usually want to do both, adding about 15 extra characters for no > good reason seems like a bad idea. . . > >>> copytree - I removed it. In shutil it's documented as being mostly a >>> demonstration, and I'm not sure if it's really useful. >> Er, not sure I've used it, but it seems useful. Why force people to >> reinvent the wheel with their own recursive loops that they may get >> wrong? > > Because the handling of exceptional cases is almost always going to be > application specific. Note that even os.walk provides a callback hook for if > the call to os.listdir() fails when attempting to descend into a directory. > > For copytree, the issues to be considered are significantly worse: > - what to do if listdir fails in the source tree? > - what to do if reading a file fails in the source tree? > - what to do if a directory doesn't exist in the target tree? > - what to do if a directory already exists in the target tree? > - what to do if a file already exists in the target tree? > - what to do if writing a file fails in the target tree? > - should the file contents/mode/time be copied to the target tree? > - what to do with symlinks in the source tree? > > Now, what might potentially be genuinely useful is paired walk methods that > allowed the following: > > # Do path.walk over this directory, and also return the corresponding > # information for a destination directory (so the dest dir information > # probably *won't* match that file system > for src_info, dest_info in src_path.pairedwalk(dest_path): > src_dirpath, src_subdirs, src_files = src_info > dest_dirpath, dest_subdirs, dest_files = dest_info > # Do something useful > > # Ditto for path.walkdirs > for src_dirpath, dest_dirpath in src_path.pairedwalkdirs(dest_path): > # Do something useful > > # Ditto for path.walkfiles > for src_path, dest_path in src_path.pairedwalkfiles(dest_path): > src_path.copy_to(dest_path) > >> You've got two issues here. One is to go to a tuple base and replace >> several properties with slicing. The other is all your other proposed >> changes. Ideally the PEP would be written in a way that these other >> changes can be propagated back and forth between the PEPs as consensus >> builds. > > The main thing Jason's path object has going for it is that it brings together > Python's disparate filesystem manipulation API's into one place. Using it is a > definite improvement over using the standard lib directly. > > However, the choice to use a string as the internal storage instead a more > appropriate format (such as the three-piece structure I suggest of root, path, > extension), it doesn't do as much as it could to abstract away the hassles of > os.sep and os.extsep. > > By focusing on the idea that strings are for path input and output operations, > rather than for path manipulation, it should be possible to build something > even more usable than path.py > > If it was done within the next several months and released on PyPI, it might > even be a contender for 2.6. > > Cheers, > Nick. > From ncoghlan at gmail.com Thu May 4 15:36:50 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 04 May 2006 23:36:50 +1000 Subject: [Python-Dev] Python long command line options In-Reply-To: <200605040829.53140.me+python-dev@modelnine.org> References: <200605040829.53140.me+python-dev@modelnine.org> Message-ID: <445A0372.3030007@gmail.com> Heiko Wundram wrote: > Anyway, back on topic, I personally agree with the people who posted to > comp.lang.python that --version (and possibly --help, possibly other long > parameters too) would be useful additions to Pythons command-line parameters, > as it's increasingly getting more common amongst GNU and BSD utilities to > support these command-line options to get information about the utility at > hand (very popular amongst system administrators) and to use long commandline > options to be able to easily see what an option does when encountered in a > shell script of some sort. +0 from me, as long as the 'best guess' bit removed. Otherwise '-v' would be "verbose", while "--v" was "version". And if we added '--verbose' later, scripts relying on '--v' would start getting an error. Much better to force people to spell the option right in the first place. And any such patch would require additional tests in test_cmd_line.py if the new option is equivalent to an option that's already tested by that file. Being able to give less cryptic names to the various options would be good for shell scripts and sys calls. e.g.: -c ==> --command -d ==> --debugparser -E ==> --noenv -h ==> --help -i ==> --interactive -m ==> --runmodule -O ==> -OO ==> -Q ==> --div old, --div warn, --div warnall, --div new -S ==> --nosite -t ==> --warntabs -tt ==> --errtabs -u ==> --unbuffered -v ==> --verbose -V ==> --version -W ==> --warn -x ==> --skipfirstline As far as I know, the only place these are documented is in "python -h" and the Linux man pages. And good luck to you if you encounter a sys call containing "python -U". Even though not recognising the meaning of the option is likely to be the least of your worries in that case, at least you'd have some idea *why* some Python scripts start collapsing in a screaming heap when you try it ;) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From g.brandl at gmx.net Thu May 4 15:41:54 2006 From: g.brandl at gmx.net (Georg Brandl) Date: Thu, 04 May 2006 15:41:54 +0200 Subject: [Python-Dev] Python long command line options In-Reply-To: <200605040829.53140.me+python-dev@modelnine.org> References: <200605040829.53140.me+python-dev@modelnine.org> Message-ID: Heiko Wundram wrote: > Anyway, back on topic, I personally agree with the people who posted to > comp.lang.python that --version (and possibly --help, possibly other long > parameters too) would be useful additions to Pythons command-line parameters, > as it's increasingly getting more common amongst GNU and BSD utilities to > support these command-line options to get information about the utility at > hand (very popular amongst system administrators) and to use long commandline > options to be able to easily see what an option does when encountered in a > shell script of some sort. > > And, as this doesn't break any old code (-V isn't going away by the patch), I > personally find this to be a very useful change. > > Your thoughts? Personally, I'm +1, but wonder if it would be enough to support '--help' and '--version'. We then could cut out the "best guess" code and the code to enable --opt=value. Georg From me+python-dev at modelnine.org Thu May 4 15:51:22 2006 From: me+python-dev at modelnine.org (Heiko Wundram) Date: Thu, 4 May 2006 15:51:22 +0200 Subject: [Python-Dev] Python long command line options In-Reply-To: References: <200605040829.53140.me+python-dev@modelnine.org> Message-ID: <200605041551.22595.me+python-dev@modelnine.org> Am Donnerstag 04 Mai 2006 15:41 schrieb Georg Brandl: > Heiko Wundram wrote: > > Your thoughts? > > Personally, I'm +1, but wonder if it would be enough to support '--help' > and '--version'. We then could cut out the "best guess" code and the code > to enable --opt=value. The code for the above functionality is about 10-12 lines of C of the whole patch. If there's concensus to remove it, I'll gladly prepare a patch that doesn't contain this, but I don't think it's sensible to do so just because it makes the code shorter. But, the "best guess" functionality most certainly is debatable on other grounds. --- Heiko. From ncoghlan at gmail.com Thu May 4 15:55:34 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 04 May 2006 23:55:34 +1000 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <445A017D.4080207@ofai.at> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445A017D.4080207@ofai.at> Message-ID: <445A07D6.403@gmail.com> Stefan Rank wrote: >> I suggest storing the first element separately from the rest of the path. The >> reason for suggesting this is that you use 'os.sep' to separate elements in >> the normal path, but *not* to separate the first element from the rest. > > I want to add that people might want to manipulate paths that are not > for the currently running OS. Therefore I think the `sep` should be an > attribute of the "root" element. I meant to mention that. The idea I had was for normal path objects to use os.sep and os.extsep (so they can be pickled and unpickled successfully between platforms), and then have a mechanism that allowed a platform specific path to be selected based on the desired platform (i.e. one of the possible values of os.name: 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos'). My inclination was to have a PlatformPath subclass that accepted 'os', 'sep' and 'extsep' keyword arguments to the constructor, and provided the appropriate 'sep' and 'extsep' attributes (supplying 'os' would just be a shortcut to avoid specifying the separators explicitly). That way the main class can avoid being complicated by the relatively rare need to operate on another platform's paths, while still supporting the ability. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From xah at xahlee.org Thu May 4 15:56:38 2006 From: xah at xahlee.org (xahlee) Date: Thu, 4 May 2006 06:56:38 -0700 Subject: [Python-Dev] lambda in Python In-Reply-To: <7bf78738c8226235c5e4290d41a8922f@cogeco.ca> References: <7bf78738c8226235c5e4290d41a8922f@cogeco.ca> Message-ID: <593B03DB-0FE3-49DC-ADD1-EF4BD7B05884@xahlee.org> I do not wish to be the subject of mobbing here. If you have opinions on what i wrote, respond to the subject on topic as with any discussion. Please do not start a gazillion war-cry on me. If you cannot tolerate the way i express my opinions, at this moment write a polite request to me and cc to the sys op of this forum. If the sysop deems fit, I'd be happy to be asked to leave by the sysop. Thanks. Xah xah at xahlee.org ? http://xahlee.org/ On 2006 May 4, at 6:21 AM, Jay Parlar wrote: On May 4, 2006, at 6:00 AM, Talin wrote: > xahlee xahlee.org> writes: > >> Today i ran into one of Guido van Rossum's blog article titled >> ?Language Design Is Not Just Solving Puzzles? at >> http://www.artima.com/weblogs/viewpost.jsp?thread=147358 > > The confrontational tone of this post makes it pretty much impossible > to have a reasonable debate on the subject. I'd suggest that if you > really want to be heard (instead of merely having that "I'm right" > feeling) that you try a different approach. > > -- Talin Xah Lee is a well known troll, he does stuff like this on c.l.p. all the time. Best to just ignore him, he doesn't listen to reason. Jay P. _______________________________________________ Python-Dev mailing list Python-Dev at python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/xah% 40xahlee.org ? From p.f.moore at gmail.com Thu May 4 16:18:29 2006 From: p.f.moore at gmail.com (Paul Moore) Date: Thu, 4 May 2006 15:18:29 +0100 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <445A07D6.403@gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445A017D.4080207@ofai.at> <445A07D6.403@gmail.com> Message-ID: <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> On 5/4/06, Nick Coghlan wrote: > My inclination was to have a PlatformPath subclass that accepted 'os', 'sep' > and 'extsep' keyword arguments to the constructor, and provided the > appropriate 'sep' and 'extsep' attributes (supplying 'os' would just be a > shortcut to avoid specifying the separators explicitly). > > That way the main class can avoid being complicated by the relatively rare > need to operate on another platform's paths, while still supporting the ability. You ought to have predefined classes for the standard OSes. Expecting people to know the values for sep and extsep seems unhelpful. In fact, unless you expect to support the os.path interface forever, as well as the new interface, I'd assume there would have to be internal WindowsPath and PosixPath classes anyway - much like the current ntpath and posixpath modules. So keeping that structure, and simply having if os.name == 'posix': Path = PosixPath elif os.name == 'nt': Path = WindowsPath ... etc at the end, would seem simplest. (But all the current proposals seem to build on os.path, so maybe I should assume otherwise, that os.path will remain indefinitely...) Paul. From sanxiyn at gmail.com Tue May 2 09:55:24 2006 From: sanxiyn at gmail.com (Sanghyeon Seo) Date: Tue, 2 May 2006 16:55:24 +0900 Subject: [Python-Dev] Time since the epoch Message-ID: <5b0248170605020055g2d6747baya099b967c9ae83fc@mail.gmail.com> Hello, Python library reference 6.11 says, "The epoch is the point where the time starts. On January 1st of that year, at 0 hours, the "time since the epoch'' is zero. For Unix, the epoch is 1970." To me this seems to suggest that the epoch may vary among platforms and implementations as long as it's consistent. Am I correct? For example, does it make sense to file bug reports to Python projects assuming that time.time() returns seconds since the Unix epoch? I am asking because currently Python and IronPython returns very different values for time.time() even if they run on the same computer and at the same time. Seo Sanghyeon From fredrik at pythonware.com Thu May 4 16:21:16 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Thu, 4 May 2006 16:21:16 +0200 Subject: [Python-Dev] Python long command line options References: <200605040829.53140.me+python-dev@modelnine.org> <200605041551.22595.me+python-dev@modelnine.org> Message-ID: Heiko Wundram wrote: >> Personally, I'm +1, but wonder if it would be enough to support '--help' >> and '--version'. We then could cut out the "best guess" code and the code >> to enable --opt=value. > > The code for the above functionality is about 10-12 lines of C of the whole > patch. > > If there's concensus to remove it, I'll gladly prepare a patch that doesn't > contain this, but I don't think it's sensible to do so just because it makes > the code shorter. > But, the "best guess" functionality most certainly is debatable on other grounds. exactly. as the zen says, "explicit is better than I know what you mean, even if you don't mean what I think you mean". I'm +1 on adding --help and --version, +1 on adding -? and /? for windows only, -0=slightly sceptical if adding a generic long option machinery is worth it, and -1 on a guessing machinery. From thomas at python.org Thu May 4 16:45:55 2006 From: thomas at python.org (Thomas Wouters) Date: Thu, 4 May 2006 16:45:55 +0200 Subject: [Python-Dev] Time since the epoch In-Reply-To: <5b0248170605020055g2d6747baya099b967c9ae83fc@mail.gmail.com> References: <5b0248170605020055g2d6747baya099b967c9ae83fc@mail.gmail.com> Message-ID: <9e804ac0605040745ia9582a7l3f1bd4d2a0ce077@mail.gmail.com> On 5/2/06, Sanghyeon Seo wrote: > > Hello, > > Python library reference 6.11 says, "The epoch is the point where the > time starts. On January 1st of that year, at 0 hours, the "time since > the epoch'' is zero. For Unix, the epoch is 1970." > > To me this seems to suggest that the epoch may vary among platforms > and implementations as long as it's consistent. Am I correct? Yes. (I believe the C standard doesn't specify the 'epoch', just POSIX does -- for C. Regardless of that, Python's 'epoch' isn't guaranteed anywhere, and the docs you quote are probably the most authorative docs on the question.) For example, does it make sense to file bug reports to Python projects > assuming that time.time() returns seconds since the Unix epoch? I would say so, yes. I am asking because currently Python and IronPython returns very > different values for time.time() even if they run on the same computer > and at the same time. As long as the value returned by time.time() is still 'seconds', and everything in the time and datetime modules properly considers the same epoch, I would say it's a bug (for third-party modules or for other parts of the standard library) to break. -- Thomas Wouters Hi! I'm a .signature virus! copy me into your .signature file to help me spread! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-dev/attachments/20060504/73dc0031/attachment-0001.htm From stefan.rank at ofai.at Thu May 4 17:22:34 2006 From: stefan.rank at ofai.at (Stefan Rank) Date: Thu, 04 May 2006 17:22:34 +0200 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445A017D.4080207@ofai.at> <445A07D6.403@gmail.com> <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> Message-ID: <445A1C3A.9040309@ofai.at> on 04.05.2006 16:18 Paul Moore said the following: > On 5/4/06, Nick Coghlan wrote: >> My inclination was to have a PlatformPath subclass that accepted 'os', 'sep' >> and 'extsep' keyword arguments to the constructor, and provided the >> appropriate 'sep' and 'extsep' attributes (supplying 'os' would just be a >> shortcut to avoid specifying the separators explicitly). >> >> That way the main class can avoid being complicated by the relatively rare >> need to operate on another platform's paths, while still supporting the ability. > > You ought to have predefined classes for the standard OSes. Expecting > people to know the values for sep and extsep seems unhelpful. > I assume that having subclasses (at least for the different os filesystem paths) is not necessary. The sep and extsep that needs to be used is determined by the root of the path. The root, I suppose, is set when constructing the path from a string. The ambiguous cases are relative paths and `p = path()`. (Also think of the proposed URL root which normally would mandate '/' as sep. Actually, the format depends on the 'scheme' part of the URL...) On the output side ( `str(pathinstance)` ) the format is determined by the root. At least if you ignore people who want to have C:/this/style/of/acceptable/windows/path When constructing a relative path, I suggest creating a os dependent one (root==None) by default, even if you use:: p = path('./unix/relative/style') on Windows. Daring people can later use:: p.root = path.WINDOWSRELATIVE # or p.root = path.UNIXRELATIVE if they need to. stefan From g.brandl at gmx.net Thu May 4 17:31:16 2006 From: g.brandl at gmx.net (Georg Brandl) Date: Thu, 04 May 2006 17:31:16 +0200 Subject: [Python-Dev] lambda in Python In-Reply-To: <593B03DB-0FE3-49DC-ADD1-EF4BD7B05884@xahlee.org> References: <7bf78738c8226235c5e4290d41a8922f@cogeco.ca> <593B03DB-0FE3-49DC-ADD1-EF4BD7B05884@xahlee.org> Message-ID: xahlee wrote: > I do not wish to be the subject of mobbing here. > > If you have opinions on what i wrote, respond to the subject on topic > as with any discussion. Please do not start a gazillion war-cry on me. > > If you cannot tolerate the way i express my opinions, at this moment > write a polite request to me and cc to the sys op of this forum. If > the sysop deems fit, I'd be happy to be asked to leave by the sysop. There's no sysop needed to tell you this: This is a mailing list and newsgroup (no "forum") devoted to the development *of* *Python*. Obviously, we all like Python the way it is and people who disagree (especially those who accuse the BDFL of being ignorant) don't belong here. Georg From vys at renet.ru Thu May 4 18:29:58 2006 From: vys at renet.ru (Vladimir 'Yu' Stepanov) Date: Thu, 04 May 2006 20:29:58 +0400 Subject: [Python-Dev] binary trees. Review obmalloc.c In-Reply-To: <1f7befae0604282117r61b3e1ewf451542aa4cb7ac0@mail.gmail.com> References: <20060424114024.66D0.JCARLSON@uci.edu> <444F1E36.30302@renet.ru> <20060426094148.66EE.JCARLSON@uci.edu> <44508866.60503@renet.ru> <445294E8.1080401@v.loewis.de> <1f7befae0604282117r61b3e1ewf451542aa4cb7ac0@mail.gmail.com> Message-ID: <445A2C06.4090606@renet.ru> Tim Peters wrote: > [Vladimir 'Yu' Stepanov] >>> * To adapt allocation of blocks of memory with other alignment. Now >>> alignment is rigidly set on 8 bytes. As a variant, it is possible to >>> use alignment on 4 bytes. And this value can be set at start of the >>> interpreter through arguments/variable environments/etc. At testing >>> with alignment on 4 or 8 bytes difference in speed of work was not >>> appreciable. > > [Martin v. L?wis] >> That depends on the hardware you use, of course. Some architectures >> absolutely cannot stand mis-aligned accesses, and programs will just >> crash if they try to perform such accesses. > > Note that we _had_ to add a goofy "long double" to the PyGC_Head union > because some Python platform required 8-byte alignment for some types > ... see rev 25454. Any spelling of malloc() also needs to return > memory aligned for any legitimate purpose, and 8-byte alignment is the > strictest requirement we know of across current Python platforms. It is possible to receive the reference about these tests? I have lead some tests, which very small difference of speed of work at alignment on 4 and 8 byte (a maximum of 8%, and in the basic less than one percent). In tests consecutive search of elements in one piece of memory was used. I understand, that it is necessary to lead still the test with a casual choice of addresses to minimize optimization of work cache the processor. And certainly not all platforms will show the same result (I shall try to not forget to attach a source code of the test and its result of work :) ). On the other hand reduction of a memory size by each separate copy of object is capable to increase speed by the same percent that is lost at change of displacement about 8 bytes up to 4 :) Besides begins to refuse probably superstructures on allocation of memory at some objects, since int. >> So Python should err on the safe side, and only use a smaller alignment >> when it is known not to hurt. >> >> OTOH, I don't see the *advantage* in reducing the alignment. > > It could cut wasted bytes. There is no per-object memory overhead in > a release-build obmalloc: the allocatable part of a pool is entirely > used for user-visible object memory, except when the alignment > requirement ends up forcing unused (by both the user and by obmalloc) > pad bytes. For example, Python ints consume 12 bytes on 32-bit boxes, > but if space were allocated for them by obmalloc (it's not), obmalloc > would have to use 16 bytes per int to preserve 8-byte alignment. Good note. > OTOH, obmalloc (unlike PyGC_Head) has always used 8-byte alignment, > because that's what worked best for Vladimir Marangozov during his > extensive timing tests. It's not an isolated decision -- e.g., it's > also influenced by, and influences, "the best" pool size, and (of > course) cutting alignment to 4 would double the number of "size > classes" obmalloc has to juggle. Yes, the maximum quantity of buffers will really be doubled. But it should not to affect as that productivity of system, or on total amount of consumed memory. Change of a fragmentation of memory to count it is impossible, since it will depend on the concrete application. >>> * To expand the maximal size which can be allocated by means of the >>> given module. Now the maximal size is 256 bytes. > >> Right. This is somewhat deliberate, though; the expectation is that >> fragmentation will increase dramatically if even larger size classes >> are supported. > > It's entirely deliberate ;-) obmalloc is no way trying to be a > general-purpose allocator. It was designed specifically for the > common memory patterns in Python, aiming at large numbers of small > objects of the same size. That's extremely common in Python, and > allocations larger than 256 bytes are not. The maximum size was > actually 64 bytes at first. After that, dicts grew an embedded > 8-element table, which vastly increased the size of the dict struct. > obmalloc's limit was boosted to 256 then, although it could have > stopped at the size of a dict (in the rough ballpark of 150 bytes). > There was no reason (then or now) to go beyond 256. See below. >>> * At the size of the allocated memory close to maximal, the >>> allocation of blocks becomes inefficient. For example, for the >>> sizesof blocks 248 and 256 (blocksize), values of quantity of >>> elements (PAGESIZE/blocksize) it is equal 16. I.e. it would be >>> possible to use for the sizes of the block 248 same page, as for the >>> size of the block 256. > >> Good idea; that shouldn't be too difficult to implement: for sizes above >> 215, pools need to be spaced apart only at 16 bytes. > > I'd rather drop the limit to 215 then <0.3 wink>. Allocations that > large probably still aren't important to obmalloc, but it is important > that finding a requested allocation's "size index" be as cheap as > possible. Uniformity helps that. An available module on allocation of memory really does not approach for overall aims. And speed of work can "blink" in case of existing non-uniform realization on allocation of memory. In some cases allocation of memory in the module `obmalloc.c' work as function of a wrapper for standard malloc/free, that does not raise speed :) . For an example we shall assume, that two pieces of memory are allocated. One is allocated `obmalloc.c'. Another is allocated standard malloc. Both of a piece are small enough to be realized by similar methods. In a number of OS malloc will lose in speed of work for multi-thread programs, because of blocking the global lock on allocation of memory. Certainly it concerns not to all operational systems. > On modern boxes, it may be desirable to boost POOL_SIZE -- nobody has > run timing experiments as comprehensive as Vladimir ran way back when, > and there's no particular reason to believe that the same set of > tradeoffs would look best on current architectures. As to speed of work it will be not less than in available systems of allocation of memory. Naturally, there are no pluses without what that of minuses. In my opinion available minuses can be made insignificant. Language Python has obviously expressed specificity on allocation of memory that it is possible to use favourably, having developed system of allocation of memory is direct under it. The properties inherent in language Python: * At work in multi-thread a mode already there is blocking GIL which can be used and in case of with allocation of memory. * Objects which are often used, it is better to adapt on the real size, instead of on log2(size(ob)) therefore as function realloc is carried out extremely seldom or even less often :) . * Extremely seldom there are objects the size of the allocated memory multiple 512, 1024, 2048 since before them heading Python of object, and the parameters describing properties of object is placed still. First two items concern and to present `obmalloc.c', but for a narrow circle of allocated blocks of memory. In some interpreters own system of allocation of memory is used. Adjustment of a control system of memory not the latest step to acceleration Python. Thanks everyone who has answered. The theme on former is interesting. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: aligntest.c Url: http://mail.python.org/pipermail/python-dev/attachments/20060504/8a7a928e/attachment.asc -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: out-ia32.txt Url: http://mail.python.org/pipermail/python-dev/attachments/20060504/8a7a928e/attachment.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: out-amd64.txt Url: http://mail.python.org/pipermail/python-dev/attachments/20060504/8a7a928e/attachment-0001.txt From zbir at urbanape.com Thu May 4 18:03:39 2006 From: zbir at urbanape.com (Zachery Bir) Date: Thu, 4 May 2006 12:03:39 -0400 Subject: [Python-Dev] lambda in Python In-Reply-To: References: <7bf78738c8226235c5e4290d41a8922f@cogeco.ca> <593B03DB-0FE3-49DC-ADD1-EF4BD7B05884@xahlee.org> Message-ID: On May 4, 2006, at 11:31 AM, Georg Brandl wrote: > Obviously, we all like Python the way it is and people who disagree > (especially those who accuse the BDFL of being ignorant) don't belong > here. If that were really the case, there wouldn't be much point to having a Python-Dev list, now would there? Zac From gjcarneiro at gmail.com Thu May 4 18:36:19 2006 From: gjcarneiro at gmail.com (Gustavo Carneiro) Date: Thu, 4 May 2006 17:36:19 +0100 Subject: [Python-Dev] Shared libs on Linux (Was: test failures in test_ctypes (HEAD)) In-Reply-To: <4458FC3C.1040407@python.net> References: <4458FC3C.1040407@python.net> Message-ID: On 5/3/06, Thomas Heller wrote: > > [Crossposting to both python-dev and ctypes-users, please respond to the > list > that seems most appropriate] > > Guido van Rossum wrote: > > File "/home/guido/projects/python/trunk/Lib/ctypes/__init__.py", > > line 288, in __init__ > > self._handle = _dlopen(self._name, mode) > > OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion It means that /usr/lib/libglut.so.3 is not explicitly linking to xlibs, but it should. Nothing wrong with python, it's the GL library that was not correctly linked. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-dev/attachments/20060504/4c88fb97/attachment.htm From guido at python.org Thu May 4 18:37:02 2006 From: guido at python.org (Guido van Rossum) Date: Thu, 4 May 2006 09:37:02 -0700 Subject: [Python-Dev] lambda in Python In-Reply-To: References: <7bf78738c8226235c5e4290d41a8922f@cogeco.ca> <593B03DB-0FE3-49DC-ADD1-EF4BD7B05884@xahlee.org> Message-ID: Reminder: the best way to get rid of a troll is to ignore him. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From guido at python.org Thu May 4 18:47:47 2006 From: guido at python.org (Guido van Rossum) Date: Thu, 4 May 2006 09:47:47 -0700 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <4459FA21.6030508@gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> Message-ID: On 5/4/06, Nick Coghlan wrote: > Guido has indicated strong dissatisfaction with the idea of subclassing > str/unicode with respect to PEP 355. That's not my only problem with that PEP; I'm not at all convinced that an object is a better solution than a module for this particular use case. FWIW, subclassing tuple isn't any better in my book than subclassing str/unicode. My only other comment on this discussion: I don't really have time for it; but don't let that stop you all from having a jolly good time. If you need me to pronounce on something, put me (and python-dev) in the To: header and limit your post to 20 lines. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From gustavo at niemeyer.net Thu May 4 18:47:52 2006 From: gustavo at niemeyer.net (Gustavo Niemeyer) Date: Thu, 4 May 2006 13:47:52 -0300 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: References: Message-ID: <20060504164751.GA13442@localhost.localdomain> > The biggest conceptual change is that my path object is a subclass of > ''tuple'', not a subclass of str. For example, Using tuples is a nice idea! Object paths using tuples is a somewhat common concept. I don't see an immediate reason to be a *subclass* of tuple, though, as opposed to using it as an internal representation. > {{{ > p.normpath() -> Isn't needed - done by the constructor > p.basename() -> p[-1] > p.splitpath() -> (p[:-1], p[-1]) > p.splitunc() -> (p[0], p[1:]) (if isinstance(p[0], path.UNCRoot)) > p.splitall() -> Isn't needed > p.parent -> p[:-1] > p.name -> p[-1] > p.drive -> p[0] (if isinstance(p[0], path.Drive)) > p.uncshare -> p[0] (if isinstance(p[0], path.UNCRoot)) > > and of course: > p.join(q) [or anything like it] -> p + q > }}} Nice indeed. > The only drawback I can see in using a logical representation is that > giving a path object to functions which expect a path string won't > work. The immediate solution is to simply use str(p) instead of p. The > long-term solution is to make all related functions accept a path > object. Let's use __path_.. I mean, generic functions! ;-) (...) > * A ''relative path'' is a path without a root element, so it can be > concatenated to other paths. > * An ''absolute path'' is a path whose meaning doesn't change when > the current working directory changes. That sounds right. > == Easier attributes for stat objects == > > The current path objects includes: > * isdir, isfile, islink, and - > * atime, mtime, ctime, size. (...) This indeed shouldn't be attributes of path, IMO, since they are operations that depend on the state of the filesystem, and will change behind your back. > I think that isfile, isdir should be kept (along with lisfile, > lisdir), since I think that doing what they do is quite common, and > requires six lines: I don't agree. "isdir" is an attribute of the filesystem, not of the path object. I'd never expect that e.g. a network operation could result from accessing an attribute in Python, and that could certainly happen if the path is referencing a network filesystem. -- Gustavo Niemeyer http://niemeyer.net From guido at python.org Thu May 4 18:49:32 2006 From: guido at python.org (Guido van Rossum) Date: Thu, 4 May 2006 09:49:32 -0700 Subject: [Python-Dev] Python long command line options In-Reply-To: References: <200605040829.53140.me+python-dev@modelnine.org> <200605041551.22595.me+python-dev@modelnine.org> Message-ID: On 5/4/06, Fredrik Lundh wrote: > I'm +1 on adding --help and --version, +1 on adding -? and /? for windows only, > -0=slightly sceptical if adding a generic long option machinery is worth it, and -1 > on a guessing machinery. I fully support Fredrik's position on this issue. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From gustavo at niemeyer.net Thu May 4 18:53:57 2006 From: gustavo at niemeyer.net (Gustavo Niemeyer) Date: Thu, 4 May 2006 13:53:57 -0300 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445A017D.4080207@ofai.at> <445A07D6.403@gmail.com> <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> Message-ID: <20060504165357.GB13442@localhost.localdomain> > You ought to have predefined classes for the standard OSes. Expecting > people to know the values for sep and extsep seems unhelpful. (...) Why not something as simple as having path.sep == None meaning the default for the platform, and a defined value for otherwise? -- Gustavo Niemeyer http://niemeyer.net From martin at v.loewis.de Thu May 4 19:52:23 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Thu, 04 May 2006 19:52:23 +0200 Subject: [Python-Dev] Python long command line options In-Reply-To: References: <200605040829.53140.me+python-dev@modelnine.org> <200605041551.22595.me+python-dev@modelnine.org> Message-ID: <445A3F57.9020002@v.loewis.de> Fredrik Lundh wrote: > I'm +1 on adding --help and --version, +1 on adding -? and /? for windows only, > -0=slightly sceptical if adding a generic long option machinery is worth it, and -1 > on a guessing machinery. I also agree with all these judgments. Regards, Martin From tjreedy at udel.edu Thu May 4 20:01:24 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 4 May 2006 14:01:24 -0400 Subject: [Python-Dev] Alternative path suggestion References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> Message-ID: "Mike Orr" wrote in message news:6e9196d20605040113x2a2d563ah23fabf02c49a0778 at mail.gmail.com... > Intriguing idea, Noam, and excellent thinking. I'd say it's worth a > separate PEP. I am glad to see this idea resurface and developed. So +1 on an alternate PEP. > The main difficulty with this approach is it's so radical. Only locally. Last July, I wrote the following for clp: http://article.gmane.org/gmane.comp.python.general/412997 Subject: Re: PEP on path module for standard library Date: 2005-07-22 18:47:00 GMT " Very interesting. Java's File class is a system-independent "abstract representation of file and directory pathnames" which is constructed from and converted to system-dependent string-form pathnames (including URL/URI file:... forms). A File consist of an optional prefix and a *sequence* of zero or more string names. In other words, Java's File class is what Duncan and I thought Python's Path class might or possibly should be. So this internal representation might be worth considering as an option. Of course, if the interface is done right, it mostly should not make too much difference to the user. " I believe a previous post gave the reference to the File doc, which might be worth consulting. As I remember, the general response at that time was that the existing string-based path class was tried, useful, and well accepted, so why try anything more different. That seems to have become clearer with time. Terry Jan Reedy From tim.peters at gmail.com Thu May 4 20:08:49 2006 From: tim.peters at gmail.com (Tim Peters) Date: Thu, 4 May 2006 14:08:49 -0400 Subject: [Python-Dev] [Python-checkins] r45898 - in python/trunk: Lib/test/test_os.py Lib/test/test_shutil.py Misc/NEWS Modules/posixmodule.c In-Reply-To: <445A3E4A.8060402@v.loewis.de> References: <20060504100844.5C1691E4007@bag.python.org> <445A3E4A.8060402@v.loewis.de> Message-ID: <1f7befae0605041108j65d7f6f4jc320282696b6893f@mail.gmail.com> [Guido] >> I wonder if it's time to move the Win32 code out of posixmodule.c? It >> seems the current mess of #ifdefs can't be very maintainable. [Martin v. L?wis] > I vaguely recall that we had considered that before, and rejected it, > for some reason. Not sure what the reason was, but one might have been > that there still is OS/2 code in there, also. Martin worked up a patch for this in 2002, which he withdrew based on mixed reviews (a +0.5 and two -0); the comments still seem relevant: http://www.python.org/sf/592529 From rasky at develer.com Thu May 4 21:01:01 2006 From: rasky at develer.com (Giovanni Bajo) Date: Thu, 4 May 2006 21:01:01 +0200 Subject: [Python-Dev] [Python-checkins] r45898 - in python/trunk:Lib/test/test_os.py Lib/test/test_shutil.py Misc/NEWSModules/posixmodule.c References: <20060504100844.5C1691E4007@bag.python.org><445A3E4A.8060402@v.loewis.de> <1f7befae0605041108j65d7f6f4jc320282696b6893f@mail.gmail.com> Message-ID: <04d901c66fad$15edf720$bf03030a@trilan> Tim Peters wrote: > [Martin v. L?wis] >> I vaguely recall that we had considered that before, and rejected it, >> for some reason. Not sure what the reason was, but one might have >> been that there still is OS/2 code in there, also. > > Martin worked up a patch for this in 2002, which he withdrew based on > mixed reviews (a +0.5 and two -0); the comments still seem relevant: > > http://www.python.org/sf/592529 I think another way of doing it would be to keep the single module posixmodule (maybe appropriately renamed) and then internally dispatch function implementations where possible. If the dispatching is done correctly (through a fixed size virtual table for all the platforms), BuildBot should be able to tell you quite fast if you forgot something. At least, this setup would fix the docstring and the largefile issues raised in your comment in that bug. -- Giovanni Bajo From amk at amk.ca Thu May 4 22:22:32 2006 From: amk at amk.ca (A.M. Kuchling) Date: Thu, 4 May 2006 16:22:32 -0400 Subject: [Python-Dev] Confirmed: DC-area sprint on Sat. June 3rd Message-ID: <20060504202232.GA31662@rogue.amk.ca> The DC-area sprint is now confirmed. It'll be on Saturday June 3, from 10 AM to 5 PM at the Arlington Career Center in Arlington VA. I've created a wiki page at ; please add your name if you'll be coming. The wiki page can also be used to brainstorm about tasks to work on. While this started out as a Python core sprint, there's no problem if people want to come and work on something other than the Python core (space permitting). I'm still waiting to get an upper limit on attendance, and will add that figure to the wiki page once I get it. --amk From me+python-dev at modelnine.org Thu May 4 21:25:49 2006 From: me+python-dev at modelnine.org (Heiko Wundram) Date: Thu, 4 May 2006 21:25:49 +0200 Subject: [Python-Dev] Python long command line options In-Reply-To: References: <200605040829.53140.me+python-dev@modelnine.org> <200605041551.22595.me+python-dev@modelnine.org> Message-ID: <200605042125.49602.me+python-dev@modelnine.org> Am Donnerstag 04 Mai 2006 16:21 schrieb Fredrik Lundh: > I'm +1 on adding --help and --version, +1 on adding -? and /? for windows > only, -0=slightly sceptical if adding a generic long option machinery is > worth it, and -1 on a guessing machinery. I've updated the patch on the SourceForge tracker to reflect this criticism. In effect: 1) --help and --version are added unconditionally on all platforms 2) -? and /? are recognized on Windows, as are /help and /version, because / is just a different longopt-specifier on Windows for the getopt machinery in _PyOS_GetOpt 3) I removed the prefix matching 4) I removed the last reference to a string function in _PyOS_GetOpt 5) --command, which was a test-case for me, has been removed as a long-opt again. The module has undergone a complete rewrite with this patch, and I've adapted the module header to reflect this (because there's absolutely no legacy code left now, which can be seen pretty clearly when you look at a diff...). The usage output in Modules/main.c has also been adapted, as have the test cases in test_cmd_line.py for usage and version, which pass cleanly for me. The patch doesn't produce any warnings on gcc 3.4.6, and I've tested the Windows-specific additions to _PyOS_GetOpt by injecting MS_WINDOWS into the compilation on my system for Python/getopt.c, and it produces correct results on /?, /version, /help, and -?, but as I said before I can't tell whether there are bugs left which surface when it's being compiled on Windows directly, as I don't have a Windows system to test this patch on. Anyway, would be glad to hear any feedback. --- Heiko. From me+python-dev at modelnine.org Thu May 4 22:12:09 2006 From: me+python-dev at modelnine.org (Heiko Wundram) Date: Thu, 4 May 2006 22:12:09 +0200 Subject: [Python-Dev] Python long command line options In-Reply-To: <200605042125.49602.me+python-dev@modelnine.org> References: <200605040829.53140.me+python-dev@modelnine.org> <200605042125.49602.me+python-dev@modelnine.org> Message-ID: <200605042212.10035.me+python-dev@modelnine.org> Am Donnerstag 04 Mai 2006 21:25 schrieb Heiko Wundram: > 2) -? and /? are recognized on Windows, as are /help and /version, > because / is just a different longopt-specifier on Windows for the > getopt machinery in _PyOS_GetOpt Just on a side-note: I chose for '/' to be a long-opt identifier on Windows, because it is for pretty much any Microsoft programming tool out there, starting with the linker, ending with the compiler of MSVC++, amongst others. I know that shell commands such as dir, etc. take / to be similar to - on *nix (as single character command line arguments), but I guess the former is more useful. It's no problem to change this behaviour, though. --- Heiko. From fredrik at pythonware.com Thu May 4 23:20:09 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Thu, 4 May 2006 23:20:09 +0200 Subject: [Python-Dev] context guards, context entry values, context managers, context contexts Message-ID: fwiw, I just tested http://pyref.infogami.com/with on a live audience, and most people seemed to grok the "context guard" concept quite quickly. note sure about the "context entry value" term, though. anyone has a better idea ? From pje at telecommunity.com Thu May 4 23:39:24 2006 From: pje at telecommunity.com (Phillip J. Eby) Date: Thu, 04 May 2006 17:39:24 -0400 Subject: [Python-Dev] context guards, context entry values, context managers, context contexts In-Reply-To: Message-ID: <5.1.1.6.0.20060504173609.01e89930@mail.telecommunity.com> At 11:20 PM 5/4/2006 +0200, Fredrik Lundh wrote: >fwiw, I just tested > > http://pyref.infogami.com/with > >on a live audience, and most people seemed to grok the "context >guard" concept quite quickly. > >note sure about the "context entry value" term, though. anyone >has a better idea ? "guarded value"? That works for files, at least. From ncoghlan at gmail.com Thu May 4 23:43:45 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Fri, 05 May 2006 07:43:45 +1000 Subject: [Python-Dev] context guards, context entry values, context managers, context contexts In-Reply-To: References: Message-ID: <445A7591.8040302@gmail.com> Fredrik Lundh wrote: > fwiw, I just tested > > http://pyref.infogami.com/with > > on a live audience, and most people seemed to grok the "context > guard" concept quite quickly. Compared to the various other changes made lately to PEP 343, s/manager/guard/ would be a fairly straightforward one :) I'm personally +1 on switching to 'guard' for the following reasons: - 'guarding' block entry and exit seems much more natural terminology to me than 'managing' entry and exit (since the block entry and exit is really still managed by the interpreter - the guard is just given the change to intervene in both cases). - 'manager' is a pretty generic term ('wooly' as Greg put it), so it needs to be qualified a lot more often than 'guard' does. - .NET uses 'managed code' in relation to sandboxes (as I understand it), so I suspect 'context manager' would up causing at least a bit of confusion in relation to IronPython OTOH, I also think getting rid of __context__() has made the problems with the term context manager far less severe, so I'm not averse to the idea of leaving it alone, either. > note sure about the "context entry value" term, though. anyone > has a better idea ? The latest version of the PEP punts on this entirely - for most real use cases, you're going to be talking about a specific thing, anyway (such as the new decimal context returned by a decimal context manager). "context entry value" really isn't that much better than "result of the __enter__ method", and the latter has the virtue of being explicit. . . Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From ncoghlan at gmail.com Thu May 4 23:49:42 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Fri, 05 May 2006 07:49:42 +1000 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> Message-ID: <445A76F6.4080101@gmail.com> Guido van Rossum wrote: > On 5/4/06, Nick Coghlan wrote: >> Guido has indicated strong dissatisfaction with the idea of subclassing >> str/unicode with respect to PEP 355. > > That's not my only problem with that PEP; I'm not at all convinced > that an object is a better solution than a module for this particular > use case. Object vs module isn't my objection to the standard library status quo, either - it's the fact that it's a choice of using one object vs 5 or 6 different modules ;) However, I'm going to have to bow out of this discussion for now, too - it's interesting, but Python 2.5 is a lot closer than Python 2.6. . . Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From tdelaney at avaya.com Fri May 5 00:46:52 2006 From: tdelaney at avaya.com (Delaney, Timothy (Tim)) Date: Fri, 5 May 2006 08:46:52 +1000 Subject: [Python-Dev] lambda in Python Message-ID: <2773CAC687FD5F4689F526998C7E4E5FF1E6C5@au3010avexu1.global.avaya.com> Guido van Rossum wrote: > Reminder: the best way to get rid of a troll is to ignore him. Indeed. Xah got past Spambayes for me because this time he posted on Python-dev - I doubt that he'll get past Spambayes again by doing that :) Should we add an explicit rule to the Python-dev spam filter for Xah? Based on his past history, I doubt we'll ever see anything useful from him. Tim Delaney From greg.ewing at canterbury.ac.nz Fri May 5 02:59:24 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 05 May 2006 12:59:24 +1200 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> Message-ID: <445AA36C.9080700@canterbury.ac.nz> Mike Orr wrote: > The main difficulty with this approach is it's so radical. It would > require a serious champion to convince people it's as good as our > tried-and-true strings. Another thing you would need to do is implement it for some of the less Unix-like path syntaxes, such as Classic MacOS and VMS, to make sure that it's feasible to fit them into your tuple-like format. > The question is, does forcing people to use .stat() expose an > implementation detail that should be hidden, and does it smell of > Unixism? Most people think a file *is* a regular file or a directory. > The fact that this is encoded in the file's permission bits -- which > stat() examines -- is a quirk of Unix. Permission bits aren't the only thing that stat() examines. I don't see anything wrong with having stat() be the way to get at whatever metadata there is about a file on a platform. And having .isdir etc. attributes on the stat() result abstracts whether they're obtained from the permission bits or not. -- Greg From greg.ewing at canterbury.ac.nz Fri May 5 03:29:15 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 05 May 2006 13:29:15 +1200 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <4459FA21.6030508@gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> Message-ID: <445AAA6B.7030108@canterbury.ac.nz> Nick Coghlan wrote: > Similarly, I would separate out the extension to a distinct attribute, as it > too uses a different separator from the normal path elements ('.' most places, > but '/' on RISC OS, for example) -1. What constitutes "the extension" is not well-defined in all cases. What about filenames with multiple suffixes, such as "spam.tar.gz"? What part of that would you put in the extension attribute? -- Greg From greg.ewing at canterbury.ac.nz Fri May 5 04:03:44 2006 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 05 May 2006 14:03:44 +1200 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445476CC.3080008@v.loewis.de> <4455A0CF.3080008@v.loewis.de> <445644D1.3050200@v.loewis.de> <44573D75.40007@canterbury.ac.nz> <445805EA.7000501@canterbury.ac.nz> <740c3aec0605031621v48f33dd0g591cb12a131764e8@mail.gmail.com> <44598128.8060506@canterbury.ac.nz> Message-ID: <445AB280.8060701@canterbury.ac.nz> Terry Reedy wrote: > The dispute is about the sensibility and > politeness of requiring a small fixed number of required, no-default args > to be passed by name only There seems to be some confusion between two different subthreads here. BJ?rn Lindqvist seemed to be saying that instead of my suggested make_person(=name, =age, =phone, =location) as a substitute for make_person(name=name, age=age, phone=phone, location=location) it would be better to pass the arguments positionally. I was pointing out that you can't do this when the thing you're calling requires them to be passed by keyword. -- Greg From tim.peters at gmail.com Fri May 5 07:16:15 2006 From: tim.peters at gmail.com (Tim Peters) Date: Fri, 5 May 2006 01:16:15 -0400 Subject: [Python-Dev] Python sprint mechanics Message-ID: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> There's going to be a Python sprint in Iceland later this month, and it raises some management issues we also see on Bug Days, but more so: a relatively large number of people slinging code without commit privileges, and a relative handful with commit privileges. The latter end up spending all their time reviewing and doing commits for the former. While that may be unavoidable for Bug Days, a major difference for the sprint is that little of the code is likely _intended_ to end up on the trunk at this time. Instead it would make best sense for each sprint project to work in its own branch, something SVN makes very easy, but only for those who _can_ commit. This year's PyCon core sprint isn't a good model here, as everyone there did have commit privs -- and that's unusual. Since I hope we see a lot more of these problems in the future, what can be done to ease the pain? I don't know enough about SVN admin to know what might be realistic. Adding a pile of "temporary committers" comes to mind, but wouldn't really work since people will want to keep working on their branches after the sprint ends. Purely local SVN setups wouldn't work either, since sprint projects will generally have more than one worker bee, and they need to share code changes. There: I think that's enough to prove I don't have a clue :-) From nnorwitz at gmail.com Fri May 5 07:25:18 2006 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 4 May 2006 22:25:18 -0700 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> Message-ID: On 5/4/06, Tim Peters wrote: > > Since I hope we see a lot more of these problems in the future, what Me too. > can be done to ease the pain? I don't know enough about SVN admin to > know what might be realistic. Adding a pile of "temporary > committers" comes to mind, but wouldn't really work since people will > want to keep working on their branches after the sprint ends. Purely > local SVN setups wouldn't work either, since sprint projects will > generally have more than one worker bee, and they need to share code > changes. There: I think that's enough to prove I don't have a clue I guess that means it's my turn to let my ignorance shine yet again. :-) Could we take a snapshot of the SVN repo, hosted on python.org, open it up for public commit during the period? That seems easy to setup. The difficulty would come in when we need to merge back to the real SVN. n From martin at v.loewis.de Fri May 5 07:37:15 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Fri, 05 May 2006 07:37:15 +0200 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> Message-ID: <445AE48B.1070508@v.loewis.de> Tim Peters wrote: > Since I hope we see a lot more of these problems in the future, what > can be done to ease the pain? I don't know enough about SVN admin to > know what might be realistic. Adding a pile of "temporary > committers" comes to mind, but wouldn't really work since people will > want to keep working on their branches after the sprint ends. Purely > local SVN setups wouldn't work either, since sprint projects will > generally have more than one worker bee, and they need to share code > changes. I think Fredrik Lundh points to svk at such occasions. People usually get commit privileges when they have demonstrates to simultaneously meet a number of requirements, such as - following style guides - never committing anything without discussion which might cause strong opposition - always committing tests and documentation along with the actual code changes - licensing all of their own changes to the PSF - ...more things I can't put into words right now. Of course, many committers miss some of these rules some of the time, but I hope they all feel guilty when doing so :-) It might be reasonable to waive the "have demonstrated" part for some group of people, i.e. give them commit privs after telling them what the rules are. However, in this case, I'd would really like to see some "shepherd" who oversees this group of people. gcc has a "commit-after-approval" privilege; if you have that, you can only commit after somebody (a "maintainer") has approved a change. Approvals are 'on file' in a mailing list archive. I could imagine such a model for sprint participants, if there would be somebody to volunteer as a shepherd. That person would have to track the status of the individual projects, and either revoke commit privs when the project is eventually completed, or grant the contributors permanent (without-approval) commit privs if he considers this appropriate. Regards, Martin From anthony at interlink.com.au Fri May 5 07:54:17 2006 From: anthony at interlink.com.au (Anthony Baxter) Date: Fri, 5 May 2006 15:54:17 +1000 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> Message-ID: <200605051554.23062.anthony@interlink.com.au> On Friday 05 May 2006 15:16, Tim Peters wrote: > While that may be unavoidable for Bug Days, a major difference for > the sprint is that little of the code is likely _intended_ to end > up on the trunk at this time. Given where we are in the 2.5 release cycle, I'd _hope_ that only safe changes are considered for landing on the trunk. Massive refactorings really don't fill me with happy thoughts. Anthony -- Anthony Baxter It's never too late to have a happy childhood. From sluggoster at gmail.com Fri May 5 09:05:49 2006 From: sluggoster at gmail.com (Mike Orr) Date: Fri, 5 May 2006 00:05:49 -0700 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <445AAA6B.7030108@canterbury.ac.nz> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445AAA6B.7030108@canterbury.ac.nz> Message-ID: <6e9196d20605050005u432ea0a4w9666d81cc2537f37@mail.gmail.com> I've updated the wiki with a second proposal based on this thread, and also summarized the Python-dev discussions. Please make sure your favorite feature or pet peeve is adequately represented. http://wiki.python.org/moin/AlternativePathClass -- Mike Orr (mso at oz.net address is semi-reliable) From sluggoster at gmail.com Fri May 5 09:15:39 2006 From: sluggoster at gmail.com (Mike Orr) Date: Fri, 5 May 2006 00:15:39 -0700 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <4459FA21.6030508@gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> Message-ID: <6e9196d20605050015g492ae7c9p3e3d63e238729fe6@mail.gmail.com> On 5/4/06, Nick Coghlan wrote: > Mike Orr wrote: > >> == a tuple instead of a string == > >> > >> The biggest conceptual change is that my path object is a subclass of > >> ''tuple'', not a subclass of str. > > Why subclass anything? The path should internally represent the filesystem > path as a list or tuple, but it shouldn't *be* a tuple. Good point. > Also, was it a deliberate design decision to make the path objects immutable, > or was that simply copied from the fact that strings are immutable? > > Given that immutability allows the string representation to be calculated once > and then cached, I'll go with that interpretation. Immutability also allows them to be dictionary keys. This is convenient in many applications. > Similarly, I would separate out the extension to a distinct attribute, as it > too uses a different separator from the normal path elements ('.' most places, > but '/' on RISC OS, for example) That would be too surprising to users. p[-1] should be the full filename. We can use p.name, p.extsep, and p.ext for the parts. > Alternatively, if the path elements are stored in separate attributes, there's > nothing stopping the main object from inheriting from str or unicode the way > the PEP 355 path object does. Do the string methods call .__str__(), or how do they get the string value? > I wouldn't expose stat() - as you say, it's a Unixism. Instead, I'd provide a > subclass of Path that used lstat instead of stat for symbolic links. > > So if I want symbolic links followed, I use the normal Path class. This class > just generally treat symbolic links as if they were the file pointed to > (except for the whole not recursing into symlinked subdirectories thing). > > The SymbolicPath subclass would treat normal files as usual, but *wouldn't* > follow symbolic links when stat'ting files (instead, it would stat the symlink). Normally I'd be processing the subdirectories, then the symlinks, off the same path. I'd rather just call a different method rather than having to construct another object. > >> == One Method for Finding Files == > >> > >> (They're actually two, but with exactly the same interface). The > >> original path object has these methods for finding files: > >> > >> {{{ > >> def listdir(self, pattern = None): ... > >> def dirs(self, pattern = None): ... > >> def files(self, pattern = None): ... > >> def walk(self, pattern = None): ... > >> def walkdirs(self, pattern = None): ... > >> def walkfiles(self, pattern = None): ... > >> def glob(self, pattern): > >> }}} > >> > >> I suggest one method that replaces all those: > >> {{{ > >> def glob(self, pattern='*', topdown=True, onlydirs=False, onlyfiles=False): ... > >> }}} > > Swiss army methods are even more evil than wide APIs. I don't see the point in combining these either. There's the problem of walking special files, but these are so rare and diverse that we either have to provide methods for all of them, or an argument, or force the user to use .walk(). Since they are rare, the latter is OK. > Now, what might potentially be genuinely useful is paired walk methods that > allowed the following: > > # Do path.walk over this directory, and also return the corresponding > # information for a destination directory (so the dest dir information > # probably *won't* match that file system > for src_info, dest_info in src_path.pairedwalk(dest_path): > src_dirpath, src_subdirs, src_files = src_info > dest_dirpath, dest_subdirs, dest_files = dest_info > # Do something useful > > # Ditto for path.walkdirs > for src_dirpath, dest_dirpath in src_path.pairedwalkdirs(dest_path): > # Do something useful > > # Ditto for path.walkfiles > for src_path, dest_path in src_path.pairedwalkfiles(dest_path): > src_path.copy_to(dest_path) These look like os.walk() derivatives. I've never found that as useful as getting a flat iteration of paths. But if enough people want it... -- Mike Orr (mso at oz.net address is semi-reliable) From sluggoster at gmail.com Fri May 5 09:26:45 2006 From: sluggoster at gmail.com (Mike Orr) Date: Fri, 5 May 2006 00:26:45 -0700 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445A017D.4080207@ofai.at> <445A07D6.403@gmail.com> <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> Message-ID: <6e9196d20605050026o6675b2d4jc97380bb4dde4ced@mail.gmail.com> On 5/4/06, Paul Moore wrote: > On 5/4/06, Nick Coghlan wrote: > > My inclination was to have a PlatformPath subclass that accepted 'os', 'sep' > > and 'extsep' keyword arguments to the constructor, and provided the > > appropriate 'sep' and 'extsep' attributes (supplying 'os' would just be a > > shortcut to avoid specifying the separators explicitly). > > > > That way the main class can avoid being complicated by the relatively rare > > need to operate on another platform's paths, while still supporting the ability. > > You ought to have predefined classes for the standard OSes. Expecting > people to know the values for sep and extsep seems unhelpful. > > In fact, unless you expect to support the os.path interface forever, > as well as the new interface, I'd assume there would have to be > internal WindowsPath and PosixPath classes anyway - much like the > current ntpath and posixpath modules. So keeping that structure, and > simply having > > if os.name == 'posix': > Path = PosixPath > elif os.name == 'nt': > Path = WindowsPath > ... etc > > at the end, would seem simplest. Why not just put a platform-specific Path class inside posixpath, macpath, etc. Python already chooses os.path for the actual platform, and you can import a foreign module directly if you want to. > (But all the current proposals seem to build on os.path, so maybe I > should assume otherwise, that os.path will remain indefinitely...) They build on os.path because that's what we're familiar with using. There's no reason to write the platform-specific classes until we agree on an API; that would just be work down the drain. When the new classes are in the library, we can: (one or more) - Leave os.path.foo() alone because it works and most existing programs need it. - Discourage os.path.foo() in the documentation but continue to support it. - Rewrite os.path.foo() to use Path.foo(). A lot of useless work if we... - Remove os.path.foo() in Python 3.0. -- Mike Orr (mso at oz.net address is semi-reliable) From fredrik at pythonware.com Fri May 5 09:27:16 2006 From: fredrik at pythonware.com (Fredrik Lundh) Date: Fri, 5 May 2006 09:27:16 +0200 Subject: [Python-Dev] Python sprint mechanics References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> <445AE48B.1070508@v.loewis.de> Message-ID: Martin v. Löwis wrote: > I think Fredrik Lundh points to svk at such occasions. SVK makes it trivial to mirror a remote SVN repository, and make zillions of local light-weight branches against that repository (e.g.one branch per bug you're working on); see e.g. http://gcc.gnu.org/wiki/SvkHelp for a brief tutorial. I think you can set things up so others can work against your local repository, but I haven't done that myself. anyone here knows more about this ? (if that turns out to be hard, it's trivial to work with patch sets under SVK). From vys at renet.ru Fri May 5 09:50:12 2006 From: vys at renet.ru (Vladimir 'Yu' Stepanov) Date: Fri, 05 May 2006 11:50:12 +0400 Subject: [Python-Dev] binary trees. Review obmalloc.c In-Reply-To: <20060502222033.678D.JCARLSON@uci.edu> References: <20060426094148.66EE.JCARLSON@uci.edu> <44508866.60503@renet.ru> <20060502222033.678D.JCARLSON@uci.edu> Message-ID: <445B03B4.6070600@renet.ru> Josiah Carlson wrote: > "Vladimir 'Yu' Stepanov" wrote: > > >> Comparison of functions of sorting and binary trees not absolutely >> correctly. I think that function sort will lose considerably on >> greater lists. Especially after an insert or removal of all one element. >> > > Generally speaking, people who understand at least some of Python's > internals (list internals specifically), will not be *removing* entries > from lists one at a time (at least not using list.pop(0) ), because that > is slow. If they need to remove items one at a time from the smallest > to the largest, they will usually use list.reverse(), then repeatedly > list.pop(), as this is quite fast (in general). > Yes. I understood it when resulted a set example. > However, as I just said, people usually don't remove items from > just-sorted lists, they tend to iterate over them via 'for i in list:' . > Such problem arises at creation of the list of timers. And this list is in constant change: addition/removal of elements in the list. collections.deque here does not approach, as if addition in the big list is made or search of the nearest value on the average it is necessary to lead quantity of checks N/2 is made. For a binary tree the quantity of necessary checks on former is equal log2 (N). Other variant of use of binary trees: search of concurrence to ranges. Such ranges can be blocks IP of addresses. Also this kind of the dictionary can be used for a fast finding, whether the given point enters into one of pieces. These problems can be realized by means of binary search. For binary search the same lacks, as for above resulted example are characteristic: the insert and removal for lists are carried out slowly and after an insert sorting of the list is required. Except for that function of binary search is absent in standard package Python. It is possible to write its analogue on pure Python, but it will be more than twice more slowly. > - Josiah > > As an aside, I have personally implemented trees a few times for > different reasons. One of the issues I have with most tree > implementations is that it is generally difficult to do things like > "give me the kth smallest/largest item". Of course the standard > solution is what is generally called a "partial order" or "order > statistic" tree, but then you end up with yet another field in your > structure. One nice thing about Red-Black trees combined with > order-statistic trees, is that you can usually use the uppermost bit of > the order statistics for red/black information. Of course, this is > really only interesting from an "implement this in C" perspective; > because if one were implementing it in Python, one may as well be really > lazy and not bother implementing guaranteed balanced trees and be > satisfied with randomized-balancing via Treaps. Here that I have found through Google on a line " order statistic binary tree ": http://www.cs.mcgill.ca/~cs251/OldCourses/1997/topic20/ I have understood, that similar I have already made something :). The result of the test shows on the most bad result, but is certainly worse, than a usual tree. Badly that up to the end I have not tested this realization. Percent on 90 I am assured that it is efficient. There is a question. What API should be used? Therefore as if to address to object, as to MAP to object __getitem__ will return one result. And if as to the list - another. Here the list of already existing attributes and methods: class xtree(__builtin__.object) | X-Tree. Binary tree with AVL balance mechanism. | | Methods defined here: | | __contains__(...) | x.__contains__(y) <==> y in x | | __delitem__(...) | x.__delitem__(y) <==> del x[y] | | __getitem__(...) | x.__getitem__(y) <==> x[y] | | __iter__(...) | x.__iter__() <==> iter(x) | | __len__(...) | x.__len__() <==> len(x) | | __repr__(...) | x.__repr__() <==> repr(x) | | __setitem__(...) | x.__setitem__(i, y) <==> x[i]=y | | append(...) | D.append((k: v)) -> None, append new pair element into tree with sorting. | Return pair element if argument is exist. | | clear(...) | D.clear() -> None. Remove all items from D. | | copy(...) | D.copy() -> a shallow copy of D. | | get(...) | D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. | | has_key(...) | D.has_key(k) -> True if D has a key k, else False. | | items(...) | D.items() -> list of D's (key, value) pairs. | | iteritems(...) | D.iteritems() -> an iterator over the (key, value) items of D. | | iterkeys(...) | D.iterkeys() -> an iterator over the keys of D. | | itervalues(...) | D.itervalues() -> an iterator over the values of D. | | keys(...) | D.keys() -> list of D's keys. | | pop(...) | D.pop(k[,d]) -> v, remove specified key and return the corresponding value. | If key is not found, d is returned if given, otherwise KeyError is raised. | | popitem(...) | D.popmin() -> (k, v), remove and return minimal (key, value) pair as a | 2-tuple; but raise KeyError if D is empty. | | popmax(...) | D.popmax() -> (k, v), remove and return maximal (key, value) pair as a | 2-tuple; but raise KeyError if D is empty. | | popmin(...) | D.popmin() -> (k, v), remove and return minimal (key, value) pair as a | 2-tuple; but raise KeyError if D is empty. | | pushmax(...) | D.pushmax(item) -> (k, v), remove and return maximal (key, value) pair as a | 2-tuple; but raise KeyError if D is empty. | | pushmin(...) | D.pushmin(item) -> (k, v), remove and return minimal (key, value) pair as a | 2-tuple; but raise KeyError if D is empty. | | rebuild(...) | D.rebuild() -> None. Take compare function for rebuild dictionary. | It works without use of additional memory on a place. | | setdefault(...) | D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D. | | update(...) | D.update(E) -> None. Update D from E and F: for k in E: D[k] = E[k] | (if E has keys else: for (k, v) in E: D[k] = v). | | values(...) | D.values() -> list of D's values. | | ---------------------------------------------------------------------- | Data descriptors defined here: | | cmp | function of comparison of objects | | freeze | to block an opportunity change of object. | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __new__ = | T.__new__(S, ...) -> a new object with type S, a subtype of T > Of course all of this discussion about trees in Python is fine, though > there is one major problem. With minimal work, one can construct 3 > values such that ((a < b < c) and (c < a)) is true. > The same problem is inherent in the standard dictionary - dict (), only roots at it, it is others. For example: class test: def __hash__(self): return random.randint(0, 1000000) The binary tree is very easy for tearing down. Therefore when any reference to it is made, blocking either on reading, or on record should be established. If it is opened iterator on the given object also blocking on reading should be established where iterator will not come to the end or while it will not be closed or destroyed. Thus it is possible to guarantee security of object. Functions of blocking are similar on pthread_rdlock_trylock, and pthread_wrlock_trylock. If blocking is impossible, exception RDLockError, WRLockError, FreezeLockError is generated. Thanks. -- Vladimir Stepanov -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: avl-timeit.py Url: http://mail.python.org/pipermail/python-dev/attachments/20060505/6dd159df/attachment.asc -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test-normal.txt Url: http://mail.python.org/pipermail/python-dev/attachments/20060505/6dd159df/attachment.txt -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test-order-statistic.txt Url: http://mail.python.org/pipermail/python-dev/attachments/20060505/6dd159df/attachment-0001.txt From p.f.moore at gmail.com Fri May 5 10:13:00 2006 From: p.f.moore at gmail.com (Paul Moore) Date: Fri, 5 May 2006 09:13:00 +0100 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> Message-ID: <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> On 5/5/06, Tim Peters wrote: > Since I hope we see a lot more of these problems in the future, what > can be done to ease the pain? I don't know enough about SVN admin to > know what might be realistic. Adding a pile of "temporary > committers" comes to mind, but wouldn't really work since people will > want to keep working on their branches after the sprint ends. Purely > local SVN setups wouldn't work either, since sprint projects will > generally have more than one worker bee, and they need to share code > changes. There: I think that's enough to prove I don't have a clue > :-) Is it possible to create a branch in the main Python svn, and grant commit privs to that branch only, for sprint participants? I seem to recall something like mod_authzsvn being involved, but I don't know much more... Paul. From ncoghlan at gmail.com Fri May 5 10:48:39 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Fri, 05 May 2006 18:48:39 +1000 Subject: [Python-Dev] Alternative path suggestion In-Reply-To: <6e9196d20605050026o6675b2d4jc97380bb4dde4ced@mail.gmail.com> References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com> <4459FA21.6030508@gmail.com> <445A017D.4080207@ofai.at> <445A07D6.403@gmail.com> <79990c6b0605040718s10b6e177s95906387806e2508@mail.gmail.com> <6e9196d20605050026o6675b2d4jc97380bb4dde4ced@mail.gmail.com> Message-ID: <445B1167.5000401@gmail.com> Mike Orr wrote: > On 5/4/06, Paul Moore wrote: >> (But all the current proposals seem to build on os.path, so maybe I >> should assume otherwise, that os.path will remain indefinitely...) > > They build on os.path because that's what we're familiar with using. > There's no reason to write the platform-specific classes until we > agree on an API; that would just be work down the drain. When the new > classes are in the library, we can: (one or more) > > - Leave os.path.foo() alone because it works and most existing programs need it. The threading module doesn't really obsolete the thread module, it just provides a higher level, more convenient API. Similarly, I don't believe it's a given that a nice path object will obsolete the low level operations. When translating a shell script to Python (or vice versa), having access to the comparable low level operations would be of benefit. At most, I would expect provision of an OO path API to result in a comment in the documentation of various modules (os.path, shutil, fnmatch, glob) saying that "pathlib.Path" (or whatever it ends up being called) is generally a more convenient API. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From murman at gmail.com Fri May 5 15:20:02 2006 From: murman at gmail.com (Michael Urman) Date: Fri, 5 May 2006 08:20:02 -0500 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <44573D75.40007@canterbury.ac.nz> <445805EA.7000501@canterbury.ac.nz> <740c3aec0605031621v48f33dd0g591cb12a131764e8@mail.gmail.com> <44598128.8060506@canterbury.ac.nz> <445AB280.8060701@canterbury.ac.nz> Message-ID: On 5/5/06, Terry Reedy wrote: > At present, Python allows this as a choice. Not always - take a look from another perspective: def make_person(**kwds): name = kwds.pop('name', None) age = kwds.pop('age', None) phone = kwds.pop('phone', None) location = kwds.pop('location', None) ... This already requires the caller to use keywords, but results in horrid introspection based documentation. You know it takes some keywords, but you have no clue what keywords they are. It's as bad as calling help() on many of the C functions in the python stdlib. So what allowing named keyword-only arguments does for us is allows us to document this case. That is an absolute win. Michael -- Michael Urman http://www.tortall.net/mu/blog From benji at benjiyork.com Fri May 5 15:48:05 2006 From: benji at benjiyork.com (Benji York) Date: Fri, 05 May 2006 09:48:05 -0400 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> Message-ID: <445B5795.60104@benjiyork.com> Paul Moore wrote: > Is it possible to create a branch in the main Python svn, and grant > commit privs to that branch only, for sprint participants? I'm not familiar with the mechanics, recent versions of Subversion allow per-directory security. We do this to give some customers read access to parts of the repo, and read-write to others. It shouldn't be difficult (given a recent enough Subversion) to set up a sprint area in the repo. -- Benji York From fdrake at acm.org Fri May 5 15:51:03 2006 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Fri, 5 May 2006 09:51:03 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: References: <4453B025.3080100@acm.org> <445AB280.8060701@canterbury.ac.nz> Message-ID: <200605050951.04048.fdrake@acm.org> On Friday 05 May 2006 02:38, Terry Reedy wrote: > My point has been that the function writer should not make such a > requirement (for four no-defaut, required params) and that proposing to do > so with the proposed '*' is an abuse (for public code). The caller should And what exactly is the point at which constraining use goes from unreasonable to reasonable? Perhaps that involves a judgement call? I think it does. Since we're all consenting adults, we should have the tools to make our judgements easy to apply. Since it requires specific action to make the constraint (insertion of the "*" marker), there doesn't appear to be any real issue here. -Fred -- Fred L. Drake, Jr. From exarkun at divmod.com Fri May 5 16:01:23 2006 From: exarkun at divmod.com (Jean-Paul Calderone) Date: Fri, 5 May 2006 10:01:23 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: Message-ID: <20060505140123.22481.872593371.divmod.quotient.21698@ohm> On Fri, 5 May 2006 08:20:02 -0500, Michael Urman wrote: >On 5/5/06, Terry Reedy wrote: >> At present, Python allows this as a choice. > >Not always - take a look from another perspective: > >def make_person(**kwds): > name = kwds.pop('name', None) > age = kwds.pop('age', None) > phone = kwds.pop('phone', None) > location = kwds.pop('location', None) > ... > >This already requires the caller to use keywords, but results in >horrid introspection based documentation. You know it takes some >keywords, but you have no clue what keywords they are. It's as bad as >calling help() on many of the C functions in the python stdlib. > >So what allowing named keyword-only arguments does for us is allows us >to document this case. That is an absolute win. Here you go: import inspect @decorator def keyword(f): def g(*a, **kw): if a: raise TypeError("Arguments must be passed by keyword") args = [] expectedArgs = inspect.getargspec(f)[0] defaults = inspect.getargspec(f)[-1] for i, a in enumerate(expectedArgs): if a in kw: args.append(kw[a]) elif i >= len(expectedArgs) - len(defaults): args.append(defaults[i - len(expectedArgs)]) else: raise TypeError("Missing argument for " + a) return f(*args) return g @keyword def foo(a, b, c=10, d=20, e=30): return a, b, c, d, e try: foo() except TypeError: pass else: assert False, "Should have raised TypeError" try: foo(1) except TypeError: pass else: assert False, "Should have raised TypeError" try: foo(a=1) except TypeError: pass else: assert False, "Should have raised TypeError" assert foo(a=1, b=2) == (1, 2, 10, 20, 30) assert foo(a=1, b=2, c=3) == (1, 2, 3, 20, 30) assert foo(a=1, b=2, d=4) == (1, 2, 10, 4, 30) assert foo(a=1, b=2, c=3, d=4, e=5) == (1, 2, 3, 4, 5) print 'Success!' From ncoghlan at gmail.com Fri May 5 16:16:15 2006 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sat, 06 May 2006 00:16:15 +1000 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <200605050951.04048.fdrake@acm.org> References: <4453B025.3080100@acm.org> <445AB280.8060701@canterbury.ac.nz> <200605050951.04048.fdrake@acm.org> Message-ID: <445B5E2F.4080900@gmail.com> Fred L. Drake, Jr. wrote: > On Friday 05 May 2006 02:38, Terry Reedy wrote: > > My point has been that the function writer should not make such a > > requirement (for four no-defaut, required params) and that proposing to do > > so with the proposed '*' is an abuse (for public code). The caller should > > And what exactly is the point at which constraining use goes from unreasonable > to reasonable? Perhaps that involves a judgement call? I think it does. > Since we're all consenting adults, we should have the tools to make our > judgements easy to apply. > > Since it requires specific action to make the constraint (insertion of the "*" > marker), there doesn't appear to be any real issue here. And I imagine API designers that abused the feature would end up being abused by their users :) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- http://www.boredomandlaziness.org From fdrake at acm.org Fri May 5 16:50:45 2006 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Fri, 5 May 2006 10:50:45 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <445B5E2F.4080900@gmail.com> References: <4453B025.3080100@acm.org> <200605050951.04048.fdrake@acm.org> <445B5E2F.4080900@gmail.com> Message-ID: <200605051050.45802.fdrake@acm.org> On Friday 05 May 2006 10:16, Nick Coghlan wrote: > And I imagine API designers that abused the feature would end up being > abused by their users :) If used to create poor APIs, I think that's a reasonable outcome. :-) I don't think using such a feature to constrain APIs is necessarily abuse, which is what seems to be the point of disagreement in this thread. -Fred -- Fred L. Drake, Jr. From coder_infidel at hotmail.com Fri May 5 19:06:54 2006 From: coder_infidel at hotmail.com (Luke Dunstan) Date: Sat, 6 May 2006 01:06:54 +0800 Subject: [Python-Dev] Python for Windows CE References: <44591A9F.1090304@v.loewis.de> Message-ID: ----- Original Message ----- From: ""Martin v. L?wis"" To: "Luke Dunstan" Cc: Sent: Thursday, May 04, 2006 5:03 AM Subject: Re: [Python-Dev] Python for Windows CE > Luke Dunstan wrote: >> 1. Is there any reason in principle why patches for Windows CE support >> would >> be rejected? > > No, not in principle. Of course, > - the patch shouldn't break anything > - you should state an explicit commitment to support the port for > some years (or else it might get removed at the slightest problem) Thanks for your response. I hope I can continue to support Python for Windows CE for a while at least. >> 4. The latest existing patch set uses os.name = "ce", and this can be >> used >> to distinguish Windows CE from other operating systems in Python code. >> The >> existing patches also set sys.platform = "Pocket PC", but I am not so >> keen >> on keeping this, mainly because Windows CE is equivalent to Win32 in many >> cases. Any comments? > > I would guide the decision based on the number of API changes you need > to make to the standard library (e.g. distutils). In any case, the > platform module should be able to reliably report the specific system > (including the specific processor architecture). OK. Actually I think distutils will be the last thing to be ported because it is not necessary for using the rest of Python. Does distutils has support for cross-compiling anyway? > >> (b) Instead we could use #ifdef HAVE_DIRECT_H, requiring patches to >> #define >> HAVE_DIRECT_H for other platforms > > That would be best. Python generally uses autoconf methodology, which > implies that conditionally-existing headers should be detected using > HAVE_*_H. > > Regards, > Martin OK, but what about ANSI C headers like signal.h? I expected HAVE_SIGNAL_H to exist already but I just came across this patch: http://svn.python.org/view/python/trunk/pyconfig.h.in?rev=35255&r1=35221&r2=35255 I am guessing that the reason for this patch was to reduce the number of #ifdefs in the Python source to ease maintenance. Would you want to add some of them back again? Luke From jcarlson at uci.edu Fri May 5 20:27:42 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Fri, 05 May 2006 11:27:42 -0700 Subject: [Python-Dev] binary trees. Review obmalloc.c In-Reply-To: <445B03B4.6070600@renet.ru> References: <20060502222033.678D.JCARLSON@uci.edu> <445B03B4.6070600@renet.ru> Message-ID: <20060505105630.67BE.JCARLSON@uci.edu> "Vladimir 'Yu' Stepanov" wrote: > Josiah Carlson wrote: > > However, as I just said, people usually don't remove items from > > just-sorted lists, they tend to iterate over them via 'for i in list:' . > > > Such problem arises at creation of the list of timers. I've never seen that particular use-case. Please understand something. I believe that trees can be useful in some cases. However, I don't believe that they are generally useful enough in Python, given that we already have key,value dictionaries and sortable lists. They become even less worthwhile in Python, given the total ordering problem that I describe later in this message. > Except for that function of binary search is absent in standard > package Python. Binary search exists in the standard library as the bisect module. > Here that I have found through Google on a line " order statistic binary > tree ": > > http://www.cs.mcgill.ca/~cs251/OldCourses/1997/topic20/ Yes, that link does describe what an 'order statistic tree' is. One thing to note is that you can add order statistics to any tree wih one more field on each tree node. That is, you can have your AVL or Red-Black tree, and add order statistics to it. Allowing tree['x'] to return the associated value for the key 'x' (the same as a dictionary), as well as offer the ability to do tree.select(10) to get the 10th (or 11th if one counts from 0) smallest key (or key,value), or get the 'rank' of a key with tree.rank('x'). > > Of course all of this discussion about trees in Python is fine, though > > there is one major problem. With minimal work, one can construct 3 > > values such that ((a < b < c) and (c < a)) is true. > > > The same problem is inherent in the standard dictionary - dict (), only > roots at it, it is others. For example: This problem has nothing to do with dictionaries and hashing, it has to do with the fact that there may not be a total ordering on the elements of a sequence. >>> 'b' < (0,) < u'a' < 'b' True >>> x = ['b', (0,), u'a'] >>> random.shuffle(x) >>> x.sort() >>> x [u'a', 'b', (0,)] >>> random.shuffle(x) >>> x.sort() >>> x ['b', (0,), u'a'] >>> What effect does this have on trees? Imagine, for a moment, that your tree looked like: (0,) / \ 'b' u'a' Then you added sufficient data so that your tree was rebalanced to be something like: u'a' / \ (0,) (stuff) / 'b' If you were searching for 'b', you would never find it, because in your search, you would compare 'b' against u'a', and take the right branch, where 'b' isn't. - Josiah From jcarlson at uci.edu Fri May 5 20:32:30 2006 From: jcarlson at uci.edu (Josiah Carlson) Date: Fri, 05 May 2006 11:32:30 -0700 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <20060505140123.22481.872593371.divmod.quotient.21698@ohm> References: <20060505140123.22481.872593371.divmod.quotient.21698@ohm> Message-ID: <20060505113104.67C1.JCARLSON@uci.edu> Jean-Paul Calderone wrote: > > On Fri, 5 May 2006 08:20:02 -0500, Michael Urman wrote: > >On 5/5/06, Terry Reedy wrote: > >> At present, Python allows this as a choice. > > > >Not always - take a look from another perspective: > > > >def make_person(**kwds): > > name = kwds.pop('name', None) > > age = kwds.pop('age', None) > > phone = kwds.pop('phone', None) > > location = kwds.pop('location', None) > > ... > > > >This already requires the caller to use keywords, but results in > >horrid introspection based documentation. You know it takes some > >keywords, but you have no clue what keywords they are. It's as bad as > >calling help() on many of the C functions in the python stdlib. > > > >So what allowing named keyword-only arguments does for us is allows us > >to document this case. That is an absolute win. > > Here you go: [snip] Nice work! So, can we add this to the functools module right next to decorator, and bypass the syntax change? - Josiah From ian.bollinger at gmail.com Fri May 5 21:25:22 2006 From: ian.bollinger at gmail.com (Ian D. Bollinger) Date: Fri, 05 May 2006 15:25:22 -0400 Subject: [Python-Dev] lambda in Python In-Reply-To: <2773CAC687FD5F4689F526998C7E4E5FF1E6C5@au3010avexu1.global.avaya.com> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6C5@au3010avexu1.global.avaya.com> Message-ID: <445BA6A2.50901@gmail.com> Delaney, Timothy (Tim) wrote: > Should we add an explicit rule to the Python-dev spam filter for Xah? > Based on his past history, I doubt we'll ever see anything useful from > him. > I'm not sure Xah is so much a troll as he is completely out of his mind. At any rate, it seems he never has anything coherent to contribute. I, however, dislike the idea of censoring someone just for being incoherent and obnoxious. Ignoring him is probably the most pragmatic thing to do. -- Ian D. Bollinger From tjreedy at udel.edu Fri May 5 22:19:19 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 5 May 2006 16:19:19 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <44573D75.40007@canterbury.ac.nz><445805EA.7000501@canterbury.ac.nz><740c3aec0605031621v48f33dd0g591cb12a131764e8@mail.gmail.com><44598128.8060506@canterbury.ac.nz> <445AB280.8060701@canterbury.ac.nz> Message-ID: "Michael Urman" wrote in message news:dcbbbb410605050620s5f0844f0idb9b852bab924e7f at mail.gmail.com... > On 5/5/06, Terry Reedy wrote: >> At present, Python allows this as a choice. I made that statement in the context of comparing these syntaxes def make_person(name, age, phone, location) # current def make_person(*, name, age, phone, location) # possible future for a function with required, no-default parameters. In that context, my statement is true. > Not always - take a look from another perspective: As I wrote it, I was aware that it was not true in the alternate context (not perspective) of using **names. Many true statements become otherwise when their context is ripped away. > def make_person(**kwds): > name = kwds.pop('name', None) > age = kwds.pop('age', None) > phone = kwds.pop('phone', None) > location = kwds.pop('location', None) This version gives the parameters default values and make them optional. The current version, ignoring error messages, of the possible future above is def make_person(**names): name = names.pop('name') age = names.pop('age') phone = names.pop('phone') location = names.pop('location') if names: raise KeyError("Extra named args passed") Now there are no defaults and all are required. > This already requires the caller to use keywords, Your version allows the seemingly senseless no-keyword call make_person(). > but results in horrid introspection based documentation. > You know it takes some > keywords, but you have no clue what keywords they are. It's as bad as > calling help() on many of the C functions in the python stdlib. Improving doc strings for C functions is a separate issue. > So what allowing named keyword-only arguments does for us is allows us > to document this case. That is an absolute win. That is your opinion, whereas mine is that this generally a bad case that should not be written and that making it easier to write and therefore more likely is a loss. Terry Jan Reedy From benji at benjiyork.com Fri May 5 23:01:26 2006 From: benji at benjiyork.com (Benji York) Date: Fri, 05 May 2006 17:01:26 -0400 Subject: [Python-Dev] lambda in Python In-Reply-To: <445BA6A2.50901@gmail.com> References: <2773CAC687FD5F4689F526998C7E4E5FF1E6C5@au3010avexu1.global.avaya.com> <445BA6A2.50901@gmail.com> Message-ID: <445BBD26.9010302@benjiyork.com> Ian D. Bollinger wrote: > I'm not sure Xah is so much a troll as he is completely out of his > mind. Is that Bollinger's law? Any sufficiently advanced insanity is indistinguishable from trolling. -- Benji York From tjreedy at udel.edu Fri May 5 23:26:51 2006 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 5 May 2006 17:26:51 -0400 Subject: [Python-Dev] PEP 3102: Keyword-only arguments References: <4453B025.3080100@acm.org> <445AB280.8060701@canterbury.ac.nz> <200605050951.04048.fdrake@acm.org> Message-ID: "Fred L. Drake, Jr." wrote in message news:200605050951.04048.fdrake at acm.org... > On Friday 05 May 2006 02:38, Terry Reedy wrote: > > My point has been that the function writer should not make such a > > requirement (for four no-defaut, required params) and that proposing to > > do > > so with the proposed '*' is an abuse (for public code). The caller > > should > > And what exactly is the point at which constraining use goes from > unreasonable > to reasonable? Perhaps that involves a judgement call? I think it does. Well, if so, it is my increasingly strong judgment that requiring another programmer to junk up his or her code with make_person(name=name, age=age, phone=phone, location = location) # instead of # make_person(name, age, phone, location) # or * make_person(name=person_data[0], age=person_data[2], phone=person_data[3], location=person_data[3]) # instead # make_person(*person_data) is generally unreasonable. Remember, any person who actually prefers to write the longer forms is free to do so. > Since we're all consenting adults, That is the basis for my objection. Most of the 'reasons' given for imposing the longer forms above have been about *not* treating function-calling programmers as fellow consenting adults, or rather, about treating them as non-adults. One exception is the claim that in the alpha phase of a library project, the developer might be willing to freeze parameter names before freezing parameter positions. But this should be rare, temporary, and might be dealt with as well by the common procedure of stating that function signatures (APIs) are subject to change, while indicating which aspect are considered most stable or unstable. > we should have the tools to make our judgements easy to apply. The discussion is about a tool to make a very disputable judgment easier to impose on others > Since it requires specific action to make the constraint (insertion of > the "*" > marker), there doesn't appear to be any real issue here. I do not see the logic of this statement. I could just as well claim that it is constraints that require action, and which are therefore, in a sense, optional, that are disputable issues. Terry Jan Reedy From martin at v.loewis.de Fri May 5 23:50:10 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Fri, 05 May 2006 23:50:10 +0200 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> Message-ID: <445BC892.1060808@v.loewis.de> Paul Moore wrote: > Is it possible to create a branch in the main Python svn, and grant > commit privs to that branch only, for sprint participants? I seem to > recall something like mod_authzsvn being involved, but I don't know > much more... We couldn't technically enforce it - but I'm sure sprint participants would restrict checkins to a branch if they were told to. However, I don't see how that would help. Regards, Martin From martin at v.loewis.de Fri May 5 23:51:09 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Fri, 05 May 2006 23:51:09 +0200 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <445B5795.60104@benjiyork.com> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> <445B5795.60104@benjiyork.com> Message-ID: <445BC8CD.7060909@v.loewis.de> Benji York wrote: > I'm not familiar with the mechanics, recent versions of Subversion allow > per-directory security. We do this to give some customers read access > to parts of the repo, and read-write to others. It shouldn't be > difficult (given a recent enough Subversion) to set up a sprint area in > the repo. It works fine for http(s), but not for svn+ssh. Regards, Martin From martin at v.loewis.de Fri May 5 23:59:10 2006 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Fri, 05 May 2006 23:59:10 +0200 Subject: [Python-Dev] Python for Windows CE In-Reply-To: References: <44591A9F.1090304@v.loewis.de> Message-ID: <445BCAAE.2010000@v.loewis.de> Luke Dunstan wrote: > OK. Actually I think distutils will be the last thing to be ported because > it is not necessary for using the rest of Python. Does distutils has support > for cross-compiling anyway? No, it doesn't. > OK, but what about ANSI C headers like signal.h? I expected HAVE_SIGNAL_H to > exist already but I just came across this patch: > > http://svn.python.org/view/python/trunk/pyconfig.h.in?rev=35255&r1=35221&r2=35255 > > I am guessing that the reason for this patch was to reduce the number of > #ifdefs in the Python source to ease maintenance. Would you want to add some > of them back again? Yes. with a record what system (and version) requires them, so we can remove them again when the system becomes unsupported. Regards, From benji at benjiyork.com Sat May 6 00:18:39 2006 From: benji at benjiyork.com (Benji York) Date: Fri, 05 May 2006 18:18:39 -0400 Subject: [Python-Dev] Python sprint mechanics In-Reply-To: <445BC8CD.7060909@v.loewis.de> References: <1f7befae0605042216t6da65be1v736899a11de4a719@mail.gmail.com> <79990c6b0605050113j5b05396dle6b467325633fa1@mail.gmail.com> <445B5795.60104@benjiyork.com> <445BC8CD.7060909@v.loewis.de> Message-ID: <445BCF3F.5040909@benjiyork.com> Martin v. L?wis wrote: > Benji York wrote: > >>I'm not familiar with the mechanics, recent versions of Subversion allow >>per-directory security. > > It works fine for http(s), but not for svn+ssh. Versions prior to 1.3 could use Apache's authorization system. Subversion 1.3 added a path-based authorization feature to svnserve. -- Benji York From murman at gmail.com Sat May 6 01:07:21 2006 From: murman at gmail.com (Michael Urman) Date: Fri, 5 May 2006 18:07:21 -0500 Subject: [Python-Dev] PEP 3102: Keyword-only arguments In-Reply-To: <20060505140123.22481.872593371.divmod.quotient.21698@ohm> References: <20060505140123.22481.872593371.divmod.quotient.21698@ohm> Message-ID: On 5/5/06, Jean-Paul Calderone wrote: > @keyword > def foo(a, b, c=10, d=20, e=30): > return a, b, c, d, e Cute, indeed. That decorator implementation is not as flexible as the * which can go after positional parameters, but of course that is easy to tweak. However the part I didn't bring up as a reason to prefer explicit syntax for required-as-keyword is performance. I suspect syntactic support will be faster than **kw.pop; I'm almost certain it's faster than decorator gimmicks. I'm not certain at all that it's a concern either way. Michael -- Michael Urman http://www.tortall.net/mu/blog From rasky at develer.com Sat May 6 01:12:33 2006 From: rasky at develer.com (Giovanni Bajo) Date: Sat, 6 May 2006 01:12:33 +0200 Subject: [Python-Dev] Alternative path suggestion References: Message-ID: <151d01c67099$63e3f9b0$8d472597@bagio> Noam Raphael wrote: > The only drawback I can see in using a logical representation is that > giving a path object to functions which expect a path string won't > work. The immediate solution is to simply use str(p) instead of p. The > long-term solution is to make all related functions accept a path > object. I'm not an expert in this field, but I believe that if you can make your Path object support the so-called buffer interface, it would be directly usable for functions like open() without an explicit conversion. Giovanni Bajo From rasky at develer.com Sat May 6 01:16:07 2006 From: rasky at develer.com (Giovanni Bajo) Date: Sat, 6 May 2006 01:16:07 +0200 Subject: [Python-Dev] Alternative path suggestion References: <6e9196d20605040113x2a2d563ah23fabf02c49a0778@mail.gmail.com><4459FA21.6030508@gmail.com> <445AAA6B.7030108@canterbury.ac.nz> Message-ID: <152b01c67099$e3a89020$8d472597@bagio> Greg Ewing wrote: >> Similarly, I would separate out the extension to a distinct >> attribute, as it too uses a different separator from the normal path >> elements ('.' most places, but '/' on RISC OS, for example) > > -1. What constitutes "the extension" is not well-defined in > all cases. What about filenames with multiple suffixes, > such as "spam.tar.gz"? What part of that would you put in > the extension attribute? .gz of course: Path = "foo.tar.gz" Path.ext = ".gz" Path.name.ext = ".tar" Path.name.name.ext = "" Which is exactly the *same* thing that os.path.splitext() does. And yes, I do use splitext quite a lot. Giovanni Bajo From xah at xahlee.org Sat May 6 02:23:14 2006 From: xah at xahlee.org (xahlee) Date: Fri, 5 May 2006 17:23:14 -0700 Subject: [Python-Dev] A critic of Guido's blog on Python's lambda In-Reply-To: References: Message-ID: <9271BA58-9A0A-4713-AE3D-388C487ECC8F@xahlee.org> In this post, i'd like to deconstruct one of Guido's recent blog about lambda in Python. In Guido's blog written in 2006-02-10 at http://www.artima.com/ weblogs/viewpost.jsp?thread=147358 is first of all, the title ?Language Design Is Not Just Solving Puzzles?. In the outset, and in between the lines, we are told that ?I'm the supreme intellect, and I created Python?. This seems impressive, except that the tech geekers due to their ignorance of sociology as well as lack of analytic abilities of the mathematician, do not know that creating a language is a act that requires little qualifications. However, creating a language that is used by a lot people takes considerable skill, and a big part of that skill is salesmanship. Guido seems to have done it well and seems to continue selling it well, where, he can put up a title of belittlement and get away with it too. Gaudy title aside, let's look at the content of his say. If you peruse the 700 words, you'll find that it amounts to that Guido does not like the suggested lambda fix due to its multi-line nature, and says that he don't think there could possibly be any proposal he'll like. The reason? Not much! Zen is bantered about, mathematician's impractical ways is waved, undefinable qualities are given, human's right brain (neuroscience) is mentioned for support, Rube Goldberg contrivance phraseology is thrown, and coolness of Google Inc is reminded for the tech geekers (in juxtaposition of a big notice that Guido works there.). If you are serious, doesn't this writing sounds bigger than its content? Look at the gorgeous ending: ?This is also the reason why Python will never have continuations, and even why I'm uninterested in optimizing tail recursion. But that's for another installment.?. This benevolent geeker is gonna give us another INSTALLMENT! There is a computer language leader by the name of Larry Wall, who said that ?The three chief virtues of a programmer are: Laziness, Impatience and Hubris? among quite a lot of other ingenious outpourings. It seems to me, the more i learn about Python and its leader, the more similarities i see. So Guido, i understand that selling oneself is a inherent and necessary part of being a human animal. But i think the lesser beings should be educated enough to know that fact. So that when minions follow a leader, they have a clear understanding of why and what. ---- Regarding the lambda in Python situation... conceivably you are right that Python lambda is perhaps at best left as it is crippled, or even eliminated. However, this is what i want: I want Python literatures, and also in Wikipedia, to cease and desist stating that Python supports functional programing. (this is not necessarily a bad publicity) And, I want the Perl literatures to cease and desist saying they support OOP. But that's for another installment. This post is archived at: http://xahlee.org/UnixResource_dir/writ/python_lambda_guido.html Xah xah at xahlee.org ? http://xahlee.org/ ? From kbk at shore.net Sat May 6 05:35:38 2006 From: kbk at shore.net (Kurt B. Kaiser) Date: Fri, 5 May 2006 23:35:38 -0400 (EDT) Subject: [Python-Dev] Weekly Python Patch/Bug Summary Message-ID: <200605060335.k463Zc9n003686@bayview.thirdcreek.com> Patch / Bug Summary ___________________ Patches : 378 open ( +0) / 3216 closed (+17) / 3594 total (+17) Bugs : 894 open ( -7) / 5811 closed (+19) / 6705 total (+12) RFE : 216 open ( +2) / 215 closed ( +1) / 431 total ( +3) New / Reopened Patches ______________________ Rename functional to functools (2006-04-29) http://python.org/sf/1478788 opened by Collin Winter Take advantage of BaseException/Exception split in cookielib (2006-04-29) http://python.org/sf/1478993 opened by John J Lee Split open() and file() (2006-04-29) CLOSED http://python.org/sf/1479181 opened by Aahz ColorDelegator - Several bug fixes (2006-04-30) http://python.org/sf/1479219 opened by Tal Einat Fix building with SWIG's -c++ option set in setup.py (2006-04-30) http://python.org/sf/1479255 opened by dOb Make urllib2 digest auth and basic auth play together (2006-04-30) http://python.org/sf/1479302 opened by John J Lee with statement context managers - with should be keyword (2006-04-30) CLOSED http://python.org/sf/1479438 opened by Matt Fleming speed up function calls (2006-04-30) http://python.org/sf/1479611 opened by Neal Norwitz Heavy revisions to urllib2 howto (2006-05-01) http://python.org/sf/1479977 opened by John J Lee weakref dict methods (2006-05-01) CLOSED http://python.org/sf/1479988 opened by Fred L. Drake, Jr. urllib2 digest auth redirection bug causes 400 error (2006-05-01) CLOSED http://python.org/sf/1480067 opened by John J Lee patch smtplib:when SMTPDataError, rset crashes with sslerror (2006-05-03) http://python.org/sf/1481032 opened by kxroberto Support HTTP_REFERER in CGIHTTPServer.py (2006-05-03) http://python.org/sf/1481079 opened by S??bastien Martini Python long option support (2006-05-03) http://python.org/sf/1481112 opened by Heiko Wundram Cleaned up 16x16px icons for windows. (2006-05-03) http://python.org/sf/1481304 opened by goxe imputil "from" os.path import bug (2006-05-03) CLOSED http://python.org/sf/1481530 opened by Eric Huss Patches Closed ______________ --enable-universalsdk on Mac OS X (2006-04-17) http://python.org/sf/1471883 closed by ronaldoussoren Split open() and file() (2006-04-29) http://python.org/sf/1479181 closed by nnorwitz urllib2 ProxyBasicAuthHandler broken (2006-04-15) http://python.org/sf/1470846 closed by gbrandl Forbid iteration over strings (2006-04-16) http://python.org/sf/1471291 closed by gbrandl Fix for urllib/urllib2 ftp bugs 1357260 and 1281692 (2006-04-15) http://python.org/sf/1470976 closed by gbrandl cPickle produces locale-dependent dumps (2006-04-20) http://python.org/sf/1473625 closed by gbrandl IndentationError for unexpected indent (2006-04-25) http://python.org/sf/1475845 closed by loewis rlcompleter to be usable without readline (2006-04-19) http://python.org/sf/1472854 closed by gbrandl fix for #1472251 (2006-04-18) http://python.org/sf/1472263 closed by gbrandl with statement context managers - with should be keyword (2006-04-30) http://python.org/sf/1479438 closed by gbrandl fixed handling of nested comments in mail addresses (2006-04-05) http://python.org/sf/1464708 closed by bwarsaw weakref dict methods (2006-05-01) http://python.org/sf/1479988 closed by fdrake urllib2 digest auth redirection bug causes 400 error (2006-05-01) http://python.org/sf/1480067 closed by gbrandl Fix to allow urllib2 digest auth to talk to livejournal.com (2005-02-18) http://python.org/sf/1143695 closed by gbrandl pdb: fix for #1472191('clear' command bug) (2006-04-18) http://python.org/sf/1472184 closed by gbrandl __init__.py'less package import warnings (2006-04-26) http://python.org/sf/1477281 closed by gbrandl imputil "from" os.path import bug (2006-05-04) http://python.org/sf/1481530 closed by gbrandl New / Reopened Bugs ___________________ urllib2.Request constructor to urllib.quote the url given (2006-04-20) CLOSED http://python.org/sf/1473560 reopened by gbrandl 'compile' built-in function failures when missing EOL (2006-04-30) http://python.org/sf/1479099 opened by Ori Peleg test_inspect fails on WinXP (2.5a2) (2006-04-30) CLOSED http://python.org/sf/1479226 opened by Miki Tebeka Segmentation fault while using Tkinter (2006-05-01) http://python.org/sf/1479586 opened by Ali Gholami Rudi Uninstall does not clearn registry (2006-05-01) http://python.org/sf/1479626 opened by Miki Tebeka float->str rounding bug (2006-05-01) CLOSED http://python.org/sf/1479776 opened by Michael Nolta Quitter object masked (2006-05-01) http://python.org/sf/1479785 opened by Jim Jewett mmap tries to truncate special files (2006-05-02) CLOSED http://python.org/sf/1480678 opened by Carl Banks long(float('nan'))!=0L (2006-05-03) http://python.org/sf/1481296 opened by Erik Dahl parse_makefile doesn't handle $$ correctly (2006-05-03) http://python.org/sf/1481347 opened by Han-Wen Nienhuys Docs on import of email.MIMExxx classes wrong (2006-05-04) http://python.org/sf/1481650 opened by Hugh Gibson hpux ia64 shared lib ext should be ".so" (2006-05-04) http://python.org/sf/1481770 opened by David Everly Shift+Backspace exhibits odd behavior (2006-05-04) http://python.org/sf/1482122 opened by NothingCanFulfill socket.getsockopt bug (2006-05-05) CLOSED http://python.org/sf/1482328 opened by ganges master Forwarding events and Tk.mainloop problem (2006-05-05) http://python.org/sf/1482402 opened by Matthias Kievernagel asyncore is not listed in test_sundry (2006-05-05) http://python.org/sf/1482746 opened by jackilyn Bugs Closed ___________ urllib2.Request constructor to urllib.quote the url given (2006-04-20) http://python.org/sf/1473560 closed by gbrandl size limit exceeded for read() from network drive (2006-04-28) http://python.org/sf/1478529 closed by tim_one urllib2 AuthHandlers can pass a bad host to HTTPPasswordMgr (2004-02-20) http://python.org/sf/900898 closed by gbrandl test_inspect fails on WinXP (2.5a2) (2006-04-30) http://python.org/sf/1479226 closed by gbrandl urllib violates rfc 959 (2005-09-04) http://python.org/sf/1281692 closed by gbrandl urllib/urllib2 cannot ftp files which are not listable. (2005-11-15) http://python.org/sf/1357260 closed by gbrandl test_ctypes: undefined symbol: XGetExtensionVersion (2006-04-28) http://python.org/sf/1478253 closed by gbrandl compiler module does not detect a syntax error (2005-12-19) http://python.org/sf/1385040 closed by gbrandl Tkinter hangs in test_tcl (2006-04-23) http://python.org/sf/1475162 closed by loewis float->str rounding bug (2006-05-01) http://python.org/sf/1479776 closed by tim_one setup.py --help-commands exception (2006-04-16) http://python.org/sf/1471407 closed by jwpye HTMLParser doesn't treat endtags in