PEP new assert idiom

  • Thread starter =?ISO-8859-1?Q?F=E1bio?= Mendes
  • Start date
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

I'm sorry if it's an replicate. Either my e-mail program is messing with
things or the python-list sent my msg to /dev/null. I couldn't find
anything related in previous PEP's, so here it goes a very early draft
for a new "assert" syntax:

This was inspired in Ruby's assert syntax. I'm not familiar with Ruby at
all, so the chances are that this piece of code is broken, but I think
the idea is very obvious. In Ruby, assert is simply a method which gets
a block argument:

This elegant syntax is NOT equivalent to python's not so ellegant:

In Ruby, the Assertion error is raised if executing statement 1, then 2,
then 3... etc raises an error. This is a subtle thingm the error COULD
NOT be raised if each statement is executed alone, as each statement may
have side effects which make the order of execution relevant. To
suceccefully emulate this behaviour, the python programmer have to
resort to a even more cumbersome solution:

My proposal is to add the following syntax to the language:

Or, if the user prefers, the traditional comma rules also applies:

This simple syntax change introduces a very useful idiom for unittesting
and may equally be useful in other kinds of code. The most problematic
issue, I see, is the potential ambiguity a assert usage:

As the 'Errormsg' argument is optional, it could be interpreted either
as being the statement (n + 1) or as the errormsg. This is not a
non-issue as the following syntax is valid in the current implementation
and is very useful:
Traceback
....
AssertionError

This is useful to assert that a string is not empty. My proposal is that
assert will always check all statements, (including the eventual error
message) and issue AssertError exceptions if find any problem. This will
catch only empty strings. If the last argument is a string, and an a
False statement was found, it will print the last argument in the shell.

The only piece of code I see would be broken in the new implementation
is:

This will always raise an exception in the new implementation on the
opposition to the current behaviour in which the exception is raised
only if 'statement' is false, returning an empty error message. I don't
see any use for this pattern of code and is very unlikelly anyone has
ever implemented it, so I guess nobody would mind breaking this.

I'm interested to write a formal PEP if I receive good feedback from the
community, but I never wrote a PEP before, and (the worst problem) my
english is not so good. Anyone helps?

Thanks,
Fabio
 
A

Alex Martelli

Fábio Mendes said:
This elegant syntax is NOT equivalent to python's not so ellegant:

Why isn't this equivalent? Apart from the fact that you keep, here and
elsewhere, using 'statement' where you hopefully mean 'expression' --
you cannot assert a statement, you can only assert an expression.
In Ruby, the Assertion error is raised if executing statement 1, then 2,
then 3... etc raises an error. This is a subtle thingm the error COULD
NOT be raised if each statement is executed alone, as each statement may
have side effects which make the order of execution relevant. To

Can you give one Python example where the sequence of asserts would
behave differently from what you propose? I cannot see any.
suceccefully emulate this behaviour, the python programmer have to
resort to a even more cumbersome solution:

I assume you mean to call foo, because if you don't, it will surely be
true and the assert will just never trigger.

Now, calling expressions expressions, rather than very confusingly
statements, can you explain how the semantics of this, with foo being
called, would differ from those of

assert exp1 and exp2 and exp3 ... and expN, 'errormsg'

???

My proposal is to add the following syntax to the language:

Again: can you explain how the semantics of this, would differ from
those of:

assert exp1 and exp2 and exp3 ... and expN, 'errormsg'

???
Or, if the user prefers, the traditional comma rules also applies:

There is no such "traditional" rule (or rules) in Python. Both a
statement and an expression can perfectly well end in a comma; the comma
does NOT imply any kind of continuation.


Alex
 
A

Andrew Koenig

I'm sorry if it's an replicate. Either my e-mail program is messing with
things or the python-list sent my msg to /dev/null. I couldn't find
anything related in previous PEP's, so here it goes a very early draft
for a new "assert" syntax:

Do you have a use case? That is, can you give a plausible example that
shows why your proposal would be useful and how it would work?
 
J

John Roth

Fábio Mendes said:
I'm sorry if it's an replicate. Either my e-mail program is messing with
things or the python-list sent my msg to /dev/null. I couldn't find
anything related in previous PEP's, so here it goes a very early draft
for a new "assert" syntax:
[...]

I'm interested to write a formal PEP if I receive good feedback from the
community, but I never wrote a PEP before, and (the worst problem) my
english is not so good. Anyone helps?

