Julia: Scoping issue in `@testset`

Created on 28 Jun 2016  ·  11Comments  ·  Source: JuliaLang/julia

The following piece of code:

using Base.Dates
using Base.Test
@testset "blah" begin
a = Date(2013)
@show a, "before"
function testlengths(n)
    a = Dates.Date(2000)
    for i = 1:n
        @test length(range(a,i)) == i
    end
    return a+Dates.Day(n)
end
testlengths(100000)
@show a, "after"
end

gives the output:

(a,"before") = (2013-01-01,"before")
(a,"after") = (2000-01-01,"after")

Notice that a has changed and shouldn't.

bug test

Most helpful comment

Chalk up another point for requiring outer (or similar keyword) to assign a variable in an outer scope, I'd have to say.

All 11 comments

Nice MCVE.

AFAIK, this is the expected behavior in a local scope. So should @testset be changed to not introduce a new scope?

Test sets introduce a new scope by design since, like try/catch they introduce rollback points. In other words, if a test in a test set fails, the tests will continue after the test set. This allows us to get much more complete testing information even when some tests fail – since the tests can continue after a failure.

In another word this is a won't fix or dup of https://github.com/JuliaLang/julia/issues/14948 ?

I'm not sure how this is a dup of #14948 since there are no threads involved, but I do think we need to decide if this is the right behavior for test sets and it does perhaps shed some light on one of the more potentially confusing corners of Julia's scoping rules. @JeffBezanson may be interested.

14948 is not really about threading but the scope lifting due to a variable with the same name in the outer scope

Chalk up another point for requiring outer (or similar keyword) to assign a variable in an outer scope, I'd have to say.

That seems like it may well make the scoping rules simpler and clearer.

X-refs: #5331, #10559, #14959, #16727, #14959

I also encountered the problem. This case may be much harder to notice:

using Base.Test

@testset begin
    @testset "foo" begin
        sum = 1
    end

    @testset "bar" begin
        mktemp() do path, io
            @test sum([1,2,3]) == 6
        end
    end
end

Original example now warns and the second one works.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sbromberger picture sbromberger  ·  3Comments

i-apellaniz picture i-apellaniz  ·  3Comments

omus picture omus  ·  3Comments

tkoolen picture tkoolen  ·  3Comments

StefanKarpinski picture StefanKarpinski  ·  3Comments