如何将函数标记为“@deprecate”?

How to mark functions as `@deprecate`d?

(问题参考Julia v1.5版本)

我正在尝试了解 @deprecate 宏在 Julia 中的工作原理。 documentation 不幸的是我不清楚:

@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)

那我该怎么办?

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)

这个@deprecate宏的目的好像是替换函数?我觉得这违反直觉。如何将一个函数标记为已弃用(即用户应该收到警告和提示使用什么作为替代品,它也应该在文档中)?

编辑:我注意到我的错误。签名(在我的例子中是 ::Int)必须相同才能工作。但是,如何获得警告?

假设您将此方法作为第 1 版库​​的 public API 的一部分:

# v1.0.0
mult3(x::Int) = 3x

在版本 2 中,您希望停止支持 mult3(这是一项重大更改)。但是使用更通用的方法仍然可以使用相同的功能:

# v2.0.0
mult(x, y) = x * y

版本 1 的用户习惯使用 mult3,这意味着当他们更新到 v2 时,他们的代码会崩溃。因此,您可能希望在 v1.x 系列中发布一个中间版本,其中 mult3 存在但已弃用并根据 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

v1 API 在晚期 v1.x 版本中没有损坏,但调用已弃用方法的用户将看到以下类型的消息,以帮助他们过渡到较新的 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

(但从 Julia 1.5 开始,只有在 Julia 的命令行中提供了 --depwarn=yes 或者它出现在测试套件 运行 中时才会显示警告 Pkg.test() )


或者,如评论中所述,您可能希望保留旧的实现,只是在用户调用时警告用户。为此,可以直接使用Base.depwarn

# 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

当在 Julia 的命令行中提供 --depwarn=yes 时,这会产生与 @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

从 Julia 1.6 开始,depwarn 将接受一个关键字参数以强制发出警告,即使用户没有使用 --depwarn=yes:

请求它们
julia> Base.depwarn("Foo is deprecated", :foo, force=true)
┌ Warning: Foo is deprecated
│   caller = ip:0x0
└ @ Core :-1