Thanks,
Fabio

I see two difficulties with it.

First, you can do the same thing (I think) with a
try block around a sequence of statements and
an assert in the except block. This means you
will need a fairly strong use case based on
convenience to add the syntax to the language.
You will have to show that it will be used a lot.

Second, the statement form has the potential to
cause side effects. There is a very strong
community of thought that says that asserts
are debugging or validation statements that
should not cause any behavior change by
removing them. This can be dealt with by
making it some form of block that has its
own local variables that are discarded on
exit.

John Roth
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

erromsg = 'Errormsg'
Why isn't this equivalent? Apart from the fact that you keep, here and
elsewhere, using 'statement' where you hopefully mean 'expression' --
you cannot assert a statement, you can only assert an expression.

There is only the conceptually subtle difference that in the 1st you
asserts the whole block of expressions, the second you assert each
expression. They're likely to be the same, probably they will be
equivalent in all cases but I can't backup the truth or falsity of that
statement. The pythonic counterpart involves too much typing and is more
error prone.
Now, calling expressions expressions, rather than very confusingly
statements, can you explain how the semantics of this, with foo being
called, would differ from those of

assert exp1 and exp2 and exp3 ... and expN, 'errormsg'

This is very similar to what I'm proposing, with the only inconvinience
that is uglier to type:

assert \
exp1 and \
exp2 and \
...
expn,
'ErrorMsg'

Instead of:

assert \
exp1,
exp2,
...
expn,
'Errormsg'

Well, I realize I didn't expressed my thoughts very clearly and that
it's indeed a very minor change in python's syntax. It won't let anyone
does anything new, IFAIK, but it makes a common pattern of code a little
more beautiful, (and why not? more expressive). If one consider the fact
that it won't break old code (only in one very unlikely case) I don't
see it as a completely unreasonable suggestion. Other people may think
differently though.

Thanks,
Fabio
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

I see two difficulties with it.
First, you can do the same thing (I think) with a
try block around a sequence of statements and
an assert in the except block. This means you
will need a fairly strong use case based on
convenience to add the syntax to the language.
You will have to show that it will be used a lot.

I meant expression instead of statement, sorry, that's my fault. It's a
minor cosmetic change I should say, only to avoid long grouping of
expressions with an 'and' operator. It's better expressed as: let the
commas take the place of 'and' in assertion verifications... Maybe that
could be extended to other parts of the language, but the only place I
think it would be useful is in assertion statements.

Thanks,
Fabio
 
R

Raymond Hettinger

[Fábio Mendes]
This is very similar to what I'm proposing, with the only inconvinience
that is uglier to type:

assert \
exp1 and \
exp2 and \
...
expn,
'ErrorMsg'

Instead of:

assert \
exp1,
exp2,
...
expn,
'Errormsg'

Well, I realize I didn't expressed my thoughts very clearly and that
it's indeed a very minor change in python's syntax. It won't let anyone
does anything new, IFAIK, but it makes a common pattern of code a little
more beautiful, (and why not? more expressive). If one consider the fact
that it won't break old code (only in one very unlikely case) I don't
see it as a completely unreasonable suggestion. Other people may think
differently though.

The odds of Guido accepting this proposal are about zero. As you say, it
doesn't do anything new, but it does require altering the grammar. Besides,
TOOWTDI.

Also, Guido tends to not be persuaded by arguments about "too much typing".
This is doubly true is you're talking about replacing an "and" with a comma (big
whoop).

Also, one of the existing alternatives is quite readable:

err = 'Errormsg'
assert exp1, err
assert exp2, err
assert exp3, err

The alternative has the advantage that a failure will point to the exact
expression that failed. The disadvantage is the repetition of the error
message; however, I disagree that your use case is common. Instead, it is
likely more advantageous to have different error messages for each expression.
For example, the following comes from the post condition checks in QR matrix
decomposition:

assert Q.tr().mmul(Q)==eye(min(m,n)), "Q is not orthonormal"
assert isinstance(R,UpperTri), "R is not upper triangular"
assert R.size==(m,n), "R is does not match the original dimensions"
assert Q.mmul(R)==self, "Q*R does not reproduce the original matrix"

One could link all of these by an "and" or the proposed comma, but then you
end-up with a single, less informative error message, "The QR decomposition
bombed, but I won't tell you why ;-) ".


Raymond Hettinger
 
P

Paul Rubin

