Skip to content
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

Add type declarations where backwards compatible #1122

Merged
merged 1 commit into from Jan 7, 2020

Conversation

greg0ire
Copy link
Member

@greg0ire greg0ire commented Jan 6, 2020

That means:

Copy link
Member

@ostrolucky ostrolucky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good, but needs rebase

@@ -74,7 +74,10 @@ public function explainAction($token, $connectionName, $query)
]));
}

private function explainSQLitePlatform(Connection $connection, $query)
/**
* @param mixed[] $query
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look useful

* @param string[] $enabledFilters
* @param string[] $filtersParameters
* @param string[] $enabledFilters
* @param array<array<string,string>> $filtersParameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param array<array<string,string>> $filtersParameters
* @param array<string,array<string,string>> $filtersParameters

*/
private function getMockContainer($connectionName, $params = null)
private function getMockContainer(string $connectionName, $params = null) : MockObject
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private function getMockContainer(string $connectionName, $params = null) : MockObject
private function getMockContainer(string $connectionName, array $params) : MockObject

*/
private function getMockContainer($connectionName, $params = null)
private function getMockContainer(string $connectionName, $params = null) : MockObject
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private function getMockContainer(string $connectionName, $params = null) : MockObject
private function getMockContainer(string $connectionName, array $params) : MockObject

That means:

- methods in final classes
- final methods (none of those found)
- private methods
- methods in Tests (that excludes setUp(), tearDown() and test*, which
  are handled with an automated tool in a separate commit)
@greg0ire
Copy link
Member Author

greg0ire commented Jan 7, 2020

@ostrolucky here is why we need to use mixed[]: https://travis-ci.org/doctrine/DoctrineBundle/jobs/633955021#L328-L33

I initially did it to convey the fact that I did my due diligence and looked into the type of the items only to find it's mixed instead of just being lazy and use array.

@ostrolucky ostrolucky merged commit e52fb91 into doctrine:2.0.x Jan 7, 2020
@greg0ire greg0ire deleted the type-declarations branch January 8, 2020 06:49
@alcaeus
Copy link
Member

alcaeus commented Jan 8, 2020

Please don't target stable releases with such changes - only bug fixes should hit a stable branch with all other changes going to master.

@greg0ire
Copy link
Member Author

greg0ire commented Jan 8, 2020

Sorry, my bad!

@ostrolucky
Copy link
Member

These are not features either though. It would make solving conflicts much easier to target lowest affected branch.

@greg0ire
Copy link
Member Author

greg0ire commented Jan 8, 2020

It would make solving conflicts much easier to target lowest affected branch.

That's a good point, and IMO it would be more coherent with our stance on docs fixes that don't affect the software either but that should be contributed to the lowest affected branch.

@alcaeus
Copy link
Member

alcaeus commented Jan 10, 2020

I'm not going to revert it, but we may want to limit such changes to upcoming releases to avoid issues in patch releases.

@ostrolucky
Copy link
Member

I think these are very safe changes, I don't see any way to break anything

@greg0ire
Copy link
Member Author

I'm torn: on one hand it will make things more complicated for us with the upmerges, especially for that kind of change that touch a lot of files, on the other hand it's hard to say that every pedantic change will always be risk-free, and it's equally hard to ask maintainers to use their best judgment and handle this on a case by case basis. Maybe we should try it for a while and see if it does result in an instability that we are not willing to accept, but maybe some of you already did that in the past, I don't know.

@alcaeus
Copy link
Member

alcaeus commented Jan 10, 2020

I've generally avoided touching the type system in patch releases since the breaks can be very subtle, even for private methods. Think about @param string $foo vs. string $foo - these behave very differently with stringables when strict_types is enabled. Introducing such breaks in patch releases is unnecessary, which is why I normally avoid it.

@alcaeus alcaeus added this to the 2.0.7 milestone Jan 18, 2020
@@ -39,7 +39,7 @@ public function __construct(ContainerInterface $container = null)
/**
* {@inheritdoc}
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName)
public function getRepository(EntityManagerInterface $entityManager, $entityName) : ObjectRepository
Copy link
Contributor

@Majkl578 Majkl578 Mar 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is in fact a BC break because before repositories were not enforced to be subclass of ObjectRepository. Now they have to be otherwise this will crash on TypeError.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But ContainerRepositoryFactory is final and users can't extends from it. Isn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But ContainerRepositoryFactory is final and users can't extends from it. Isn't it?

Precisely.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrew-demb Yes but in Symfony ContainerRepositoryFactory overrides default RepositoryFactory from Doctrine, making it a BC break. Not a BC break in the contract of this class but a BC break in the bundle itself. It's no longer possible to use custom repositories not extending ObjectRepository and doing so makes the app crash due to this added typehint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been documented as supposed to be ObjectRepository since the creation of RepositoryFactory 7 years ago (!) : doctrine/orm@7eb7441

repositories were not enforced to be subclass of ObjectRepository because type declarations did not exist back then, but even if the contract is not enforced, it's still a contract. Call me heartless, but I can't say I feel sorry for apps experiencing this crash, they kind of had it coming, don't you agree?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't agree, this kind of stuff does not belong to a patch version.

Copy link
Contributor

@Majkl578 Majkl578 Mar 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requirement for the ObjectRepository/EntityRepository was never documented:

It was also never validated:

There is return annotation for EntityManager::getRepository():

It's not nice "feature" and I don't like it either but it was working and documented behaviour ("You can overwrite this behaviour by specifying the class name of your own Entity Repository in the Annotation, XML or YAML metadata.").
With the above said it rather looks like getRepository()'s @return is incorrect, it's the only place that goes against the actual code.

I don't personally need this "feature" but I don't think this should've been merged as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't personally need this "feature" but I don't think this should've been merged as is.

You are, as always, entitled to your opinion. To look at the facts:
ContainerRepositoryFactory has always implemented RepositoryFactory from ORM with an @inheritdoc docblock.
RepositoryFactory in ORM has had an @return ObjectRepository on its getRepository method since this commit in 2013, where it was widened from ORM's EntityRepository to the persistence library's ObjectRepository: doctrine/orm@3488049.

I don't know where you see the BC break, but if we treat docblocks as a contract (which we always have and always should), this change is perfectly fine. You are always welcome to improve documentation which is clearly wrong in this case, as the code contains the absolute truth, which is that the contract always specified an ObjectRepository return type for as long as the class has existed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know where you see the BC break

The BC break I see is that upgrading doctrine/doctrine-bundle from 2.0.6 to 2.0.7 leads to fatal errors.

as the code contains the absolute truth

The code can actually contain bugs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BC break I see is that upgrading doctrine/doctrine-bundle from 2.0.6 to 2.0.7 leads to fatal errors.

Please post an example that passes on 2.0.6 and produces a fatal error on 2.0.7 and I'll fix it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants