>  2) Some OTHER exception occurs on the reevaluation. It's a chained
> exception like any other.

Except it's not a chained exception and displaying as such would be VERY
confusing IMO.
Granted we could easily strip the chained exception and just return the
original one.  So after
reconsideration I agree this is not an issue.

>  It's only really the fourth case that would be confusing

I generally agree with your analysis but I think this 4th case is more
problematic than you think.
Given no information I am immediately going to split my assertion so I can
see what part is failing.
However, if the interpreter gives me incorrect information I am going to be
super confused.  Most people
will not have carefully read section 7.3 of the language reference  and
will not understand this critical
aspect of the execution of assertion statements.  They will assume that the
interpreter is not lying to them.

I think storing the intermediate results on the stack is vastly preferable
to revaluation for this reason.

On Mon, Oct 4, 2021 at 3:20 PM Chris Angelico <ros...@gmail.com> wrote:

> On Tue, Oct 5, 2021 at 9:02 AM Caleb Donovick <donov...@cs.stanford.edu>
> wrote:
> >
> > > I wonder, could this be simplified a bit, on the assumption that a
> > > well-written assertion shouldn't have a problem with being executed
> > > twice?
> >
> > While I agree as an engineering principle an assert should not have side
> effects
> > and hence re-evaluation should be fine in most cases, it is not
> universal. It is possible
> > for assertions to not have side effects but yet change value between
> evaluations if they
> > interact with a shared resource such as the file system..
> >
> > For example consider the following assertion:
> >
> > assert  os.path.isdir("config") and os.path.isfile("config/setup.yml")
> >
> > It is completely possible for the value of this expression to change
> between evaluations. Granted this would
> > like mean their is some more significant issue with my code, however, I
> would like the interpreter to give me
> > accurate information about why my assertion failed. Bad information is
> worse than no information. Like imagine
> > that on the first evaluation the directory config does not exist but on
> the second it has been created by another process.
> > A naive revaluation strategy would likely result in it pointing at the
> second clause and saying the assertion failed their
> > when it really failed on the first clause. This would send me down a
> rabbit hole of debugging why setup.yml was not
> > constructed properly instead of debugging why the config directory
> didn’t exist.
>
> That seems like an abuse of assertions. If you have assertions that
> depend on external state that can change that quickly, then the
> assertion is *already useless*. What do you gain by asserting
> something that might have changed by the next line of code?
>
> > Further while it is bad engineering practices to have side effects in an
> assert it is completely possible.
> > For example consider the following pathological example:
> >
> > class PathologicalFoo:
> >     def __init__(self):
> >         self._val = 0
> >
> >     def get(self):
> >         old_val = self._val
> >         self._val = 1
> >         return old_val
> >
> > foo = PathologicalFoo()
> > assert foo.get() == 1
> >
>
> Yes, side effects in assertions are always possible. If someone has
> assertions with side effects, do we say that python -O is buggy, or
> the assertion is buggy? In a world in which assertions might and might
> not be evaluated, is it such a stretch to demand that they can be
> safely reevaluated (in the same context)? Yes, it's a change to the
> expectations, but one which well-designed assertions shouldn't be
> bothered by.
>
> My imagining of this is that it'd be handled when an AssertionError
> reaches top level, and it'd be broadly thus:
>
> try:
>     all_your_code()
> except AssertionError as e:
>     ... reevaluate etc
>
> Meaning there are four possibilities:
> 1) The assertion is consistent, and the extra info is absolutely correct
> 2) Some OTHER exception occurs on the reevaluation. It's a chained
> exception like any other.
> 3) No assertion failure happens (eg PathologicalFoo). Might require a
> minor special case "if nothing goes wrong, print out the original" but
> that's the most obvious thing to do.
> 4) The assertion fails in an inconsistent way, but it still fails.
> You'll get the second form instead of the first.
>
> It's only really the fourth case that would be confusing, and only if
> the first evaluation actually causes the problem (otherwise it's just
> an inconsistent assertion and you'd need to debug both parts anyway).
> This is a pretty narrow problem, and even then, you've been shown a
> weird assertion that needs to be debugged. Is it that bad to say that
> an assertion that gives inconsistent results is buggy?
>
> ChrisA
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/GYNRJA4U5N3RMUVTWU6WJUKC46G5TOTF/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/FV7BELE6WNYJ3HV36BE2YURZVU63Y7EI/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to