Some time ago I found myself proposing a new "Validate" statement,
which would work exactly like "assert", except:

1) it would throw a ValidationError instead of AssertionError
if the condition failed

2) it would NOT be turned into a no-op by the optimizing compiler.

The purpose is runtime validation of user data, rather than sanity
checking the program logic. Example: I keep finding myself writing
code like:

x = float(raw_input('Enter a positive number: '))
assert x > 0, 'number wasn't positive'

This is incorrect because the assert statement is not guaranteed to be
executed. I propose to say instead,

validate x > 0, 'number wasn't positive'

which would do the right thing.

This proposal was reasonably well received when I've posted it before,
but I don't remember if there was any conclusion, and there was no
follow-up. Since we're again talking about PEP's regarding the assert
statement, should I try to put one together for this, in my copious
(hah) free time?
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

Some time ago I found myself proposing a new "Validate" statement,
which would work exactly like "assert", except:

1) it would throw a ValidationError instead of AssertionError
if the condition failed

2) it would NOT be turned into a no-op by the optimizing compiler.
[...]
This sounds great. I like the validate syntax. This also sounds very
useful to me. If it doesn't go mainstream, it should, at least be a
parameter controlled at runtime:

Ideally, for me, python would support a decent DPC-like semantics:


The (python) implementation of this syntax can be something like this.
If dbc is enable, foo method becames:

The program executes normally, then, if non fatal errors happens,
contracViolations.report() will print a nice formated report of what was
violated, similar to what unittest module does. This is not pure DBC I
guess, but is nice.

Thanks,
Fabio
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

The alternative has the advantage that a failure will point to the exact
expression that failed. The disadvantage is the repetition of the error
message; however, I disagree that your use case is common. Instead, it is
likely more advantageous to have different error messages for each expression.
For example, the following comes from the post condition checks in QR matrix
decomposition:

assert Q.tr().mmul(Q)==eye(min(m,n)), "Q is not orthonormal"
assert isinstance(R,UpperTri), "R is not upper triangular"
assert R.size==(m,n), "R is does not match the original dimensions"
assert Q.mmul(R)==self, "Q*R does not reproduce the original matrix"

One could link all of these by an "and" or the proposed comma, but then you
end-up with a single, less informative error message, "The QR decomposition
bombed, but I won't tell you why ;-) ".
You have a good point here. Maybe what I proposed is only a distraction.
We don't want a syntax tailored to every sittuation as it will serve
only for showcase selected programs that express the full elegance of
the language, but to the programmer, it gains the burden of memorizing
the 100 and so operators that makes the language very expressive. Of
course each person will develop a personal dialect, which will make his
code very expressive in a specific domain, but he'll talk to
nobodyelse... For that we have perl. So I guess i'm off this thread, but
someone pointed a PEP for a 'validate' statement which still holds. At
least it will help to elucidate the somewhat confusing meaning of the
assert statement. (you shouldn't use it at runtime?? which level of
optimizations disable it?).

Fabio
 
R

Raymond Hettinger

Paul Rubin said:
Some time ago I found myself proposing a new "Validate" statement,
which would work exactly like "assert", except:

1) it would throw a ValidationError instead of AssertionError
if the condition failed

2) it would NOT be turned into a no-op by the optimizing compiler.

The purpose is runtime validation of user data, rather than sanity
checking the program logic. Example: I keep finding myself writing
code like:

x = float(raw_input('Enter a positive number: '))
assert x > 0, 'number wasn't positive'

This is incorrect because the assert statement is not guaranteed to be
executed. I propose to say instead,

validate x > 0, 'number wasn't positive'

which would do the right thing.

Why do you need a statement for this?
IMO, a plain function will do the trick:

def validate(expression, msg=None):
if expression: return
if msg is None:
raise ValidationError
else
raise ValidationError(msg)


Raymond Hettinger
 
P

Paul Rubin

Raymond Hettinger said:
Why do you need a statement for this?
IMO, a plain function will do the trick:

I do write such functions sometimes, but using a statement is more
natural. That's why the assert statement exists, for example.

Because of that naturalness, the temptation to misuse the assert
statement is very great, and I find myself doing it all the time
thinking I'll clean it up later. So I think having a statement for
runtime checking would be in the correct spirit.
 
A

Alex Martelli

Fábio Mendes said:
This is very similar to what I'm proposing, with the only inconvinience
that is uglier to type:

