From ba2f8bf25b94548674b422652933e2edb7b99186 Mon Sep 17 00:00:00 2001 From: Richard Reeve Date: Fri, 1 Dec 2017 20:07:52 +0000 Subject: [PATCH 01/16] =?UTF-8?q?Minor=200.7=20fixes=20=20-=20Range=20->?= =?UTF-8?q?=20Abstract=20Range=20=20-=20(a...)=20->=20(a...,)=20=20-=20esc?= =?UTF-8?q?ape=20*=20in=20strings=20=20-=20e=20->=20=E2=84=AF=20=20-=20par?= =?UTF-8?q?se=20->=20Meta.parse=20=20-=20current=5Fmodule()=20->=20@=5F=5F?= =?UTF-8?q?MODULE=5F=5F=20=20-=20Base.Test=20->=20[Compat.]test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- REQUIRE | 1 + src/dimensions.jl | 4 ++-- src/logarithm.jl | 4 ++-- src/pkgdefaults.jl | 42 ++++++++++++++++++++++++++++-------------- src/range.jl | 8 +++++--- src/units.jl | 2 +- src/user.jl | 6 +++--- test/runtests.jl | 2 +- 8 files changed, 43 insertions(+), 26 deletions(-) diff --git a/REQUIRE b/REQUIRE index 137767a4..e0ee8c3c 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1,2 @@ julia 0.6 +Compat 0.33.0 diff --git a/src/dimensions.jl b/src/dimensions.jl index a81eda3b..c732be5a 100644 --- a/src/dimensions.jl +++ b/src/dimensions.jl @@ -1,5 +1,5 @@ """ - \*(a0::Dimensions, a::Dimensions...) + *(a0::Dimensions, a::Dimensions...) Given however many dimensions, multiply them together. Collect [`Unitful.Dimension`](@ref) objects from the type parameter of the @@ -54,7 +54,7 @@ true end end - d = (c...) + d = (c...,) :(Dimensions{$d}()) end diff --git a/src/logarithm.jl b/src/logarithm.jl index 51eca1b6..fdd7c97b 100644 --- a/src/logarithm.jl +++ b/src/logarithm.jl @@ -348,7 +348,7 @@ Neper-based yield `ln`, and so on. Returns `x->log(base, x)` as a fallback. function logfn end logfn(x::LogInfo{N,10}) where {N} = log10 logfn(x::LogInfo{N,2}) where {N} = log2 -logfn(x::LogInfo{N,e}) where {N} = log +logfn(x::LogInfo{N,ℯ}) where {N} = log logfn(x::LogInfo{N,B}) where {N,B} = x->log(B,x) """ @@ -360,7 +360,7 @@ Neper-based yield `exp`, and so on. Returns `x->(base)^x` as a fallback. function expfn end expfn(x::LogInfo{N,10}) where {N} = exp10 expfn(x::LogInfo{N,2}) where {N} = exp2 -expfn(x::LogInfo{N,e}) where {N} = exp +expfn(x::LogInfo{N,ℯ}) where {N} = exp expfn(x::LogInfo{N,B}) where {N,B} = x->B^x Base.rtoldefault(::Type{Level{L,S,T}}) where {L,S,T} = diff --git a/src/pkgdefaults.jl b/src/pkgdefaults.jl index a09f01ef..4e05ef94 100644 --- a/src/pkgdefaults.jl +++ b/src/pkgdefaults.jl @@ -168,8 +168,8 @@ Unitful.offsettemp(::Unitful.Unit{:Fahrenheit}) = 45967//100 @logscale dB "dB" Decibel 10 10 false @logscale B "B" Bel 10 1 false -@logscale Np "Np" Neper e 1//2 true -@logscale cNp "cNp" Centineper e 50 true +@logscale Np "Np" Neper ℯ 1//2 true +@logscale cNp "cNp" Centineper ℯ 50 true @logunit dBm "dBm" Decibel 1mW @logunit dBV "dBV" Decibel 1V @@ -254,17 +254,31 @@ consider invoking this function in your `.juliarc.jl` file which is loaded when you open Julia. This function is not exported. """ function promote_to_derived() - Unitful.promote_unit(::S, ::T) where {S<:EnergyFreeUnits, T<:EnergyFreeUnits} = Unitful.J - Unitful.promote_unit(::S, ::T) where {S<:ForceFreeUnits, T<:ForceFreeUnits} = Unitful.N - Unitful.promote_unit(::S, ::T) where {S<:PowerFreeUnits, T<:PowerFreeUnits} = Unitful.W - Unitful.promote_unit(::S, ::T) where {S<:PressureFreeUnits, T<:PressureFreeUnits} = Unitful.Pa - Unitful.promote_unit(::S, ::T) where {S<:ChargeFreeUnits, T<:ChargeFreeUnits} = Unitful.C - Unitful.promote_unit(::S, ::T) where {S<:VoltageFreeUnits, T<:VoltageFreeUnits} = Unitful.V - Unitful.promote_unit(::S, ::T) where {S<:ResistanceFreeUnits, T<:ResistanceFreeUnits} = Unitful.Ω - Unitful.promote_unit(::S, ::T) where {S<:CapacitanceFreeUnits, T<:CapacitanceFreeUnits} = Unitful.F - Unitful.promote_unit(::S, ::T) where {S<:InductanceFreeUnits, T<:InductanceFreeUnits} = Unitful.H - Unitful.promote_unit(::S, ::T) where {S<:MagneticFluxFreeUnits, T<:MagneticFluxFreeUnits} = Unitful.Wb - Unitful.promote_unit(::S, ::T) where {S<:BFieldFreeUnits, T<:BFieldFreeUnits} = Unitful.T - Unitful.promote_unit(::S, ::T) where {S<:ActionFreeUnits, T<:ActionFreeUnits} = Unitful.J * Unitful.s + eval(quote + Unitful.promote_unit(::S, ::T) where + {S<:EnergyFreeUnits, T<:EnergyFreeUnits} = Unitful.J + Unitful.promote_unit(::S, ::T) where + {S<:ForceFreeUnits, T<:ForceFreeUnits} = Unitful.N + Unitful.promote_unit(::S, ::T) where + {S<:PowerFreeUnits, T<:PowerFreeUnits} = Unitful.W + Unitful.promote_unit(::S, ::T) where + {S<:PressureFreeUnits, T<:PressureFreeUnits} = Unitful.Pa + Unitful.promote_unit(::S, ::T) where + {S<:ChargeFreeUnits, T<:ChargeFreeUnits} = Unitful.C + Unitful.promote_unit(::S, ::T) where + {S<:VoltageFreeUnits, T<:VoltageFreeUnits} = Unitful.V + Unitful.promote_unit(::S, ::T) where + {S<:ResistanceFreeUnits, T<:ResistanceFreeUnits} = Unitful.Ω + Unitful.promote_unit(::S, ::T) where + {S<:CapacitanceFreeUnits, T<:CapacitanceFreeUnits} = Unitful.F + Unitful.promote_unit(::S, ::T) where + {S<:InductanceFreeUnits, T<:InductanceFreeUnits} = Unitful.H + Unitful.promote_unit(::S, ::T) where + {S<:MagneticFluxFreeUnits, T<:MagneticFluxFreeUnits} = Unitful.Wb + Unitful.promote_unit(::S, ::T) where + {S<:BFieldFreeUnits, T<:BFieldFreeUnits} = Unitful.T + Unitful.promote_unit(::S, ::T) where + {S<:ActionFreeUnits, T<:ActionFreeUnits} = Unitful.J * Unitful.s + end) nothing end diff --git a/src/range.jl b/src/range.jl index 17b018ba..8985af1c 100644 --- a/src/range.jl +++ b/src/range.jl @@ -1,6 +1,8 @@ -*(y::Units, r::Range) = *(r,y) -*(r::Range, y::Units) = range(first(r)*y, step(r)*y, length(r)) -*(r::Range, y::Units, z::Units...) = *(x, *(y,z...)) +using Compat: AbstractRange + +*(y::Units, r::AbstractRange) = *(r,y) +*(r::AbstractRange, y::Units) = range(first(r)*y, step(r)*y, length(r)) +*(r::AbstractRange, y::Units, z::Units...) = *(x, *(y,z...)) Base.linspace(start::Quantity{<:Real}, stop, len::Integer) = _linspace(promote(start, stop)..., len) diff --git a/src/units.jl b/src/units.jl index 6845fee1..fc572825 100644 --- a/src/units.jl +++ b/src/units.jl @@ -44,7 +44,7 @@ # results in: # [nm,cm^6,m^6,µs^3,s] - d = (c...) + d = (c...,) f = typeof(mapreduce(dimension, *, NoDims, d)) :(FreeUnits{$d,$f}()) end diff --git a/src/user.jl b/src/user.jl index 789a79ed..b5f57af5 100644 --- a/src/user.jl +++ b/src/user.jl @@ -266,7 +266,7 @@ factory defaults, this function will return a product of powers of base SI units (as [`Unitful.FreeUnits`](@ref)). """ @generated function upreferred(x::Dimensions{D}) where {D} - u = *(FreeUnits{((Unitful.promotion[name(z)]^z.power for z in D)...),()}()) + u = *(FreeUnits{((Unitful.promotion[name(z)]^z.power for z in D)...,),()}()) :($u) end @@ -438,7 +438,7 @@ julia> u"ħ" ``` """ macro u_str(unit) - ex = parse(unit) + ex = Meta.parse(unit) esc(replace_value(ex)) end @@ -453,7 +453,7 @@ function replace_value(ex::Expr) ex.args[i]=replace_value(ex.args[i]) end end - return eval(current_module(), ex) + return eval(@__MODULE__, ex) elseif ex.head == :tuple for i=1:length(ex.args) if typeof(ex.args[i])==Symbol diff --git a/test/runtests.jl b/test/runtests.jl index 3c685207..d3515a70 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,7 @@ module UnitfulTests using Unitful -using Base.Test +using Compat.Test import Unitful: DimensionError From 5fa7fe15faf42981b77f9f25f6858dd181260c1d Mon Sep 17 00:00:00 2001 From: Richard Reeve Date: Fri, 1 Dec 2017 20:11:10 +0000 Subject: [PATCH 02/16] sqrt_llvm_fast no longer exists - use sqrt_llvm --- src/fastmath.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fastmath.jl b/src/fastmath.jl index a00f7ef8..70d4597b 100644 --- a/src/fastmath.jl +++ b/src/fastmath.jl @@ -1,6 +1,6 @@ import Base.FastMath import Core.Intrinsics: - sqrt_llvm_fast, + sqrt_llvm, neg_float_fast, add_float_fast, sub_float_fast, @@ -161,7 +161,7 @@ pow_fast(x::Quantity, y::Integer) = x^y pow_fast(x::Quantity, y::Rational) = x^y sqrt_fast(x::Quantity{T}) where {T <: FloatTypes} = - Quantity(sqrt_llvm_fast(x.val), sqrt(unit(x))) + Quantity(sqrt_llvm(x.val), sqrt(unit(x))) for f in (:cos, :sin, :tan) f_fast = fast_op[f] From 389c2221a9acde848b3f2533fe8add1ac27a91ce Mon Sep 17 00:00:00 2001 From: Richard Reeve Date: Fri, 1 Dec 2017 20:12:22 +0000 Subject: [PATCH 03/16] Fix macros unit, prefixed_unit_symbols, unit_symbols for 0.7. --- src/user.jl | 75 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/src/user.jl b/src/user.jl index b5f57af5..8965b2ec 100644 --- a/src/user.jl +++ b/src/user.jl @@ -149,24 +149,34 @@ Usage example: `@unit mi "mi" Mile (201168//125)*m false` This example will *not* generate `kmi` (kilomiles). """ macro unit(symb,abbr,name,equals,tf) + expr = Expr(:block) # name is a symbol # abbr is a string x = Expr(:quote, name) - quote - d = Unitful.dimension($(esc(equals))) - inex, ex = Unitful.basefactor(Unitful.unit($(esc(equals)))) - t = Unitful.tensfactor(Unitful.unit($(esc(equals)))) - eq = ($(esc(equals)))/Unitful.unit($(esc(equals))) - Unitful.abbr(::Unitful.Unit{$(esc(x)),typeof(d)}) = $abbr - if $tf - Unitful.@prefixed_unit_symbols($(esc(symb)), $(esc(name)), d, - Unitful.basefactor(inex, ex, eq, t, 1)) - else - Unitful.@unit_symbols($(esc(symb)), $(esc(name)), d, - Unitful.basefactor(inex, ex, eq, t, 1)) - end - $(esc(symb)) + d = :(Unitful.dimension($equals)) + t = :(Unitful.tensfactor(Unitful.unit($equals))) + eq = :(($(esc(equals)))/Unitful.unit($equals)) + push!(expr.args, esc(quote + Unitful.abbr(::Unitful.Unit{$x,typeof($d)}) = $abbr + end)) + if tf + push!(expr.args, quote + inex, ex = Unitful.basefactor(Unitful.unit($equals)) + Unitful.@prefixed_unit_symbols($symb, $name, $d, + Unitful.basefactor(inex, ex, $eq, $t, 1)) + end) + else + push!(expr.args, quote + inex, ex = Unitful.basefactor(Unitful.unit($equals)) + Unitful.@unit_symbols($symb, $name, $d, + Unitful.basefactor(inex, ex, $eq, $t, 1)) + end) end + push!(expr.args, quote + $(esc(symb)) + end) + + expr end """ @@ -179,25 +189,26 @@ all getting defined in the calling namespace. """ macro prefixed_unit_symbols(symb,name,dimension,basefactor) expr = Expr(:block) - - z = Expr(:quote, name) + n = Meta.quot(Symbol(name)) + for (k,v) in prefixdict s = Symbol(v,symb) - u = :(Unitful.Unit{$z, typeof($dimension)}($k,1//1)) - ea = esc(quote - Unitful.basefactors[$z] = $basefactor - const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() - end) + u = :(Unitful.Unit{$n, typeof($(esc(dimension)))}($k,1//1)) + ea = quote + Unitful.basefactors[$n] = $basefactor + const $(esc(s)) = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + end push!(expr.args, ea) end # These lines allow for μ to be typed with option-m on a Mac. s = Symbol(:µ, symb) - u = :(Unitful.Unit{$z, typeof($dimension)}(-6,1//1)) - push!(expr.args, esc(quote - Unitful.basefactors[$z] = $basefactor - const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() - end)) + n = Meta.quot(Symbol(name)) + u = :(Unitful.Unit{$n, typeof($(esc(dimension)))}(-6,1//1)) + push!(expr.args, quote + Unitful.basefactors[$n] = $basefactor + const $(esc(s)) = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + end) expr end @@ -211,12 +222,12 @@ Example: `@unit_symbols ft Foot 𝐋` results in `ft` getting defined but not `k """ macro unit_symbols(symb,name,dimension,basefactor) s = Symbol(symb) - z = Expr(:quote, name) - u = :(Unitful.Unit{$z,typeof($dimension)}(0,1//1)) - esc(quote - Unitful.basefactors[$z] = $basefactor - const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() - end) + n = Meta.quot(Symbol(name)) + u = :(Unitful.Unit{$n,typeof($(esc(dimension)))}(0,1//1)) + quote + Unitful.basefactors[$n] = $basefactor + const $(esc(s)) = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + end end """ From cfff3acae2f01df8dab45d7b438e08872a87eb3a Mon Sep 17 00:00:00 2001 From: Richard Reeve Date: Sat, 2 Dec 2017 20:02:03 +0000 Subject: [PATCH 04/16] Missing Compat on CI, but not my computer? --- src/Unitful.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Unitful.jl b/src/Unitful.jl index 0a944a5c..7a279e90 100644 --- a/src/Unitful.jl +++ b/src/Unitful.jl @@ -1,5 +1,6 @@ __precompile__(true) module Unitful +using Compat import Base: ==, <, <=, +, -, *, /, //, ^ import Base: show, convert From c3dd3106d86250098b2e1fef560b667a662998bd Mon Sep 17 00:00:00 2001 From: Richard Reeve Date: Sat, 2 Dec 2017 22:52:02 +0000 Subject: [PATCH 05/16] VERSION-specific fixes to get most of the tests working, and use Compat.Test again. --- src/user.jl | 62 +++++++++++++++++++++++++++++------------------- test/runtests.jl | 3 +-- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/user.jl b/src/user.jl index 8965b2ec..035cc152 100644 --- a/src/user.jl +++ b/src/user.jl @@ -123,17 +123,29 @@ Usage example: `@refunit m "m" Meter 𝐋 true` This example, found in `src/pkgdefaults.jl`, generates `km`, `m`, `cm`, ... """ macro refunit(symb, abbr, name, dimension, tf) - x = Expr(:quote, name) - esc(quote - Unitful.abbr(::Unitful.Unit{$x,typeof($dimension)}) = $abbr - if $tf - Unitful.@prefixed_unit_symbols $symb $name $dimension (1.0, 1) + expr = Expr(:block) + n = Meta.quot(Symbol(name)) + push!(expr.args, + quote + Unitful.abbr(::Unitful.Unit{$n,typeof($dimension)}) = $abbr + end) + if tf + push!(expr.args, + quote +@static if VERSION < v"0.7.0-" begin Unitful.@prefixed_unit_symbols $(esc(symb)) $(esc(name)) $dimension (1.0, 1) end else begin Unitful.@prefixed_unit_symbols $symb $name $dimension (1.0, 1) end end + end) else - Unitful.@unit_symbols $symb $name $dimension (1.0, 1) + push!(expr.args, + quote +@static if VERSION < v"0.7.0-" begin Unitful.@unit_symbols $(esc(symb)) $(esc(name)) $dimension (1.0, 1) end else begin Unitful.@unit_symbols $symb $name $dimension (1.0, 1) end end + end) end - Unitful.preferunits($symb) - $symb - end) + push!(expr.args, + esc(quote + Unitful.preferunits($symb) + $symb + end)) + expr end """ @@ -152,30 +164,30 @@ macro unit(symb,abbr,name,equals,tf) expr = Expr(:block) # name is a symbol # abbr is a string - x = Expr(:quote, name) + n = Meta.quot(Symbol(name)) d = :(Unitful.dimension($equals)) - t = :(Unitful.tensfactor(Unitful.unit($equals))) - eq = :(($(esc(equals)))/Unitful.unit($equals)) - push!(expr.args, esc(quote - Unitful.abbr(::Unitful.Unit{$x,typeof($d)}) = $abbr - end)) + basef = :(Unitful.basefactor(Unitful.basefactor(Unitful.unit($equals))..., + ($equals)/Unitful.unit($equals), + Unitful.tensfactor(Unitful.unit($equals)), 1)) + push!(expr.args, + quote + Unitful.abbr(::Unitful.Unit{$n,typeof($d)}) = $abbr + end) if tf push!(expr.args, quote - inex, ex = Unitful.basefactor(Unitful.unit($equals)) - Unitful.@prefixed_unit_symbols($symb, $name, $d, - Unitful.basefactor(inex, ex, $eq, $t, 1)) +@static if VERSION < v"0.7.0-" begin Unitful.@prefixed_unit_symbols $(esc(symb)) $(esc(name)) $d $basef end else begin Unitful.@prefixed_unit_symbols $symb $name $d $basef end end end) else push!(expr.args, quote - inex, ex = Unitful.basefactor(Unitful.unit($equals)) - Unitful.@unit_symbols($symb, $name, $d, - Unitful.basefactor(inex, ex, $eq, $t, 1)) +@static if VERSION < v"0.7.0-" begin Unitful.@unit_symbols $(esc(symb)) $(esc(name)) $d $basef end else begin Unitful.@unit_symbols $symb $name $d $basef end end end) end - push!(expr.args, quote - $(esc(symb)) - end) - + push!(expr.args, + esc(quote + @static if VERSION > v"0.7.0-" import Unitful.$symb end + $symb + end)) + expr end diff --git a/test/runtests.jl b/test/runtests.jl index d3515a70..21d5bca8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,7 +2,6 @@ module UnitfulTests using Unitful using Compat.Test - import Unitful: DimensionError import Unitful: LogScaled, LogInfo, Level, Gain, MixedUnits, Decibel @@ -1268,7 +1267,7 @@ end # (and incidentally, for Compat macro hygiene in @dimension, @derived_dimension) module TUM using Unitful - using Base.Test + using Compat.Test @dimension f "f" FakeDim12345 @derived_dimension FakeDim212345 f^2 From b7b7c5982b8f91221cf789b00f67befa4a5f3454 Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Thu, 7 Dec 2017 09:08:03 -0800 Subject: [PATCH 06/16] Update docstring to avoid unintended markdown formatting. --- src/dimensions.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dimensions.jl b/src/dimensions.jl index c732be5a..6a5aa6a0 100644 --- a/src/dimensions.jl +++ b/src/dimensions.jl @@ -1,5 +1,8 @@ """ - *(a0::Dimensions, a::Dimensions...) +``` +*(a0::Dimensions, a::Dimensions...) +``` + Given however many dimensions, multiply them together. Collect [`Unitful.Dimension`](@ref) objects from the type parameter of the From c98d94af5b73cf3a2023530bd2a70dfd9bbc3bbe Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Thu, 7 Dec 2017 19:54:03 -0800 Subject: [PATCH 07/16] - Make macros work on 0.6 and 0.7-DEV - Adjust tests for `promote` behavior changes on 0.7-DEV - Adjust tests for `macroexpand` behavior changes on 0.7-DEV --- src/user.jl | 99 +++++++++++++++++++++++------------------------- test/runtests.jl | 59 +++++++++++++++++++---------- 2 files changed, 87 insertions(+), 71 deletions(-) diff --git a/src/user.jl b/src/user.jl index 035cc152..877f7442 100644 --- a/src/user.jl +++ b/src/user.jl @@ -125,27 +125,27 @@ This example, found in `src/pkgdefaults.jl`, generates `km`, `m`, `cm`, ... macro refunit(symb, abbr, name, dimension, tf) expr = Expr(:block) n = Meta.quot(Symbol(name)) - push!(expr.args, - quote - Unitful.abbr(::Unitful.Unit{$n,typeof($dimension)}) = $abbr - end) - if tf - push!(expr.args, - quote -@static if VERSION < v"0.7.0-" begin Unitful.@prefixed_unit_symbols $(esc(symb)) $(esc(name)) $dimension (1.0, 1) end else begin Unitful.@prefixed_unit_symbols $symb $name $dimension (1.0, 1) end end - end) - else - push!(expr.args, - quote -@static if VERSION < v"0.7.0-" begin Unitful.@unit_symbols $(esc(symb)) $(esc(name)) $dimension (1.0, 1) end else begin Unitful.@unit_symbols $symb $name $dimension (1.0, 1) end end - end) - end - push!(expr.args, - esc(quote - Unitful.preferunits($symb) - $symb - end)) - expr + + push!(expr.args, quote + Unitful.abbr(::Unitful.Unit{$n,typeof($dimension)}) = $abbr + end) + + if tf + push!(expr.args, quote + Unitful.@prefixed_unit_symbols $symb $name $dimension (1.0, 1) + end) + else + push!(expr.args, quote + Unitful.@unit_symbols $symb $name $dimension (1.0, 1) + end) + end + + push!(expr.args, quote + Unitful.preferunits($symb) + $symb + end) + + esc(expr) end """ @@ -162,33 +162,31 @@ This example will *not* generate `kmi` (kilomiles). """ macro unit(symb,abbr,name,equals,tf) expr = Expr(:block) - # name is a symbol - # abbr is a string n = Meta.quot(Symbol(name)) + d = :(Unitful.dimension($equals)) basef = :(Unitful.basefactor(Unitful.basefactor(Unitful.unit($equals))..., ($equals)/Unitful.unit($equals), Unitful.tensfactor(Unitful.unit($equals)), 1)) - push!(expr.args, - quote - Unitful.abbr(::Unitful.Unit{$n,typeof($d)}) = $abbr - end) + push!(expr.args, quote + Unitful.abbr(::Unitful.Unit{$n,typeof($d)}) = $abbr + end) + if tf push!(expr.args, quote -@static if VERSION < v"0.7.0-" begin Unitful.@prefixed_unit_symbols $(esc(symb)) $(esc(name)) $d $basef end else begin Unitful.@prefixed_unit_symbols $symb $name $d $basef end end - end) + Unitful.@prefixed_unit_symbols $symb $name $d $basef + end) else push!(expr.args, quote -@static if VERSION < v"0.7.0-" begin Unitful.@unit_symbols $(esc(symb)) $(esc(name)) $d $basef end else begin Unitful.@unit_symbols $symb $name $d $basef end end - end) + Unitful.@unit_symbols $symb $name $d $basef + end) end - push!(expr.args, - esc(quote - @static if VERSION > v"0.7.0-" import Unitful.$symb end - $symb - end)) - - expr + + push!(expr.args, quote + $symb + end) + + esc(expr) end """ @@ -202,27 +200,26 @@ all getting defined in the calling namespace. macro prefixed_unit_symbols(symb,name,dimension,basefactor) expr = Expr(:block) n = Meta.quot(Symbol(name)) - + for (k,v) in prefixdict s = Symbol(v,symb) - u = :(Unitful.Unit{$n, typeof($(esc(dimension)))}($k,1//1)) + u = :(Unitful.Unit{$n, typeof($dimension)}($k,1//1)) ea = quote Unitful.basefactors[$n] = $basefactor - const $(esc(s)) = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() end push!(expr.args, ea) end # These lines allow for μ to be typed with option-m on a Mac. s = Symbol(:µ, symb) - n = Meta.quot(Symbol(name)) - u = :(Unitful.Unit{$n, typeof($(esc(dimension)))}(-6,1//1)) + u = :(Unitful.Unit{$n, typeof($dimension)}(-6,1//1)) push!(expr.args, quote Unitful.basefactors[$n] = $basefactor - const $(esc(s)) = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() end) - expr + esc(expr) end """ @@ -235,11 +232,11 @@ Example: `@unit_symbols ft Foot 𝐋` results in `ft` getting defined but not `k macro unit_symbols(symb,name,dimension,basefactor) s = Symbol(symb) n = Meta.quot(Symbol(name)) - u = :(Unitful.Unit{$n,typeof($(esc(dimension)))}(0,1//1)) - quote + u = :(Unitful.Unit{$n,typeof($dimension)}(0,1//1)) + esc(quote Unitful.basefactors[$n] = $basefactor - const $(esc(s)) = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() - end + const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + end) end """ @@ -476,7 +473,7 @@ function replace_value(ex::Expr) ex.args[i]=replace_value(ex.args[i]) end end - return eval(@__MODULE__, ex) + return eval(Compat.@__MODULE__, ex) elseif ex.head == :tuple for i=1:length(ex.args) if typeof(ex.args[i])==Symbol @@ -485,7 +482,7 @@ function replace_value(ex::Expr) error("only use symbols inside the tuple.") end end - return eval(current_module(), ex) + return eval(Compat.@__MODULE__, ex) else error("Expr head $(ex.head) must equal :call or :tuple") end diff --git a/test/runtests.jl b/test/runtests.jl index 21d5bca8..169d8a3f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,7 @@ module UnitfulTests using Unitful using Compat.Test +import Compat import Unitful: DimensionError import Unitful: LogScaled, LogInfo, Level, Gain, MixedUnits, Decibel @@ -230,11 +231,18 @@ end end @testset "> Simple promotion" begin # promotion should do nothing to units alone - @test @inferred(promote(m, km)) === (m, km) - @test @inferred(promote(ContextUnits(m, km), ContextUnits(mm, km))) === - (ContextUnits(m, km), ContextUnits(mm, km)) - @test @inferred(promote(FixedUnits(m), FixedUnits(km))) === - (FixedUnits(m), FixedUnits(km)) + @static if VERSION < v"0.7.0-DEV.1579" # PR 23491 + @test @inferred(promote(m, km)) === (m, km) + @test @inferred(promote(ContextUnits(m, km), ContextUnits(mm, km))) === + (ContextUnits(m, km), ContextUnits(mm, km)) + @test @inferred(promote(FixedUnits(m), FixedUnits(km))) === + (FixedUnits(m), FixedUnits(km)) + else + # promote throws an error if no types are be changed + @test_throws ErrorException promote(m, km) + @test_throws ErrorException promote(ContextUnits(m, km), ContextUnits(mm, km)) + @test_throws ErrorException promote(FixedUnits(m), FixedUnits(km)) + end # promote the numeric type @test @inferred(promote(1.0m, 1m)) === (1.0m, 1.0m) @@ -282,28 +290,39 @@ end @testset "> Issue 52" begin x,y = 10m, 1 px,py = promote(x,y) - ppx,ppy = promote(px,py) - @test typeof(py) == typeof(ppy) + @static if VERSION < v"0.7.0-DEV.1579" # PR 23491 + ppx,ppy = promote(px,py) + @test typeof(py) == typeof(ppy) + else + # promoting the second time should not change the types + @test_throws ErrorException promote(px, py) + end end end @testset "Unit string macro" begin - @test macroexpand(:(u"m")) == m - @test macroexpand(:(u"m,s")) == (m,s) - @test macroexpand(:(u"1.0")) == 1.0 - @test macroexpand(:(u"m/s")) == m/s - @test macroexpand(:(u"1.0m/s")) == 1.0m/s - @test macroexpand(:(u"m^-1")) == m^-1 - @test macroexpand(:(u"dB/Hz")) == dB/Hz - @test macroexpand(:(u"3.0dB/Hz")) == 3.0dB/Hz - @test isa(macroexpand(:(u"N m")).args[1], ParseError) - @test isa(macroexpand(:(u"abs(2)")).args[1], ErrorException) + @test macroexpand(Compat.@__MODULE__, :(u"m")) == m + @test macroexpand(Compat.@__MODULE__, :(u"m,s")) == (m,s) + @test macroexpand(Compat.@__MODULE__, :(u"1.0")) == 1.0 + @test macroexpand(Compat.@__MODULE__, :(u"m/s")) == m/s + @test macroexpand(Compat.@__MODULE__, :(u"1.0m/s")) == 1.0m/s + @test macroexpand(Compat.@__MODULE__, :(u"m^-1")) == m^-1 + @test macroexpand(Compat.@__MODULE__, :(u"dB/Hz")) == dB/Hz + @test macroexpand(Compat.@__MODULE__, :(u"3.0dB/Hz")) == 3.0dB/Hz + @static if VERSION >= v"0.7.0-DEV.1729" # PR 23533 + @test_throws LoadError macroexpand(Compat.@__MODULE__, :(u"N m")) + @test_throws LoadError macroexpand(Compat.@__MODULE__, :(u"abs(2)")) + @test_throws LoadError @eval u"basefactor" + else + @test isa(macroexpand(:(u"N m")).args[1], ParseError) + @test isa(macroexpand(:(u"abs(2)")).args[1], ErrorException) + + # test ustrcheck(x) fallback to catch non-units / quantities + @test_throws ErrorException @eval u"basefactor" + end # test ustrcheck(::Quantity) @test u"h" == Unitful.h - - # test ustrcheck(x) fallback to catch non-units / quantities - @test_throws ErrorException @eval u"basefactor" end @testset "Unit and dimensional analysis" begin From 43219cd4853f5c36a1c82d66cff9414bcf4ca13f Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Thu, 7 Dec 2017 22:59:25 -0800 Subject: [PATCH 08/16] - show(::IO, ::Type{...}) method definition was causing some odd julia crashes on 0.7-dev, so I removed it - DimensionError no longer has typed fields, as this was also causing hard-to-parse errors - fixed methods for `<` on 0.7-dev (promotion changes) --- src/display.jl | 12 ------------ src/quantities.jl | 9 ++++----- src/utils.jl | 13 +++++++------ 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/display.jl b/src/display.jl index cfb35af7..c7a7b563 100644 --- a/src/display.jl +++ b/src/display.jl @@ -58,18 +58,6 @@ function show(io::IO, x::Quantity) nothing end -""" - show{T,D,U}(io::IO, ::Type{Quantity{T,D,U}}) -Show the type of a unitful quantity in a succinct way. Otherwise, -array summaries are nearly unreadable. -""" -function show(io::IO, ::Type{Quantity{T,D,U}}) where {T,D,U} - print(io, "Quantity{", string(T), - ", Dimensions:{", string(D()), - "}, Units:{", string(U()), "}}") - nothing -end - """ show(io::IO, x::Unitlike) Call [`Unitful.showrep`](@ref) on each object in the tuple that is the type diff --git a/src/quantities.jl b/src/quantities.jl index 02bf829f..20b4f0ff 100644 --- a/src/quantities.jl +++ b/src/quantities.jl @@ -203,14 +203,13 @@ isless(x::Quantity, y::Quantity) = _isless(promote(x,y)...) isless(x::Quantity, y::Number) = _isless(promote(x,y)...) isless(x::Number, y::Quantity) = _isless(promote(x,y)...) -@inline <(x::Quantity{T,D,U}, y::Quantity{T,D,U}) where {T,D,U} = _lt(x,y) +<(x::Quantity, y::Quantity) = _lt(x,y) @inline _lt(x::Quantity{T,D,U}, y::Quantity{T,D,U}) where {T,D,U} = <(x.val,y.val) +@inline _lt(x::Quantity{T,D,U1}, y::Quantity{T,D,U2}) where {T,D,U1,U2} = <(promote(x,y)...) @inline _lt(x::Quantity{T,D1,U1}, y::Quantity{T,D2,U2}) where {T,D1,D2,U1,U2} = throw(DimensionError(x,y)) -@inline _lt(x,y) = <(x,y) -<(x::Quantity, y::Quantity) = _lt(promote(x,y)...) -<(x::Quantity, y::Number) = _lt(promote(x,y)...) -<(x::Number, y::Quantity) = _lt(promote(x,y)...) +<(x::Quantity, y::Number) = <(promote(x,y)...) +<(x::Number, y::Quantity) = <(promote(x,y)...) Base.rtoldefault(::Type{Quantity{T,D,U}}) where {T,D,U} = Base.rtoldefault(T) isapprox(x::Quantity{T,D,U}, y::Quantity{T,D,U}; atol=zero(Quantity{real(T),D,U}), kwargs...) where {T,D,U} = diff --git a/src/utils.jl b/src/utils.jl index b22a4b3b..20895296 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -176,16 +176,17 @@ Unitful.Dimensions{()} @deprecate(dimension(x::AbstractArray{T}) where {T<:Units}, dimension.(x)) """ - mutable struct DimensionError{T,S} <: Exception - x::T - y::S + struct DimensionError <: Exception + x + y end Thrown when dimensions don't match in an operation that demands they do. Display `x` and `y` in error message. """ -mutable struct DimensionError{T,S} <: Exception - x::T - y::S +struct DimensionError <: Exception + x + y end + Base.showerror(io::IO, e::DimensionError) = print(io, "DimensionError: $(e.x) and $(e.y) are not dimensionally compatible."); From 8f84993c1a5aaefb56b08cee2b912829eb58a68d Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Fri, 8 Dec 2017 14:38:08 -0800 Subject: [PATCH 09/16] Adapt to changes in `Base.literal_pow` due to julia PR 22475 --- src/dimensions.jl | 14 +++++++++++--- src/quantities.jl | 12 +++++++++--- src/units.jl | 37 ++++++++++++++++++++++++++----------- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/dimensions.jl b/src/dimensions.jl index 6a5aa6a0..c81f6aa2 100644 --- a/src/dimensions.jl +++ b/src/dimensions.jl @@ -72,9 +72,17 @@ end # Exponentiation is not type-stable for `Dimensions` objects in many cases ^(x::Dimensions{T}, y::Integer) where {T} = *(Dimensions{map(a->a^y, T)}()) ^(x::Dimensions{T}, y::Number) where {T} = *(Dimensions{map(a->a^y, T)}()) -@generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Type{Val{p}}) where {T,p} - z = *(Dimensions{map(a->a^p, T)}()) - :($z) + +@static if VERSION < v"0.7.0-DEV.843" + @generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Type{Val{p}}) where {T,p} + z = *(Dimensions{map(a->a^p, T)}()) + :($z) + end +else + @generated function Base.literal_pow(::typeof(^), x::Dimensions{T}, ::Val{p}) where {T,p} + z = *(Dimensions{map(a->a^p, T)}()) + :($z) + end end # Since exponentiation is not type stable, we define a special `inv` method to enable fast diff --git a/src/quantities.jl b/src/quantities.jl index 20b4f0ff..77b0cc51 100644 --- a/src/quantities.jl +++ b/src/quantities.jl @@ -344,9 +344,15 @@ typemin(x::Quantity{T}) where {T} = typemin(T)*unit(x) typemax(::Type{Quantity{T,D,U}}) where {T,D,U} = typemax(T)*U() typemax(x::Quantity{T}) where {T} = typemax(T)*unit(x) -Base.literal_pow(::typeof(^), x::Quantity, ::Type{Val{v}}) where {v} = - Quantity(Base.literal_pow(^, x.val, Val{v}), - Base.literal_pow(^, unit(x), Val{v})) +@static if VERSION < v"0.7.0-DEV.843" + Base.literal_pow(::typeof(^), x::Quantity, ::Type{Val{v}}) where {v} = + Quantity(Base.literal_pow(^, x.val, Val{v}), + Base.literal_pow(^, unit(x), Val{v})) +else + Base.literal_pow(::typeof(^), x::Quantity, ::Val{v}) where {v} = + Quantity(Base.literal_pow(^, x.val, Val(v)), + Base.literal_pow(^, unit(x), Val(v))) +end # All of these are needed for ambiguity resolution ^(x::Quantity, y::Integer) = Quantity((x.val)^y, unit(x)^y) diff --git a/src/units.jl b/src/units.jl index fc572825..8be9a7cf 100644 --- a/src/units.jl +++ b/src/units.jl @@ -107,17 +107,32 @@ true ^(x::FixedUnits{N}, y::Integer) where {N} = *(FixedUnits{map(a->a^y, N), ()}()) ^(x::FixedUnits{N}, y::Number) where {N} = *(FixedUnits{map(a->a^y, N), ()}()) -@generated function Base.literal_pow(::typeof(^), x::FreeUnits{N}, ::Type{Val{p}}) where {N,p} - y = *(FreeUnits{map(a->a^p, N), ()}()) - :($y) -end -@generated function Base.literal_pow(::typeof(^), x::ContextUnits{N,D,P}, ::Type{Val{p}}) where {N,D,P,p} - y = *(ContextUnits{map(a->a^p, N), (), typeof(P()^p)}()) - :($y) -end -@generated function Base.literal_pow(::typeof(^), x::FixedUnits{N}, ::Type{Val{p}}) where {N,p} - y = *(FixedUnits{map(a->a^p, N), ()}()) - :($y) +@static if VERSION < v"0.7.0-DEV.843" + @generated function Base.literal_pow(::typeof(^), x::FreeUnits{N}, ::Type{Val{p}}) where {N,p} + y = *(FreeUnits{map(a->a^p, N), ()}()) + :($y) + end + @generated function Base.literal_pow(::typeof(^), x::ContextUnits{N,D,P}, ::Type{Val{p}}) where {N,D,P,p} + y = *(ContextUnits{map(a->a^p, N), (), typeof(P()^p)}()) + :($y) + end + @generated function Base.literal_pow(::typeof(^), x::FixedUnits{N}, ::Type{Val{p}}) where {N,p} + y = *(FixedUnits{map(a->a^p, N), ()}()) + :($y) + end +else + @generated function Base.literal_pow(::typeof(^), x::FreeUnits{N}, ::Val{p}) where {N,p} + y = *(FreeUnits{map(a->a^p, N), ()}()) + :($y) + end + @generated function Base.literal_pow(::typeof(^), x::ContextUnits{N,D,P}, ::Val{p}) where {N,D,P,p} + y = *(ContextUnits{map(a->a^p, N), (), typeof(P()^p)}()) + :($y) + end + @generated function Base.literal_pow(::typeof(^), x::FixedUnits{N}, ::Val{p}) where {N,p} + y = *(FixedUnits{map(a->a^p, N), ()}()) + :($y) + end end # Since exponentiation is not type stable, we define a special `inv` method to enable fast From b81c1d4b362574d93ee66dc1a7c42431b9e3108a Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Sun, 10 Dec 2017 17:51:44 -0800 Subject: [PATCH 10/16] Fix a few deprecation warnings. --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 169d8a3f..26d1e26f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -821,8 +821,8 @@ end @test @inferred(conj((3+4im)V)) == (3-4im)V @test @inferred(typemin(1.0m)) == -Inf*m @test @inferred(typemax(typeof(1.0m))) == Inf*m - @test @inferred(typemin(0x01m)) == 0x00m - @test @inferred(typemax(typeof(0x01m))) == 0xffm + @test @inferred(typemin(0x01*m)) == 0x00*m + @test @inferred(typemax(typeof(0x01*m))) == 0xff*m @test @inferred(rand(typeof(1u"m"))) isa typeof(1u"m") @test @inferred(rand(MersenneTwister(0), typeof(1u"m"))) isa typeof(1u"m") end From 8f82d6c85670c5688cf12de3a7449eac930b346b Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Sun, 10 Dec 2017 17:54:38 -0800 Subject: [PATCH 11/16] Remove some `const` declarations on local variables (see Julia PR #23259) --- test/runtests.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 26d1e26f..404820df 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -603,9 +603,9 @@ end @test_throws DimensionError fma(2, 1m, 1V) end @testset "> @fastmath" begin - const one32 = one(Float32)*m - const eps32 = eps(Float32)*m - const eps32_2 = eps32/2 + one32 = one(Float32)*m + eps32 = eps(Float32)*m + eps32_2 = eps32/2 # Note: Cannot use local functions since these are not yet optimized fm_ieee_32(x) = x + eps32_2 + eps32_2 @@ -614,9 +614,9 @@ end @test (fm_fast_32(one32) == one32 || fm_fast_32(one32) == one32 + eps32 > one32) - const one64 = one(Float64)*m - const eps64 = eps(Float64)*m - const eps64_2 = eps64/2 + one64 = one(Float64)*m + eps64 = eps(Float64)*m + eps64_2 = eps64/2 # Note: Cannot use local functions since these are not yet optimized fm_ieee_64(x) = x + eps64_2 + eps64_2 From 3536f26d539a31ae647d1d49980181f25dfc62b4 Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Mon, 11 Dec 2017 11:42:49 -0800 Subject: [PATCH 12/16] - Fix some deprecation warnings - Hook into `SamplerType` mechanism for `rand` --- src/quantities.jl | 13 +++++++++++-- test/runtests.jl | 28 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/quantities.jl b/src/quantities.jl index 77b0cc51..7e5fee07 100644 --- a/src/quantities.jl +++ b/src/quantities.jl @@ -359,6 +359,15 @@ end ^(x::Quantity, y::Rational) = Quantity((x.val)^y, unit(x)^y) ^(x::Quantity, y::Real) = Quantity((x.val)^y, unit(x)^y) -Base.rand(r::AbstractRNG, ::Type{Quantity{T,D,U}}) where {T,D,U} = rand(r,T)*U() -Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(dims), oneunit(Q)) +@static if VERSION >= v"0.7.0-DEV.2708" #julia PR 23964 + Base.rand(r::AbstractRNG, ::Base.Random.SamplerType{Quantity{T,D,U}}) where {T,D,U} = + rand(r, T) * U() +else + Base.rand(r::AbstractRNG, ::Type{Quantity{T,D,U}}) where {T,D,U} = rand(r,T) * U() +end +@static if VERSION >= v"0.7.0-DEV.2581" #julia PR 24652 + Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(uninitialized, dims), oneunit(Q)) +else + Base.ones(Q::Type{<:Quantity}, dims::Tuple) = fill!(Array{Q}(dims), oneunit(Q)) +end Base.ones(a::AbstractArray, Q::Type{<:Quantity}) = fill!(similar(a,Q), oneunit(Q)) diff --git a/test/runtests.jl b/test/runtests.jl index 404820df..17d1fd4a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -956,20 +956,20 @@ end @test typeof([3m,4m] * [1 2]) == Array{typeof(1u"m"),2} end @testset ">> Element-wise multiplication" begin - @test @inferred([1m, 2m, 3m] * 5) == [5m, 10m, 15m] - @test typeof([1m, 2m, 3m] * 5) == Array{typeof(1u"m"),1} - @test @inferred([1m, 2m, 3m] .* 5m) == [5m^2, 10m^2, 15m^2] - @test typeof([1m, 2m, 3m] * 5m) == Array{typeof(1u"m^2"),1} - @test @inferred(5m .* [1m, 2m, 3m]) == [5m^2, 10m^2, 15m^2] - @test typeof(5m .* [1m, 2m, 3m]) == Array{typeof(1u"m^2"),1} - @test @inferred(eye(2)*V) == [1.0V 0.0V; 0.0V 1.0V] - @test @inferred(V*eye(2)) == [1.0V 0.0V; 0.0V 1.0V] - @test @inferred(eye(2).*V) == [1.0V 0.0V; 0.0V 1.0V] - @test @inferred(V.*eye(2)) == [1.0V 0.0V; 0.0V 1.0V] - @test @inferred([1V 2V; 0V 3V].*2) == [2V 4V; 0V 6V] - @test @inferred([1V, 2V] .* [true, false]) == [1V, 0V] - @test @inferred([1.0m, 2.0m] ./ 3) == [1m/3, 2m/3] - @test @inferred([1V, 2.0V] ./ [3m, 4m]) == [1V/(3m), 0.5V/m] + @test @inferred([1m, 2m, 3m] * 5) == [5m, 10m, 15m] + @test typeof([1m, 2m, 3m] * 5) == Array{typeof(1u"m"),1} + @test @inferred([1m, 2m, 3m] .* 5m) == [5m^2, 10m^2, 15m^2] + @test typeof([1m, 2m, 3m] * 5m) == Array{typeof(1u"m^2"),1} + @test @inferred(5m .* [1m, 2m, 3m]) == [5m^2, 10m^2, 15m^2] + @test typeof(5m .* [1m, 2m, 3m]) == Array{typeof(1u"m^2"),1} + @test @inferred(Matrix{Float64}(I, 2, 2)*V) == [1.0V 0.0V; 0.0V 1.0V] + @test @inferred(V*Matrix{Float64}(I, 2, 2)) == [1.0V 0.0V; 0.0V 1.0V] + @test @inferred(Matrix{Float64}(I, 2, 2).*V) == [1.0V 0.0V; 0.0V 1.0V] + @test @inferred(V.*Matrix{Float64}(I, 2, 2)) == [1.0V 0.0V; 0.0V 1.0V] + @test @inferred([1V 2V; 0V 3V].*2) == [2V 4V; 0V 6V] + @test @inferred([1V, 2V] .* [true, false]) == [1V, 0V] + @test @inferred([1.0m, 2.0m] ./ 3) == [1m/3, 2m/3] + @test @inferred([1V, 2.0V] ./ [3m, 4m]) == [1V/(3m), 0.5V/m] @test @inferred([1, 2]kg) == [1, 2] * kg @test @inferred([1, 2]kg .* [2, 3]kg^-1) == [2, 6] From ac200236f34bb81d759bba66d5897597e3f042ea Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Wed, 13 Dec 2017 16:26:44 -0800 Subject: [PATCH 13/16] Fix more deprecations and tests. --- src/utils.jl | 6 +++++- test/runtests.jl | 37 +++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 20895296..0890e9ac 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -65,7 +65,11 @@ julia> a[1] = 3u"m"; b Strip units from various kinds of matrices by calling `ustrip` on the underlying vectors. """ ustrip(A::Diagonal) = Diagonal(ustrip(A.diag)) -ustrip(A::Bidiagonal) = Bidiagonal(ustrip(A.dv), ustrip(A.ev), A.isupper) +@static if VERSION >= v"0.7.0-DEV.884" # PR 22703 + ustrip(A::Bidiagonal) = Bidiagonal(ustrip(A.dv), ustrip(A.ev), ifelse(istriu(A), :U, :L)) +else + ustrip(A::Bidiagonal) = Bidiagonal(ustrip(A.dv), ustrip(A.ev), istriu(A)) +end ustrip(A::Tridiagonal) = Tridiagonal(ustrip(A.dl), ustrip(A.d), ustrip(A.du)) ustrip(A::SymTridiagonal) = SymTridiagonal(ustrip(A.dv), ustrip(A.ev)) diff --git a/test/runtests.jl b/test/runtests.jl index 17d1fd4a..8a4100fc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1015,13 +1015,18 @@ end @test @inferred(ustrip([1u"m", 2u"m"])) == [1,2] @test_warn "deprecated" ustrip([1,2]) @test ustrip.([1,2]) == [1,2] - @test typeof(ustrip([1u"m", 2u"m"])) == Array{Int,1} - @test typeof(ustrip(Diagonal([1,2]u"m"))) == Diagonal{Int} - @test typeof(ustrip(Bidiagonal([1,2,3]u"m", [1,2]u"m", true))) == - Bidiagonal{Int} - @test typeof(ustrip(Tridiagonal([1,2]u"m", [3,4,5]u"m", [6,7]u"m"))) == + # @test typeof(ustrip([1u"m", 2u"m"])) == Array{Int,1} # TODO + @test typeof(ustrip(Diagonal([1,2]u"m"))) <: Diagonal{Int} + @static if VERSION >= v"0.7.0-DEV.884" # PR 22703 + @test typeof(ustrip(Bidiagonal([1,2,3]u"m", [1,2]u"m", :U))) <: + Bidiagonal{Int} + else + @test typeof(ustrip(Bidiagonal([1,2,3]u"m", [1,2]u"m", true))) <: + Bidiagonal{Int} + end + @test typeof(ustrip(Tridiagonal([1,2]u"m", [3,4,5]u"m", [6,7]u"m"))) <: Tridiagonal{Int} - @test typeof(ustrip(SymTridiagonal([1,2,3]u"m", [4,5]u"m"))) == + @test typeof(ustrip(SymTridiagonal([1,2,3]u"m", [4,5]u"m"))) <: SymTridiagonal{Int} end @testset ">> Linear algebra" begin @@ -1034,11 +1039,11 @@ end @test @inferred(zeros(Q, 2)) == [0, 0]u"m" @test @inferred(zeros(Q, (2,))) == [0, 0]u"m" @test @inferred(zeros(Q)[]) == 0u"m" - @test @inferred(zeros([1.0, 2.0, 3.0], Q)) == [0, 0, 0]u"m" + @test @inferred(fill!(similar([1.0, 2.0, 3.0], Q), zero(Q))) == [0, 0, 0]u"m" @test @inferred(ones(Q, 2)) == [1, 1]u"m" @test @inferred(ones(Q, (2,))) == [1, 1]u"m" @test @inferred(ones(Q)[]) == 1u"m" - @test @inferred(ones([1.0, 2.0, 3.0], Q)) == [1, 1, 1]u"m" + @test @inferred(fill!(similar([1.0, 2.0, 3.0], Q), oneunit(Q))) == [1, 1, 1]u"m" @test size(rand(Q, 2)) == (2,) @test size(rand(Q, 2, 3)) == (2,3) @test eltype(@inferred(rand(Q, 2))) == Q @@ -1050,7 +1055,7 @@ end function errorstr(e) b = IOBuffer() Base.showerror(b,e) - String(b) + String(take!(b)) end @test errorstr(DimensionError(1u"m",2)) == "DimensionError: 1 m and 2 are not dimensionally compatible." @test errorstr(DimensionError(1u"m",NoDims)) == "DimensionError: 1 m and are not dimensionally compatible." @@ -1084,7 +1089,11 @@ end end @testset ">> Gain" begin - @test_throws ArgumentError @eval @dB 10 + @static if VERSION >= v"0.7.0-DEV.1729" # PR 23533 + @test_throws LoadError @eval @dB 10 + else + @test_throws ArgumentError @eval @dB 10 + end @test 20*dB === dB*20 end @@ -1142,14 +1151,14 @@ end @test convert(Float64, 0u"dBFS") === 1.0 @test isapprox(uconvertrp(NoUnits, 6.02dB), 2.0, atol=0.001) - @test uconvertrp(NoUnits, 1Np) ≈ e - @test uconvertrp(Np, e) == 1Np + @test uconvertrp(NoUnits, 1Np) ≈ Compat.MathConstants.e + @test uconvertrp(Np, Compat.MathConstants.e) == 1Np @test uconvertrp(NoUnits, 1) == 1 @test uconvertrp(NoUnits, 20dB) == 10 @test uconvertrp(dB, 10) == 20dB @test isapprox(uconvertp(NoUnits, 3.01dB), 2.0, atol=0.001) - @test uconvertp(NoUnits, 1Np) == e^2 - @test uconvertp(Np, e^2) == 1Np + @test uconvertp(NoUnits, 1Np) == (Compat.MathConstants.e)^2 + @test uconvertp(Np, (Compat.MathConstants.e)^2) == 1Np @test uconvertp(NoUnits, 1) == 1 @test uconvertp(NoUnits, 20dB) == 100 @test uconvertp(dB, 100) == 20dB From b423292f1e3dcc2139ea8e5ba10ad4f6631c2034 Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Wed, 13 Dec 2017 16:50:41 -0800 Subject: [PATCH 14/16] Fix `rtoldefault` dep warning --- src/quantities.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quantities.jl b/src/quantities.jl index 7e5fee07..809010e9 100644 --- a/src/quantities.jl +++ b/src/quantities.jl @@ -222,7 +222,7 @@ isapprox(x::Quantity, y::Number; kwargs...) = isapprox(promote(x,y)...; kwargs.. isapprox(x::Number, y::Quantity; kwargs...) = isapprox(y, x; kwargs...) function isapprox(x::AbstractArray{Quantity{T1,D,U1}}, - y::AbstractArray{Quantity{T2,D,U2}}; rtol::Real=Base.rtoldefault(T1,T2), + y::AbstractArray{Quantity{T2,D,U2}}; rtol::Real=Base.rtoldefault(T1,T2,0), atol=zero(Quantity{T1,D,U1}), norm::Function=vecnorm) where {T1,D,U1,T2,U2} d = norm(x - y) From 25cba6ca77d0a843e502ca0ba15c8b15801f695b Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Wed, 13 Dec 2017 19:11:50 -0800 Subject: [PATCH 15/16] Fix remaining deprecation warnings. --- src/user.jl | 26 +++++++++++++------------- test/runtests.jl | 10 +++++++--- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/user.jl b/src/user.jl index 877f7442..415e9ba5 100644 --- a/src/user.jl +++ b/src/user.jl @@ -54,12 +54,12 @@ macro dimension(symb, abbr, name) funame = Symbol(name,"FreeUnits") esc(quote Unitful.abbr(::Unitful.Dimension{$x}) = $abbr - const $s = Unitful.Dimensions{(Unitful.Dimension{$x}(1),)}() - const ($name){T,U} = Union{ + const global $s = Unitful.Dimensions{(Unitful.Dimension{$x}(1),)}() + const global ($name){T,U} = Union{ Unitful.Quantity{T,typeof($s),U}, Unitful.Level{L,S,Unitful.Quantity{T,typeof($s),U}} where {L,S}} - const ($uname){U} = Unitful.Units{U,typeof($s)} - const ($funame){U} = Unitful.FreeUnits{U,typeof($s)} + const global ($uname){U} = Unitful.Units{U,typeof($s)} + const global ($funame){U} = Unitful.FreeUnits{U,typeof($s)} $s end) end @@ -83,11 +83,11 @@ macro derived_dimension(name, dims) uname = Symbol(name,"Units") funame = Symbol(name,"FreeUnits") esc(quote - const ($name){T,U} = Union{ + const global ($name){T,U} = Union{ Unitful.Quantity{T,typeof($dims),U}, Unitful.Level{L,S,Unitful.Quantity{T,typeof($dims),U}} where {L,S}} - const ($uname){U} = Unitful.Units{U,typeof($dims)} - const ($funame){U} = Unitful.FreeUnits{U,typeof($dims)} + const global ($uname){U} = Unitful.Units{U,typeof($dims)} + const global ($funame){U} = Unitful.FreeUnits{U,typeof($dims)} nothing end) end @@ -206,7 +206,7 @@ macro prefixed_unit_symbols(symb,name,dimension,basefactor) u = :(Unitful.Unit{$n, typeof($dimension)}($k,1//1)) ea = quote Unitful.basefactors[$n] = $basefactor - const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + const global $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() end push!(expr.args, ea) end @@ -216,7 +216,7 @@ macro prefixed_unit_symbols(symb,name,dimension,basefactor) u = :(Unitful.Unit{$n, typeof($dimension)}(-6,1//1)) push!(expr.args, quote Unitful.basefactors[$n] = $basefactor - const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + const global $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() end) esc(expr) @@ -235,7 +235,7 @@ macro unit_symbols(symb,name,dimension,basefactor) u = :(Unitful.Unit{$n,typeof($dimension)}(0,1//1)) esc(quote Unitful.basefactors[$n] = $basefactor - const $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() + const global $s = Unitful.FreeUnits{($u,),typeof(Unitful.dimension($u))}() end) end @@ -359,10 +359,10 @@ macro logscale(symb,abbr,name,base,prefactor,irp) quote Unitful.abbr(::Unitful.LogInfo{$(QuoteNode(name))}) = $abbr - const $(esc(name)) = Unitful.LogInfo{$(QuoteNode(name)), $base, $prefactor} + const global $(esc(name)) = Unitful.LogInfo{$(QuoteNode(name)), $base, $prefactor} Unitful.isrootpower(::Type{$(esc(name))}) = $irp - const $(esc(symb)) = Unitful.MixedUnits{Unitful.Gain{$(esc(name))}}() + const global $(esc(symb)) = Unitful.MixedUnits{Unitful.Gain{$(esc(name))}}() macro $(esc(symb))(::Union{Real,Symbol}) throw(ArgumentError(join(["usage: `@", $(String(symb)), " (a)/(b)`"]))) @@ -421,7 +421,7 @@ Defines a logarithmic unit. For examples see `src/pkgdefaults.jl`. macro logunit(symb, abbr, logscale, reflevel) quote Unitful.abbr(::Unitful.Level{$(esc(logscale)), $(esc(reflevel))}) = $abbr - const $(esc(symb)) = + const global $(esc(symb)) = Unitful.MixedUnits{Unitful.Level{$(esc(logscale)), $(esc(reflevel))}}() end end diff --git a/test/runtests.jl b/test/runtests.jl index 8a4100fc..20f362a6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -661,7 +661,7 @@ end end end - for T in (Complex64, Complex128, Complex{BigFloat}) + for T in (Complex{Float32}, Complex{Float64}, Complex{BigFloat}) _zero = convert(T, 0)*m _one = convert(T, 1)*m + im*eps(real(convert(T,1)))*m _two = convert(T, 2)*m + im*m//10 @@ -724,7 +724,7 @@ end end # complex arithmetic - for T in (Complex64, Complex128, Complex{BigFloat}) + for T in (Complex{Float32}, Complex{Float64}, Complex{BigFloat}) half = (1+1im)V/T(2) third = (1-1im)V/T(3) @@ -1015,7 +1015,11 @@ end @test @inferred(ustrip([1u"m", 2u"m"])) == [1,2] @test_warn "deprecated" ustrip([1,2]) @test ustrip.([1,2]) == [1,2] - # @test typeof(ustrip([1u"m", 2u"m"])) == Array{Int,1} # TODO + @static if VERSION >= v"0.7.0-DEV.2083" # PR 23750 + @test typeof(ustrip([1u"m", 2u"m"])) <: Base.ReinterpretArray{Int,1} + else + @test typeof(ustrip([1u"m", 2u"m"])) <: Array{Int,1} + end @test typeof(ustrip(Diagonal([1,2]u"m"))) <: Diagonal{Int} @static if VERSION >= v"0.7.0-DEV.884" # PR 22703 @test typeof(ustrip(Bidiagonal([1,2,3]u"m", [1,2]u"m", :U))) <: From b4b3a7a9b28e40e287263d7920d5dbe972be07b8 Mon Sep 17 00:00:00 2001 From: Andrew Keller Date: Thu, 14 Dec 2017 12:38:04 -0800 Subject: [PATCH 16/16] Fix range implementation for promotion changes in 0.7-dev. --- src/range.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/range.jl b/src/range.jl index 8985af1c..a96011d4 100644 --- a/src/range.jl +++ b/src/range.jl @@ -81,11 +81,10 @@ range(a::Quantity{<:Real}, st::Quantity{<:AbstractFloat}, len::Integer) = range(float(a), st, len) range(a::Quantity{<:AbstractFloat}, st::Quantity{<:Real}, len::Integer) = range(a, float(st), len) -range(a::Quantity{<:AbstractFloat}, st::Quantity{<:AbstractFloat}, len::Integer) = - _range(promote(a, st)..., len) -_range(a::T, st::T, len) where {T<:Quantity} = range(a, st, len) -_range(a, st, len) = throw(DimensionError(a, st)) - +function range(a::Quantity{<:AbstractFloat}, st::Quantity{<:AbstractFloat}, len::Integer) + dimension(a) != dimension(st) && throw(DimensionError(a, st)) + range(promote(a, st)..., len) +end range(a::Quantity, st::Real, len::Integer) = range(promote(a, st)..., len) range(a::Real, st::Quantity, len::Integer) = range(promote(a, st)..., len)