Skip to content

Commit 35ec98d

Browse files
stevengjJeffBezanson
authored andcommitted
new deprecate_moved macro, better support for replacing deprecated bindings (#22763)
new deprecate_moved macro, and better support for replacing deprecated bindings without warnings
1 parent b0b0cbc commit 35ec98d

File tree

4 files changed

+42
-49
lines changed

4 files changed

+42
-49
lines changed

base/deprecated.jl

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function firstcaller(bt::Array{Ptr{Void},1}, funcsyms)
103103
return lkup
104104
end
105105

106-
deprecate(m::Module, s::Symbol) = ccall(:jl_deprecate_binding, Void, (Any, Any), m, s)
106+
deprecate(m::Module, s::Symbol, flag=1) = ccall(:jl_deprecate_binding, Void, (Any, Any, Cint), m, s, flag)
107107

108108
macro deprecate_binding(old, new, export_old=true)
109109
return Expr(:toplevel,
@@ -112,6 +112,18 @@ macro deprecate_binding(old, new, export_old=true)
112112
Expr(:call, :deprecate, __module__, Expr(:quote, old)))
113113
end
114114

115+
macro deprecate_moved(old, new, export_old=true)
116+
eold = esc(old)
117+
return Expr(:toplevel,
118+
:(function $eold(args...; kwargs...)
119+
error($eold, " has been moved to the package ", $new, ".jl.\n",
120+
"Run `Pkg.add(\"", $new, "\")` to install it, restart Julia,\n",
121+
"and then run `using ", $new, "` to load it.")
122+
end),
123+
export_old ? Expr(:export, eold) : nothing,
124+
Expr(:call, :deprecate, __module__, Expr(:quote, old), 2))
125+
end
126+
115127
# BEGIN 0.6-alpha deprecations (delete when 0.6 is released)
116128

117129
@deprecate isambiguous(m1::Method, m2::Method, b::Bool) isambiguous(m1, m2, ambiguous_bottom=b) false
@@ -684,21 +696,12 @@ end
684696
@deprecate xor(A::AbstractArray, B::AbstractArray) xor.(A, B)
685697

686698
# QuadGK moved to a package (#19741)
687-
function quadgk(args...; kwargs...)
688-
error(string(quadgk, args, " has been moved to the package QuadGK.jl.\n",
689-
"Run Pkg.add(\"QuadGK\") to install QuadGK on Julia v0.6 and later, and then run `using QuadGK`."))
690-
end
691-
export quadgk
699+
@deprecate_moved quadgk "QuadGK"
692700

693701
# Collections functions moved to a package (#19800)
694702
module Collections
695-
export PriorityQueue, enqueue!, dequeue!, heapify!, heapify, heappop!, heappush!, isheap, peek
696703
for f in (:PriorityQueue, :enqueue!, :dequeue!, :heapify!, :heapify, :heappop!, :heappush!, :isheap, :peek)
697-
@eval function ($f)(args...; kwargs...)
698-
error(string($f, args, " has been moved to the package DataStructures.jl.\n",
699-
"Run Pkg.add(\"DataStructures\") to install DataStructures on Julia v0.6 and later, ",
700-
"and then run `using DataStructures`."))
701-
end
704+
@eval Base.@deprecate_moved $f "DataStructures"
702705
end
703706
end
704707
export Collections
@@ -1288,14 +1291,7 @@ for f in (:airyai, :airyaiprime, :airybi, :airybiprime, :airyaix, :airyaiprimex,
12881291
:eta, :zeta, :digamma, :invdigamma, :polygamma, :trigamma,
12891292
:hankelh1, :hankelh1x, :hankelh2, :hankelh2x,
12901293
:airy, :airyx, :airyprime)
1291-
@eval begin
1292-
function $f(args...; kwargs...)
1293-
error(string($f, args, " has been moved to the package SpecialFunctions.jl.\n",
1294-
"Run Pkg.add(\"SpecialFunctions\") to install SpecialFunctions on Julia v0.6 and later,\n",
1295-
"and then run `using SpecialFunctions`."))
1296-
end
1297-
export $f
1298-
end
1294+
@eval @deprecate_moved $f "SpecialFunctions"
12991295
end
13001296

13011297
@deprecate_binding LinearIndexing IndexStyle false
@@ -1443,43 +1439,22 @@ module DFT
14431439
:plan_dct, :plan_dct!, :plan_fft, :plan_fft!, :plan_idct, :plan_idct!,
14441440
:plan_ifft, :plan_ifft!, :plan_irfft, :plan_rfft, :rfft]
14451441
pkg = endswith(String(f), "shift") ? "AbstractFFTs" : "FFTW"
1446-
@eval begin
1447-
function $f(args...; kwargs...)
1448-
error($f, " has been moved to the package $($pkg).jl.\n",
1449-
"Run `Pkg.add(\"$($pkg)\")` to install $($pkg) then run `using $($pkg)` ",
1450-
"to load it.")
1451-
end
1452-
export $f
1453-
end
1442+
@eval Base.@deprecate_moved $f $pkg
14541443
end
14551444
module FFTW
14561445
for f in [:r2r, :r2r!, :plan_r2r, :plan_r2r!]
1457-
@eval begin
1458-
function $f(args...; kwargs...)
1459-
error($f, " has been moved to the package FFTW.jl.\n",
1460-
"Run `Pkg.add(\"FFTW\")` to install FFTW then run `using FFTW` ",
1461-
"to load it.")
1462-
end
1463-
export $f
1464-
end
1446+
@eval Base.@deprecate_moved $f "FFTW"
14651447
end
14661448
end
14671449
export FFTW
14681450
end
14691451
using .DFT
1470-
for f in names(DFT)
1452+
for f in filter(s -> isexported(DFT, s), names(DFT, true))
14711453
@eval export $f
14721454
end
14731455
module DSP
14741456
for f in [:conv, :conv2, :deconv, :filt, :filt!, :xcorr]
1475-
@eval begin
1476-
function $f(args...; kwargs...)
1477-
error($f, " has been moved to the package DSP.jl.\n",
1478-
"Run `Pkg.add(\"DSP\")` to install DSP then run `using DSP` ",
1479-
"to load it.")
1480-
end
1481-
export $f
1482-
end
1457+
@eval Base.@deprecate_moved $f "DSP"
14831458
end
14841459
end
14851460
using .DSP