assert \
exp1 and \
exp2 and \
...
expn,
'ErrorMsg'

Instead of:

assert \
exp1,
exp2,
...
expn,
'Errormsg'

So follow PEP 8's recommendation instead:

assert (
exp1 and
exp2 and
...
expn
), 'Errormsg'

I don't see the parentheses (which clarify the syntax issue you
mentioned in your first post) and 'and' as any uglier than the commas.
And having commas mean line continuation is out of the question.


Alex
 
B

Bengt Richter

[Fábio Mendes]
This is very similar to what I'm proposing, with the only inconvinience
that is uglier to type:

assert \
exp1 and \
exp2 and \
...
expn,
'ErrorMsg'

Instead of:

assert \
exp1,
exp2,
...
expn,
'Errormsg'

Well, I realize I didn't expressed my thoughts very clearly and that
it's indeed a very minor change in python's syntax. It won't let anyone
does anything new, IFAIK, but it makes a common pattern of code a little
more beautiful, (and why not? more expressive). If one consider the fact
that it won't break old code (only in one very unlikely case) I don't
see it as a completely unreasonable suggestion. Other people may think
differently though.

The odds of Guido accepting this proposal are about zero. As you say, it
doesn't do anything new, but it does require altering the grammar. Besides,
TOOWTDI.

Also, Guido tends to not be persuaded by arguments about "too much typing".
This is doubly true is you're talking about replacing an "and" with a comma (big
whoop).

Also, one of the existing alternatives is quite readable:

err = 'Errormsg'
assert exp1, err
assert exp2, err
assert exp3, err

The alternative has the advantage that a failure will point to the exact
expression that failed. The disadvantage is the repetition of the error
message; however, I disagree that your use case is common. Instead, it is
likely more advantageous to have different error messages for each expression.
For example, the following comes from the post condition checks in QR matrix
decomposition:

assert Q.tr().mmul(Q)==eye(min(m,n)), "Q is not orthonormal"
assert isinstance(R,UpperTri), "R is not upper triangular"
assert R.size==(m,n), "R is does not match the original dimensions"
assert Q.mmul(R)==self, "Q*R does not reproduce the original matrix"

One could link all of these by an "and" or the proposed comma, but then you
end-up with a single, less informative error message, "The QR decomposition
bombed, but I won't tell you why ;-) ".
Besides, if you want the single message with comma-delimited expressions,
you can already write:
... True,
... 1,
... 2==2
... )), 'Error message'

Or to show what happens ... True,
... 1,
... 2==3
... )), 'Error message'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError: Error message

Or with a little helper, and then two boilerplate lines for the assert,
you can have individual messages:
... """find first false xpr in seq xpr ,msg, xpr, msg and yield pair"""
... it = iter(xm)
... for x in it:
... m = it.next()
... if not x: yield x, m; break
... ... assert not [t for t in fff(
...
... True, 'true msg',
... 1, 'one msg',
... 2==x, '2 eq x msg',
... 'xx', 'xx msg'
...
... )], 'Error: expr == %r, msg = %r'%t
... Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
AssertionError: Error: expr == False, msg = '2 eq x msg'

Actually, why not just make a utility function "asserts" to do it:
... """find first false expression value and assert it with paired message"""
... it = iter(expr_msg_seq)
... for x in it:
... m = it.next()
... if not x:
... assert x, '%r -> %r'%(x, m)
... ... asserts(
... True, 'true msg',
... 1, 'one msg',
... x, 'bool(x) is not True',
... x==2, '2 eq x msg',
... 'xx', 'xx msg'
... )
... Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test

I doesn't shortcut, so you could get an exception in preparing the arg list for
a sequence like
asserts(
den !=0, 'denom must be zero',
num/den>5, 'better write it as assert num>5*den'
)
which would be safer as
assert den !=0, 'denom must be zero'
assert num/den>5 'better write it as assert num>5*den'

Not to mention side effects, but you shouldn't have those in asserts anyway.

Silliness ;-)

Regards,
Bengt Richter
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

Em Sáb, 2004-11-06 às 22:48 -0800, Paul Rubin escreveu:
I do write such functions sometimes, but using a statement is more
natural. That's why the assert statement exists, for example.

Because of that naturalness, the temptation to misuse the assert
statement is very great, and I find myself doing it all the time
thinking I'll clean it up later. So I think having a statement for
runtime checking would be in the correct spirit.

