Why not just show the out-of-range index?

J

John Machin

OKB said:
On reflection I think my alternative suggestion might be just as
good: the interpreter could indicate the character position within the
line. This also handles cases where the operands aren't simple names.
(Not that I have any idea how much harder/easier this would be to
implement.)

OTTOMH, it would be easier. The compiler would "only" have to ensure
that the line number and position within the line of each operator was
available at run time (currently keeping only the line number of the
first line in each statement). The cost/benefit ratio would IMHO still
be far too high.
I ask for names and values because that is what I want. If I have
some expression containing a bunch of variables and an exception is
raised, the most helpful information for me is the source code token
that is causing the error, because I can see the source code in my text
editor. The value is not as important, because there may be many
different variables that could be holding the same incorrect value. I
only want to look at the one that is ACTUALLY holding the incorrect
value.

Firstly, you may say that you want to look only at the ONE that is
actually bound to THE incorrect value, but the interpreter has in
general no way of telling which one is bad. For example:

foo = "a"
bar = [1]
baz= "z"
goo = [26]
x = foo + bar

This causes: "TypeError: cannot concatenate 'str' and 'list' objects"

Which ONE out of foo and bar is actually bound to THE "incorrect"
value? Did you mean to write "foo + baz", or did you mean to write "goo
+ bar"?

Secondly, if you have so many variables referenced in one statement all
with the same operator (e.g. +) that you have difficulty in working out
where the problem is, I'd say that you have a statement that is far too
long, and you have far too many variables in your function.

Can you give a real example from your code where the location of such a
human error (you cause a variable to bound to a value of inappropriate
type) would be difficult to find, plus an estimate of how often you
would make such an error?

Cheers,
John
 
F

Fredrik Lundh

BJörn Lindqvist said:
Maybe so, but that doesn't mean that it is not possible to make the
IndexError messages Pythons sequence objects throws better. You don't
need to change the semantics of x.


are you claiming that the fact that you can change every single index
check somehow prove that you *had* thought this through when you argued
that it could be implemented as a global PyObject_IsIndexOutOfBounds
helper, that relies on ob_size ?

(maybe I should stop using a threaded newsreader to read this group;
it's obvious that nobody else ever bothers to check what subthread a
message is appearing in.)

have you posted your patch to the patch tracker, btw?

</F>
 
B

Ben Finney

Russ said:
At this point I don't even plan to submit a formal request. I have too
many accounts and passwords already.

If the implication here (that submitting a change request requires an
account on the server) is true, then I must concur with Russ that it's
a significant barrier to entry against a user who has one suggestion
to make.

We all use software from many different vendors (or projects, or
whatever), so requiring separate, rarely-used accounts on each one's
tracking system is plenty enough to ensure that a great deal of
suggestions never go through that channel.

I hope that, instead, it's possible to perform the research needed to
describe the requested change, submit it as an email or online form,
and never have to care about an account and password on a server that
likely will never be visited again. This way, the mechanics of
submitting the request are a low enough burden that it's reasonable to
encourage people to go through that channel.
 
F

Fredrik Lundh

Ben said:
I hope that, instead, it's possible to perform the research needed to
describe the requested change, submit it as an email or online form

are you perhaps volunteering to help setup and monitoring such a sub-
mission channel ?