src/julia.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ typedef struct {
400400
uint8_t constp:1;
401401
uint8_t exportp:1;
402402
uint8_t imported:1;
403-
uint8_t deprecated:1;
403+
uint8_t deprecated:2; // 0=not deprecated, 1=renamed, 2=moved to another package
404404
} jl_binding_t;
405405

406406
typedef struct _jl_module_t {

src/module.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ static jl_binding_t *jl_get_binding_(jl_module_t *m, jl_sym_t *var, modstack_t *
191191
// couldn't resolve; try next using (see issue #6105)
192192
continue;
193193
if (owner != NULL && tempb->owner != b->owner &&
194+
!tempb->deprecated && !b->deprecated &&
194195
!(tempb->constp && tempb->value && b->constp && b->value == tempb->value)) {
195196
jl_printf(JL_STDERR,
196197
"WARNING: both %s and %s export \"%s\"; uses of it in module %s must be qualified\n",
@@ -461,10 +462,12 @@ JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var)
461462
return b && b->constp;
462463
}
463464

464-
JL_DLLEXPORT void jl_deprecate_binding(jl_module_t *m, jl_sym_t *var)
465+
// set the deprecated flag for a binding:
466+
// 0=not deprecated, 1=renamed, 2=moved to another package
467+
JL_DLLEXPORT void jl_deprecate_binding(jl_module_t *m, jl_sym_t *var, int flag)
465468
{
466469
jl_binding_t *b = jl_get_binding(m, var);
467-
if (b) b->deprecated = 1;
470+
if (b) b->deprecated = flag;
468471
}
469472

470473
JL_DLLEXPORT int jl_is_binding_deprecated(jl_module_t *m, jl_sym_t *var)
@@ -478,7 +481,10 @@ extern int jl_lineno;
478481

479482
void jl_binding_deprecation_warning(jl_binding_t *b)
480483
{
481-
if (b->deprecated && jl_options.depwarn) {
484+
// Only print a warning for deprecated == 1 (renamed).
485+
// For deprecated == 2 (moved to a package) the binding is to a function
486+
// that throws an error, so we don't want to print a warning too.
487+
if (b->deprecated == 1 && jl_options.depwarn) {
482488
if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR)
483489
jl_printf(JL_STDERR, "WARNING: ");
484490
if (b->owner)

test/misc.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,10 +769,22 @@ module DeprecationTests # to test @deprecate
769769
# test deprecation of a constructor
770770
struct A{T} end
771771
@deprecate A{T}(x::S) where {T, S} f()
772+
773+
# test that @deprecate_moved can be overridden by an import
774+
Base.@deprecate_moved foo1234 "Foo"
775+
Base.@deprecate_moved bar "Bar" false
772776
end # module
777+
module Foo1234
778+
export foo1234
779+
foo1234(x) = x+1
780+
end
773781

774782
@testset "@deprecate" begin
775783
using .DeprecationTests
784+
using .Foo1234
785+
@test foo1234(3) == 4
786+
@test_throws ErrorException DeprecationTests.bar(3)
787+
776788
# enable when issue #22043 is fixed
777789
# @test @test_warn "f1 is deprecated, use f instead." f1()
778790
# @test @test_nowarn f1()

0 commit comments

Comments
 (0)