swh:1:snp:a72e953ecd624a7df6e6196bbdd05851996c5e40
Tip revision: 1a8513cbb5166c3d096043de9d6e28e8e14ebb4d authored by Kristoffer Carlsson on 09 July 2022, 19:40:59 UTC
only locate packages in envs at or above in the load path where they were identified
only locate packages in envs at or above in the load path where they were identified
Tip revision: 1a8513c
deprecation_exec.jl
# 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()
module Sub
f1() = true
function f2 end
end
@deprecate Sub.f1() f() false
@deprecate Sub.f2 f false
# 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
# Create a consistent call frame for nowarn tests
@noinline call(f, args...) = @noinline f(args...)
# Given this is a sub-processed test file, not using @testsets avoids
# leaking the report print into the Base test runner report
begin # @deprecate
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
@test @test_warn "`f1` is deprecated, use `f` instead." f1()
@test_throws UndefVarError f2() # not exported
@test @test_warn "`f2` is deprecated, use `f` instead." DeprecationTests.f2()
@test @test_warn "`f3()` is deprecated, use `f()` instead." f3()
@test_throws UndefVarError f4() # not exported
@test @test_warn "`f4()` is deprecated, use `f()` instead." DeprecationTests.f4()
@test @test_warn "`f5(x::T) where T` is deprecated, use `f()` instead." f5(1)
@test @test_warn "`A{T}(x::S) where {T, S}` is deprecated, use `f()` instead." A{Int}(1.)
@test @test_warn "`Sub.f1()` is deprecated, use `f()` instead." DeprecationTests.Sub.f1()
redirect_stderr(devnull) do
@test call(f1)
@test call(DeprecationTests.f2)
@test call(f3)
@test call(DeprecationTests.f4)
@test call(f5, 1)
@test call(A{Int}, 1.)
@test call(DeprecationTests.Sub.f1)
@test call(DeprecationTests.Sub.f2)
end
@test @test_nowarn call(f1)
@test @test_nowarn call(DeprecationTests.f2)
@test @test_nowarn call(f3)
@test @test_nowarn call(DeprecationTests.f4)
@test @test_nowarn call(f5, 1)
@test @test_nowarn call(A{Int}, 1.)
@test @test_nowarn call(DeprecationTests.Sub.f1)
@test @test_nowarn call(DeprecationTests.Sub.f2)
# issue #21972
@noinline function f21972()
T21972()
end
@test_deprecated "something" f21972()
end
f24658() = depwarn24658()
depwarn24658() = Base.firstcaller(backtrace(), :_func_not_found_)
begin # firstcaller
# 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
begin # parser syntax deprecations
# #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
end
# END 0.7 deprecations
begin # tuple indexed by float deprecation
@test_deprecated getindex((1,), 1.0) === 1
@test_deprecated getindex((1,2), 2.0) === 2
@test Base.JLOptions().depwarn == 1
@test_throws Exception @test_warn r"`getindex(t::Tuple, i::Real)` is deprecated" getindex((), 1.0)
@test_throws Exception @test_warn r"`getindex(t::Tuple, i::Real)` is deprecated" getindex((1,2), 0.0)
@test_throws Exception @test_warn r"`getindex(t::Tuple, i::Real)` is deprecated" getindex((1,2), -1.0)
end
@testset "@deprecated error message" begin
@test_throws(
"if the third `export_old` argument is not specified or `true`,",
@eval @deprecate M.f() g()
)
@test_throws(
"if the third `export_old` argument is not specified or `true`,",
@eval @deprecate M.f() g() true
)
# Given `@deprecated Old{T} where {...} new`, it is unclear if we should generate
# `Old{T}(args...) where {...} = new(args...)` or
# `(Old{T} where {...})(args...) = new(args...)`.
# Since nobody has requested this feature yet, make sure that it throws, until we
# conciously define
@test_throws(
"invalid usage of @deprecate",
@eval @deprecate Foo{T} where {T <: Int} g true
)
end