[Python-Dev] Closing old bugs
Old age and a missing OP is not sufficient reason to close a bug. But if closing a bug is an effective way of kicking things into life again... I'm seeing this effect in a lot of bugs I closed as old ones. That means they shouldn't have been closed and that we almost lost a valid report. Also, for the most part, kicking to life means getting a qualified reviewer to take time to decide an appropriate course of action. Typically, the OP is not that person. Usually, the only kick to life we need from an OP is clarification if their post was not sufficiently specific; otherwise, they usually shouldn't have to do anything. Take note that for closing it, first there's a warning, and if in a *month* (which really happens to delay into several months, my fault) the interested people don't take care again of that bug... A better use of time is to BE one of the interested people and take care of the bug. Just closing it doesn't make the problem go away. Also, inactivity does not imply that a bug is not a recurring irritant. We encourage posters to scan existing bug reports before filing a new one. Likewise, we immediately close duplicates. If the original report then disappears without having been cleared, then we've broken our promises to the othesr who did or would have posted a more current report. The existence of an old report means the problem has been registered and is awaiting a thoughtful response. Because of the way SF is setup, the other interested people are not likely to receive your one month warnings. Closing reports without analyzing their contents is not progress. AFAICT, that has never been our policy. Is there anyone else on python-dev who thinks it's a bad idea to automatically close reports without checking whether the issue is real? Raymond ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] AST manipulation and source code generation
?!ng: Well, i should refine that a bit to say that the Lisp macro system is a little more specific. Whereas AST transformations in Python are open-ended (you could generate any result you want), the key interesting property of Lisp macros is that they are constrained to be safe, in the sense that the bindings of variable names are always preserved. I'm not quite sure what ?!ng means by the bindings of variable names are always preserved, but I conjecture that he is thinking of the hygienic macros in Scheme rather than the macros in Common Lisp which permit arbitrary code transformations. -- g ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Closing old bugs
Raymond writes: Is there anyone else on python-dev who thinks it's a bad idea to automatically close reports without checking whether the issue is real? Raymond: I'm speaking up with some trepidation here, since I am NOT one of those who frequently closes bugs. But I think that at least sometimes there IS an advantage to closing old bugs. I can envision a world in which there would be only 5-10 open bug reports at any given time, with enough developer volunteers available to respond to new reports as they come in. And I realize that we are nowhere near such a world and we're not going to be getting there anytime soon. But it is still the case that MOST people are intimidated by the enormous stack of open bugs. Perhaps intimidated is the wrong word... what I want to convey is that most people have no idea what's important or where to start -- it's just too big a pile. Perhaps all of the people who would actually work to close Python bugs are perfectly happy with the existing system. Or perhaps we scare off some potential volunteers because they have no idea where to start. I've seen some systems that solve this problem by allowing users to vote for favorite bugs... then you can tell the important bugs because they are more likely to have lots of votes. As I see it, Facundo is using a variant of that system. He is asking whether there is *ONE PERSON* out there who cares enough about a bug to subscribe to it and then to respond to his inquiry. If there's not even one such person, then he's closing the bug (but if one such person comes along later, they can re-report it). Sure, we may be throwing away some useful information by closing a bug report without proper investigation. But we're not in a situation where we are short of information... we've got plenty of information (bug reports), what we lack is developer time. If throwing away information helps to better focus the developer time we have, then it may be a useful process! And someday when nirvana arrives and there are only 5-10 open bugs, we can send intrepid volunteers digging through the archives to examine bugs that got closed without proper investigation. I'm not holding my breath. -- Michael Chermside ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Vestigial code in threadmodule?
Looking at bug #1209880, the following function from threadmodule.c is referenced. I think the args==NULL case, which can return None instead of a Boolean value, can never be reached because PyArg_ParseTuple() will fail if args==NULL. Before ripping the args==NULL code out, I wanted to be sure my analysis is correct; is there some subtlety here I'm missing that makes args==NULL possible? --amk static PyObject * lock_PyThread_acquire_lock(lockobject *self, PyObject *args) { int i = 1; if (!PyArg_ParseTuple(args, |i:acquire, i)) return NULL; Py_BEGIN_ALLOW_THREADS i = PyThread_acquire_lock(self-lock_lock, i); Py_END_ALLOW_THREADS if (args == NULL) { Py_INCREF(Py_None); return Py_None; } else return PyBool_FromLong((long)i); } ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Closing old bugs
I've seen some systems that solve this problem by allowing users to vote for favorite bugs... then you can tell the important bugs because they are more likely to have lots of votes. As I see it, Facundo is using a variant of that system. He is asking whether there is *ONE PERSON* out there who cares enough about a bug to subscribe to it and then to respond to his inquiry. If there's not even one such person, then he's closing the bug (but if one such person comes along later, they can re-report it). -1 This is both silly and harmful. It in no way resembles a professional approach to bug resolution. It throws away valuable information based on some vague theory of developer marketing (i.e. threatening to close a bug will cause a qualified, interested developer to suddenly have both the time and inclination to address it properly). If the real goal is to kick some life into bug resolution, then do something that directly fulfills that goal. Host a bug day. Make a newsgroup posting requesting thoughts on your favorite ten bugs. Write email to people who you think are capable of addressing the particular issue in question. Go recruit some qualified developers. Or just find a bug that interests you and fix it. Closing bugs without reading them is an anti-contribution. If it were a best practice, then there would already be a cron job in place to do it automatically. Raymond ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Closing old bugs
Raymond Hettinger wrote: I've seen some systems that solve this problem by allowing users to vote for favorite bugs... then you can tell the important bugs because they are more likely to have lots of votes. As I see it, Facundo is using a variant of that system. He is asking whether there is *ONE PERSON* out there who cares enough about a bug to subscribe to it and then to respond to his inquiry. If there's not even one such person, then he's closing the bug (but if one such person comes along later, they can re-report it). -1 This is both silly and harmful. It in no way resembles a professional approach to bug resolution. It throws away valuable information based on some vague theory of developer marketing (i.e. threatening to close a bug will cause a qualified, interested developer to suddenly have both the time and inclination to address it properly). ACK so far. If the real goal is to kick some life into bug resolution, then do something that directly fulfills that goal. Host a bug day. Make a newsgroup posting requesting thoughts on your favorite ten bugs. Write email to people who you think are capable of addressing the particular issue in question. Go recruit some qualified developers. Or just find a bug that interests you and fix it. Well, to fix it is not so easy for most people. You have to post a patch or attach it to the bug and then wait for someone to check it in. It's not sure that this is done anytime soon (no complaint; time is short, I know). Even fixes that are agreed upon by several people are not always checked in for a long time. Reinhold -- Mail address is perfectly valid! ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Vestigial code in threadmodule?
On 6/2/05, A.M. Kuchling [EMAIL PROTECTED] wrote: Looking at bug #1209880, the following function from threadmodule.c is referenced. I think the args==NULL case, which can return None instead of a Boolean value, can never be reached because PyArg_ParseTuple() will fail if args==NULL. Before ripping the args==NULL code out, I wanted to be sure my analysis is correct; is there some subtlety here I'm missing that makes args==NULL possible? I think the args == NULL code should be ripped out, but there seems to be a different problem. If args is NULL to PyArg_ParseTuple() an assertion will be triggered (or it'll just crash). See vgetargs1() in Python/getargs.c::138. args can be NULL if load_args() in Python/ceval.c fails (line 3724). The trace starts at line 3551, PyCFunction_Call() will be called with the NULL args on line 3553. PyCFunction_Call() will call a PyMethod that will likely call PyArg_ParseTuple() or something like it. I think the following patch should fix this (it just adds an if condition). Does this make sense or am I missing something? n -- Index: Python/ceval.c === RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.422 diff -u -r2.422 ceval.c --- Python/ceval.c 4 Apr 2005 15:49:02 - 2.422 +++ Python/ceval.c 2 Jun 2005 13:16:14 - @@ -3549,9 +3549,13 @@ else { PyObject *callargs; callargs = load_args(pp_stack, na); - READ_TIMESTAMP(*pintr0); - C_TRACE(x=PyCFunction_Call(func,callargs,NULL)); - READ_TIMESTAMP(*pintr1); + if (callargs) { + READ_TIMESTAMP(*pintr0); + C_TRACE(x=PyCFunction_Call(func,callargs,NULL));+ READ_TIMESTAMP(*pintr1); + } + else + x = NULL; Py_XDECREF(callargs); } } else { ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
Guido van Rossum wrote: [Phillip J. Eby] * The transaction handler could also be written as: @with_template def transactional(db): db.begin() try: yield db except: db.rollback() else: db.commit() at least, if I understand it correctly. Ah, of course. I've updated the PEP. This template eats eats the exception, which will cause a RuntimeError in the proposed Wrapper, I think. A raise after rollback is needed. - Arnold ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Vestigial code in threadmodule?
If you're digging into the threadmodule.c could you take a look at bug #1163563 (http://sourceforge.net/tracker/index.php?func=detailaid=1163563group_id=5470atid=105470) I've posted a patch (http://sourceforge.net/tracker/index.php? func=detailaid=1203393group_id=5470atid=305470) Regards, Max On 6/2/05, A.M. Kuchling [EMAIL PROTECTED] wrote: Looking at bug #1209880, the following function from threadmodule.c is referenced. I think the args==NULL case, which can return None instead of a Boolean value, can never be reached because PyArg_ParseTuple() will fail if args==NULL. Before ripping the args==NULL code out, I wanted to be sure my analysis is correct; is there some subtlety here I'm missing that makes args==NULL possible? --amk static PyObject * lock_PyThread_acquire_lock(lockobject *self, PyObject *args) { int i = 1; if (!PyArg_ParseTuple(args, |i:acquire, i)) return NULL; Py_BEGIN_ALLOW_THREADS i = PyThread_acquire_lock(self-lock_lock, i); Py_END_ALLOW_THREADS if (args == NULL) { Py_INCREF(Py_None); return Py_None; } else return PyBool_FromLong((long)i); } ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/anothermax%40gmail.com -- flickr: http://www.flickr.com/photos/anothermax/sets ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Vestigial code in threadmodule?
[A.M. Kuchling] Looking at bug #1209880, the following function from threadmodule.c is referenced. I think the args==NULL case, which can return None instead of a Boolean value, can never be reached because PyArg_ParseTuple() will fail if args==NULL. It would assert-fail in a debug build. In a release build the most likely outcome would be a segfault (NULL-pointer dereference in the expansion of vgetargs1's PyTuple_Check(args)). Before ripping the args==NULL code out, I wanted to be sure my analysis is correct; is there some subtlety here I'm missing that makes args==NULL possible? Rip it out; blame me wink. --amk static PyObject * lock_PyThread_acquire_lock(lockobject *self, PyObject *args) Noe that this is a file-local function. The only references are here: static PyMethodDef lock_methods[] = { {acquire_lock, (PyCFunction)lock_PyThread_acquire_lock, METH_VARARGS, acquire_doc}, {acquire, (PyCFunction)lock_PyThread_acquire_lock, METH_VARARGS, acquire_doc}, METH_VARARGS always passes a tuple (possibly empty). These are very old functions, so I bet they used to use METH_OLDARGS (implied by absence at the time) ... yup, METH_VARARGS was introduced here in rev 2.48, and unintentionally changed the return contract of this function. So that was a backward incompatibility introduced in Python 2.3a1. Since nobody complained then or since, I vote to keep the new return contract and fiddle the docs to match it. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
Arnold deVos wrote: This template eats eats the exception, which will cause a RuntimeError in the proposed Wrapper, I think. A raise after rollback is needed. Actually, the Wrapper as written in the PEP does not raise RuntimeError if the generator catches a block's exception. Shouldn't the relevant clause in the Wrapper go like this: try: self.gen.throw(type, value, traceback) except type: return except StopIteration: raise RuntimeError(generator caught exception) else: raise RuntimeError(generator didn't stop) And the transaction template would go like this (re-raising the exception): @with_template def transactional(db): db.begin() try: yield None except: db.rollback() raise else: db.commit() At least this is what I gleaned from the earlier threads. It means that the template does not appear to supress an exception that it cannot actually supress. - Arnold ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
[Arnold deVos, responding to himself] This template eats eats the exception, which will cause a RuntimeError in the proposed Wrapper, I think. A raise after rollback is needed. No, the generator returns after rolling back, which causes throw() to raise StopIteration, which is good enough for the wrapper as written. Actually, the Wrapper as written in the PEP does not raise RuntimeError if the generator catches a block's exception. Shouldn't the relevant clause in the Wrapper go like this: try: self.gen.throw(type, value, traceback) except type: return except StopIteration: raise RuntimeError(generator caught exception) else: raise RuntimeError(generator didn't stop) I considered that, but decided that it should be okay for the generator to respond to a throw() by returning (thus replacing the exception thrown by StopIteration) since the call to __exit__() is contained inside a finally-clause, so that when __exit__() returns normally, the finally-clause will re-raise the original exception anyway. Note that there are currently no other use cases for throw() except the with_template decorator and the close() method. Both allow the generator to respond either by letting the exception pass through it unchanged (after executing finally-clauses if present) or by simply returning (which will raise StopIteration in the caller of throw()). Erroneous behaviors are, in both cases, raising some other exception or *yielding* another value. There may be *other* use cases for yielding a value, for example, a future (looping) block-statement a la PEP 343. Raising another exception is always an indication of a bug in the generator. And the transaction template would go like this (re-raising the exception): @with_template def transactional(db): db.begin() try: yield None except: db.rollback() raise else: db.commit() At least this is what I gleaned from the earlier threads. It means that the template does not appear to supress an exception that it cannot actually supress. I disagree (at the -0 to -0.5 level); given that the with_template decorator allows StopIteration, I think that appearing to suppress an exception it doesn't actually suppress is a minor sin -- the key point is that the cleanup gets executed and doesn't raise a new exception or reaches a yield-statement. I'll summarize this discussion in the PEP. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
[me] I'll summarize this discussion in the PEP. I've added this section to the PEP. Is anyone dead set against the tentative resolutions here? Open Issues Discussion on python-dev has revealed some open issues. I list them here, with my preferred resolution and its motivation. The PEP as currently written reflects this preferred resolution. 1. What exception should be raised by close() when the generator yields another value as a response to the GeneratorExit exception? I originally chose TypeError because it represents gross misbehavior of the generator function, which should be fixed by changing the code. But the with_template decorator class uses RuntimeError for similar offenses. Arguably they should all use the same exception. I'd rather not introduce a new exception class just for this purpose, since it's not an exception that I want people to catch: I want it to turn into a traceback which is seen by the programmer who then fixes the code. So now I believe they should both raise RuntimeError. There are some precedents for that: it's raised by the core Python code in situations where endless recursion is detected, and for uninitialized objects (and for a variety of miscellaneous conditions). 2. Both the generator close() method and the __exit__() method of the with_template decorator class catch StopIteration and consider it equivalent to re-raising the exception passed to throw(). Is allowing StopIteration right here? This is so that a generator doing cleanup depending on the exception thrown (like the transactional() example below) can *catch* the exception thrown if it wants to and doesn't have to worry about re-raising it. I find this more convenient for the generator writer. Against this was brought in that the generator *appears* to suppress an exception that it cannot suppress: the transactional() example would be more clear according to this view if it re-raised the original exception after the call to db.rollback(). I personally would find the requirement to re-raise the exception an annoyance in a generator used as a with-template, since all the code after yield is used for is cleanup, and it is invoked from a finally-clause (the one implicit in the with-statement) which re-raises the original exception anyway. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
Guido van Rossum wrote: I hope that I've got the rewrite of PEP 343 to include generator extensions right now. I've chosen the 'with' keyword. Please review here; I think this is ready for review by the unwashed masses. :-) http://www.python.org/peps/pep-0343.html Looks pretty good to me (looking at version 1.19). One comment is that, in the 'optional extensions' section, where you say 'such mistakes are easily diagnosed', you could point to your generator wrapper as an example where attempting to reuse the block handler raises a RuntimeError on the second attempt. Also, I'm wondering if it would be useful to have a 'closing' template that looked like: @with_template def closing(obj): try: yield obj finally: obj.close() That can be used to deterministically close anything with a close method, be it file, generator, or something else: with closing(open(argument.txt)) as contradiction: for line in contradiction: print line with closing(some_gen()) as data: for datum in data: process(datum) Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.blogspot.com ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
At 01:08 AM 6/3/2005 +1000, Nick Coghlan wrote: Also, I'm wondering if it would be useful to have a 'closing' template that looked like: @with_template def closing(obj): try: yield obj finally: obj.close() +1 if you make it 'if hasattr(obj,close): obj.close()' in the finally clause, so that it will still work if the type of the object changes. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
On 6/2/05, Phillip J. Eby [EMAIL PROTECTED] wrote: At 01:08 AM 6/3/2005 +1000, Nick Coghlan wrote: Also, I'm wondering if it would be useful to have a 'closing' template that looked like: @with_template def closing(obj): try: yield obj finally: obj.close() +1 if you make it 'if hasattr(obj,close): obj.close()' in the finally clause, so that it will still work if the type of the object changes. But then you'd get back the bug where it would silently do nothing when you pass it the wrong thing; wasn't that argument used against an earlier proposal to skip calling __exit__() when it doesn't exist? -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
At 09:20 AM 6/2/2005 -0700, Guido van Rossum wrote: On 6/2/05, Phillip J. Eby [EMAIL PROTECTED] wrote: At 01:08 AM 6/3/2005 +1000, Nick Coghlan wrote: Also, I'm wondering if it would be useful to have a 'closing' template that looked like: @with_template def closing(obj): try: yield obj finally: obj.close() +1 if you make it 'if hasattr(obj,close): obj.close()' in the finally clause, so that it will still work if the type of the object changes. But then you'd get back the bug where it would silently do nothing when you pass it the wrong thing; That's not a bug, it's a feature. If the object doesn't have a 'close()' method, clearly it doesn't need to be closed. If it's the wrong object for what you're using it for in the body of the 'with' block, it'll show up there, so this doesn't hide any errors. The idea is that with closing(foo): is just an assertion that you only intend to use 'foo' in the body of that block, and not afterwards, so if 'foo' is something that needs closing, go ahead and close it. The specific use case I have in mind is situations where a piece of code expects an iterable, but there are callers (or callees) that need to do cleanup. On the other hand some callers (or callees) would like to just pass in or return a list, or are passing or returning an object from somewhere else that may or may not have a close() method. Thus, a whole bunch of code would suddenly be strewed with assumptions about whether things can be closed or not, which seems like pure administrivia. The important functionality is what the object does *before* you close it; that's what the programmer should be able to remain focused on. wasn't that argument used against an earlier proposal to skip calling __exit__() when it doesn't exist? I thought the resolution of that discussion was that you should use an explicit wrapper if you want this behavior -- which is what 'closing()' is. Anyway, if you don't like it, don't put it in. I just thought it would be a good example to include for a wrapper whose behavior is more optional in nature. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] [Python-checkins] python/dist/src/Lib sre_compile.py, 1.57, 1.58
Index: sre_compile.py === RCS file: /cvsroot/python/python/dist/src/Lib/sre_compile.py,v retrieving revision 1.57 retrieving revision 1.58 diff -u -d -r1.57 -r1.58 --- sre_compile.py28 Feb 2005 19:27:52 - 1.57 +++ sre_compile.py2 Jun 2005 13:35:52 - 1.58 @@ -167,7 +167,7 @@ emit(av-1) elif op is GROUPREF_EXISTS: emit(OPCODES[op]) -emit((av[0]-1)*2) +emit(av[0]-1) skipyes = _len(code); emit(0) _compile(code, av[1], flags) if av[2]: The times two operation also occurs twice in nearby code. Are those also incorrect? Raymond Hettinger ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] [Python-checkins] python/dist/src/Lib sre_compile.py, 1.57, 1.58
On Thu, Jun 02, 2005 at 03:34:17PM -0400, Raymond Hettinger wrote: The times two operation also occurs twice in nearby code. Are those also incorrect? I believe they're correct. EXPN: The regex engine refers to both 'groups', where group #N means the corresponding group in the pattern, and 'marks', which is a table of indexes into the string; group #0 - mark 0 and 1, group #1 - mark 2 and 3, etc. The compiler was storing the mark value, but then the code for the GROUPREF_EXISTS opcode was doubling it, converting group to mark: case SRE_OP_GROUPREF_EXISTS: TRACE((|%p|%p|GROUPREF_EXISTS %d\n, ctx-pattern, ctx-ptr, ctx-pattern[0])); /* GROUPREF_EXISTS group skip codeyes JUMP codeno ... */ i = ctx-pattern[0]; { int groupref = i+i; if (groupref = state-lastmark) { ctx-pattern += ctx-pattern[1]; break; } else { ... } The two other uses of *2 are for the MARK opcode, which stores the current position in the string in the corresponding entry in the table; it really does want the mark number, so the doubling is correct. The 'groupref = i+i' in the above code is a bit odd -- why not write 2*i? I thought it might be a typo for i+1, but that wouldn't make sense either; eventually I decided this was just a stylistic thing. --amOnly the effbot knows for surek ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
Phillip J. Eby wrote: At 10:00 PM 6/1/2005 +0200, Eric Nieuwland wrote: Phillip J. Eby wrote: -1, too confusing. A matter of taste, I guess. IMHO 'with' secretly handling exceptions is confusing. It doesn't secretly handle them; it simply gets access to them, which is an entirely different thing. By confusing, I mean that it is not clear from your construct what exceptions are caught by the 'except' clause, due to its structural layout. It's also not clear whether the __enter__/__exit__ of EXPR wrap BLOCK1 only, or both BLOCK1 and BLOCK2. These aspects are confusing because whatever decision you make about the semantics, someone will have to *remember* them, as opposed to being unambiguously represented by the block structure. By contrast, if you remove the except: clause from your construct, it is clear that BLOCK1 is what is wrapped, and there is no possible confusion about who sees what exceptions. Exceptions inside the block are communicated to __exit__, exceptions outside (including those in the 'with' statement itself) are not. OK. This forwarding (is that the proper expression here?) of an exception to __exit__ is what I meant by 'secretly handling'. If everybody agrees I'll write with EXPR as VAR: try: BLOCK1 except EXCEPTION: BLOCK2 instead. Seems a waiste to me, though. I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles uncaught exceptions by forwarding it to EXPR's __exit__ method. No confusion with me. --eric ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
At 10:04 PM 6/2/2005 +0200, Eric Nieuwland wrote: I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles uncaught exceptions by forwarding it to EXPR's __exit__ method. No confusion with me. No doubt. However, it's not obvious what happens to an exception in EXPR; surely it can't be passed to EXPR's __exit__ method. So, is it handled by the try, or does it pass out of the block? Whichever answer you give, there is somebody who will think the opposite. And this is precisely the ambiguity I've been talking about. In contrast, a 'with' unmixed with 'try' is absolutely unambiguous as to which except: clauses handle what exceptions where. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
On 2 jun 2005, at 22:12, Phillip J. Eby wrote: At 10:04 PM 6/2/2005 +0200, Eric Nieuwland wrote: I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles uncaught exceptions by forwarding it to EXPR's __exit__ method. No confusion with me. No doubt. However, it's not obvious what happens to an exception in EXPR; surely it can't be passed to EXPR's __exit__ method. So, is it handled by the try, or does it pass out of the block? Whichever answer you give, there is somebody who will think the opposite. And this is precisely the ambiguity I've been talking about. In contrast, a 'with' unmixed with 'try' is absolutely unambiguous as to which except: clauses handle what exceptions where. slap forehead I never thought of that! Now I see what you mean. I could only save my idea by stating the scope of 'try' only starts after the ':', but that seems too artificial. --eric ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
At 10:16 PM 6/2/2005 +0200, Eric Nieuwland wrote: On 2 jun 2005, at 22:12, Phillip J. Eby wrote: At 10:04 PM 6/2/2005 +0200, Eric Nieuwland wrote: I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles uncaught exceptions by forwarding it to EXPR's __exit__ method. No confusion with me. No doubt. However, it's not obvious what happens to an exception in EXPR; surely it can't be passed to EXPR's __exit__ method. So, is it handled by the try, or does it pass out of the block? Whichever answer you give, there is somebody who will think the opposite. And this is precisely the ambiguity I've been talking about. In contrast, a 'with' unmixed with 'try' is absolutely unambiguous as to which except: clauses handle what exceptions where. slap forehead I never thought of that! Now I see what you mean. I could only save my idea by stating the scope of 'try' only starts after the ':', but that seems too artificial. That's what I mean: if you have to solve it by decree, it becomes a rule that people have to *remember* (or at least read carefully and think about it), which goes against the executable pseudocode nature. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
Phillip J. Eby wrote: That's not a bug, it's a feature. If the object doesn't have a 'close()' method, clearly it doesn't need to be closed. If it's the wrong object for what you're using it for in the body of the 'with' block, it'll show up there, so this doesn't hide any errors. For those semantics, I think one of the following would be better: with local(obj): with scoped(obj): but those semantics apply better to __enter__ and __exit__ anyway. I think a closing adaptor should only work with objects that have a close() method. Perhaps: with scoped_closable(obj): Tim Delaney ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
[Nick Coghlan] Also, I'm wondering if it would be useful to have a 'closing' template that looked like: @with_template def closing(obj): try: yield obj finally: obj.close() That can be used to deterministically close anything with a close method, be it file, generator, or something else: with closing(open(argument.txt)) as contradiction: for line in contradiction: print line with closing(some_gen()) as data: for datum in data: process(datum) I just realized this has a race condition. The bytecode for the expression closing(open(...)) must necessarily contain a bytecode that calls open() followed by another bytecode that calls closing(). If a ^C happens between these two byte codes, the stack contains an open file object that won't be closed explicitly. With the original opening() template, this race can be avoided (and I intend to do so) by implementing opening() in C (as a class with __enter__ and __exit__ methods), and by making sure that the interpreter does *not* check for interrupts between the call to __enter__ and the start of the try-finally-statement in the translation of the with-statement. The only way to avoid the race that I can see with the closing() template would be to disable signals for the duration of the evaluation of the expression in the with-statement, but I really don't like that solution at all -- system calls like that can be excruciatingly expensive compared to bytecode execution. Most applications don't catch ^C so they don't need this extra protection -- but the compiler doesn't know that so everybody pays for it. The solution for avoiding interrupts between the __enter__() call and the try start doesn't require disabling signals; there can be a single opcode that calls __enter__ and sets up the try-finally context. -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] sys.path in interactive session
While looking at bug #779191, I saw that sys.path's first element is '' in interactive sessions, but the current dir otherwise. Is this intentional? Reinhold -- Mail address is perfectly valid! ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] sys.path in interactive session
I've always liked it this way; using instead of . means that if you os.path.join() it with a script name you don't get a spurious ./ prepended. I think that the absolutizing of sys.path entries is relatively new (seems to have started in 2.3). Also note that it's not really the current directory but the directory containing the script; that is definitely intentional. On 6/2/05, Reinhold Birkenfeld [EMAIL PROTECTED] wrote: While looking at bug #779191, I saw that sys.path's first element is '' in interactive sessions, but the current dir otherwise. Is this intentional? Reinhold -- Mail address is perfectly valid! ___ Python-Dev mailing list Python-Dev@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/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] sys.path in interactive session
On Jun 2, 2005, at 4:50 PM, Guido van Rossum wrote: On 6/2/05, Reinhold Birkenfeld reinhold-birkenfeld- [EMAIL PROTECTED] wrote: While looking at bug #779191, I saw that sys.path's first element is '' in interactive sessions, but the current dir otherwise. Is this intentional? I've always liked it this way; using instead of . means that if you os.path.join() it with a script name you don't get a spurious ./ prepended. I think that the absolutizing of sys.path entries is relatively new (seems to have started in 2.3). Also note that it's not really the current directory but the directory containing the script; that is definitely intentional. The absolutizing of sys.path in site.py is misbehavior anyway.. it spits in the face of path hooks, for example http://mail.python.org/ pipermail/python-dev/2005-April/052885.html. I still haven't committed that patch, I haven't had a whole lot of Python-time lately with co-founding a new company, preparing to move, WWDC, etc... but nobody bothered to complain, so if someone wants to commit http://python.org/sf/1174614 before I get a chance, feel free! -bob ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] sys.path in interactive session
At 05:08 PM 6/2/2005 -0700, Bob Ippolito wrote: On Jun 2, 2005, at 4:50 PM, Guido van Rossum wrote: I think that the absolutizing of sys.path entries is relatively new (seems to have started in 2.3). Also note that it's not really the current directory but the directory containing the script; that is definitely intentional. The absolutizing of sys.path in site.py is misbehavior anyway.. Your patch doesn't fix it doing this to __file__; probably this should not touch __file__ if a module has a __loader__ set, or if the path it's absolutizing doesn't exist. Actually, your patch doesn't fix it doing this to all the sys.path entries, either. It appears that site.py may be quite broken with respect to PEP 302. Fixing it is going to be interesting, since it's quite possible that you can have stuff on PYTHONPATH for which the sys.path_hooks entries don't exist yet. Thus, you can't guarantee when you absolutize a path entry that it is in fact a filename, unless you check for its existence - which in principle could be a coincidence. It may be that we need to define more clearly what is allowed on sys.path, such that site.py can tell the difference between filesystem paths, and non-filesystem PEP 302 specifiers. Right now, the only major PEP 302 implementation that I know of is zipimport, but zipimport uses strings that are effectively filesystem paths, so site.py doesn't break them. ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 343 rewrite complete
Guido van Rossum wrote: [...] a generator doing cleanup depending on the exception thrown (like the transactional() example below) can *catch* the exception thrown if it wants to and doesn't have to worry about re-raising it. I find this more convenient for the generator writer. Against this was brought in that the generator *appears* to suppress an exception that it cannot suppress: the transactional() example would be more clear according to this view if it re-raised the original exception after the call to db.rollback(). [...] Of course, the explicit re-raise is only needed in a minority of use cases where the exception is caught. Two additional points in favour of this: - refactoring a naked try as a with + template is more direct and uniform across all use cases. - it is upwards compatible if the prohibition on templates suppressing exceptions is ever reconsidered. (Flow control macro discussion not withstanding.) - Arnold ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] For review: PEP 343: Anonymous Block Redux and Generator Enhancements
After many rounds of discussion on python-dev, I'm inviting public comments for PEP 343. Rather than posting the entire PEP text here, I'm inviting everyone to read it on line (http://www.python.org/peps/pep-0343.html) and then post comments on a Wiki page I've created for this purpose (http://wiki.python.org/moin/WithStatement). I think this is a good one; I hope people agree. Its acceptance will obsolete about 4 other PEPs! (A sign that it fulfills a need and that the proposed solution is powerful.) -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com