it's a certain amount of work to keep out the spammers and scammers, as
should be obvious for anyone who's looked at an unmonitored wiki or bug
tracker (or looked at his mail program's spam folder), but nothing that
cannot be fit into a reasonably structured developer's daily routine.

</F>
 
S

stdazi

Usually, when I make some coding mistake (index out of range - in this
case) I just care to fix the mistake and I usually don't mind to
inspect by how much the index was overflowed. It really seems like a
feature that should be embedded in some Python debugger than a feature
in the interpreter itself.
 
T

Thomas Ploch

stdazi said:
Usually, when I make some coding mistake (index out of range - in this
case) I just care to fix the mistake and I usually don't mind to
inspect by how much the index was overflowed. It really seems like a
feature that should be embedded in some Python debugger than a feature
in the interpreter itself.

I read the whole thread and this is more or less the first post which
actually has a good thing to say without saying any bad thing about anyone.

Thomas
 
A

Aahz

(maybe I should stop using a threaded newsreader to read this group;
it's obvious that nobody else ever bothers to check what subthread a
message is appearing in.)

Hey! I've been using trn3.6 for more than fifteen years, and what's good
enough for me is good enough for you!
 
R

Russ

stdazi said:
Usually, when I make some coding mistake (index out of range - in this
case) I just care to fix the mistake and I usually don't mind to
inspect by how much the index was overflowed. It really seems like a
feature that should be embedded in some Python debugger than a feature
in the interpreter itself.

Then why have the interpreter generate error messages at all? I think
it makes sense to make the interpreter as self-contained as possible,
within reason, so you don't depend on a debugger any more than
necessary.

And it's not that I care "how much the index was overflowed." It's that
something unexpected happened, and I want a clue what it was. I'll need
to find out somehow anyway. What is the next logical step if not to
find out what the out-of-range index was?

Having said that, I reiterate that I don't know the implementation
difficulty, so I defer on the decision as to whether it is worth
implementing or not.
 
R

rurpy

Russ said:
Folks,

I'm truly sorry that so many feathers got ruffled in this thread. Let's
see if I can put this thing to rest gracefully.

I too am tired of this and I apologize to you
(Russ) for jumping into it and for this (hopefullly
last) followup. But the same thing happened here
a short time ago and in that incident too, someone
who made a suggestion was attacked and charged
unjustifiably with rudeness.

In neither that case nor this did anyone protest
the unjustness and hypocrisy that was blatant.
So this time I could not sit idly and watch.

To summarize the "insults" subtread (for closure)

An observation was made about a suboptimal error
message and a suggestion about how to improve it
made in good faith. (Even harebrained suggestions
deserve a non-insulting explanation of why they're
not a good idea, and this was not harebrained.)

This resulted in a suggestion to "submit a patch".

The response was (correctly) that it was not
a viable suggestion. (characterized by "silly"
hardly a strong epithet on usenet), that it would
be "trivial" to fix and should "take 2 minutes" by
someone with the requisite experience (obviously
an opinion, not a claim, since the OP said in
the same post that he was unfamiliar with Python
internals).

Obviously it takes more than two minutes. This
was a usenet post for god's sake, not a PhD
dissertation. And "trivial" is used almost as slang
by many computer and science types and means
"very easy" (as if you didn't know).

o it is reasonable to question the description
"trivial" and ask what actually would need
to be done. It is not reasonable to be
insulted by it.
o Anyone who honestly interprets "two minutes"
as 120 seconds should seek clinical help.
A reasonable reading if this is that "it would
take someone who works on Python internals
regularly orders of magnitude less time than
me, and with a higher probability of getting
it right." Sorry folks. that is a factually
true statement. Nothing to do with your time
is less valuable than mine. More imaginary
insults.

The OP was blameless in this thread and this
was another case the regulars here overreacting
to imagined (or deliberately misinterpreted)
"insults" that were not there.

One can speculate that this serves a purpose
of suppressing interference from "outsiders"
in the development process. Or maybe it is
just the alpha dogs asserting their authority.
Either way, it should not be allowed to pass
uncriticised.
 
B

Ben Finney

Fredrik Lundh said:
are you perhaps volunteering to help setup and monitoring such a
sub- mission channel ?

I have done for other projects. I don't have the resources to do it
for every project that I'm interested in, and Python is one of many
that miss out.

I also wasn't insisting that anyone else do so; merely pointing out
some negative consequences of (what I understand to be) the current
situation, that may not be apparent to those who are closest to the
issue tracker.
 
O

OKB (not okblacke)

John said:
Firstly, you may say that you want to look only at the ONE that is
actually bound to THE incorrect value, but the interpreter has in
general no way of telling which one is bad. For example:

foo = "a"
bar = [1]
baz= "z"
goo = [26]
x = foo + bar

This causes: "TypeError: cannot concatenate 'str' and 'list'
objects"

Which ONE out of foo and bar is actually bound to THE "incorrect"
value? Did you mean to write "foo + baz", or did you mean to write
"goo + bar"?

My amended proposal handles this, because the error message should
point to the line position of the operand. (Or if it points to one of
the operands, that's fine too, at least I know what's going on.)
Secondly, if you have so many variables referenced in one statement
all with the same operator (e.g. +) that you have difficulty in
working out where the problem is, I'd say that you have a statement
that is far too long, and you have far too many variables in your
function.

See my example below.
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
 
G

Gabriel Genellina

At said:
So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

Some arguments from my head:
- because error messages should be short
- because error messages are not debugging tools (better use unit
tests to avoid most common errors)
- because it's a lot of work to actually obtain such information in
each posible case, and sometimes, it may not be posible.
- because none of the core developers has interest on it
- because nobody else cares to submit a patch


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 
J

John Machin

OKB said:
John said:
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

It should be extremely easy (rather than "not impossible") for anybody
with half a clue to find the problem given only the offending statement
(rather than your "knowledge of the program"). There are 6
possibilities; 3 are string constants. That leaves us with
len(something), searchInfo.recordName, and "][".join(something). len()
very definitely returns an integer (unless some lunatic has bound the
name to something else) and it's the *first* of the possibilities --
one can normally expect execution to proceed from left to right.
recordName smells like a string. "][".join(blahblah) likewise unless
the rebinding mania is pandemic.

Sheesh.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

And despite your use of RHN (Reverse Hungarian Notation) you don't know
that someList is a list?
 
J

John Machin

OKB said:
John said:
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

It should be extremely easy (rather than "not impossible") for anybody
with half a clue to find the problem given only the offending statement
(rather than your "knowledge of the program"). There are 6
possibilities; 3 are string constants. That leaves us with
len(something), searchInfo.recordName, and "][".join(something). len()
very definitely returns an integer (unless some lunatic has bound the
name to something else) and it's the *first* of the possibilities --
one can normally expect execution to proceed from left to right.
recordName smells like a string. "][".join(blahblah) likewise unless
the rebinding mania is pandemic.

Sheesh.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

And despite your use of RHN (Reverse Hungarian Notation) you don't know
that someList is a list?
 
J

John Machin

OKB said:
John said:
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

It should be extremely easy (rather than "not impossible") for anybody
with half a clue to find the problem given only the offending statement
(rather than your "knowledge of the program"). There are 6
possibilities; 3 are string constants. That leaves us with
len(something), searchInfo.recordName, and "][".join(something). len()
very definitely returns an integer (unless some lunatic has bound the
name to something else) and it's the *first* of the possibilities --
one can normally expect execution to proceed from left to right.
recordName smells like a string. "][".join(blahblah) likewise unless
the rebinding mania is pandemic.

Sheesh.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

And despite your use of RHN (Reverse Hungarian Notation) you don't know
that someList is a list?
 
J

John Machin

OKB said:
John said:
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

It should be extremely easy (rather than "not impossible") for anybody
with half a clue to find the problem given only the offending statement
(rather than your "knowledge of the program"). There are 6
possibilities; 3 are string constants. That leaves us with
len(something), searchInfo.recordName, and "][".join(something). len()
very definitely returns an integer (unless some lunatic has bound the
name to something else) and it's the *first* of the possibilities --
one can normally expect execution to proceed from left to right.
recordName smells like a string. "][".join(blahblah) likewise unless
the rebinding mania is pandemic.

Sheesh.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

And despite your use of RHN (Reverse Hungarian Notation) you don't know
that someList is a list?
 
J

John Machin

OKB said:
John said:
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

It should be extremely easy (rather than "not impossible") for anybody
with half a clue to find the problem given only the offending statement
(rather than your "knowledge of the program"). There are 6
possibilities; 3 are string constants. That leaves us with
len(something), searchInfo.recordName, and "][".join(something). len()
very definitely returns an integer (unless some lunatic has bound the
name to something else) and it's the *first* of the possibilities --
one can normally expect execution to proceed from left to right.
recordName smells like a string. "][".join(blahblah) likewise unless
the rebinding mania is pandemic.

Sheesh.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

And despite your use of RHN (Reverse Hungarian Notation) you don't know
that someList is a list?
 
J

John Machin

OKB said:
John said:
Can you give a real example from your code where the location of
such a human error (you cause a variable to bound to a value of
inappropriate type) would be difficult to find, plus an estimate of
how often you would make such an error?

Here is an example:

self.outFile.write(str(len(self.hits)) + ' in ' + searchInfo.recordName
+ '\t' + ']['.join((a. group() for a in self.hits)) + '\n')

This is from a text-searching tool I have written to search
linguistic corpora. This statement writes a summary line to the output
file indicating how many hits were found in that file.

The problem in this line was that I'd forgotten to put str() around
the len(). Now, it's not impossible to find the problem, because given
my knowledge of the program I know that that's the only part of the line
that would reasonably contain the number, but I still think it would be
a lot easier if there were a caret in the error message pointing to the
offending summand.

It should be extremely easy (rather than "not impossible") for anybody
with half a clue to find the problem given only the offending statement
(rather than your "knowledge of the program"). There are 6
possibilities; 3 are string constants. That leaves us with
len(something), searchInfo.recordName, and "][".join(something). len()
very definitely returns an integer (unless some lunatic has bound the
name to something else) and it's the *first* of the possibilities --
one can normally expect execution to proceed from left to right.
recordName smells like a string. "][".join(blahblah) likewise unless
the rebinding mania is pandemic.

Sheesh.

I'm glad you asked this question, though, because in searching for
examples in my code, I discovered that most of my beefs aren't actually
of this type. A lot of them are things like this:

someStr.split(someList)

Here I meant to write someList[0] (say), but have inadvertently
passed the list instead of one of its elements.

In this case I receive an error message that says "TypeError:
expected a character buffer object". My question is: why can this error
message not say what was encountered INSTEAD of a character buffer
object?

A similar situation occurs when I do someVar[0] and get an
"unsubscriptable object" error. The error does not even tell me the
type of the offending value, just that it is unsubscriptable.

So my conclusion from this is: is there a reason that every error
message of the form "expected foo" or "this object cannot be frotzed"
cannot be changed to something like "expected foo but found bar" or
"this FooType object cannot be frotzed"?

And despite your use of RHN (Reverse Hungarian Notation) you don't know
that someList is a list?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,162
Latest member
GertrudeMa
Top