Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mark functions as `@deprecate`d?

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

like image 208
Adomas Baliuka Avatar asked Nov 05 '20 18:11

Adomas Baliuka


People also ask

How do you mark a function as deprecated in C++?

In C++14, you can mark a function as deprecated using the [[deprecated]] attribute (see section 7.6. 5 [dcl. attr. deprecated]).

What deprecated files?

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.


1 Answers

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
like image 132
François Févotte Avatar answered Sep 27 '22 19:09

François Févotte