snakeoil.deprecation.util module

class snakeoil.deprecation.util.suppress_deprecations(category=<class 'DeprecationWarning'>, wrap_generators=True, **kwargs)[source]

Bases: object

Suppress deprecations within this block. Generators and async.Task require special care to function.

This cannot be used to decorate a generator function. Using it within a generator requires explicit code flow for it to work correctly whilst not causing suppressions outside of the intended usage.

The cpython warnings filtering is designed around ContextVar- context specific to a thread, an async.Task, etc. Warnings filtering modifies a context var thus suppressions are active only within that context. Generators do not bind to any context they started in- whenever they resume, it’s resuming in the context of the thing that resumed them.

Do not do this in a generator: >>> def f(): … with suppress_deprecations(): … yield invoke_deprecated() # this will be suppressed, but leaks suppression to what consumed us. … … # in resuming, we have no guarantee we’re in the same context as before the yield, where our … # suppression was added. … yield invoke_deprecated() # this may or may not be suppressed.

You have two options. If you do not need fine grained, wrap the generator; this class will interpose between the generator and consumer and prevent this issue. For example: >>> @suppress_deprecations() … def f(): … yield invoke_deprecated() … yield invoke_deprecated()

If you need the explicit form, use this: >>> def f(): … with suppress_deprecations(): … value = invoke_deprecated() # this will be suppressed … yield value # we do not force our suppression on the consumer of the generator … with suppress_deprecations(): … another_value = invoke_deprecated() … yield another_value

kwargs
wraps_generators