-
-
Notifications
You must be signed in to change notification settings - Fork 186
add deprecation chapter #1850
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
base: 6.0
Are you sure you want to change the base?
add deprecation chapter #1850
Changes from all commits
973020c
bd6eac9
ff7461b
6027930
e6acc83
b909069
b0923fb
7ca4ede
66a58dc
c859367
4e32566
c7cad7a
a9fc020
151aa67
cff3ad6
d0286e4
1c733a3
49e96f8
8608dff
155c344
295f3f5
5db3027
cd5e77e
0bacab8
245f3b8
32a29d7
dab9e49
1803a60
ce2454c
ad3b50e
09173ee
46b14eb
ef52530
25cb25b
9bedd0e
78165e0
a1e40f4
f0e9b8c
6fa028f
0dd2608
3dd2949
6a29889
0dab30b
b05efb9
397b9d9
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,86 @@ | ||
| --- | ||
| myst: | ||
| html_meta: | ||
| "description": "Understanding deprecation in Plone - rationale, philosophy, and use cases" | ||
| "property=og:description": "Understanding deprecation in Plone - rationale, philosophy, and use cases" | ||
| "property=og:title": "Deprecation" | ||
| "keywords": "deprecation, Plone, Python, Node.js, React, philosophy, rationale, use cases" | ||
| --- | ||
|
|
||
| (conceptual-deprecation-label)= | ||
|
|
||
| # Deprecation | ||
|
|
||
| This chapter describes the rationale and philosophy of deprecations in Plone. | ||
| It is meant as a guide for how to think about deprecations in Plone core packages. | ||
|
|
||
| ```{seealso} | ||
| For implementation details and code examples, see {doc}`/developer-guide/deprecation`. | ||
| ``` | ||
|
|
||
|
|
||
| (why-deprecation-label)= | ||
|
|
||
| ## Why deprecation | ||
|
|
||
| Developers may need to get rid of old code, unify to a consistent API style, fix typos in names, move code or templates around, resolve technical debt, address security issues, or adapt to changes in external dependencies. | ||
|
|
||
| When refactoring code, it's often necessary to move modules, functions, classes, and methods. | ||
| It's critical not to break third party code imports from the old place. | ||
| It's also important that usage of old functions or methods must work for a while to allow developers to migrate or update their code. | ||
|
|
||
| Deprecated methods are usually removed with the next major release of Plone. | ||
| Plone follows the [semantic versioning guideline](https://semver.org). | ||
|
|
||
|
|
||
| ## Help programmers without annoyance | ||
|
|
||
| Developers should use code deprecations to support the consumers of the code, that is, their fellow Plone developers. | ||
| From the consumer's point of view, Plone core code is an API. | ||
| Any change may annoy them, but they feel better when deprecation warnings tell them how to adapt their code to the changes. | ||
|
|
||
| Deprecations must always log at the level of warning. | ||
|
|
||
| Deprecations should always answer the following questions. | ||
|
|
||
| - Why is the code gone from the old place? | ||
| - What should the developer do instead? | ||
|
|
||
| A short message is enough, such as the following examples. | ||
|
|
||
| - "Replaced by new API `xyz`, found at `abc.cde`". | ||
| - "Moved to `xyz`, because of `abc`". | ||
| - "Name had a typo, new name is `xyz`". | ||
|
|
||
| All logging must be done only once, in other words, on the first usage or import. | ||
| It must not flood the logs. | ||
|
|
||
|
|
||
| ## Use cases | ||
|
|
||
| The following use cases describe when to deprecate. | ||
|
|
||
| Rename | ||
| : Developers may want to rename classes, methods, functions, or global or class variables to get a more consistent API or because of a typo. | ||
| Renaming alone is not enough to deprecate code. | ||
| Always provide a deprecated version that logs a verbose deprecation warning with information for where to import from in the future. | ||
|
|
||
| Move objects | ||
| : For reasons described in {ref}`why-deprecation-label`, developers may need to move code around. | ||
| When imported from the old place, it logs a verbose deprecation warning with information of where to import from in the future. | ||
|
|
||
| Deprecation of a whole Python or npm package | ||
| : A whole {ref}`Python package <python:tut-packages>` or [npm package](https://www.npmjs.com/) may be moved to a new location. | ||
|
|
||
| - All imports still work. | ||
| - Log deprecation warnings on first import. | ||
| - The ZCML still exists, but is empty or includes the ZCML from the new place, if there's no auto import for `meta.zcml`. | ||
|
|
||
| Deprecation of a whole released or installable package | ||
| : Plone developers provide a major release with no "real" code, but only backward compatible imports of the public API. | ||
| This should be done the way described above for a whole package. | ||
| The README should clearly state why it was moved and where to find the code now. | ||
|
|
||
| Deprecation of a GenericSetup profile | ||
| : These may have been renamed for consistency or are superfluous after an update. | ||
| Code does not need to break to support this. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,266 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| myst: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| html_meta: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "description": "How to implement deprecations in Plone, including Python, ZCML and templates." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "property=og:description": "How to implement deprecations in Plone, including Python, ZCML and templates." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "property=og:title": "Implement deprecations" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "keywords": "deprecation, zcml, template, jbot, Plone, Python" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (developer-deprecation-label)= | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Deprecate code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This chapter describes how to enable deprecation warnings and best practices for deprecating code in Plone, Zope, and Python. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```{seealso} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| For background on deprecation philosophy and use cases, see {doc}`/conceptual-guides/deprecation`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Enable deprecation warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This section describes how to enable deprecation warnings in Zope, Python, and tests. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Zope | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Zope configures logging and warnings, so the steps as described below in {ref}`deprecation-warning-python-label` aren't needed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
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. If the steps in the next section aren't needed, then why do we include them?
Member
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. With next step you refer to
Member
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. And with Thinking further, I am not 100% sure if the above method is anyway ZServer only?
Contributor
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. @jensens you might be able to see it more clearly on the pull request preview, beginning at https://plone6--1850.org.readthedocs.build/developer-guide/deprecation.html#zope. This sentence refers to the next section entitled Python, and it states that the steps in that section are not needed.
Member
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. We can drop the whole section Shall we mention somehow this change in the developer guide or focus on the current state?
Contributor
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 wish I could offer advice, but this was before my time. I'll go with what you think is true and accurate, and to the best of your knowledge. We can also wait a few days for other old timers to offer advice. The only thing I can refer to is this search result: https://6.docs.plone.org/search.html?q=plone.recipe.zopeinstance I'd focus on the current state of Plone 6.x.x. I'd use a Does that help at all?
Member
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 you mean we don't need to keep the Zope subheading. The Python subheading still seems accurate. I must say I always get deprecation warnings when starting Plone though, even though I don't think I have configured anything to enable it. So when I don't want them, I explicitly disable them with
Indeed focus on current state, but if possible mention the change as Steve says.
Member
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. We then have one subheading, that is a bit pointless. But if it helps, ok.
Contributor
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. There would be two, one for Python and the other for running tests. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Using `plone.recipe.zope2instance`, add the option `deprecation-warnings = on` to the buildout's `[instance]` section. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```cfg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [buildout] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = instance | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [instance] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recipe = plone.recipe.zope2instance | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # … | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deprecation-warnings = on | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # … | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This adds the following line to the {file}`zope.conf` file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```cfg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| debug-mode on | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Without the recipe, this can be set manually as well. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| In {file}`zope.conf`, define custom filters for warnings, such as the following example. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```xml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <warnfilter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| action always | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| category exceptions.DeprecationWarning | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </warnfilter> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+57
Contributor
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. Per @mauritsvanrees's suggestion.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (deprecation-warning-python-label)= | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Enable warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : Warnings are written to `stderr` by default, but `DeprecationWarning` output is surpressed by default. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Output can be enabled by starting the Python interpreter with the {ref}`-W[all|module|once] <python:using-on-warnings>` argument. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
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.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| As an alternative, the environment variable {envvar}`python:PYTHONWARNINGS` can be set to `default`, in other words, `PYTHONWARNINGS=default`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| It's possible to enable output in code, too. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warnings.simplefilter("module") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Configure logging | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : Once output is enabled, it's possible to use {func}`python:logging.captureWarnings` to redirect warnings to the logger. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import logging | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logging.captureWarnings(True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Running tests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| In Plone, test deprecation warnings are not shown by default. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The {file}`zope.conf` setting is not taken into account. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| To enable deprecation warnings, use the `-W` command. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Given you're using a modern buildout with a virtual environment as recommended, the command would be the following | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
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.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```shell | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ./bin/python -W module ./bin/test | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Deprecation best practices | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| It's recommended to follow these best practices when deprecating code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Vanilla deprecation messages | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Python offers a built-in exception {exc}`DeprecationWarning` which can be issued using the standard library's {mod}`warnings` module. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Its basic usage is the following example. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warnings.warn("deprecated", DeprecationWarning) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Move an entire module | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Given a package {file}`old.pkg` with a module {file}`foo.py`, to move it to a package {file}`new.pkg` as {file}`bar.py`, go through the following steps. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [`zope.deprecation` Moving modules](https://zopedeprecation.readthedocs.io/en/latest/api.html#moving-modules) offers a helper. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. Move the {file}`foo.py` as {file}`bar.py` to the {file}`new.pkg`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. At the old place, create a new {file}`foo.py`, and add to it the following lines of code. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from zope.deprecation import moved | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| moved("new.pkg.bar", "Version 2.0") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. Now you can still import the module at the old place, but get a deprecation warning. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```console | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DeprecationWarning: old.pkg.foo has moved to new.pkg.bar. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Import of old.pkg.foo will become unsupported in Version 2.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Move an entire package | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| To move an entire package, the process is exactly the same as moving a module, but instead, create a file for each module in the package. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Deprecate methods and properties | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Use the `@deprecate` decorator from [`zope.deprecation` Deprecating methods and properties](https://zopedeprecation.readthedocs.io/en/latest/api.html#deprecating-methods-and-properties) to deprecate methods in a module. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from zope.deprecation import deprecate | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @deprecate("Old method is no longer supported, use new_method instead.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def old_method(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "some value" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The `@deprecated` wrapper method deprecates properties. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from zope.deprecation import deprecated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| foo = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| foo = deprecated(foo, "foo is no more, use bar instead") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Move functions and classes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This example describes how to move some classes or functions from a Python file at {file}`old/foo/bar.py` to {file}`new/baz/baaz.py`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Here, `zope.deferredimport` offers a deprecation helper. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| It also avoids circular imports at initialization time. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import zope.deferredimport | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zope.deferredimport.initialize() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zope.deferredimport.deprecated( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "Import from new.baz.baaz instead", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SomeOldClass="new.baz:baaz.SomeMovedClass", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| some_old_function="new.baz:baaz.some_moved_function", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def some_function_which_is_not_touched_at_all(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Deprecate a GenericSetup profile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| In GenericSetup, the `post_handler` attribute in ZCML can be used to call a function after the profile was applied. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Use this feature to issue a warning. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| First, register the same profile twice, under both the new name and old. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```xml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <genericsetup:registerProfile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name="default" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="My Fancy Package" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| directory="profiles/default" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description="..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provides="Products.GenericSetup.interfaces.EXTENSION" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <genericsetup:registerProfile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name="some_confusing_name" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="My Fancy Package (deprecated)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| directory="profiles/some_confusing_name" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description="... (use profile default instead)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provides="Products.GenericSetup.interfaces.EXTENSION" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| post_handler=".setuphandlers.deprecate_profile_some_confusing_name" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Then in {file}`setuphandlers.py`, add a function. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import warnings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def deprecate_profile_some_confusing_name(tool): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| warnings.warn( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'The profile with id "some_confusing_name" was renamed to "default".', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DeprecationWarning | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### Deprecate a template position | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Sometimes you need to move templates to new locations. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Since add-ons often use [`z3c.jbot`](https://github.com/zopefoundation/z3c.jbot) to override templates by their position, you'll need to point them to the new position as well as make sure that the override still works with the old position. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| To deprecate a template, follow these steps. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. In the old package folder's {file}`__init__.py`, add a dictionary `jbot_deprecations` that maps the old template locations to their new counterparts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```python | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jbot_deprecations = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "plone.locking.browser.info.pt": "plone.app.layout.viewlets.info.pt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1. Add this deprecation snippet to the package {file}`configure.zcml` file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```{code-block} xml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :emphasize-lines: 7-14 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| :linenos: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <configure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| xmlns="http://namespaces.zope.org/zope" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| xmlns:browser="http://namespaces.zope.org/browser" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| xmlns:zcml="http://namespaces.zope.org/zcml" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <include | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package="z3c.jbot" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| file="meta.zcml" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zcml:condition="installed z3c.jbot" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <browser:jbotDeprecated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zcml:condition="have jbot-deprecations" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dictionary=".jbot_deprecations" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </configure> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| If a `z3c.jbot` version that supports deprecation is found, trying to override the template with the old location will trigger a deprecation warning that will instruct the user to rename its override file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.