(Question refers to Julia version v1.5)
I'm trying to understand how the @deprecate
macro works in Julia. The documentation is unfortunately not clear to me:
@deprecate old new [ex=true]
Deprecate method old and specify the replacement call new. Prevent @deprecate from exporting old by setting ex to false. @deprecate defines a new method with the same signature as old.
Warning: As of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().
Examples
julia> @deprecate old(x) new(x)
old (generic function with 1 method)
julia> @deprecate old(x) new(x)
false old (generic function with 1 method)
So what do I do?
function old(x::Int)
print("Old behavior")
end
function new(x::Int)
print("New behavior")
end
# Adding true/false argument doesn't change my observations.
@deprecate old(x) new(x) # false
old(3)
# Prints "Old behaviour". No warning.
# Also: The deprecation is not mentioned in the help (julia>? old)
The aim of this @deprecate
macro seems to be replacing functions? I find that counterintuitive. How can mark a function as deprecated (i.e. users should receive a warning and a hint what to use as a replacement, also it should be in the documentation)?
edit: I noticed my error. The signatures (in my case the ::Int
) have to be identical for this to work. However, how do I get a warning?
In C++14, you can mark a function as deprecated using the [[deprecated]] attribute (see section 7.6. 5 [dcl. attr. deprecated]).
In IT, deprecation means that although something is available or allowed, it is not recommended or that, in the case where something must be used, to say it is deprecated means that its failings are recognized.
Imagine you have this method as part of the public API of your library in version 1:
# v1.0.0
mult3(x::Int) = 3x
In version 2, you'd like to stop supporting mult3
(which is a breaking change). But the same feature will still be available using a more general method:
# v2.0.0
mult(x, y) = x * y
Users of version 1 are used to using mult3
, which means that their code will break when they will update to v2. Therefore, you might want to release an intermediate version in the v1.x family, where mult3
exists but is deprecated and implemented in terms of mult
:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated and implemented using the old one
@deprecate mult3(x::Int) mult(3, x)
# The above is more or less equivalent to defining
# function mult3(x::Int)
# # print an error message is `--depwarn` has been set
# return mult(3, x)
# end
The v1 API is not broken in late v1.x versions, but users calling deprecated methods will see the following kind of messages to help them transition to the newer v2 API:
julia> mult3(14)
┌ Warning: `mult3(x::Int)` is deprecated, use `mult(3, x)` instead.
│ caller = top-level scope at REPL[3]:1
└ @ Core REPL[3]:1
42
(but starting with Julia 1.5, the warning will only be shown if --depwarn=yes
has been provided in Julia's command line or if it appears in a test suite run by Pkg.test()
)
Alternatively, and as mentioned in comments, you may want to leave the old implementation around, simply warning users when they call it. To this end, you can use Base.depwarn
directly:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated
# It is implemented by itself:
function mult3(x)
Base.depwarn("`mult3(x)` is deprecated, use `mult(3,x)` instead.", :mult3)
return 3x
end
When --depwarn=yes
has been provided in Julia's command line, this produces the same kind of warning as @deprecate
:
julia> mult3(14)
┌ Warning: `mult3(x)` is deprecated, use `mult(3,x)` instead.
│ caller = top-level scope at REPL[4]:1
└ @ Core REPL[4]:1
42
Starting with Julia 1.6, depwarn
will accept a keyword argument to force warning emission even when users haven't asked for them with --depwarn=yes
:
julia> Base.depwarn("Foo is deprecated", :foo, force=true)
┌ Warning: Foo is deprecated
│ caller = ip:0x0
└ @ Core :-1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With