如何将函数标记为`@deprecate`d? [英] How to mark functions as `@deprecate`d?

查看:21
本文介绍了如何将函数标记为`@deprecate`d?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(问题指 Julia 版本 v1.5)

我试图了解 @deprecate 宏在 Julia 中的工作原理.文档对我来说很遗憾:p><块引用>

@deprecate old new [ex=true]

弃用旧方法并指定替换调用新方法.避免@deprecate 通过将 ex 设置为 false 来导出旧的.@弃用定义了一个与旧方法具有相同签名的新方法.

警告:从 Julia 1.5 开始,@deprecate 定义的函数在没有设置 --depwarn=yes 标志的情况下运行 julia 时不会打印警告,因为 --depwarn 选项的默认值为 no.警告是从 Pkg.test() 运行的测试中打印出来的.

例子

朱莉娅>@deprecate old(x) new(x)

旧(具有 1 种方法的通用函数)

朱莉娅>@deprecate old(x) new(x)

假旧(具有 1 种方法的泛型函数)

那我该怎么办?

旧函数(x::Int)print("旧行为")结尾函数新(x::Int)print("新行为")结尾# 添加真/假参数不会改变我的观察结果.@deprecate old(x) new(x) # false老(3)# 打印旧行为".没有警告.# 另外:帮助中没有提到弃用(julia>?old)

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

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

解决方案

想象一下,您在版本 1 中将此方法作为库的公共 API 的一部分:

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

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

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

版本 1 的用户习惯使用 mult3,这意味着他们的代码在更新到 v2 时会中断.因此,您可能希望在 v1.x 系列中发布一个中间版本,其中存在 mult3 但已弃用并根据 mult 实现:

# v1.1 - 过渡# 这是 v2 的新 API乘(x, y) = x*y# 旧 API 仍受支持,但已弃用并使用旧 API 实现@deprecate mult3(x::Int) mult(3, x)# 上面或多或少等价于定义# 函数 mult3(x::Int)# # 打印错误信息是 `--depwarn` 已设置# 返回 mult(3, x)# 结尾

v1 API 在 v1.x 后期版本中没有损坏,但调用已弃用方法的用户会看到以下类型的消息,以帮助他们过渡到较新的 v2 API:

朱莉娅>多3(14)┌ 警告:`mult3(x::Int)` 已弃用,请改用`mult(3, x)`.│ caller = REPL[3]:1 的顶级作用域└@核心 REPL[3]:142

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


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

# v1.1 - 过渡# 这是 v2 的新 API乘(x, y) = x*y# 旧 API 仍受支持,但已弃用# 自己实现:函数 mult3(x)Base.depwarn("`mult3(x)` 已弃用,请改用`mult(3,x)`.", :mult3)返回 3x结尾

当 Julia 的命令行中提供了 --depwarn=yes 时,这会产生与 @deprecate 相同的警告:

朱莉娅>多3(14)┌ 警告:`mult3(x)` 已弃用,请改用 `mult(3,x)`.│ caller = REPL[4]:1 的顶级作用域└@核心 REPL[4]:142

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

朱莉娅>Base.depwarn(不推荐使用 Foo", :foo, force=true)┌ 警告: Foo 已弃用│ 来电者 = ip:0x0└@核心:-1

(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?

解决方案

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

这篇关于如何将函数标记为`@deprecate`d?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