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
Check for duplicate keys in multiple yield operators #1408
Comments
Hi, thanks for the proposal. Feel free to send a PR :) |
Yielding the same key is not a bug and may be perfectly valid for some use cases. You should instead open feature request for PHPUnit to report such data providers as broken. |
What are the valid cases? |
http://php.net/manual/en/language.generators.syntax.php#example-288 (the id may not be unique) |
This does not prove anything. If ID is not unique, this is also an issue. PHP allows returning duplicate keys from Generator, but there is no information about the correctness of such things. Moreover,
Since you can't have duplicate keys in associative arrays, and "generators are no different", I would say that this is not a valid case to return duplicate key from Generator, even if it is supported by the language. What are the real cases where returning a duplicate key is ok? |
Duplicates are always correct, period. There is no incorrect variant with duplicate keys because there is no such constraint implied.
This implies nothing about uniqueness. It only compares behavior to arrays. You cant ArrayAccess generator anyway. Just like duplicate keys are allowed with iterators: https://3v4l.org/Z8Wb9 |
Duplicate keys in generators work just fine in PHP. But I don't see why you'd ever wanna do something like that. Nonetheless, PHPStan should not report correct code. Just because it's a weird language quirk doesn't mean it's incorrect. You might have more success with pushing this feature in phpstan-strict-rules which is more opinionated. |
I'm okay with that, could you please transfer this issue to that repository using GitHub API? |
I wouldn't call it a quirk. There are valid use cases and you can always avoid the behaviour if you don't like it. Besides, if you assume generators/iterators produce unique array keys, you are already working with broken assumptions since even though they produce different values, they may end up the same in an array (think of I can see use cases in long-running code where you can create infinite generator that yields updates where key would be updated user entity and value would be a diff / value changed. Just because you don't use it or don't find valid use case doesn't mean it should be forbidden. I'm strongly against including this in strict-rules, it has nothing to do with strict code. |
Also you would have to report possibly duplicate keys which would produce A LOT of false positives. |
Whenever I yield ['id' => ..., 'entity': ...]; This would make it much more obvious that the same |
@iluuu1994 Then your assumption/expectation is wrong. Your proposal is valid, but complicates things and makes them a lot less readable, or even performant (in critical code).
TBH this is only a workaround for a falsey assumption you are building on top of. Yes, one can |
the description of this ticket suggests checking only real duplicate string keys, not "possible" or dynamic. I can't imagine a real case where such code would be a valid: public function anyMethod(): \Generator
{
// ...
yield 'Duplicate key' => $anyValue1;
// ...
yield 'Duplicate key' => $anyValue2;
} |
Still, the code is perfectly valid generator and there is nothing wrong. You can't statically determine whether it was intended or not. If it's a bug, consumer should be aware of that.
I can imagine multiple where it saves you trouble with arrays, both in producer and consumer. I know this is a known issue in PHPUnit, but I think the proper place is to fix the symptom - the bug in PHPUnit itself (since it silently discards duplicates), not here. |
If you need high performance you probably shouldn't use generators with a state machine behind them.
How are either of those statements true? The code looks more obvious, it's typed, you'll get nice IDE autocompletion, it's just as easy to consume. You'll get some small overhead from the heap allocation for the IMO this is a valid feature for strict-rules. @borNfreee
I'm just a contributor, @ondrejmirtes decides what makes it into which repository. Let's wait until he states his opinion on where this should go. Also, PRs are always welcome! Open source only works when people contribute. |
How exacltly would this make code stricter? IMO it's not. |
phpstan/phpstan-strict-rules is not a catch-all repo for rules that do not fit phpstan/phpstan :)
As has been said above, duplicate keys from iterators and generators are OK. Does PHPUnit handle them correctly (e.g. running a test case for each item, even with a duplicate key?) Maybe the issue should be reported there. Of course, anyone is welcome to write and use the proposed rule on their own, but it's not something generally applicable... |
BTW, fixed in PHPUnit sebastianbergmann/phpunit#3444 |
Summary of a problem or a feature request
When I use, for example, data providers in PHPUnit, I use them by
yield
ing each data set, like this:When you have a large provider, it's easy to make copy-paste error and end up with the duplicate key:
PHPUnit in this case ignores the first one, and we loose 1 test case.
Code snippet that reproduces the problem
https://phpstan.org/r/6eef732e950c1001e202097358d510cf
Expected output
Expected ouput from PHPStan:
Method sayHello() has 2 duplicate keys in yield with value 'Duplicate Key'
The text was updated successfully, but these errors were encountered: