-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
deprecation_exec.jl
355 lines (279 loc) · 13.2 KB
/
deprecation_exec.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# This file is a part of Julia. License is MIT: https://julialang.org/license
# Tests for deprecated functionality.
#
# These can't be run with --depwarn=error, so currently require special
# treatment when run inside the test system.
using Test
using Logging
using Base: remove_linenums!
module DeprecationTests # to test @deprecate
f() = true
# test the Symbol path of @deprecate
@deprecate f1 f
@deprecate f2 f false # test that f2 is not exported
# test the Expr path of @deprecate
@deprecate f3() f()
@deprecate f4() f() false # test that f4 is not exported
@deprecate f5(x::T) where T f()
# test deprecation of a constructor
struct A{T} end
@deprecate A{T}(x::S) where {T, S} f()
# test that @deprecate_moved can be overridden by an import
Base.@deprecate_moved foo1234 "Foo"
Base.@deprecate_moved bar "Bar" false
end # module
module Foo1234
export foo1234
foo1234(x) = x+1
end
# issue #21972
struct T21972
@noinline function T21972()
Base.depwarn("something", :T21972)
new()
end
end
@testset "@deprecate" begin
using .DeprecationTests
using .Foo1234
@test foo1234(3) == 4
@test_throws ErrorException DeprecationTests.bar(3)
# 22845
ex = :(module M22845; import ..DeprecationTests: bar;
bar(x::Number) = x + 3; end)
@test_warn "importing deprecated binding" eval(ex)
@test @test_nowarn(DeprecationTests.bar(4)) == 7
# enable when issue #22043 is fixed
# @test @test_warn "f1 is deprecated, use f instead." f1()
# @test @test_nowarn f1()
# @test_throws UndefVarError f2() # not exported
# @test @test_warn "f2 is deprecated, use f instead." DeprecationTests.f2()
# @test @test_nowarn DeprecationTests.f2()
# @test @test_warn "f3() is deprecated, use f() instead." f3()
# @test @test_nowarn f3()
# @test_throws UndefVarError f4() # not exported
# @test @test_warn "f4() is deprecated, use f() instead." DeprecationTests.f4()
# @test @test_nowarn DeprecationTests.f4()
# @test @test_warn "f5(x::T) where T is deprecated, use f() instead." f5(1)
# @test @test_nowarn f5(1)
# @test @test_warn "A{T}(x::S) where {T, S} is deprecated, use f() instead." A{Int}(1.)
# @test @test_nowarn A{Int}(1.)
# issue #21972
@noinline function f21972()
T21972()
end
@test_deprecated "something" f21972()
end
f24658() = depwarn24658()
depwarn24658() = Base.firstcaller(backtrace(), :_func_not_found_)
@testset "firstcaller" begin
# issue #24658
@test eval(:(if true; f24658(); end)) == (Ptr{Cvoid}(0),StackTraces.UNKNOWN)
end
# issue #25130
f25130() = Base.depwarn("f25130 message", :f25130)
# The following test is for the depwarn behavior of expressions evaluated at
# top-level, so we can't use the usual `collect_test_logs()` / `with_logger()`
testlogger = Test.TestLogger()
prev_logger = global_logger(testlogger)
# Each call at top level should be distinct. This won't be true if they're
# attributed to internal C frames (including generic dispatch machinery)
f25130()
f25130()
testlogs = testlogger.logs
@test length(testlogs) == 2
@test testlogs[1].id != testlogs[2].id
@test testlogs[1].kwargs[:caller].func == Symbol("top-level scope")
@test all(l.message == "f25130 message" for l in testlogs)
global_logger(prev_logger)
#-------------------------------------------------------------------------------
# BEGIN 0.7 deprecations
@testset "parser syntax deprecations" begin
# Test empty logs for meta.parse depwarn argument.
@test_logs Meta.parse("1.+2", depwarn=false)
# #19089
@test (@test_deprecated Meta.parse("1.+2")) == :(1 .+ 2)
# #16356
@test (@test_deprecated Meta.parse("0xapi")) == :(0xa * pi)
# #22523 #22712
@test (@test_deprecated Meta.parse("a?b:c")) == :(a ? b : c)
@test (@test_deprecated Meta.parse("a ?b:c")) == :(a ? b : c)
@test (@test_deprecated Meta.parse("a ? b:c")) == :(a ? b : c)
@test (@test_deprecated Meta.parse("a ? b :c")) == :(a ? b : c)
@test (@test_deprecated Meta.parse("?")) == Symbol("?")
# #13079
@test (@test_deprecated Meta.parse("1<<2*3")) == :(1<<(2*3))
# ([#19157], [#20418]).
@test remove_linenums!(@test_deprecated Meta.parse("immutable A; end")) ==
remove_linenums!(:(struct A; end))
@test remove_linenums!(@test_deprecated Meta.parse("type A; end")) ==
remove_linenums!(:(mutable struct A; end))
# #19987
@test remove_linenums!(@test_deprecated Meta.parse("try ; catch f() ; end")) ==
remove_linenums!(:(try ; catch; f() ; end))
# #15524
# @test (@test_deprecated Meta.parse("for a=b f() end")) == :(for a=b; f() end)
@test_broken length(Test.collect_test_logs(()->Meta.parse("for a=b f() end"))[1]) > 0
# #23076
@test (@test_deprecated Meta.parse("[a,b;]")) == :([a;b])
# #24452
@test (@test_deprecated Meta.parse("(a...)")) == :((a...,))
end
@testset "lowering syntax deprecations" begin
# #16295
@test_deprecated Meta.lower(@__MODULE__, :(A.(:+)(a,b) = 1))
# #11310
@test_deprecated r"parametric method syntax" Meta.lower(@__MODULE__, :(f{T}(x::T) = 1))
# #17623
@test_deprecated r"Deprecated syntax `function .+(...)`" Meta.lower(@__MODULE__, :(function .+(a,b) ; end))
# #21774 (more uniform let expressions)
@test_deprecated Meta.lower(@__MODULE__, Expr(:let, :a))
@test_deprecated Meta.lower(@__MODULE__, Expr(:let, :a, :(a=1), :(b=1)))
# #23157 (Expression heads for types renamed)
@test_deprecated Meta.lower(@__MODULE__, Expr(:type, true, :A, Expr(:block)))
@test_deprecated Meta.lower(@__MODULE__, Expr(:bitstype, 32, :A))
# #15032
@test_deprecated Meta.lower(@__MODULE__, :(a.(b) = 1))
# #5332
@test_deprecated Meta.lower(@__MODULE__, :(a.'))
# #19324
@test_deprecated r"implicit assignment to global" eval(
:(module M19324
x=1
for i=1:10
x += i
end
end))
# #24221
@test_deprecated r"underscores as an rvalue" Meta.lower(@__MODULE__, :(a=_))
# #22314
@test_deprecated r"Use of final value of loop variable `i`.*is deprecated. In the future the variable will be local to the loop instead." Meta.lower(@__MODULE__, :(
function f()
i=0
for i=1:10
end
i
end))
@test_deprecated r"Loop variable `i` overwrites a variable in an enclosing scope" eval(:(
module M22314
i=10
for i=1:10
end
end))
# #6080
@test_deprecated r"Syntax `&argument`.*is deprecated" Meta.lower(@__MODULE__, :(ccall(:a, Cvoid, (Cint,), &x)))
end
module LogTest
function bar(io)
info(io,"barinfo")
warn(io,"barwarn")
Base.display_error(io,"barerror",backtrace())
end
function pooh(io)
info(io,"poohinfo")
warn(io,"poohwarn")
Base.display_error(io,"pooherror",backtrace())
end
end
function foo(io)
info(io,"fooinfo")
warn(io,"foowarn")
Base.display_error(io,"fooerror",backtrace())
end
# Silence the flurry of depwarns for now.
with_logger(NullLogger()) do
@testset "Deprecated logging" begin
# Test info
@test occursin("INFO:", sprint(info, "test"))
@test occursin("INFO: test", sprint(info, "test"))
@test occursin("INFO: test 123", sprint(info, "test ", 1, 2, 3))
@test occursin("MYINFO: test", sprint(io->info(io,"test", prefix="MYINFO: ")))
# Test warn
@test occursin("WARNING: test", sprint(Base.warn_once, "test"))
@test isempty(sprint(Base.warn_once, "test"))
@test occursin("WARNING:", sprint(warn))
@test occursin("WARNING: test", sprint(warn, "test"))
@test occursin("WARNING: test 123", sprint(warn, "test ", 1, 2, 3))
@test occursin("MYWARNING: test", sprint(io->warn(io, "test", prefix="MYWARNING: ")))
@test occursin("WARNING: testonce", sprint(io->warn(io, "testonce", once=true)))
@test isempty(sprint(io->warn(io, "testonce", once=true)))
@test !isempty(sprint(io->warn(io, "testonce", once=true, key=hash("testonce",hash("testanother")))))
let bt = backtrace()
ws = split(chomp(sprint(io->warn(io, "test", bt = bt))), '\n')
bs = split(chomp(sprint(Base.show_backtrace, bt)), '\n')
@test occursin("WARNING: test", ws[1])
for (l,b) in zip(ws[2:end],bs[2:end])
@test occursin(b, l)
end
end
# PR #16213
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest, :bar; kind=:info)
@test all(occursin.(["WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest; kind=:info)
@test all(occursin.(["WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull; kind=:info)
@test all(occursin.(["WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(kind=:info)
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest, :bar; kind=:warn)
@test all(occursin.(["INFO: barinfo", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest; kind=:warn)
@test all(occursin.(["INFO: barinfo", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull; kind=:warn)
@test all(occursin.(["INFO: barinfo", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "ERROR: \"fooerror\""], sprint(foo)))
logging(kind=:warn)
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest, :bar; kind=:error)
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn"], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest; kind=:error)
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn"], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn"], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull; kind=:error)
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn"], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn"], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn"], sprint(foo)))
logging(kind=:error)
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest, :bar)
@test sprint(LogTest.bar) == ""
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull, LogTest)
@test sprint(LogTest.bar) == ""
@test sprint(LogTest.pooh) == ""
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
logging(devnull)
@test sprint(LogTest.bar) == ""
@test sprint(LogTest.pooh) == ""
@test sprint(foo) == ""
logging()
@test all(occursin.(["INFO: barinfo", "WARNING: barwarn", "ERROR: \"barerror\""], sprint(LogTest.bar)))
@test all(occursin.(["INFO: poohinfo", "WARNING: poohwarn", "ERROR: \"pooherror\""], sprint(LogTest.pooh)))
@test all(occursin.(["INFO: fooinfo", "WARNING: foowarn", "ERROR: \"fooerror\""], sprint(foo)))
end # @testset
end
# END 0.7 deprecations