Strange issue with `Pipe` read in `Test` environment

Hi folks, I seem to have run into a very strange issue with the Test environment.

Background

The specifics of this example are irrelevant, but consider the matrix

3×3 Array{Any,2}:
 :(gam * σ + 1)    :(-gam * σ)  0              
 :((z - ρ) * gam)  :(gam + 1)    :(gam * x)    
 :(-gam * y)       :(-gam * x)   :(gam * β + 1)

which is converted to an expression in another language, to take the symbolic inverse of it

eg = "mat((gam*σ+1,-gam*σ,0),((z-ρ)*gam,gam+1,gam*x),(-gam*y,-gam*x,gam*β+1))"

this conversion is done using Reduce parser. This is not the normal syntax for taking the inverse with this package, but to illustrate my issue, I am going to keep this expression as string:

julia> Algebra.:^(RExpr(eg),-1) |> string |> Reduce.RSymReplace
"mat(((-((β+1)*gam+1+(x^2+β)*gam^2))//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(-(gam*β+1)*gam*σ)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(gam^2*x*σ)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1))),(((((z-ρ)*β+x*y)*gam+z-ρ)*gam)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(-(gam^2*β*σ+1+(β+σ)*gam))//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),((gam*σ+1)*gam*x)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1))),(((((z-ρ)*x-y)*gam-y)*gam)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(-((x+y)*gam*σ+x)*gam)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),((ρ-1-z)*gam^2*σ-((σ+1)*gam+1))//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1))))"

All fine, no issues. Algebra.:^ rewrites this into a command to send to the external Reduce CSL process and then the result is read back as string (and later converted to Julia AST using the parser if necessary).

Issue

However, if I now run this in a Test environment, strange issues occur. Instead of obtaining the output from the example above, a flawed output is obtained from the Pipe output.

"2223233mat(((gam*x+gam*β+gam*β+gam+1)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β22-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam*σ*(gam*β+1))//(32333322gam*x*σ+gam*x*y*σ+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x22222+gam*z*σ+gam*β*σ+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ23233+gam+1),(-gam*x*σ)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β22-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1)),323((gam*(-gam*x*y-gam*z*β+gam*β*ρ-z+ρ))//(gam*x*σ+gam*x*y*σ3332222+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ2222+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam*β*σ32333+gam*β+gam*σ+1)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ-gam*β*ρ*σ32222222+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β-gam*ρ*σ+gam*σ32+gam*β+gam*σ+gam+1),(-gam*x*(gam*σ+1))//(gam*x*σ3333222+gam*x*y*σ+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ2222+gam*β*σ+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1)),323((gam*(-gam*x*z+gam*x*ρ+gam*y+y))//(gam*x*σ+gam*x*y*σ3332222+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ222+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam3233*(gam*x*σ+gam*y*σ+x))//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β2222-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam*z*σ-gam*ρ*σ23233+gam*σ+gam*σ+gam+1)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β22-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1)))""mat((+(-(*(gam,*(σ,-1))),1),-(*(gam,σ)),-(*(gam,0))),(-(*(gam,-(ρ,z))),+(-(*(gam,-1)),1),-(*(gam,*(x,-1)))),(-(*(gam,y)),-(*(gam,x)),+(-(*(gam,*(-1,β))),1)))"

As you can see, the string now contains some weird arrangement of 2’s and 3’s interspersed in between it. Note that the twos and threes are not only at the beginning of the string, but also in other random places through-out.

What I don’t understand is where those 2’s and 3’s are all coming from ? Why are they showing up there? Is this possibly an issue with the Julia language implementation of the Pipe in the Test environment?

It would help if someone could explain what is special / different about the testing environment, because outside of the test environment this works perfectly fine. The twos and threes only get inserted into the character stream within the Testing environment.

I have confirmed that this issue has nothing to do with my implementation of the Reduce package by directly checking the output read back from the Pipe.

The source / origin of the problem seems to happen in the readuntil function that reads back the stream from the pipe or elsewhere in the internals of Julia, and the issue only occurs in the testing environment.

Would reallly appreciate any insight on this issue.

I am not sure about this. I think that an MWE would be useful.

If you would like to reproduce the issue yourself, create a new package, say ExamplePkg and make this the test/runtests.jl script

using Base.Test
using Reduce

eg = "mat((gam*σ+1,-gam*σ,0),((z-ρ)*gam,gam+1,gam*x),(-gam*y,-gam*x,gam*β+1))"
@testset "inverse" begin
    println(Algebra.:^(RExpr(eg),-1) |> string |> Reduce.RSymReplace)
end

Then run Pkg.test("ExamplePkg") and you will see the output

julia> Pkg.test("ExamplePkg")
2223233mat(((gam*x+gam*β+gam*β+gam+1)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β22-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam*σ*(gam*β+1))//(32333322gam*x*σ+gam*x*y*σ+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x22222+gam*z*σ+gam*β*σ+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ23233+gam+1),(-gam*x*σ)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β22-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1)),323((gam*(-gam*x*y-gam*z*β+gam*β*ρ-z+ρ))//(gam*x*σ+gam*x*y*σ3332222+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ2222+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam*β*σ32333+gam*β+gam*σ+1)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ-gam*β*ρ*σ32222222+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β-gam*ρ*σ+gam*σ32+gam*β+gam*σ+gam+1),(-gam*x*(gam*σ+1))//(gam*x*σ3333222+gam*x*y*σ+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ2222+gam*β*σ+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1)),323((gam*(-gam*x*z+gam*x*ρ+gam*y+y))//(gam*x*σ+gam*x*y*σ3332222+gam*z*β*σ-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ222+gam*β-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam3233*(gam*x*σ+gam*y*σ+x))//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β2222-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1),(gam*z*σ-gam*ρ*σ23233+gam*σ+gam*σ+gam+1)//(gam*x*σ+gam*x*y*σ+gam*z*β*σ3322222-gam*β*ρ*σ+gam*β*σ+gam*x+gam*z*σ+gam*β*σ+gam*β22-gam*ρ*σ+gam*σ+gam*β+gam*σ+gam+1)))

However, when you enter it into the REPL you get

julia> include("test/runtests.jl")
mat(((-((β+1)*gam+1+(x^2+β)*gam^2))//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(-(gam*β+1)*gam*σ)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(gam^2*x*σ)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1))),(((((z-ρ)*β+x*y)*gam+z-ρ)*gam)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(-(gam^2*β*σ+1+(β+σ)*gam))//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),((gam*σ+1)*gam*x)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1))),(((((z-ρ)*x-y)*gam-y)*gam)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),(-((x+y)*gam*σ+x)*gam)//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1)),((ρ-1-z)*gam^2*σ-((σ+1)*gam+1))//(((ρ-1)*σ-(σ+1)*β-z*σ-x^2)*gam^2+((ρ-1-z)*β-(x+y)*x)*gam^3*σ-((σ+1+β)*gam+1))))