Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BC break in return type of ConstraintViolationInterface::getMessage() #34710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Majkl578 opened this issue Nov 29, 2019 · 12 comments
Closed

BC break in return type of ConstraintViolationInterface::getMessage() #34710

Majkl578 opened this issue Nov 29, 2019 · 12 comments

Comments

@Majkl578
Copy link
Contributor

Symfony version(s) affected: 4.4.0

Description
In Symfony 4.3.4 Symfony\Component\Validator\ConstraintViolationInterface::getMessage() returns string.
In Symfony 4.4.0 it returns string|object.

Widening return types is a BC break that breaks contract for consumers.

Caught by PHPStan:

Parameter #1 $message of class InvalidArgumentException constructor expects string, object|string given.
@ro0NL
Copy link
Contributor

ro0NL commented Nov 29, 2019

ref #31083, in general the upgrade path is (string) getMessage(). Agree the BC break is real, but only with strict_types involved, isnt it?

@Majkl578
Copy link
Contributor Author

Majkl578 commented Nov 29, 2019

@ro0NL No, converting arbitrary object (as specified in the phpDoc, equiv. to string|object union in PHP 8) into string is a fatal error without strict mode as well.

php > (string) new stdClass();
PHP Recoverable fatal error:  Object of class stdClass could not be converted to string in php shell code on line 1

#31083 is about __toString() but the type information doesn't match this requirement.

@xabbuh was right with his concern in #31083:

I am 👎 on making this change as it calls for breaking existing code that do not perform explicit string casts on the returned value of getMessage().

@nicolas-grekas
Copy link
Member

As mentioned by the phpdoc, not any kind of object can be returned there: only stringable ones are allowed. That was already the case before and people (eg Drupal) are using this possibility as a feature.

Not BC break here. That's a false-positive from phpstan (which might miss context for sure).

@Majkl578
Copy link
Contributor Author

Majkl578 commented Nov 29, 2019

Not BC break here. That's a false-positive from phpstan (which might miss context for sure).

Frankly by adding |object union you made it a BC break - there is no constaint for stringable objects on type level in PHP and a comment for @return annotation is not sufficient.

PHPStan is correct in this case. Just like Psalm is. We're talking about interface with generic string|object.

https://phpstan.org/r/14597979-9220-4ce1-8354-14e3954d44ca
https://psalm.dev/r/e2520d6222

@stof
Copy link
Member

stof commented Nov 29, 2019

the thing is, phpdoc does not have any way to describe "stringable objects".

@Majkl578
Copy link
Contributor Author

@stof Yes, adding |object is considered a strong BC break but some kind of stringable type would be too because objects are not implicitly convertible to strings in strict mode:
https://3v4l.org/K5fFZ
https://3v4l.org/hTYEZ
https://3v4l.org/5gkJs

So this is wrong:

Not BC break here. That's a false-positive from phpstan (which might miss context for sure).

This has to be reverted.

@nicolas-grekas
Copy link
Member

Our BC policy doesn't cover strict mode. Thanks for reporting.

@Majkl578
Copy link
Contributor Author

Majkl578 commented Nov 29, 2019

Reading through Symfony Backward Compatibility Promise document I see no mention of not covering strict mode. Strict mode is part of PHP core for 4 years already, it would be strange if Symfony didn't support it (regardless of whether Symfony itself uses it or not). Can you provide some reference for your statement?
Thank you.

All interfaces shipped with Symfony can be used in type hints. You can also call any of the methods that they declare. We guarantee that we won't break code that sticks to these rules. ... If you implement an interface, we promise that we won't ever break your code.

@enumag
Copy link
Contributor

enumag commented Nov 30, 2019

Our BC policy doesn't cover strict mode. Thanks for reporting.

@nicolas-grekas Considering most of modern PHP projects (all of my projects included) are written completely in strict mode, this is a very concerning statement. Even more so since there is no mention of this in your BC promise document. Please update it accordingly since this is something the users need to be aware of.

@nicolas-grekas
Copy link
Member

Strict mode is not compatible with adding type hints in the Symfony code base. Any string $foo added anywhere is a candidate break for ppl that enabled strict mode and pass anything that PHP can cast transparently to a string. There is nothing we can do here about this, except never adding any type hints in the code base, which is not what you're asking for I suppose. Quite the contrary actually. So here it is: strict mode is a bad idea, and you know why now.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Nov 30, 2019

To clarify, the link to the BC policy here is not accurate: what I'm referring to is the continuous upgrade path actually - we cannot provide one to people that enabled strict mode, for cases like the one mentioned in my previous comment.

About the BC policy and the issue discussed here, it does not apply to docblocks. That's the more accurate statement that applies here.

@nicolas-grekas
Copy link
Member

Last note: the LazyString class proposed in #34298 is designed to fix the inaccuracy of string|object: instead, we'll be able to use string|LazyString and get type safety.

derrabus added a commit that referenced this issue Oct 25, 2020
This PR was merged into the 3.4 branch.

Discussion
----------

[Security] Add missing Latvian translations

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Part of #34710, #34749
| License       | MIT
| Doc PR        | N/A

Commits
-------

7f2b13b [Security] Add missing Latvian translations
derrabus added a commit that referenced this issue Oct 25, 2020
This PR was squashed before being merged into the 3.4 branch.

Discussion
----------

[Form] Add missing Latvian translations

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Part of #34710, #34749
| License       | MIT
| Doc PR        | N/A

Commits
-------

871c983 [Form] Add missing Latvian translations
derrabus added a commit that referenced this issue Oct 25, 2020
This PR was submitted for the 5.x branch but it was merged into the 3.4 branch instead.

Discussion
----------

[Validator] Add missing Latvian translations

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Part of #34710, #34749
| License       | MIT
| Doc PR        | N/A

Commits
-------

4924b38 [Validator] Add missing Latvian translations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants