Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into base-logging
Browse files Browse the repository at this point in the history
Fix keyword handling related to the changes in JuliaLang#24795
  • Loading branch information
c42f committed Dec 3, 2017
2 parents 1a6ff02 + b02cf6e commit e0a746e
Show file tree
Hide file tree
Showing 60 changed files with 760 additions and 1,807 deletions.
15 changes: 15 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ New language features
* Named tuples, with the syntax `(a=1, b=2)`. These behave very similarly to tuples,
except components can also be accessed by name using dot syntax `t.a` ([#22194]).

* Keyword argument containers (`kw` in `f(; kw...)`) are now named tuples. Dictionary
functions like `haskey` and indexing can be used on them, and name-value pairs can be
iterated using `pairs(kw)`. `kw` can no longer contain multiple entries for the same
argument name ([#4916]).

* Custom infix operators can now be defined by appending Unicode
combining marks, primes, and sub/superscripts to other operators.
For example, `+̂ₐ″` is parsed as an infix operator with the same
Expand Down Expand Up @@ -401,6 +406,9 @@ Library improvements
This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting
arrays with different alignment requirements (removed in 0.6) is once again allowed ([#23750]).

* The `keys` of an `Associative` are now an `AbstractSet`. `Base.KeyIterator{<:Associative}`
has been changed to `KeySet{K, <:Associative{K}} <: AbstractSet{K}` ([#24580]).

Compiler/Runtime improvements
-----------------------------

Expand Down Expand Up @@ -1336,6 +1344,13 @@ Deprecated or removed

* `linspace` and `logspace` now require an explicit number of elements to be supplied rather than defaulting to `50`.

* Introduced the `empty` function, the functional pair to `empty!` which returns a new,
empty container ([#24390]).

* `similar(::Associative)` has been deprecated in favor of `empty(::Associative)`, and
`similar(::Associative, ::Pair{K, V})` has been deprecated in favour of
`empty(::Associative, K, V)` ([#24390]).

Command-line option changes
---------------------------

Expand Down
18 changes: 18 additions & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,24 @@ indices of `A`.
similar(f, shape::Tuple) = f(to_shape(shape))
similar(f, dims::DimOrInd...) = similar(f, dims)

"""
empty(v::AbstractVector, [eltype])
Create an empty vector similar to `v`, optionally changing the `eltype`.
# Examples
```jldoctest
julia> empty([1.0, 2.0, 3.0])
0-element Array{Float64,1}
julia> empty([1.0, 2.0, 3.0], String)
0-element Array{String,1}
```
"""
empty(a::AbstractVector) = empty(a, eltype(a))
empty(a::AbstractVector, ::Type{T}) where {T} = Vector{T}()

## from general iterable to any array

function copy!(dest::AbstractArray, src)
Expand Down
47 changes: 31 additions & 16 deletions base/associative.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ end

const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__

haskey(d::Associative, k) = in(k,keys(d))
haskey(d::Associative, k) = in(k, keys(d))

function in(p::Pair, a::Associative, valcmp=(==))
v = get(a,p[1],secret_table_token)
Expand All @@ -35,29 +35,29 @@ function summary(t::Associative)
return string(typeof(t), " with ", n, (n==1 ? " entry" : " entries"))
end

struct KeyIterator{T<:Associative}
struct KeySet{K, T <: Associative{K}} <: AbstractSet{K}
dict::T
end
KeySet(dict::Associative) = KeySet{keytype(dict), typeof(dict)}(dict)

struct ValueIterator{T<:Associative}
dict::T
end

summary(iter::T) where {T<:Union{KeyIterator,ValueIterator}} =
summary(iter::T) where {T<:Union{KeySet,ValueIterator}} =
string(T.name, " for a ", summary(iter.dict))

show(io::IO, iter::Union{KeyIterator,ValueIterator}) = show(io, collect(iter))
show(io::IO, iter::Union{KeySet,ValueIterator}) = show(io, collect(iter))

length(v::Union{KeyIterator,ValueIterator}) = length(v.dict)
isempty(v::Union{KeyIterator,ValueIterator}) = isempty(v.dict)
_tt1(::Type{Pair{A,B}}) where {A,B} = A
length(v::Union{KeySet,ValueIterator}) = length(v.dict)
isempty(v::Union{KeySet,ValueIterator}) = isempty(v.dict)
_tt2(::Type{Pair{A,B}}) where {A,B} = B
eltype(::Type{KeyIterator{D}}) where {D} = _tt1(eltype(D))
eltype(::Type{ValueIterator{D}}) where {D} = _tt2(eltype(D))

start(v::Union{KeyIterator,ValueIterator}) = start(v.dict)
done(v::Union{KeyIterator,ValueIterator}, state) = done(v.dict, state)
start(v::Union{KeySet,ValueIterator}) = start(v.dict)
done(v::Union{KeySet,ValueIterator}, state) = done(v.dict, state)

function next(v::KeyIterator, state)
function next(v::KeySet, state)
n = next(v.dict, state)
n[1][1], n[2]
end
Expand All @@ -67,7 +67,7 @@ function next(v::ValueIterator, state)
n[1][2], n[2]
end

in(k, v::KeyIterator) = get(v.dict, k, secret_table_token) !== secret_table_token
in(k, v::KeySet) = get(v.dict, k, secret_table_token) !== secret_table_token

"""
keys(iterator)
Expand Down Expand Up @@ -100,7 +100,7 @@ julia> collect(keys(a))
'a'
```
"""
keys(a::Associative) = KeyIterator(a)
keys(a::Associative) = KeySet(a)

"""
values(a::Associative)
Expand Down Expand Up @@ -138,8 +138,23 @@ pairs(collection) = Generator(=>, keys(collection), values(collection))

pairs(a::Associative) = a

"""
empty(a::Associative, [index_type=keytype(a)], [value_type=valtype(a)])
Create an empty `Associative` container which can accept indices of type `index_type` and
values of type `value_type`. The second and third arguments are optional and default to the
input's `keytype` and `valtype`, respectively. (If only one of the two types is specified,
it is assumed to be the `value_type`, and the `index_type` we default to `keytype(a)`).
Custom `Associative` subtypes may choose which specific associative type is best suited to
return for the given index and value types, by specializing on the three-argument signature.
The default is to return an empty `Dict`.
"""
empty(a::Associative) = empty(a, keytype(a), valtype(a))
empty(a::Associative, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`.

function copy(a::Associative)
b = similar(a)
b = empty(a)
for (k,v) in a
b[k] = v
end
Expand Down Expand Up @@ -418,7 +433,7 @@ Dict{Int64,String} with 1 entry:
"""
function filter(f, d::Associative)
# don't just do filter!(f, copy(d)): avoid making a whole copy of d
df = similar(d)
df = empty(d)
try
for pair in d
if f(pair)
Expand Down Expand Up @@ -527,7 +542,7 @@ mutable struct ObjectIdDict <: Associative{Any,Any}
ObjectIdDict(o::ObjectIdDict) = new(copy(o.ht))
end

similar(d::ObjectIdDict) = ObjectIdDict()
empty(d::ObjectIdDict, ::Type{Any}, ::Type{Any}) = ObjectIdDict()

function rehash!(t::ObjectIdDict, newsz = length(t.ht))
t.ht = ccall(:jl_idtable_rehash, Any, (Any, Csize_t), t.ht, newsz)
Expand Down
40 changes: 38 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ export
# constants
nothing, Main

const AnyVector = Array{Any,1}

abstract type Number end
abstract type Real <: Number end
abstract type AbstractFloat <: Real end
Expand Down Expand Up @@ -466,4 +464,42 @@ function (g::GeneratedFunctionStub)(@nospecialize args...)
end
end

NamedTuple() = NamedTuple{(),Tuple{}}(())

"""
NamedTuple{names}(args::Tuple)
Construct a named tuple with the given `names` (a tuple of Symbols) from a tuple of values.
"""
NamedTuple{names}(args::Tuple) where {names} = NamedTuple{names,typeof(args)}(args)

using .Intrinsics: sle_int, add_int

macro generated()
return Expr(:generated)
end

function NamedTuple{names,T}(args::T) where {names, T <: Tuple}
if @generated
N = nfields(names)
flds = Array{Any,1}(uninitialized, N)
i = 1
while sle_int(i, N)
arrayset(false, flds, :(getfield(args, $i)), i)
i = add_int(i, 1)
end
Expr(:new, :(NamedTuple{names,T}), flds...)
else
N = nfields(names)
NT = NamedTuple{names,T}
flds = Array{Any,1}(uninitialized, N)
i = 1
while sle_int(i, N)
arrayset(false, flds, getfield(args, i), i)
i = add_int(i, 1)
end
ccall(:jl_new_structv, Any, (Any, Ptr{Void}, UInt32), NT, fields, N)::NT
end
end

ccall(:jl_set_istopmod, Void, (Any, Bool), Core, true)
1 change: 1 addition & 0 deletions base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ include("reduce.jl")
include("bitarray.jl")
include("bitset.jl")
include("associative.jl")
include("namedtuple.jl")

# core docsystem
include("docs/core.jl")
Expand Down
2 changes: 1 addition & 1 deletion base/deepcopy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function deepcopy_internal(x::Dict, stackdict::ObjectIdDict)
return (stackdict[x] = copy(x))
end

dest = similar(x)
dest = empty(x)
stackdict[x] = dest
for (k, v) in x
dest[deepcopy_internal(k, stackdict)] = deepcopy_internal(v, stackdict)
Expand Down
4 changes: 4 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,10 @@ info(io::IO, err::Exception; prefix="ERROR: ", kw...) =
info(err::Exception; prefix="ERROR: ", kw...) =
info(STDERR, err, prefix=prefix; kw...)

# issue #24019
@deprecate similar(a::Associative) empty(a)
@deprecate similar(a::Associative, ::Type{Pair{K,V}}) where {K, V} empty(a, K, V)

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
23 changes: 10 additions & 13 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ mutable struct Dict{K,V} <: Associative{K,V}
new(copy(d.slots), copy(d.keys), copy(d.vals), d.ndel, d.count, d.age,
d.idxfloor, d.maxprobe)
end
function Dict{K, V}(slots, keys, vals, ndel, count, age, idxfloor, maxprobe) where {K, V}
new(slots, keys, vals, ndel, count, age, idxfloor, maxprobe)
end
end
function Dict{K,V}(kv) where V where K
h = Dict{K,V}()
Expand Down Expand Up @@ -166,7 +169,7 @@ end
# this is a special case due to (1) allowing both Pairs and Tuples as elements,
# and (2) Pair being invariant. a bit annoying.
function grow_to!(dest::Associative, itr)
out = grow_to!(similar(dest, Pair{Union{},Union{}}), itr, start(itr))
out = grow_to!(empty(dest, Union{}, Union{}), itr, start(itr))
return isempty(out) ? dest : out
end

Expand All @@ -176,7 +179,7 @@ function grow_to!(dest::Associative{K,V}, itr, st) where V where K
if isa(k,K) && isa(v,V)
dest[k] = v
else
new = similar(dest, Pair{typejoin(K,typeof(k)), typejoin(V,typeof(v))})
new = empty(dest, typejoin(K,typeof(k)), typejoin(V,typeof(v)))
copy!(new, dest)
new[k] = v
return grow_to!(new, itr, st)
Expand All @@ -185,8 +188,7 @@ function grow_to!(dest::Associative{K,V}, itr, st) where V where K
return dest
end

similar(d::Dict{K,V}) where {K,V} = Dict{K,V}()
similar(d::Dict, ::Type{Pair{K,V}}) where {K,V} = Dict{K,V}()
empty(a::Associative, ::Type{K}, ::Type{V}) where {K, V} = Dict{K, V}()

# conversion between Dict types
function convert(::Type{Dict{K,V}},d::Associative) where V where K
Expand Down Expand Up @@ -584,7 +586,7 @@ false
```
"""
haskey(h::Dict, key) = (ht_keyindex(h, key) >= 0)
in(key, v::KeyIterator{<:Dict}) = (ht_keyindex(v.dict, key) >= 0)
in(key, v::KeySet{<:Any, <:Dict}) = (ht_keyindex(v.dict, key) >= 0)

"""
getkey(collection, key, default)
Expand Down Expand Up @@ -716,7 +718,7 @@ end
isempty(t::Dict) = (t.count == 0)
length(t::Dict) = t.count

@propagate_inbounds function next(v::KeyIterator{<:Dict}, i)
@propagate_inbounds function next(v::KeySet{<:Any, <:Dict}, i)
return (v.dict.keys[i], skip_deleted(v.dict,i+1))
end
@propagate_inbounds function next(v::ValueIterator{<:Dict}, i)
Expand Down Expand Up @@ -794,12 +796,7 @@ next(::ImmutableDict{K,V}, t) where {K,V} = (Pair{K,V}(t.key, t.value), t.parent
done(::ImmutableDict, t) = !isdefined(t, :parent)
length(t::ImmutableDict) = count(x->true, t)
isempty(t::ImmutableDict) = done(t, start(t))
function similar(t::ImmutableDict)
while isdefined(t, :parent)
t = t.parent
end
return t
end
empty(::ImmutableDict, ::Type{K}, ::Type{V}) where {K, V} = ImmutableDict{K,V}()

_similar_for(c::Dict, ::Type{P}, itr, isz) where {P<:Pair} = similar(c, P)
_similar_for(c::Dict, ::Type{Pair{K,V}}, itr, isz) where {K, V} = empty(c, K, V)
_similar_for(c::Associative, T, itr, isz) = throw(ArgumentError("for Associatives, similar requires an element type of Pair;\n if calling map, consider a comprehension instead"))
2 changes: 1 addition & 1 deletion base/distributed/cluster.jl
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ function addprocs(manager::ClusterManager; kwargs...)
end

function addprocs_locked(manager::ClusterManager; kwargs...)
params = merge(default_addprocs_params(), AnyDict(kwargs))
params = merge(default_addprocs_params(), AnyDict(pairs(kwargs)))
topology(Symbol(params[:topology]))

if PGRP.topology != :all_to_all
Expand Down
4 changes: 2 additions & 2 deletions base/distributed/managers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ end

function check_addprocs_args(kwargs)
valid_kw_names = collect(keys(default_addprocs_params()))
for keyname in kwargs
!(keyname[1] in valid_kw_names) && throw(ArgumentError("Invalid keyword argument $(keyname[1])"))
for keyname in keys(kwargs)
!(keyname in valid_kw_names) && throw(ArgumentError("Invalid keyword argument $(keyname)"))
end
end

Expand Down
6 changes: 3 additions & 3 deletions base/distributed/messages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ null_id(id) = id == RRID(0, 0)
struct CallMsg{Mode} <: AbstractMsg
f::Function
args::Tuple
kwargs::Array
kwargs
end
struct CallWaitMsg <: AbstractMsg
f::Function
args::Tuple
kwargs::Array
kwargs
end
struct RemoteDoMsg <: AbstractMsg
f::Function
args::Tuple
kwargs::Array
kwargs
end
struct ResultMsg <: AbstractMsg
value::Any
Expand Down
4 changes: 1 addition & 3 deletions base/env.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,10 @@ variables.
"""
const ENV = EnvDict()

similar(::EnvDict) = Dict{String,String}()

getindex(::EnvDict, k::AbstractString) = access_env(k->throw(KeyError(k)), k)
get(::EnvDict, k::AbstractString, def) = access_env(k->def, k)
get(f::Callable, ::EnvDict, k::AbstractString) = access_env(k->f(), k)
in(k::AbstractString, ::KeyIterator{EnvDict}) = _hasenv(k)
in(k::AbstractString, ::KeySet{String, EnvDict}) = _hasenv(k)
pop!(::EnvDict, k::AbstractString) = (v = ENV[k]; _unsetenv(k); v)
pop!(::EnvDict, k::AbstractString, def) = haskey(ENV,k) ? pop!(ENV,k) : def
delete!(::EnvDict, k::AbstractString) = (_unsetenv(k); ENV)
Expand Down
Loading

0 comments on commit e0a746e

Please sign in to comment.