If it wasn't that we should be programming in assembly as it's faster :)
AFAIK all real world programming languages are turing equivalent, so
sugar is what differentiates on of the other. I'd love to see that sugar
in Python since defining assert functions is distracting.

Fabio
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

So follow PEP 8's recommendation instead:
assert (
exp1 and
exp2 and
...
expn
), 'Errormsg'
I didn't know this would work for 'and/or' operators (even I've read the
style guide PEP!), sorry. It's not super beautiful, but I could live
happy with that :)
I don't see the parentheses (which clarify the syntax issue you
mentioned in your first post) and 'and' as any uglier than the commas.
And having commas mean line continuation is out of the question.

I never said that commas should mean line continuation (as a backslash).
It CAN be used as implicit line continuations in lot cases, (like
function arguments, for instance. This would be just one more case.

Cheers,
Fabio
 
?

=?ISO-8859-1?Q?F=E1bio?= Mendes

Thanks for clarification :)

Fabio

Em Dom, 2004-11-07 às 07:43 +0000, Bengt Richter escreveu:
[Fbio Mendes]
This is very similar to what I'm proposing, with the only inconvinience
that is uglier to type:

assert \
exp1 and \
exp2 and \
...
expn,
'ErrorMsg'

Instead of:

assert \
exp1,
exp2,
...
expn,
'Errormsg'

Well, I realize I didn't expressed my thoughts very clearly and that
it's indeed a very minor change in python's syntax. It won't let anyone
does anything new, IFAIK, but it makes a common pattern of code a little
more beautiful, (and why not? more expressive). If one consider the fact
that it won't break old code (only in one very unlikely case) I don't
see it as a completely unreasonable suggestion. Other people may think
differently though.

The odds of Guido accepting this proposal are about zero. As you say, it
doesn't do anything new, but it does require altering the grammar. Besides,
TOOWTDI.

Also, Guido tends to not be persuaded by arguments about "too much typing".
This is doubly true is you're talking about replacing an "and" with a comma (big
whoop).

Also, one of the existing alternatives is quite readable:

err = 'Errormsg'
assert exp1, err
assert exp2, err
assert exp3, err

The alternative has the advantage that a failure will point to the exact
expression that failed. The disadvantage is the repetition of the error
message; however, I disagree that your use case is common. Instead, it is
likely more advantageous to have different error messages for each expression.
For example, the following comes from the post condition checks in QR matrix
decomposition:

assert Q.tr().mmul(Q)==eye(min(m,n)), "Q is not orthonormal"
assert isinstance(R,UpperTri), "R is not upper triangular"
assert R.size==(m,n), "R is does not match the original dimensions"
assert Q.mmul(R)==self, "Q*R does not reproduce the original matrix"

One could link all of these by an "and" or the proposed comma, but then you
end-up with a single, less informative error message, "The QR decomposition
bombed, but I won't tell you why ;-) ".
Besides, if you want the single message with comma-delimited expressions,
you can already write:
... True,
... 1,
... 2==2
... )), 'Error message'

Or to show what happens... True,
... 1,
... 2==3
... )), 'Error message'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError: Error message

Or with a little helper, and then two boilerplate lines for the assert,
you can have individual messages:
... """find first false xpr in seq xpr ,msg, xpr, msg and yield pair"""
... it = iter(xm)
... for x in it:
... m = it.next()
... if not x: yield x, m; break
...... assert not [t for t in fff(
...
... True, 'true msg',
... 1, 'one msg',
... 2==x, '2 eq x msg',
... 'xx', 'xx msg'
...
... )], 'Error: expr == %r, msg = %r'%t
...Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
AssertionError: Error: expr == False, msg = '2 eq x msg'

Actually, why not just make a utility function "asserts" to do it:
... """find first false expression value and assert it with paired message"""
... it = iter(expr_msg_seq)
... for x in it:
... m = it.next()
... if not x:
... assert x, '%r -> %r'%(x, m)
...... asserts(
... True, 'true msg',
... 1, 'one msg',
... x, 'bool(x) is not True',
... x==2, '2 eq x msg',
... 'xx', 'xx msg'
... )
...Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 7, in test

I doesn't shortcut, so you could get an exception in preparing the arg list for
a sequence like
asserts(
den !=0, 'denom must be zero',
num/den>5, 'better write it as assert num>5*den'
)
which would be safer as
assert den !=0, 'denom must be zero'
assert num/den>5 'better write it as assert num>5*den'

