-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[Review] Added detailed Backwards Compatibility Promise text #3439
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
Changes from 1 commit
840073c
7320ed0
dacd7ce
79ca9f7
0e925cb
44ecf16
afadaab
345410c
a3ad08c
31ab2db
502ed95
4c5a55d
c6e850d
db76288
54fd836
00c6ebe
efd3911
dcbe79a
af3a645
be76644
dfb3e8b
6501a35
0c6420f
69768dd
5a160c5
ef1f021
6d9edf1
8c6c7bf
4868452
e11335f
25443c0
11bb879
fd1d912
bdd3c03
2320906
90c4de6
be2251c
ce58ee9
0717192
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,7 +50,7 @@ sticks to these rules. | |
.. caution:: | ||
|
||
The exception to this rule are interfaces tagged with ``@internal``. Such | ||
interfaces should *never* be used or implemented. | ||
interfaces should not be used or implemented. | ||
|
||
If you want to implement an interface, you should first make sure that the | ||
interface is an API interface. You can recognize API interfaces by the ``@api`` | ||
|
@@ -69,9 +69,15 @@ tag in their source code:: | |
} | ||
|
||
If you implement an API interface, we promise that we won't ever break your | ||
code. Regular interfaces, by contrast, should never be implemented, because if | ||
we add a new method to the interface or add a new optional parameter to the | ||
signature of a method, we would generate a fatal error in your application. | ||
code. Regular interfaces, by contrast, may be extended between minor releases, | ||
for example by adding a new method. Be prepared to upgrade your code manually | ||
if you implement a regular interface. | ||
|
||
.. note:: | ||
|
||
Even if we do changes that require manual upgrades, we limit ourselves to | ||
changes that can be upgraded easily. We will always document the precise | ||
upgrade instructions in the UPGRADE file in Symfony's root directory. | ||
|
||
The following table explains in detail which use cases are covered by our | ||
backwards compatibility promise: | ||
|
@@ -89,9 +95,9 @@ backwards compatibility promise: | |
+-----------------------------------------------+---------------+---------------+ | ||
| Implement a method | No [1]_ | Yes | | ||
+-----------------------------------------------+---------------+---------------+ | ||
| Add a parameter to an implemented method | No [1]_ | Yes | | ||
| Add an argument to an implemented method | No [1]_ | Yes | | ||
+-----------------------------------------------+---------------+---------------+ | ||
| Add a default value to a parameter | Yes | Yes | | ||
| Add a default value to an argument | Yes | Yes | | ||
+-----------------------------------------------+---------------+---------------+ | ||
|
||
.. include:: _api_tagging.rst.inc | ||
|
@@ -107,7 +113,7 @@ public methods and properties. | |
Classes, properties and methods that bear the tag ``@internal`` as well as | ||
the classes located in the various ``*\\Tests\\`` namespaces are an | ||
exception to this rule. They are meant for internal use only and should | ||
*never* be accessed by your own code. | ||
not be accessed by your own code. | ||
|
||
Just like with interfaces, we also distinguish between regular and API classes. | ||
Like API interfaces, API classes are marked with an ``@api`` tag:: | ||
|
@@ -127,9 +133,15 @@ Like API interfaces, API classes are marked with an ``@api`` tag:: | |
The difference between regular and API classes is that we guarantee full | ||
backwards compatibility if you extend an API class and override its methods. We | ||
can't give the same promise for regular classes, because there we may, for | ||
example, add an optional parameter to a method. Consequently, the signature of | ||
example, add an optional argument to a method. Consequently, the signature of | ||
your overridden method wouldn't match anymore and generate a fatal error. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we emphasize (peharps in a note) that we will only make "simple" changes even on regular classes (such as the one you mention here) and mention that it make upgrading needed but simple enough? That way, we make it clear what we are allowed to break. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Referencing the following section about Symfony contributors might be enough. |
||
|
||
.. note:: | ||
|
||
As with interfaces, we limit ourselves to changes that can be upgraded | ||
easily. We will document the precise ugprade instructions in the UPGRADE | ||
file in Symfony's root directory. | ||
|
||
In some cases, only specific properties and methods are tagged with the ``@api`` | ||
tag, even though their class is not. In these cases, we guarantee full backwards | ||
compatibility for the tagged properties and methods (as indicated in the column | ||
|
@@ -171,9 +183,13 @@ covered by our backwards compatibility promise: | |
+-----------------------------------------------+---------------+---------------+ | ||
| Add a new method | No | No | | ||
+-----------------------------------------------+---------------+---------------+ | ||
| Add a parameter to an overridden method | No [1]_ | Yes | | ||
| Add an argument to an overridden method | No [1]_ | Yes | | ||
+-----------------------------------------------+---------------+---------------+ | ||
| Add a default value to an argument | Yes | Yes | | ||
+-----------------------------------------------+---------------+---------------+ | ||
| Call a private method (via Reflection) | No | No | | ||
+-----------------------------------------------+---------------+---------------+ | ||
| Add a default value to a parameter | Yes | Yes | | ||
| Access a private property (via Reflection) | No | No | | ||
+-----------------------------------------------+---------------+---------------+ | ||
|
||
.. include:: _api_tagging.rst.inc | ||
|
@@ -201,14 +217,14 @@ Remove parent interface No No | |
Add method Yes [2]_ No | ||
Remove method No No | ||
Change name No No | ||
Add parameter without a default value No No | ||
Add parameter with a default value Yes [2]_ No | ||
Remove parameter Yes [3]_ Yes [3]_ | ||
Add default value to a parameter Yes [2]_ No | ||
Remove default value of a parameter No No | ||
Add type hint to a parameter No No | ||
Remove type hint of a parameter Yes [2]_ No | ||
Change parameter type Yes [2]_ [4]_ No | ||
Add argument without a default value No No | ||
Add argument with a default value Yes [2]_ No | ||
Remove argument Yes [3]_ Yes [3]_ | ||
Add default value to an argument Yes [2]_ No | ||
Remove default value of an argument No No | ||
Add type hint to an argument No No | ||
Remove type hint of an argument Yes [2]_ No | ||
Change argument type Yes [2]_ [4]_ No | ||
Change return type Yes [2]_ [5]_ No | ||
============================================== ============== ============== | ||
|
||
|
@@ -236,8 +252,11 @@ Reduce visibility No No | |
Add protected property Yes Yes | ||
Remove protected property Yes [2]_ No | ||
Reduce visibility Yes [2]_ No | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should add lines about private properties and methods. My reasoning here is that you can access them from the outside via reflection. Everyone would agree that there no guarantee about those properties/methods, but as we are listing all possible cases here, it does not hurt to list all possibilities here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have added notes about private properties and methods both in the "Using Symfony" and "Working on Symfony" sections. |
||
**Private Properties** | ||
Add private property Yes Yes | ||
Remove private property Yes Yes | ||
**Constructors** | ||
Add constructor without mandatory parameters Yes [2]_ Yes [2]_ | ||
Add constructor without mandatory arguments Yes [2]_ Yes [2]_ | ||
Remove constructor Yes [2]_ No | ||
Reduce visibility of a public constructor No No | ||
Reduce visibility of a protected constructor Yes [2]_ No | ||
|
@@ -246,29 +265,43 @@ Add public method Yes Yes | |
Remove public method No No | ||
Change name No No | ||
Reduce visibility No No | ||
Add parameter without a default value No No | ||
Add parameter with a default value Yes [2]_ No | ||
Remove parameter Yes [3]_ Yes [3]_ | ||
Add default value to a parameter Yes [2]_ No | ||
Remove default value of a parameter No No | ||
Add type hint to a parameter Yes [7]_ No | ||
Remove type hint of a parameter Yes [2]_ No | ||
Change parameter type Yes [2]_ [4]_ No | ||
Add argument without a default value No No | ||
Add argument with a default value Yes [2]_ No | ||
Remove argument Yes [3]_ Yes [3]_ | ||
Add default value to an argument Yes [2]_ No | ||
Remove default value of an argument No No | ||
Add type hint to an argument Yes [7]_ No | ||
Remove type hint of an argument Yes [2]_ No | ||
Change argument type Yes [2]_ [4]_ No | ||
Change return type Yes [2]_ [5]_ No | ||
**Protected Methods** | ||
Add protected method Yes Yes | ||
Remove protected method Yes [2]_ No | ||
Change name No No | ||
Reduce visibility Yes [2]_ No | ||
Add parameter without a default value Yes [2]_ No | ||
Add parameter with a default value Yes [2]_ No | ||
Remove parameter Yes [3]_ Yes [3]_ | ||
Add default value to a parameter Yes [2]_ No | ||
Remove default value of a parameter Yes [2]_ No | ||
Add type hint to a parameter Yes [2]_ No | ||
Remove type hint of a parameter Yes [2]_ No | ||
Change parameter type Yes [2]_ [4]_ No | ||
Add argument without a default value Yes [2]_ No | ||
Add argument with a default value Yes [2]_ No | ||
Remove argument Yes [3]_ Yes [3]_ | ||
Add default value to an argument Yes [2]_ No | ||
Remove default value of an argument Yes [2]_ No | ||
Add type hint to an argument Yes [2]_ No | ||
Remove type hint of an argument Yes [2]_ No | ||
Change argument type Yes [2]_ [4]_ No | ||
Change return type Yes [2]_ [5]_ No | ||
**Private Methods** | ||
Add private method Yes Yes | ||
Remove private method Yes Yes | ||
Change name Yes Yes | ||
Reduce visibility Yes Yes | ||
Add argument without a default value Yes Yes | ||
Add argument with a default value Yes Yes | ||
Remove argument Yes Yes | ||
Add default value to an argument Yes Yes | ||
Remove default value of an argument Yes Yes | ||
Add type hint to an argument Yes Yes | ||
Remove type hint of an argument Yes Yes | ||
Change argument type Yes Yes | ||
Change return type Yes Yes | ||
================================================== ============== ============== | ||
|
||
.. [1] Your code may be broken by changes in the Symfony code. Such changes will | ||
|
@@ -277,9 +310,10 @@ Change return type Yes [2]_ [5]_ No | |
.. [2] Should be avoided. When done, this change must be documented in the | ||
UPGRADE file. | ||
|
||
.. [3] Only the last parameter(s) of a method may be removed. | ||
.. [3] Only the last argument(s) of a method may be removed, as PHP does not | ||
care about additional arguments that you pass to a method. | ||
|
||
.. [4] The parameter type may only be changed to a compatible or less specific | ||
.. [4] The argument type may only be changed to a compatible or less specific | ||
type. The following type changes are allowed: | ||
|
||
=================== ================================================================== | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meaning of
Yes
andNo
are hard to understand for me. Actually, it took me quite some time to figure out what the whole table actually means.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For instance, what does
Add custom method
mean? Is it when I add a custom method on a class that implements a Symfony interface? Or does it mean that we are allowed to add a new method in a Symfony interface?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole section is targeted at Symfony users (not developers; the dev section is below). So "Add custom method" means that a user should not add methods that do not exist in our interface (i.e. we cannot guarantee BC).
Example: