Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-05 Thread Rowan Tommins

On 05/05/2022 06:37, Juliette Reinders Folmer wrote:

I was going to mention the same example as the precedent ;-) 



Another relevant precedent, since the original RFC talked about keeping 
things "side-effect free", is that passing "99 red balloons" to an "int" 
parameter raised an E_NOTICE in PHP 7.x, so a "callable" parameter 
raising an E_DEPRECATED should be fine.



Either way, how will this get picked up now ? What are the next steps 
to put this thing in motion ?


(Note: please don't suggest for me to create a PR - I'm a PHP dev, not 
a C-dev)



If nobody else does, I can have a look at the implementation, which I 
think should be fairly straight-forward.


However, since the current behaviour was explicitly mentioned in the 
accepted RFC, and the response here wasn't immediately unanimous, it's 
probably sensible to write it up as its own RFC to be voted on. It 
doesn't need to say much, just summarise the key points from this 
discussion. See https://wiki.php.net/rfc/howto for the steps, and feel 
free to send me a message off-list if you want a hand drafting or 
proof-reading it.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



[PHP-DEV] Re: ***SPAM*** Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-04 Thread Juliette Reinders Folmer

On 2-5-2022 14:43, Rowan Tommins wrote:

On 02/05/2022 12:56, Alexandru Pătrănescu wrote:

The point is that this is not an usual deprecation, something that will
change to an error in the future.
In the end, it's just a change in behavior with no error before or 
after.

It does not fit the "deprecation".



That was my instinct too, but Juliette's analysis elsewhere on the 
thread has convinced me that it is very likely that anyone seeing this 
deprecation would want to change their code, rather than allowing it 
to change behaviour in 9.0.


Perhaps a reasonable comparison is the change in precedence of the 
concatenation operator 
[https://wiki.php.net/rfc/concatenation_precedence]. The expression 
("sum: " . $a + $b) is valid in PHP 7 and PHP 8, but has different 
results; PHP 7.4 included a deprecation notice because users would 
almost certainly want to choose which behaviour they wanted.


The difference in this case is that the code change probably won't 
happen in the same place as the is_callable() function call, but 
somewhere further up the stack. For instance, a framework function 
might accept arbitrary values and test them with is_callable; an 
application using that framework might pass "parent::foo", which will 
change behaviour in 9.0. It is the application's author who will 
benefit from the deprecation notice, so they can pass a different 
value whose behaviour isn't going to change.




I was going to mention the same example as the precedent ;-)

Either way, how will this get picked up now ? What are the next steps to 
put this thing in motion ?


(Note: please don't suggest for me to create a PR - I'm a PHP dev, not a 
C-dev)





Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Rowan Tommins

On 02/05/2022 12:56, Alexandru Pătrănescu wrote:

The point is that this is not an usual deprecation, something that will
change to an error in the future.
In the end, it's just a change in behavior with no error before or after.
It does not fit the "deprecation".



That was my instinct too, but Juliette's analysis elsewhere on the 
thread has convinced me that it is very likely that anyone seeing this 
deprecation would want to change their code, rather than allowing it to 
change behaviour in 9.0.


