-
-
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 10 commits
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
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
Our Backwards Compatibility Promise | ||
=================================== | ||
|
||
As of Symfony 2.3, we promise you backwards compatibility for all further 2.x | ||
releases. Ensuring smooth upgrades of your projects is our first priority. | ||
However, backwards compatibility comes in many different flavors. This page | ||
lists which code changes are covered by our promise and to what degree. | ||
|
||
If you are contributing to Symfony, make sure that your code changes comply to | ||
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 would perhaps say "....comply with the rules" rather than "comply to". Either that or "adhere to". 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. Thank you! Language suggestions are more than welcome. |
||
the rules listed below. | ||
|
||
.. note:: | ||
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 think a |
||
|
||
This promise is in trial until April 15th, 2014. Until then, we may change | ||
parts of it if we discover problems or limitations. | ||
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. This should be removed. As with any other document, it can be amended if needed. |
||
|
||
|
||
Interfaces | ||
---------- | ||
|
||
Normal Interfaces | ||
~~~~~~~~~~~~~~~~~ | ||
|
||
All interfaces in the ``Symfony`` namespace are **safe for use**. That means | ||
that: | ||
|
||
* You can safely type hint against the interface. | ||
|
||
* You can safely use any of the methods provided by the interface. | ||
|
||
However: | ||
|
||
* You cannot safely implement the interface. The interface may change, but all | ||
changes will be documented in the UPGRADE file. | ||
|
||
Methods tagged with ``@api`` are treated as if they belonged to an API | ||
interface. | ||
|
||
|
||
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. The meaning of 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. For instance, what does 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. Suggestion? 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. 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: /** regular interface, not API */
interface SymfonyInterface
{
public function foo();
}
class MyImplementation implements SymfonyInterface
{
// BC guaranteed for this method
public function foo() { ... }
// BC not guaranteed for this method (if we add bar() to SomeInterface, but with a different signature)
public function bar() { ... }
} |
||
API Interfaces | ||
~~~~~~~~~~~~~~ | ||
|
||
All interfaces tagged with ``@api`` are also **safe for implementation**. That | ||
means that: | ||
|
||
* You can safely implement the interface. | ||
|
||
|
||
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. Small formatting nitpick: you have a bunch of double-newlines which should be converted to single-newlines. 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 left them in before headings. I'll remove them however. |
||
Safe Operations | ||
~~~~~~~~~~~~~~~ | ||
|
||
The following table summarizes the safe operations when using our interfaces: | ||
|
||
============================================== ============== ============== | ||
Operation Normal API | ||
============================================== ============== ============== | ||
Type hint against Safe Safe | ||
Use method Safe Safe | ||
**When Implementing** | ||
Implement method Not Safe Safe | ||
Add custom method Not Safe Not Safe | ||
Add custom method parameter Not Safe Not Safe | ||
Add parameter default value Safe Safe | ||
============================================== ============== ============== | ||
|
||
|
||
Allowed Changes | ||
~~~~~~~~~~~~~~~ | ||
|
||
This table tells you which changes you are allowed to do when working on the | ||
code of Symfony's interfaces: | ||
|
||
============================================== ============== ============== | ||
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. wonder why you changed the format of the table from above to this other format 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. It's easier to maintain if the table does not have new line feeds. But we should change the other new tables, to be consistent 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. is that a new adoption on tables in the documentation in general too? interesting i did not know 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 don't know. We just choose per table which format is best (I think most of them uses the 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. It was the other way around. I used this format for the above tables initially. But then I introduced cells which span multiple columns above, so I had to switch to the |
||
Type of Change Normal API | ||
============================================== ============== ============== | ||
Remove entirely No No | ||
Change name or namespace No No | ||
Add parent interface Yes [1]_ No | ||
Remove parent interface No No | ||
**Methods** | ||
Add method Yes [1]_ No | ||
Remove method No No | ||
Change name No No | ||
Add parameter without a default value No No | ||
Add parameter with a default value Yes [1]_ No | ||
Remove parameter Yes [2]_ Yes [2]_ | ||
Add default value to a parameter Yes [1]_ No | ||
Remove default value of a parameter No No | ||
Add type hint to a parameter No No | ||
Remove type hint of a parameter Yes [1]_ No | ||
Change return type Yes [1]_ [3]_ No | ||
============================================== ============== ============== | ||
|
||
|
||
Classes | ||
------- | ||
|
||
Normal Classes | ||
~~~~~~~~~~~~~~ | ||
|
||
All classes in the ``Symfony`` namespace are **safe for use**. That means that: | ||
|
||
* You can safely type hint against the class' name. | ||
|
||
* You can safely create new instances. | ||
|
||
* You can safely extend the class. | ||
|
||
* You can safely use public properties and methods. | ||
|
||
When extending the class: | ||
|
||
* You can safely override public properties. | ||
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. But not public methods? 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. Only if the class is tagged |
||
|
||
However: | ||
|
||
* You cannot safely override methods in extending classes. The class may change, | ||
but all changes will be documented in the UPGRADE file. | ||
|
||
Properties and methods tagged with ``@api`` are treated as if they belonged | ||
to an API class. | ||
|
||
|
||
API Classes | ||
~~~~~~~~~~~ | ||
|
||
All classes tagged with ``@api`` are also **safe for extension**. That means | ||
that: | ||
|
||
* You can safely use protected properties and methods. | ||
|
||
* You can safely override protected properties. | ||
|
||
* You can safely override public or protected methods. | ||
|
||
|
||
Safe Operations | ||
~~~~~~~~~~~~~~~ | ||
|
||
The following table summarizes the safe operations when using our classes: | ||
|
||
============================================== ============== ============== | ||
Operation Normal API | ||
============================================== ============== ============== | ||
Type hint against Safe Safe | ||
Create instance Safe Safe | ||
Extend Safe Safe | ||
Use public property Safe Safe | ||
Use public method Safe Safe | ||
**When Extending** | ||
Use protected property Not Safe Safe | ||
Use protected method Not Safe Safe | ||
Override public property Safe Safe | ||
Override protected property Not Safe Safe | ||
Override public method Not Safe Safe | ||
Override protected method Not Safe Safe | ||
Add custom method Not Safe Not Safe | ||
Add custom method parameter Not Safe Not Safe | ||
Add parameter default value Safe Safe | ||
============================================== ============== ============== | ||
|
||
|
||
Allowed Changes | ||
~~~~~~~~~~~~~~~ | ||
|
||
This table tells you which changes you are allowed to do when working on the | ||
code of Symfony's classes | ||
|
||
================================================== ============== ============== | ||
Type of Change Normal API | ||
================================================== ============== ============== | ||
Remove entirely No No | ||
Make final Yes [1]_ No | ||
Make abstract No No | ||
Change name or namespace No No | ||
Change parent class Yes [4]_ Yes [4]_ | ||
Add interface Yes Yes | ||
Remove interface No No | ||
**Public Properties** | ||
Add public property Yes Yes | ||
Remove public property No No | ||
Reduce visibility No No | ||
**Protected Properties** | ||
Add protected property Yes Yes | ||
Remove protected property Yes [1]_ No | ||
Reduce visibility Yes [1]_ No | ||
**Constructors** | ||
Add constructor without mandatory parameters Yes [1]_ Yes [1]_ | ||
Remove constructor Yes [1]_ No | ||
Reduce visibility of a public constructor No No | ||
Reduce visibility of a protected constructor Yes [1]_ No | ||
**Public Methods** | ||
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 [1]_ No | ||
Remove parameter Yes [2]_ Yes [2]_ | ||
Add default value to a parameter Yes [1]_ No | ||
Remove default value of a parameter No No | ||
Add type hint to a parameter Yes [5]_ No | ||
Remove type hint of a parameter Yes [1]_ No | ||
Change return type Yes [1]_ [3]_ No | ||
**Protected Methods** | ||
Add protected method Yes Yes | ||
Remove protected method Yes [1]_ No | ||
Change name No No | ||
Reduce visibility Yes [1]_ No | ||
Add parameter without a default value Yes [1]_ No | ||
Add parameter with a default value Yes [1]_ No | ||
Remove parameter Yes [2]_ Yes [2]_ | ||
Add default value to a parameter Yes [1]_ No | ||
Remove default value of a parameter Yes [1]_ No | ||
Add type hint to a parameter Yes [1]_ No | ||
Remove type hint of a parameter Yes [1]_ No | ||
Change return type Yes [1]_ [3]_ No | ||
================================================== ============== ============== | ||
|
||
|
||
.. [1] Should be avoided. When done, this change must be documented in the | ||
UGPRADE file. | ||
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. typo: UPGRADE (apologies, I added this comment previously on an outdated diff) 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. fixed |
||
|
||
.. [2] Only the last parameter(s) of a method may be removed. | ||
|
||
.. [3] The return type may only be changed to compatible types. The following | ||
type changes are allowed: | ||
|
||
=================== ================================================================== | ||
Original Type New Type | ||
=================== ================================================================== | ||
boolean any `scalar type`_ with equivalent `boolean values`_ | ||
string any `scalar type`_ or object with equivalent `string values`_ | ||
integer any `scalar type`_ with equivalent `integer values`_ | ||
float any `scalar type`_ with equivalent `float values`_ | ||
array instance of ``ArrayAccess``, ``Traversable`` and ``Countable`` | ||
``ArrayAccess`` array | ||
``Traversable`` array | ||
``Countable`` array | ||
=================== ================================================================== | ||
|
||
.. [4] When changing the parent class, the original parent class must remain an | ||
ancestor of the class. | ||
|
||
.. [5] A type hint may only be added if passing a value with a different type | ||
previously generated a fatal error. | ||
|
||
.. _scalar type: http://php.net/manual/en/function.is-scalar.php | ||
|
||
.. _boolean values: http://php.net/manual/en/function.boolval.php | ||
|
||
.. _string values: http://www.php.net/manual/en/function.strval.php | ||
|
||
.. _integer values: http://www.php.net/manual/en/function.intval.php | ||
|
||
.. _float values: http://www.php.net/manual/en/function.floatval.php |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ Contributing Code | |
patches | ||
security | ||
tests | ||
bc | ||
standards | ||
conventions | ||
git | ||
|
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.
Just use "The Backwards Compatibility Promise", we didn't speak of "our" release cycle neither
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.
I'm not sure this feels right here. A promise is something personal, something that has only value if you know who it is from. So I think the first person and use of "our" here makes the document more credible.