bobthecow/psysh

Cannot see deprecated warnings

solodm opened this issue · 2 comments

Checked versions are Psy Shell v0.11.12 (PHP 7.4.33) and Psy Shell v0.11.16 (PHP 7.4.33).

When we run code

error_reporting(E_ALL);$a = 1?5:1?6:7;

It returns 6 as all is ok.

But if we use the php interactive shell (and there are some several ways to have been hurted by this message), we get warning

root@3cb2be255823:/var/www/html# php -a
Interactive mode enabled

php > error_reporting(E_ALL);
php > $a = 1?5:1?6:7;

Deprecated: Unparenthesized a ? b : c ? d : e is deprecated. Use either (a ? b : c) ? d : e or a ? b : (c ? d : e) in php shell code on line 1

So, why Psy keeps silence about it?

Because you're not running code without parenthesis 🙁

If you run PsySH with debugging output (psysh -vvv) it'll write the actual code evaluated along with the output. In this case, we can see that there are, in fact, parenthesis:

Screenshot 2023-05-05 at 8 40 20 AM

The reason this is happening is because PsySH can't actually execute raw user input. It requires pre-processing to create the illusion of a REPL in userland 😛

For example, take namespaces. php -a doesn't do what you'd expect with namespaces, because each new input is an eval(), so you get this:

Screenshot 2023-05-05 at 8 47 24 AM

PsySH, on the other hand, acts just like you'd expect:

Screenshot 2023-05-05 at 8 48 06 AM

… but that's because, behind the scenes, it's doing something you very much don't expect:

Screenshot 2023-05-05 at 8 48 32 AM

strict_types has similar issues in php -a:

Screenshot 2023-05-05 at 9 05 08 AM

Screenshot 2023-05-05 at 9 06 10 AM

PsySH does all this with a feature called "code cleaners". They parse input and run a bunch of transformers on it—doing everything from this namespace emulation, to input validation, to converting fatal errors to runtime errors, to return value wrangling, to making exit do what you expect—and the code they output is what is actually eval'd.

This is the man behind the curtain. It is a big piece of the magic that makes PsySH work, but doesn't come without its downsides.

In this case, the trip through tokenizing and parsing loses the fact that, originally, there weren't any parenthesis there. Because the output is just an AST writing to code, which of course emits valid code. It might be possible to detect and warn on the issue during the parsing phase, and I'll look into that, but that would be using more tricks to emulate this behavior, which as we've seen can have some downsides ¯\_(ツ)_/¯

Thanks a lot of good explanations and examples. I love psysh. However I decided to create this issue not for make psysh better only, but being in hope that I can find some information in this discussion. I try to understand why we get such warning in the unit-test in our gitlab pipeline but we don't see it at our all other kinds of running, including the same code and the same auto-test.