Not to mention side effects, but you shouldn't have those in asserts anyway.

Silliness ;-)

Regards,
Bengt Richter
 
S

Steven Bethard

Fábio Mendes said:
I never said that commas should mean line continuation (as a backslash).
It CAN be used as implicit line continuations in lot cases, (like
function arguments, for instance. This would be just one more case.

I'm not sure that I understand you correctly, but if you're saying that the
commas in a function argument list indicate an implicit line continuation, I
think this is probably not correct. It's the unclosed parentheses that indicate
the line continuation, not the commas -- this is why you can write a function
argument list across multiple lines, but it's also why you can write a tuple
across lines:
.... y, z):
.... print x, y, z
.... 1 2 3

Note that just a trailing comma definitely does not mean a line continuation:
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
NameError: name 'x' is not defined

I tried to write a tuple over multiple lines here, but (because commas do not
indicate line continuations), Python thinks I want to print the value of the
tuple containing x.

Of course, unclosed brackets work the same way as unclosed parentheses:
[x, .... y, z] = 1, 2, 3
print x, y, z
1 2 3

Steve
 
A

Alex Martelli

Fábio Mendes said:
I didn't know this would work for 'and/or' operators (even I've read the
style guide PEP!), sorry. It's not super beautiful, but I could live
happy with that :)

It works for the parentheses -- what operators are inside the
parentheses, including none at all, doesn't matter. A logical line
isn't finished until all kinds of parentheses are balanced.

I never said that commas should mean line continuation (as a backslash).
It CAN be used as implicit line continuations in lot cases, (like
function arguments, for instance. This would be just one more case.

Nope, comma can never be used as implicit line continuation in Python
(that's different from some other languages). The opened and yet
unclosed parentheses are what cause several physical lines to be part of
the same logical line -- not commas, nor other operator or punctuation.

Consider for example:

print ( 'some text'
'and some more'
'and yet more' )

look, ma: no commas (nor other punctuation nor operators, yet three
physical lines merge into just one logical line -- thanks to the
parentheses. This will print

some textand some moreand yet more

because adjacent string literals merge into one string literal (in
Python just like in C).

If you put commas there WITH the parentheses, you'd be printing out a
tuple. With the commas and WITHOUT the parentheses, syntax error.

You may be associating "commas continue lines" with "function arguments"
because function definitions and calls DO use parentheses, and separate
arguments with commas. But it's really not an ideal mental model.


Alex
 
G

Gerrit

Paul said:
I do write such functions sometimes, but using a statement is more
natural. That's why the assert statement exists, for example.

I think 'assert' being a statement is on Guido's regrets list. exec and
print are on his regrets list: both should have been a function. I
think the same holds for assert, although I'm not sure.
statement is very great, and I find myself doing it all the time
thinking I'll clean it up later. So I think having a statement for
runtime checking would be in the correct spirit.

In my opinion, assert is almost useless. It can sometimes be useful for
debugging purposes, but beyond that, it isn't. The exception raised by
'assert' is always AssertionError. That is a major disadvantage, because
it's not specific. If a method I'm calling would raise an AssertionError
is some cases, and I want to catch it, I'm catching too much. Creating a
new exception-class and raising that one is better because of this.

I don't see the use of a statement like
"assert isinstance(message, basestring)". It's by far the most common
use of assert: some assertions about the types of the arguments. This is
at best redundant. In the case of warnings.py, it's followed by
re.compile(message, ...). Removing the assertion in this example would result
in three differences:
- The error raised would be TypeError, not AssertionError. Therefore
it's more specific and thus easier to catch.
- The error would me raised by the re module, not warnings module
- The error would be "first argument must be string or compiled
pattern" instead of "message must be a string". Therefore, the
assertion makes it impossible to pass a compiled pattern instead
of a string.

Duck typing eliminates the use of assert.

In my opinion, assert should be deprecated and then removed in Py3K:
assertions are redundant, unspecific, and conflict with the philosophy
of duck typing and EAFP.

What do others think of this?

Gerrit.

--
Weather in Twenthe, Netherlands 07/11 13:25:
12.0°C wind 3.6 m/s N (57 m above NAP)
--
In the councils of government, we must guard against the acquisition of
unwarranted influence, whether sought or unsought, by the
military-industrial complex. The potential for the disastrous rise of
misplaced power exists and will persist.
-Dwight David Eisenhower, January 17, 1961
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top