The stable interface policy for MediaWiki PHP code defines what parts of the software are considered stable and safe for use by other components. Code that is considered part of this "stable interface" is subject to the deprecation process.
When changing existing code:
@stable to call
.@stable to override
.When creating new code:
It's generally stable to call public methods and access public class fields – unless these are marked otherwise.
It's generally not stable to directly instantiate classes using the new
operator – unless these are marked as @newable
.
Stable to call can apply to methods and functions. It means they stay backwards-compatible between releases. This stability applies to both the behavior (its contract), and the signature. Breaking changes that would impact callers must follow the deprecation process.
Note that methods are not stable to override by default.
Included:
@stable to call
. This means their class will be considered "newable" and thus may be instantiated using the new
operator in any code.@newable
as well as classes that are stable to extend.Not included:
@stable to call
.@deprecated
, @internal
or @unstable
.For authors:
@stable to call
, consider marking the class it belongs to as @newable
. This technically provides the stability guarantee, and is used to in discoverability of the stable constructor, and as self-documenting way to encourage a usage pattern through the new
operator. It is at the author's discretion to decide whether or not to mark a class with a stable constructor as @newable
. For example, if the class is generally only constructed through an intermediary utility method or subclass, then it may benefit users to not draw attention to the constructor.It's generally stable to mention interfaces and classes in type hints for parameters and return values.
Stable to type can apply to interfaces and classes. It means the type will continue to exist between releases and provide at least the same public methods that are stable to call. You can type against these interfaces and classes from various contexts; such as argument type declarations ("type hints"), return types, catch
statements, and instanceof
assertions.
Remember that by default interfaces are not stable to implement, and thus methods may be widened or added without notice. As PHP requires implementations to define all methods and use the same or narrower signatures, these would normally be breaking changes, but are backwards-compatible for the purpose of typehints and calling methods. For the same reason, an interface may become a class, and a class may become an interface without notice, unless it provides additional guarantees such as @stable to extend
, @stable to implement
, or @newable
.
Included:
Not included:
@deprecated
, @internal
or @unstable
.For authors:
@stable to type
. This is intended to aid the discovery of limited guarantees around interfaces.It's generally not stable to extend classes – unless these are marked @stable to extend
. This means constructor signatures may break, protected methods are unstable, and new abstract methods may be added without notice.
Stable to extend can apply to classes. It means the class and its methods will stay backward-compatible between releases and may be subclassed anywhere. Changes that affect subclasses will follow the deprecation process. Protected (and public) methods of extendable classes are automatically stable to call, unless they are marked @deprecated
, @internal
or @unstable
. Remember that by default methods remain not stable to override, unless they are abstract.
Included:
@stable to extend
.For authors:
@stable to call
.It's generally not stable to use traits – unless these are marked @stable to use
. This means method signatures may break and new abstract methods may be added without notice.
Stable to use can apply to traits. It means all methods defined in the trait will stay backward-compatible between releases. Changes that affect classes using the trait will follow the deprecation process. All methods of usable traits are automatically stable to call, unless they are marked @deprecated
, @internal
or @unstable
. Remember that by default methods remain not stable to override, unless they are abstract.
Included:
@stable to use
.It's generally not stable to write to public and protected fields, but it is stable to read them.
Stable to access applies to fields of most classes. It means that the field will not be removed, and its behavior will not change, without going through the deprecation process. It however does not mean that they will keep being read, so there is no guarantee that writing to them will have the desired effect in the future, unless such a guarantee is explicitly given in the documentation of the field.
Included:
Not included:
@deprecated
, @internal
or @unstable
For authors:
It's generally not stable to implement interfaces – unless these are marked @stable to implement
. This means existing signatures may change and new required methods may be added without notice.
Stable to implement can apply to interfaces. It means they will stay backward-compatible between releases and may be implemented anywhere. Changes that affect implementations will follow the deprecation process.
Included:
@stable to implement
.For authors:
@stable to implement
.@stable to implement
.@stable to implement
.It's generally not stable to override methods in subclasses unless the method is marked @stable to override
.
Stable to override can apply to class methods and hooks. It means the method signature will remain compatible for overriding, and the method or callback will continue to be called in relevant circumstances. Changes to that contract must follow the deprecation process.
Included:
abstract
in classes that are stable to extend.@stable to override
.Not included:
@deprecated
, @internal
or @unstable
.For authors:
When hard deprecating code that is stable to override,
MWDebug::detectDeprecatedOverride
.It's not stable to use global variables.
Global variables are not stable, not even those with the "wg" prefix.
For users:
MediaWikiServices::getMainConfig()
instead.MediaWikiServices::get*
methods instead.For authors:
@stable to call
: See Stable to call.@stable to type
: See Stable to type.@stable to extend
: See Stable to extend.@stable to implement
: See Stable to implement@stable to override
: See Stable to override.@newable
: See Stable to call.The @stable
annotations can be followed by a Since
segment to indicate that a particular use of the class or method is only supported since a specific version. For example:
/** * @since 1.17 * @stable to extend Since 1.35 */ class Foo { /* … */ }
The @stable
annotations can be followed by a Deprecated since
segment to indicate that a particular use of the class or method is currently deprecated outside of the original module. This can be used to indicate that extensions should no longer subclass, but may still call public methods. This guarantee may then be removed in the next release. Note that there is currently no mechanism for the hard-deprecation or removal of stability guarantees.
/** * @stable to extend Deprecated since 1.35 */ class Foo { /* … */ }
@internal
: Do not use outside the original module. It may change without notice.@unstable
: It may change without notice. Similar to @internal
, except that unstable things are aimed at external use and intended to become stable in the future.@deprecated
: This means something should not be used anywhere, as this may be removed in a future release, per the deprecation process. This must include a since
segment, and must include instructions for what to use instead (or state that there is no alternative). For example:/** * @deprecated since 1.35 Use expandFoo() instead. */ public function getSomething( Foo $foo );
Deprecation becomes necessary when the public interface of code needs to be changed in order to add new functionality or improve architecture. All code that falls within the scope of this policy and defines a stable interface is subject to the deprecation process defined here.
The deprecation process generally consists of the following steps, described in more detail below:
The purpose of the deprecation process is to remove usages of deprecated functionality, so that it can be dropped without breaking callers. Usage of deprecated code is considered more or less problematic depending on where it occurs: the most critical usages are within the same repository, followed by Wikimedia maintained code, further followed by code in the MediaWiki ecosystem. Usages outside the ecosystem are considered the least relevant.
This means that Wikimedia maintained code MUST receive special attention in the deprecation process, and extensions in the MediaWiki ecosystem SHOULD be given consideration and support during the deprecation process. WikiApiary.com and ExtensionDistributor can be used as indicators for an extension's relevance.
Individuals, teams and organizations that deprecate code MUST commit to follow through with the deprecation process until the obsolete code has been removed, and they SHOULD be proactive about supporting maintainers of affected code in the MediaWiki ecosystem.
Soft deprecation occurs when a developer adds a @deprecated
annotation to the documentation comment of a method, function, class, or interface.
The following rules apply to soft deprecation:
Hard deprecation occurs when the code starts emitting deprecation warnings, typically by calling wfDeprecated( __METHOD__, '1.xx' );
. Deprecation warnings cause unit tests to fail.
If it is not reasonably possible for the deprecated code to emit deprecation warnings, hard deprecation can be applied by announcing the removal on wikitech-l in a timely manner. The announcement must explain why deprecation warnings cannot be emitted, and provide an opportunity for affected parties to raise concerns and propose alternatives. In addition, the affected code MUST be annotated with a @warning
tag that announces the release in which removal is intended. This procedure is suitable e.g. for the deprecation of global variables, interfaces, and traits. It SHOULD also be used when removing parts of the stable interface by marking them as @internal
.
The following rules apply to hard deprecation:
wfDeprecated()
call MUST match the one in the @deprecated
annotation, even if the hard deprecation occurs in a different release.The following rules apply to the removal of code:
And finally: As with all policies, developers should apply their best judgement when applying it.
The motivation for this policy is two-fold:
This policy is designed to make extensions more robust against changes in MediaWiki core, and provide more freedom for MediaWiki core code to evolve.
This policy is mainly written to define a contract between MediaWiki core and MediaWiki extensions, but it also applies to the relationship between MediaWiki and libraries it uses, as well as dependencies between extensions. It applies to the following:
This policy does not apply to the following:
Those may have their own policies and practices for maintaining stable interfaces.
Providing a stable interface enables a community of third parties to create and maintain components, forming a "software ecosystem". For the purpose of this policy, the MediaWiki ecosystem is thought to consist of extensions actively maintained by entities other than the Wikimedia Foundation, if they meet all of the following criteria:
Extension developers are encouraged to make their code available in the way described above, so it can be used by others. Per this policy, such extensions will in return receive consideration and support when breaking changes need to be made. For this purpose, such extensions are automatically index by the codesearch tool.
There is also a separate Stable interface policy/Frontend policy that defines what parts of the software are considered stable and safe for use by browser-based code from other components.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4