
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. 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 Or worse it is possible for revaluation to cause errors class UniquePtr: def __init__(self, obj): self.set(obj) def get(self): if self._valid: self._valid = False obj = self._obj self._obj = None return obj else: raise ValueError() def set(self, obj): self._obj = obj self._valid = True x = UniquePtr(1)assert x.get() == 0 x.set(0) How would the interpreter handle this? On Sun, Sep 12, 2021 at 11:39 AM Chris Angelico <rosuav@gmail.com> wrote:
On Mon, Sep 13, 2021 at 1:37 AM Serhiy Storchaka <storchaka@gmail.com> wrote:
12.09.21 17:28, Guido van Rossum пише:
This is cool.
AFAIK pytest does something like this. How does your implementation
differ?
What pytest does is awesome. I though about implementing it in the standard compiler since seen it the first time.
What is your argument for making this part of the language? Why not a 3rd party library?
It needs a support in the compiler. The condition expression should be compiled to keep all immediate results of subexpressions on the stack. If the final result is true, immediate results are dropped. If it is false, the second argument of assert is evaluated and its value together with all immediate results of the first expression, together with references to corresponding subexpressions (as strings, ranges or AST nodes) are passed to the special handler. That handler can be implemented in a third-party library, because formatting and outputting a report is a complex task. The default handler can just raise an AttributeError.
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? Instead of keeping all the subexpressions around (a run-time cost), keep the AST of the expression itself (a compile-time cost). Then, when the exception is about to be printed to the console, re-evaluate it and do the display.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@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/IXPY4B... Code of Conduct: http://python.org/psf/codeofconduct/