-
Notifications
You must be signed in to change notification settings - Fork 467
[core] add Deprecation system with documentation #450
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
Conversation
ddtrace/contrib/cassandra/session.py
Outdated
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.
we can safely remove everything after going 1.0. No reason to remove these things now, even if it's reasonable safe.
ddtrace/contrib/util.py
Outdated
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.
It's more a matter of style, but I definitely prefer having ddtrace.utils with all our utils, rather than 2 different places with bunch of functions without a logical connection.
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.
If that's the API we agree on, then you can remove this comment as it makes the reader think that this is a legacy interface only for BC. Instead of understanding that this is the main interface.
Also, should this move to contrib/utils/__init__.py instead? (same for the below utils/__init__.py.
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.
Maybe I misunderstood your comment. The main interface is ddtrace.utils for internal utilities, so all others (contrib/util.py and util.py) will be removed in 1.0. I would prefer to keep everything inside ddtrace.utils rather than splitting it in ddtrace.utils and ddtrace.contrib.utils.
In Django, for instance, you have everything under this package and then they're separated in multiple modules by functionality.
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.
Alright my bad! Got it after a second read :)
ddtrace/util.py
Outdated
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.
If deprecation warnings are activated, this action will trigger a deprecation message (and will not crash with an import fail):
from ddtrace.util import asbool
ddtrace/utils/deprecation.py
Outdated
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.
It's to ensure consistency for all our deprecation calls.
ddtrace/utils/wrappers.py
Outdated
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 function is never used in our repo and it should not be used by anyone. But since there is no reason to remove it in this minor release, I would prefer to keep it till 1.0.0 where we can definitely clean a lot our code.
docs/index.rst
Outdated
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.
Section that is in line with Django Web Framework. Credits to this great community!
Ref: https://docs.djangoproject.com/en/2.0/howto/upgrade-version/#resolving-deprecation-warnings
tests/test_utils.py
Outdated
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.
tested as suggested in the stdlib: https://docs.python.org/3/library/warnings.html#testing-warnings
…fe_patch`; they will note be used anymore * `ddtrace.util` is replaced with `ddtrace.utils` package * `ddtrace.contrib.util` is replaced with `ddtrace.utils.importlib` * `safe_patch` will be removed because not used anymore
21e2c86 to
6e4712d
Compare
… going to be removed
| from functools import wraps | ||
|
|
||
|
|
||
| class RemovedInDDTrace10Warning(DeprecationWarning): |
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.
Used to create messages such as:
script.py:10: RemovedInDDTrace10Warning: [...]
| env = 'DD_{}'.format(key) | ||
|
|
||
| # [Backward compatibility]: `DATADOG_` variables should be supported; | ||
| # add a deprecation warning later if it's used, so that we can drop the key |
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.
Is it time to do it? or we might forget.
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.
oh good call! I totally forgot about it
| # or | ||
|
|
||
| $ PYTHONWARNINGS=all python app.py | ||
|
|
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.
Is there a programatic way we could add and document too?
Dev might not have access to the runtime options but they could change something like in tracer.configure.
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.
Yes-ish?
logging.captureWarnings and warnings.simplefilter offer some options, but the developer will need to be careful about where those calls are made.
Specifically, they will need to make those calls before any ddtrace imports happen (since most of the warnings of interest happen at import time). Additionally, they may have some other import sequencing considerations depending on what their logging infra/setup looks like.
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.
What could be the plan here? I may add something programmatic here, but as said by @SeanOC it may not work 100% of the time. I totally agree that devs may not have access to the runtime, but these warnings can still be raised in a local development environment (i.e. running application tests).
If we don't want to provide a programmatic way, I can reword a bit better this part of the documentation explicitly saying what I wrote in the previous paragraph.
SeanOC
left a comment
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.
Overall looks good.
Gave some hopefully helpful context re: options for enabling warnings without control over the runtime command/environment. For me, this falls into the category of nice to have, especially given Django doesn't specifically mention it.
| # or | ||
|
|
||
| $ PYTHONWARNINGS=all python app.py | ||
|
|
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.
Yes-ish?
logging.captureWarnings and warnings.simplefilter offer some options, but the developer will need to be careful about where those calls are made.
Specifically, they will need to make those calls before any ddtrace imports happen (since most of the warnings of interest happen at import time). Additionally, they may have some other import sequencing considerations depending on what their logging infra/setup looks like.
|
@SeanOC @LotharSee I would like to agree in the deprecation warning (programmatically or better documentation?) before proceeding with the merge. |
|
Chewing on it a little more, I'm actually inclined to not provide documentation on setting this programmatically. By design, these warnings really should only get turned on in a dev environment where a developer should have access to either the run command or environment variables. If we include instructions on how to enable them programmatically, I suspect we'll mostly just confuse people and leave people making a noisy mess in their production logs (e.g. people just skim the docs and blindly apply the programmatic approach). Should questions come up about it, we can always either one-off point people towards options or update the docs later. Knowing the Django folks, if this was a problem for a non-trivial portion of folks, they'd have included it in their docs. |
|
Totally agreed, especially because the Django community is quite big and had lot of use cases in the past. Let's wait for @LotharSee if there is anything else we can improve here. |
|
Sounds fair, good to me! |
Overview
This patch introduces a deprecation system via
warningsmodule. It offers a way to add deprecation around our code, when we need to alter/remove a functionality in newer releases. The deprecation log is silent by default, though it could be activated via Python flag / environment variable. This approach should be considered "safe" especially because it's used by many web frameworks (i.e. Django) and well documented in the Python official docs.ddtrace.util->ddtrace.utils.*(split in many modules)ddtrace.contrib.util->ddtrace.utils.importlibUser impact
No impact for the user since the
DeprecationWarningis silent by default, so unless the production application is run via-Wall, nothing will be printed in users' logs.What is missing
It's more part of a process, but we should document somewhere (even with a simple list) every time we add a deprecation warning. In that way, users can find easily what's going to be changed in the next major release. A good example is Django: https://docs.djangoproject.com/en/dev/internals/deprecation/