Perhaps a reasonable comparison is the change in precedence of the 
concatenation operator 
[https://wiki.php.net/rfc/concatenation_precedence]. The expression 
("sum: " . $a + $b) is valid in PHP 7 and PHP 8, but has different 
results; PHP 7.4 included a deprecation notice because users would 
almost certainly want to choose which behaviour they wanted.


The difference in this case is that the code change probably won't 
happen in the same place as the is_callable() function call, but 
somewhere further up the stack. For instance, a framework function might 
accept arbitrary values and test them with is_callable; an application 
using that framework might pass "parent::foo", which will change 
behaviour in 9.0. It is the application's author who will benefit from 
the deprecation notice, so they can pass a different value whose 
behaviour isn't going to change.


Regards,

--
Rowan Tommins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Guilliam Xavier
On Mon, May 2, 2022 at 1:57 PM Alexandru Pătrănescu  wrote:
> On Mon, May 2, 2022 at 2:15 PM Guilliam Xavier  
> wrote:
>> I too would rather have "extra" deprecation notices in 8.2 than
>> *sudden errors / silent behavior changes* in 9.0 (for the callable
>> type declaration / the is_callable() function)...
>
> The point is that this is not an usual deprecation, something that will 
> change to an error in the future.
> In the end, it's just a change in behavior with no error before or after. It 
> does not fit the "deprecation".

This has already been said earlier, and answered:

On Wed, Apr 20, 2022 at 12:22 AM Claude Pache  wrote:
> > Le 19 avr. 2022 à 20:20, Andreas Hennings  a écrit :
> > A deprecation warning on is_callable() would imply that in a future
> > version of PHP that call will be illegal.
>
> No,  in the case of `is_callable()`, the deprecation warning will imply that, 
> in a future version of PHP, the behaviour will change.  There are precedents 
> of deprecation warning for changing behaviour: https://3v4l.org/Iqo4N

Regards,

-- 
Guilliam Xavier

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Andreas Leathley

On 02.05.22 13:56, Alexandru Pătrănescu wrote:

The point is that this is not an usual deprecation, something that will
change to an error in the future.
In the end, it's just a change in behavior with no error before or after.
It does not fit the "deprecation".

As I dealt with several PHP upgrades, and I'm still going to deal with them
in the future, I proposed an idea at some point on the mailing list:
To find a way to "flag" a behavior change.
The problem is that it should be something outside E_ALL, or to be able to
handle it in a totally different way than setting an error handler for it.
Something that can be used when preparing for an PHP upgrade, something
like:
register_version_change_handler(callable $callback, $toPhpVersion)
While preparing for a future runtime version, it would be deployed to
production and would record behavioral changes in a logging system.
These changes need to be manually reviewed, of course, as a change can be
to return false instead of null and if that value would be used further in
an if.
When using in a library maybe there could be some token like @@@ to not
trigger the handler.


To me, adding another error/change handler system seems like a bad way
of dealing with this, not to mention that you need to introduce this
behavior in a PHP version first before anyone can then use it, so it
would be years before this could be useful, and even more years until
there would be established patterns and enough knowledge around it.
Using the existing way of notices, warnings and errors seems just as
good to me, and people have been handling those for many years. Any new
way of dealing with this should have a very high bar to clear and would
need to prove a huge gain in value.

To me this does fit the definition of a deprecation - behavior for the
given code will change intentionally in a future version, and you are
warning about that future change. But one could also emit a notice, or a
warning. The advantage of deprecation notices is that many tools ignore
those specifically, as they are something to look at, but not
necessarily right at this moment. Being more lenient in certain
situations with deprecation notices is therefore a good pattern for
easier adoption of new versions. I have included that behavior in my own
applications, by logging deprecations separately - I will check them out
once in a while, but they do not need immediate attention. Any other PHP
notice or warning would warrant immediate attention, as it would be
unexpected.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Alexandru Pătrănescu
On Mon, May 2, 2022 at 2:15 PM Guilliam Xavier 
wrote:

> On Wed, Mar 16, 2022 at 9:57 AM Christian Schneider
>  wrote:
> >
> > Am 16.03.2022 um 06:52 schrieb Juliette Reinders Folmer <
> php-internals_nos...@adviesenzo.nl>:
> > > I've just been looking in detail at the Partially Supported Callables
> deprecation RFC:
> https://wiki.php.net/rfc/deprecate_partially_supported_callables
> > >
> > > The RFC explicitly excludes the `is_callable()` function and the
> `callable` type from throwing deprecation notices.
> > >
> > > [...] I wonder if the decision [...] is the right one (though I
> understand the desire to keep [them] side-effect free).
> > >
> > > Consider these code samples:
> > >
> > >  function foo(callable $callback) {}
> > >  foo('static::method');
> > >
> > > [...] in PHP 9.0 the function will start throwing a TypeError.
> >
> > [...] This is a major problem because code which was "just working"
> directly goes to a TypeError without a migration phase warning about it.
> This is something I've repeatedly advocated against.
> >
> > >  if (is_callable('static::method')) {
> > >  static::method();
> > >  }
> > >
> > > [...] in PHP 9.0, the behaviour of this code will be silently reversed
> for those callbacks which would previously result in `is_callable()`
> returning true, which makes this a potentially dangerous change without
> deprecation notice.
> >
> > I agree with you here: Code which silently changes behavior is also a
> migration hassle.
>
> Hi,
>
> I too would rather have "extra" deprecation notices in 8.2 than
> *sudden errors / silent behavior changes* in 9.0 (for the callable
> type declaration / the is_callable() function)...
>
>
>
The point is that this is not an usual deprecation, something that will
change to an error in the future.
In the end, it's just a change in behavior with no error before or after.
It does not fit the "deprecation".

As I dealt with several PHP upgrades, and I'm still going to deal with them
in the future, I proposed an idea at some point on the mailing list:
To find a way to "flag" a behavior change.
The problem is that it should be something outside E_ALL, or to be able to
handle it in a totally different way than setting an error handler for it.
Something that can be used when preparing for an PHP upgrade, something
like:
register_version_change_handler(callable $callback, $toPhpVersion)
While preparing for a future runtime version, it would be deployed to
production and would record behavioral changes in a logging system.
These changes need to be manually reviewed, of course, as a change can be
to return false instead of null and if that value would be used further in
an if.
When using in a library maybe there could be some token like @@@ to not
trigger the handler.

So yeah, this cannot really be an usual deprecation, it needs to be
something else, IMO.

Regards,
Alex


Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Guilliam Xavier
On Wed, Mar 16, 2022 at 9:57 AM Christian Schneider
 wrote:
>
> Am 16.03.2022 um 06:52 schrieb Juliette Reinders Folmer 
> :
> > I've just been looking in detail at the Partially Supported Callables 
> > deprecation RFC: 
> > https://wiki.php.net/rfc/deprecate_partially_supported_callables
> >
> > The RFC explicitly excludes the `is_callable()` function and the `callable` 
> > type from throwing deprecation notices.
> >
> > [...] I wonder if the decision [...] is the right one (though I understand 
> > the desire to keep [them] side-effect free).
> >
> > Consider these code samples:
> >
> >  function foo(callable $callback) {}
> >  foo('static::method');
> >
> > [...] in PHP 9.0 the function will start throwing a TypeError.
>
> [...] This is a major problem because code which was "just working" directly 
> goes to a TypeError without a migration phase warning about it. This is 
> something I've repeatedly advocated against.
>
> >  if (is_callable('static::method')) {
> >  static::method();
> >  }
> >
> > [...] in PHP 9.0, the behaviour of this code will be silently reversed for 
> > those callbacks which would previously result in `is_callable()` returning 
> > true, which makes this a potentially dangerous change without deprecation 
> > notice.
>
> I agree with you here: Code which silently changes behavior is also a 
> migration hassle.

Hi,

I too would rather have "extra" deprecation notices in 8.2 than
*sudden errors / silent behavior changes* in 9.0 (for the callable
type declaration / the is_callable() function)...

Regards,

-- 
Guilliam Xavier

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-04-21 Thread Juliette Reinders Folmer

On 22-4-2022 3:02, php-internals_nos...@adviesenzo.nl wrote:


On 21-4-2022 21:56, Andreas Hennings wrote:

On Thu, 21 Apr 2022 at 11:18, Rowan Tommins  wrote:

On Wed, 20 Apr 2022 at 19:16, Claude Pache  wrote:


You make a very important claim in your bug report:


However, in real world, is_callable() is almost never given totally

arbitrary stuff

My concern is that we have no way of knowing whether this is true, and

whether there will always be a clear action for users who see the
deprecation notice.

In this case, there is always the possibility for them to use the error
suppression operator. That remains easy, and looks like a reasonable use
case of that operator.


The error suppression operator is a big blunt tool, and using it to squash
a deprecation notice would be an absolute last resort. Note that in
contrast to the strpos() case where both behaviours can be achieved with
*permanent* changes, the error suppression would only be a temporary
workaround for error logging, with no value in itself.




If we have to balance between addressing the verified issue of not
emitting deprecation notice for well-known and fairly frequent code
patterns, and addressing the potential and non-fatal issue of emitting too
much notices for totally unknown use cases, the choice should be
straightforward.


Again, this is true IF you are correct that one set of patterns is common
and the other is not, but so far I've not seen any attempt to find out
whether that's true. The idea of ignoring "unknown" use cases seems really
dangerous - like closing your eyes so you can't see the bad effects of what
you do. What we need to know is whether such use cases are *rare*, or
whether the people using them are just not subscribed to this list.

One starting point would be to find usages in the top 100 or 1000 packages
on Packagist usinghttps://github.com/nikic/popular-package-analysis  -
perhaps Juliette has already done that when testing their PHPCompatibility
sniff?

As a package author, you might not really know where the value is coming from.
A parameter will be declared as `@param mixed $callback_or_not`, if it
internally calls the`is_callable()` method.
And a static analysis tool will only see `mixed`, not "mixed, but if
it is a string, it does not start with 'static::', or if i's an array,
the first value is not 'static'.".

On the other hand, the value probably won't be completely arbitrary.
It might be coming from a discovery process that reads yml files or
annotations, or that calls some kind of hook in php. Or it is
generated with string concatenation.
Whatever it is, it is probably explicitly or implicitly hard-coded somewhere.

Here is a starting point for a search. But only for explicit calls.
https://sourcegraph.com/search?q=context:global+is_callable%5C%28%28%5C%5B%27%28static%7Cself%29%27%7C%27%28static%7Cself%29::.*%27%29%2C+lang:php=regexp



I appreciate it very much that Claude is trying to move the issue I 
raised forward.


Some responses to the discussion which has ensued:

1. In my opinion, the deprecation should only be shown when one of the 
deprecated syntaxes is passed either to a function with a `callable` 
type declaration or to `is_callable()`.
The deprecation notice should not be shown in any other circumstances, 
so an arbitrary invalid value being passed to `is_callable()` should 
still return `false` without deprecation notice.


2. While I do extensively test new PHPCompatibility sniffs, I have not 
run the WIP sniff against the top 1000 projects from Packagist, nor do 
I intend to or have the setup to do so.
I agree it would be a good idea to run a package analysis, but to be 
fair, in all honesty that should have been done for the original RFC, 
which was completely missing an impact analysis.


3. As for the pattern being common or not - the fact that I found it 
so easily in multiple random projects which I elected to test the 
sniff against, makes me believe the pattern is not _uncommon_.
I should also point out that all three of the projects which I 
highlighted as examples in my previous response are used extensively, 
the first two both have over 100 million downloads via Packagist, with 
the first being a dependency for PHPUnit.
The third doesn't show anywhere near as many downloads, but is a 
dependency of WordPress, which doesn't use Composer/Packagist for 
distribution, but is - as we're all aware - widely used.


In case anyone is looking for them - these were the examples I posted 
previously:


> Some examples:
> * 
https://github.com/symfony/service-contracts/blob/bc0a2247c72d29241b5a06fb60dc1c9d9acf2a3a/ServiceSubscriberTrait.php#L39 

> * 
https://github.com/mockery/mockery/blob/c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac/library/Mockery/Mock.php#L960 

> * 
https://github.com/simplepie/simplepie/blob/dacf0ed495d2e8fb306e526ca3f2a846af78a7c9/tests/oldtests/absolutize/RFC3986.5.4/base.php#L13


Kind regards,
Juliette


P.S.: and yes, the issues in the first two examples 

Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-03-16 Thread Christian Schneider
Am 16.03.2022 um 06:52 schrieb Juliette Reinders Folmer 
:
> I've just been looking in detail at the Partially Supported Callables 
> deprecation RFC: 
> https://wiki.php.net/rfc/deprecate_partially_supported_callables
> 
> The RFC explicitly excludes the `is_callable()` function and the `callable` 
> type from throwing deprecation notices.
> 
>> The |is_callable()| function and |callable| type remain side-effect free and 
>> do not throw a deprecation warning. They will continue to accept these 
>> callables until support is removed entirely. 
> 
> While I can fully support this for the `callable` type, I wonder if the 
> decision to not throw a deprecation on use in `is_callable()` is the right 
> one (though I understand the desire to keep it side-effect free).
> 
> Consider these code samples:
> 
>  function foo(callable $callback) {}
>  foo('static::method');
> 
> This function call not throwing a deprecation is not problematic as in PHP 
> 9.0 the function will start throwing a TypeError.

My reaction to your last sentence is actually quite the opposite: This is a 
major problem because code which was "just working" directly goes to a 
TypeError without a migration phase warning about it. This is something I've 
repeatedly advocated against.

>  if (is_callable('static::method')) {
>  static::method();
>  }
> 
> The second code sample, however, is problematic, as in PHP 9.0, the behaviour 
> of this code will be silently reversed for those callbacks which would 
> previously result in `is_callable()` returning true, which makes this a 
> potentially dangerous change without deprecation notice.

I agree with you here: Code which silently changes behavior is also a migration 
hassle.

- Chris

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php