From bad0f6a7de7e189c230810f5fae3590a6c2f47da Mon Sep 17 00:00:00 2001 From: rafaqz Date: Tue, 12 Dec 2023 00:43:08 +0100 Subject: [PATCH 1/7] inherit --- BaseInterfaces/src/interfaces/array.jl | 2 +- BaseInterfaces/src/interfaces/dict.jl | 2 +- BaseInterfaces/src/interfaces/set.jl | 2 +- src/implements.jl | 3 ++ src/interface.jl | 45 +++++++++++++++++++------- src/test.jl | 13 +++++--- 6 files changed, 48 insertions(+), 19 deletions(-) diff --git a/BaseInterfaces/src/interfaces/array.jl b/BaseInterfaces/src/interfaces/array.jl index 0d3289a..b755548 100644 --- a/BaseInterfaces/src/interfaces/array.jl +++ b/BaseInterfaces/src/interfaces/array.jl @@ -201,4 +201,4 @@ array_components = (; _wrappertype(A) = Base.typename(typeof(A)).wrapper -@interface ArrayInterface AbstractArray array_components "Base Julia AbstractArray interface" +@interface ArrayInterface <: IterationInterface{(:reverse,:indexing)} AbstractArray array_components "Base Julia AbstractArray interface" diff --git a/BaseInterfaces/src/interfaces/dict.jl b/BaseInterfaces/src/interfaces/dict.jl index 8053e76..c6c83e5 100644 --- a/BaseInterfaces/src/interfaces/dict.jl +++ b/BaseInterfaces/src/interfaces/dict.jl @@ -1,5 +1,5 @@ -@interface DictInterface AbstractDict ( # <: CollectionInterface +@interface DictInterface <: IterationInterface AbstractDict ( # <: CollectionInterface mandatory = (; iterate = "AbstractDict follows the IterationInterface" => a -> Interfaces.test(IterationInterface, a.d; show=false) && first(iterate(a.d)) isa Pair, eltype = "eltype is a Pair" => a -> eltype(a.d) <: Pair, diff --git a/BaseInterfaces/src/interfaces/set.jl b/BaseInterfaces/src/interfaces/set.jl index b8d754e..6d88e5d 100644 --- a/BaseInterfaces/src/interfaces/set.jl +++ b/BaseInterfaces/src/interfaces/set.jl @@ -67,4 +67,4 @@ set_components = (; ) ) -@interface SetInterface AbstractSet set_components "The `AbstractSet` interface" +@interface SetInterface <: IterationInterface AbstractSet set_components "The `AbstractSet` interface" diff --git a/src/implements.jl b/src/implements.jl index fc6e4b7..05867ff 100644 --- a/src/implements.jl +++ b/src/implements.jl @@ -39,6 +39,7 @@ using BaseInterfaces, Interfaces macro implements(interface, objtype, test_objects) _implements_inner(interface, objtype, test_objects) end + function _implements_inner(interface, objtype, test_objects; show=false) if interface isa Expr && interface.head == :curly interfacetype = interface.args[1] @@ -60,6 +61,8 @@ function _implements_inner(interface, objtype, test_objects; show=false) $Interfaces.implements(::Type{<:$interfacetype}, ::Type{<:$objtype}) = true $Interfaces.implements(T::Type{<:$interfacetype{Options}}, O::Type{<:$objtype}) where Options = $Interfaces._all_in(Options, $Interfaces.optional_keys(T, O)) + $Interfaces.implements(T::Type{<:$interfacetype{<:Any,Options}}, O::Type{<:$objtype}) where Options = + $Interfaces._all_in(Options, $Interfaces.optional_keys(T, O)) # Define which optional components the object implements $Interfaces.optional_keys(::Type{<:$interfacetype}, ::Type{<:$objtype}) = $optional_keys $Interfaces.test_objects(::Type{<:$interfacetype}, ::Type{<:$objtype}) = $test_objects diff --git a/src/interface.jl b/src/interface.jl index 6c0cd82..d71d321 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -6,7 +6,7 @@ Abstract supertype for all Interfaces.jl interfaces. Components is an `Tuple` of `Symbol`. """ -abstract type Interface{Components} end +abstract type Interface{Components,Inherits} end """ optional_keys(T::Type{<:Interface}, O::Type) @@ -67,29 +67,52 @@ description = "A description of the interface" @interface MyInterface Any components description ``` """ -macro interface(interface::Symbol, type, components, description) +macro interface(interface_expr, type, components, description) + _error(interface_expr) = throw(ArgumentError("$interface_expr not recognised as an interface type.")) + + interface_expr = if interface_expr isa Symbol + interface_type = interface_expr + :(abstract type $interface_type{Components,Inherited} <: $Interfaces.Interface{Components,()} end) + else + interface_expr.head == :<: || _error(interface_expr) + interface_type = interface_expr.args[1] + inherits_expr = interface_expr.args[2] + if inherits_expr isa Expr && inherits_expr.head == :curly + inherits_type = inherits_expr.args[1] + inherits_keys = inherits_expr.args[2] + :(abstract type $interface_type{Components,Inherited} <: $inherits_type{Components,$inherits_keys} end) + elseif inherits_expr isa Symbol + inherits_type = inherits_expr + :(abstract type $interface_type{Components,Inherited} <: $inherits_type{Components,()} end) + else + _error(interface_expr) + end + end + quote @assert $type isa Type @assert $components isa NamedTuple{(:mandatory,:optional)} @assert $description isa String # Define the interface type (should it be concrete?) - abstract type $interface{Components} <: $Interfaces.Interface{Components} end + $interface_expr # Define the interface component methods - $Interfaces.requiredtype(::Type{<:$interface}) = $type - $Interfaces.components(::Type{<:$interface}) = $components - $Interfaces.description(::Type{<:$interface}) = $description + $Interfaces.requiredtype(::Type{<:$interface_type}) = $type + $Interfaces.components(::Type{<:$interface_type}) = $components + $Interfaces.description(::Type{<:$interface_type}) = $description # Generate a docstring for the interface let description=$description, - interfacesym=$(QuoteNode(interface)), - m_keys=$Interfaces.mandatory_keys($interface), - o_keys=$Interfaces.optional_keys($interface) + interface_sym=$(QuoteNode(interface_type)), + m_keys=$Interfaces.mandatory_keys($interface_type), + o_keys=$Interfaces.optional_keys($interface_type) @doc """ - $(" ") $interfacesym + $(" ") $interface_sym An Interfaces.jl `Interface` with mandatory components `$m_keys` and optional components `$o_keys`. $description - """ $interface + """ $interface_type end end |> esc end + +_namedtuple_expr_err() = error("components must be defined in-line in the macro with both `mandatory` and `optional` fields, not passed as a variable. E.g. (; mandatory=(; x=x_predicate), optional=(; y=y_predicate))") diff --git a/src/test.jl b/src/test.jl index 2d4549f..063d333 100644 --- a/src/test.jl +++ b/src/test.jl @@ -72,10 +72,9 @@ test(mod::Module; kw...) = _test_module_implements(Any, mod; kw...) test(T::Type{<:Interface}; kw...) = _test_module_implements(Type{_check_no_options(T)}, nothing; kw...) -function _check_no_options(T) - T isa UnionAll || throw(ArgumentError("Interface options not accepted for more than one implementation")) - return T -end +_check_no_options(T::Type) = T +_check_no_options(::Type{<:Interface{Keys}}) where Keys = + throw(ArgumentError("Interface options not accepted for more than one implementation")) # Here we test all the `implements` methods in `methodlist` that were defined in `mod`. # Basically we are using the `implements` method table as the global state of all # available implementations. @@ -99,7 +98,11 @@ function _test_module_implements(T, mod; show=true, kw...) t = b.parameters[2].var.ub t isa UnionAll || return nothing, true - interface = t.body.name.wrapper + if t.body isa UnionAll + interface = t.body.body.name.wrapper + else + interface = t.body.name.wrapper + end implementation = b.parameters[3].var.ub implementation == Any && return nothing, true From 3d64d25276caffac7fef48acc0b36f7d6a5b2a1c Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 3 Mar 2024 11:24:58 +0100 Subject: [PATCH 2/7] multiple --- BaseInterfaces/src/BaseInterfaces.jl | 4 +- .../src/implementations/iteration.jl | 18 +++---- BaseInterfaces/src/interfaces/array.jl | 2 +- BaseInterfaces/src/interfaces/dict.jl | 2 +- BaseInterfaces/test/runtests.jl | 16 +++++++ src/implements.jl | 48 +++++++++++++++++-- src/interface.jl | 32 +++++++++++-- 7 files changed, 101 insertions(+), 21 deletions(-) diff --git a/BaseInterfaces/src/BaseInterfaces.jl b/BaseInterfaces/src/BaseInterfaces.jl index 5b966bf..40d254f 100644 --- a/BaseInterfaces/src/BaseInterfaces.jl +++ b/BaseInterfaces/src/BaseInterfaces.jl @@ -9,13 +9,13 @@ export Interfaces export ArrayInterface, DictInterface, IterationInterface, SetInterface include("interfaces/iteration.jl") -include("interfaces/dict.jl") include("interfaces/set.jl") +include("interfaces/dict.jl") include("interfaces/array.jl") include("implementations/iteration.jl") -include("implementations/dict.jl") include("implementations/set.jl") +include("implementations/dict.jl") include("implementations/array.jl") end diff --git a/BaseInterfaces/src/implementations/iteration.jl b/BaseInterfaces/src/implementations/iteration.jl index 422a353..6c79a7c 100644 --- a/BaseInterfaces/src/implementations/iteration.jl +++ b/BaseInterfaces/src/implementations/iteration.jl @@ -1,8 +1,8 @@ -@implements IterationInterface{(:reverse,:indexing)} UnitRange [1:5, -2:2] -@implements IterationInterface{(:reverse,:indexing)} StepRange [1:2:10, 20:-10:-20] -@implements IterationInterface{(:reverse,:indexing)} Array [[1, 2, 3, 4], [:a :b; :c :d]] -@implements IterationInterface{(:reverse,:indexing)} Tuple [(1, 2, 3, 4)] +# @implements IterationInterface{(:reverse,:indexing)} UnitRange [1:5, -2:2] +# @implements IterationInterface{(:reverse,:indexing)} StepRange [1:2:10, 20:-10:-20] +# @implements IterationInterface{(:reverse,:indexing)} Array [[1, 2, 3, 4], [:a :b; :c :d]] +# @implements IterationInterface{(:reverse,:indexing)} Tuple [(1, 2, 3, 4)] @static if VERSION >= v"1.9.0" @implements IterationInterface{(:reverse,:indexing)} NamedTuple [(a=1, b=2, c=3, d=4)] else @@ -14,11 +14,11 @@ end @implements IterationInterface{:reverse} Base.Generator [(i for i in 1:5), (i for i in 1:5)] # @implements IterationInterface{(:reverse,:indexing)} Base.EachLine [eachline(joinpath(dirname(pathof(BaseInterfaces)), "implementations.jl"))] -@implements IterationInterface Set [Set((1, 2, 3, 4))] -@implements IterationInterface BitSet [BitSet((1, 2, 3, 4))] -@implements IterationInterface Dict [Dict("a" => 2, :b => 3.0)] -@implements IterationInterface Base.EnvDict [Arguments(d=Base.EnvDict())] -@implements IterationInterface Base.ImmutableDict [Arguments(d=Base.ImmutableDict(:a => 1, :b => 2))] +# @implements IterationInterface Set [Set((1, 2, 3, 4))] +# @implements IterationInterface BitSet [BitSet((1, 2, 3, 4))] +# @implements IterationInterface Dict [Dict("a" => 2, :b => 3.0)] +# @implements IterationInterface Base.EnvDict [Arguments(d=Base.EnvDict())] +# @implements IterationInterface Base.ImmutableDict [Arguments(d=Base.ImmutableDict(:a => 1, :b => 2))] # @implements IterationInterface IdDict # @implements IterationInterface WeakKeyDict diff --git a/BaseInterfaces/src/interfaces/array.jl b/BaseInterfaces/src/interfaces/array.jl index b755548..e82b321 100644 --- a/BaseInterfaces/src/interfaces/array.jl +++ b/BaseInterfaces/src/interfaces/array.jl @@ -201,4 +201,4 @@ array_components = (; _wrappertype(A) = Base.typename(typeof(A)).wrapper -@interface ArrayInterface <: IterationInterface{(:reverse,:indexing)} AbstractArray array_components "Base Julia AbstractArray interface" +@interface ArrayInterface <: Union{IterationInterface{(:reverse,:indexing)}} AbstractArray array_components "Base Julia AbstractArray interface" diff --git a/BaseInterfaces/src/interfaces/dict.jl b/BaseInterfaces/src/interfaces/dict.jl index c6c83e5..db79bbf 100644 --- a/BaseInterfaces/src/interfaces/dict.jl +++ b/BaseInterfaces/src/interfaces/dict.jl @@ -1,5 +1,5 @@ -@interface DictInterface <: IterationInterface AbstractDict ( # <: CollectionInterface +@interface DictInterface <: Union{IterationInterface{(:reverse,)}} AbstractDict ( # <: CollectionInterface mandatory = (; iterate = "AbstractDict follows the IterationInterface" => a -> Interfaces.test(IterationInterface, a.d; show=false) && first(iterate(a.d)) isa Pair, eltype = "eltype is a Pair" => a -> eltype(a.d) <: Pair, diff --git a/BaseInterfaces/test/runtests.jl b/BaseInterfaces/test/runtests.jl index 65bbc5f..d1e87e5 100644 --- a/BaseInterfaces/test/runtests.jl +++ b/BaseInterfaces/test/runtests.jl @@ -6,6 +6,22 @@ using Test @implements SetInterface{(:empty,:emptymutable,:hasfastin,:intersect,:union,:sizehint!)} Test.GenericSet [Test.GenericSet(Set((1, 2)))] @implements DictInterface Test.GenericDict [Arguments(d=Test.GenericDict(Dict(:a => 1, :b => 2)), k=:c, v=3)] +@test "inheritance" begin + # Inherited interfaces are stored in the second parameter of the supertype + @test supertype(ArrayInterface) <: Interfaces.Interface{<:Any,IterationInterface{(:reverse, :indexing)}} + @test supertype(DictInterface) <: Interfaces.Interface{<:Any,IterationInterface{(:reverse,)}} + + @test Interfaces.implements(ArrayInterface, Array) + @test Interfaces.implements(IterationInterface, Array) + @test !Interfaces.implements(DictInterface, Array) + @test !Interfaces.implements(SetInterface, Array) + @test Interfaces.implements(IterationInterface{(:reverse,:indexing)}, Array) + + @test Interfaces.implements(IterationInterface, Dict) + @test !Interfaces.implements(IterationInterface{:indexing}, Dict) + @test !Interfaces.implements(ArrayInterface, Dict) +end + # Test all interfaces @test Interfaces.test() diff --git a/src/implements.jl b/src/implements.jl index 05867ff..650bcdd 100644 --- a/src/implements.jl +++ b/src/implements.jl @@ -16,7 +16,10 @@ all the mandatory components of the interace are implemented. """ function implements end implements(T::Type{<:Interface}, obj) = implements(T, typeof(obj)) -implements(::Type{<:Interface}, obj::Type) = false +implements(T::Type{<:Interface}, obj::Type) = inherits(T, obj) + +function inherits end +inherits(::Type{<:Interface}, obj) = false """ @implements(interface, objtype, test_objects) @@ -40,6 +43,24 @@ macro implements(interface, objtype, test_objects) _implements_inner(interface, objtype, test_objects) end +inherited_type(::Type{<:Interface{<:Any,Inherits}}) where Inherits = Inherits +inherited_basetype(::Type{T}) where T = basetypeof(inherited_type(T)) + +inherited_optional_keys(::Type{<:Interface{Optional}}) where Optional = Optional +Base.@assume_effects :foldable function inherited_optional_keys(::Type{T}) where T<:Union + map(propertynames(T)) do pn + inherited_optional_keys(getproperty(T, pn)) + end +end +inherited_optional_keys(::Type) = () + +function inherited_interfaces(::Type{T}) where T <: Union + map(propertynames(T)) do pn + t = getproperty(T, pn) + inherited_optional_keys(t) + end +end + function _implements_inner(interface, objtype, test_objects; show=false) if interface isa Expr && interface.head == :curly interfacetype = interface.args[1] @@ -61,8 +82,11 @@ function _implements_inner(interface, objtype, test_objects; show=false) $Interfaces.implements(::Type{<:$interfacetype}, ::Type{<:$objtype}) = true $Interfaces.implements(T::Type{<:$interfacetype{Options}}, O::Type{<:$objtype}) where Options = $Interfaces._all_in(Options, $Interfaces.optional_keys(T, O)) - $Interfaces.implements(T::Type{<:$interfacetype{<:Any,Options}}, O::Type{<:$objtype}) where Options = - $Interfaces._all_in(Options, $Interfaces.optional_keys(T, O)) + function $Interfaces.inherits(::Type{T}, ::Type{<:$objtype}) where {T<:$Interfaces.inherited_basetype($interfacetype)} + implementation_keys = $Interfaces.inherited_optional_keys($Interfaces.inherited_type($interfacetype)) + user_keys = $Interfaces._as_tuple($Interfaces._user_optional_keys(T)) + all(map(in(implementation_keys), user_keys)) + end # Define which optional components the object implements $Interfaces.optional_keys(::Type{<:$interfacetype}, ::Type{<:$objtype}) = $optional_keys $Interfaces.test_objects(::Type{<:$interfacetype}, ::Type{<:$objtype}) = $test_objects @@ -70,12 +94,30 @@ function _implements_inner(interface, objtype, test_objects; show=false) end |> esc end +_user_optional_keys(::Type{<:Interface{Options}}) where Options = Options +_user_optional_keys(::Type{<:Interface}) = () + _all_in(items::Tuple, collection) = all(map(in(collection), items)) _all_in(item::Symbol, collection) = in(item, collection) +_as_tuple(xs::Tuple) = xs +_as_tuple(x) = (x,) + struct Implemented{T<:Interface} end struct NotImplemented{T<:Interface} end +Base.@assume_effects :foldable function basetypeof(::Type{T}) where T + if T isa Union + types = map(propertynames(T)) do pn + t = getproperty(T, pn) + getfield(parentmodule(t), nameof(t)) + end + Union{types...} + else + getfield(parentmodule(T), nameof(T)) + end +end + """ implemented_trait(T::Type{<:Interface}, obj) implemented_trait(T::Type{<:Interface{Option}}, obj) diff --git a/src/interface.jl b/src/interface.jl index d71d321..fee6115 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -21,6 +21,29 @@ optional_keys(T::Type{<:Interface}) = keys(components(T).optional) mandatory_keys(T::Type{<:Interface}, args...) = keys(components(T).mandatory) +function _flatten_inheritance(::Type{T}) where T + t = if T isa Union + types = map(propertynames(T)) do pn + _flatten_inheritance(getproperty(T, pn)) + end + Union{T,types...} + else + T + end + @show T t + println() + println() + return t +end +function _flatten_inheritance( + ::Type{T} +) where T<:Interface{Options,Inherited} where {Options,Inherited} + t = Inherited <: Nothing ? T : Union{T,Inherited} + @show T t + println() + return t +end + """ test_objects(T::Type{<:Interface}, O::Type) @@ -72,18 +95,17 @@ macro interface(interface_expr, type, components, description) interface_expr = if interface_expr isa Symbol interface_type = interface_expr - :(abstract type $interface_type{Components,Inherited} <: $Interfaces.Interface{Components,()} end) + :(abstract type $interface_type{Components,Inherited} <: $Interfaces.Interface{Components,Nothing} end) else interface_expr.head == :<: || _error(interface_expr) interface_type = interface_expr.args[1] inherits_expr = interface_expr.args[2] if inherits_expr isa Expr && inherits_expr.head == :curly - inherits_type = inherits_expr.args[1] - inherits_keys = inherits_expr.args[2] - :(abstract type $interface_type{Components,Inherited} <: $inherits_type{Components,$inherits_keys} end) + inherits_type = inherits_expr + :(abstract type $interface_type{Components,Inherited} <: $Interfaces.Interface{Components,$Interfaces._flatten_inheritance($inherits_type)} end) elseif inherits_expr isa Symbol inherits_type = inherits_expr - :(abstract type $interface_type{Components,Inherited} <: $inherits_type{Components,()} end) + :(abstract type $interface_type{Components,Inherited} <: $Interfaces.Interface{Components,$inherits_type} end) else _error(interface_expr) end From ac11070d0dbf388a3156ef1ba88adcc9ea9f880a Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 3 Mar 2024 11:28:27 +0100 Subject: [PATCH 3/7] some comments --- src/implements.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/implements.jl b/src/implements.jl index 650bcdd..35792b3 100644 --- a/src/implements.jl +++ b/src/implements.jl @@ -80,12 +80,15 @@ function _implements_inner(interface, objtype, test_objects; show=false) end # Define a `implements` trait stating that `objtype` implements `interface` $Interfaces.implements(::Type{<:$interfacetype}, ::Type{<:$objtype}) = true + # Define implements with user-specified `Options` to check $Interfaces.implements(T::Type{<:$interfacetype{Options}}, O::Type{<:$objtype}) where Options = $Interfaces._all_in(Options, $Interfaces.optional_keys(T, O)) + # Define a method using `inherited_basetype` to generate the type that + # will dispatch when another Interface inherits this Interface. function $Interfaces.inherits(::Type{T}, ::Type{<:$objtype}) where {T<:$Interfaces.inherited_basetype($interfacetype)} implementation_keys = $Interfaces.inherited_optional_keys($Interfaces.inherited_type($interfacetype)) user_keys = $Interfaces._as_tuple($Interfaces._user_optional_keys(T)) - all(map(in(implementation_keys), user_keys)) + return all(map(in(implementation_keys), user_keys)) end # Define which optional components the object implements $Interfaces.optional_keys(::Type{<:$interfacetype}, ::Type{<:$objtype}) = $optional_keys From 54210a455f529276f90caf50b86d7d1e8f26a5c9 Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 3 Mar 2024 11:42:58 +0100 Subject: [PATCH 4/7] delete IterationInteferface implementations, theyre inherited now --- BaseInterfaces/src/implementations/iteration.jl | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/BaseInterfaces/src/implementations/iteration.jl b/BaseInterfaces/src/implementations/iteration.jl index 6c79a7c..5268fcf 100644 --- a/BaseInterfaces/src/implementations/iteration.jl +++ b/BaseInterfaces/src/implementations/iteration.jl @@ -1,8 +1,3 @@ - -# @implements IterationInterface{(:reverse,:indexing)} UnitRange [1:5, -2:2] -# @implements IterationInterface{(:reverse,:indexing)} StepRange [1:2:10, 20:-10:-20] -# @implements IterationInterface{(:reverse,:indexing)} Array [[1, 2, 3, 4], [:a :b; :c :d]] -# @implements IterationInterface{(:reverse,:indexing)} Tuple [(1, 2, 3, 4)] @static if VERSION >= v"1.9.0" @implements IterationInterface{(:reverse,:indexing)} NamedTuple [(a=1, b=2, c=3, d=4)] else @@ -13,12 +8,3 @@ end @implements IterationInterface Number [1, 1.0, 1.0f0, UInt(8), false] @implements IterationInterface{:reverse} Base.Generator [(i for i in 1:5), (i for i in 1:5)] # @implements IterationInterface{(:reverse,:indexing)} Base.EachLine [eachline(joinpath(dirname(pathof(BaseInterfaces)), "implementations.jl"))] - -# @implements IterationInterface Set [Set((1, 2, 3, 4))] -# @implements IterationInterface BitSet [BitSet((1, 2, 3, 4))] -# @implements IterationInterface Dict [Dict("a" => 2, :b => 3.0)] -# @implements IterationInterface Base.EnvDict [Arguments(d=Base.EnvDict())] -# @implements IterationInterface Base.ImmutableDict [Arguments(d=Base.ImmutableDict(:a => 1, :b => 2))] -# @implements IterationInterface IdDict -# @implements IterationInterface WeakKeyDict - From 1dfc7f28aa2d8cd2a205a2b34523c8e4edb95550 Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 3 Mar 2024 11:51:56 +0100 Subject: [PATCH 5/7] cleanup --- BaseInterfaces/src/interfaces/array.jl | 2 +- BaseInterfaces/src/interfaces/dict.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseInterfaces/src/interfaces/array.jl b/BaseInterfaces/src/interfaces/array.jl index e82b321..b755548 100644 --- a/BaseInterfaces/src/interfaces/array.jl +++ b/BaseInterfaces/src/interfaces/array.jl @@ -201,4 +201,4 @@ array_components = (; _wrappertype(A) = Base.typename(typeof(A)).wrapper -@interface ArrayInterface <: Union{IterationInterface{(:reverse,:indexing)}} AbstractArray array_components "Base Julia AbstractArray interface" +@interface ArrayInterface <: IterationInterface{(:reverse,:indexing)} AbstractArray array_components "Base Julia AbstractArray interface" diff --git a/BaseInterfaces/src/interfaces/dict.jl b/BaseInterfaces/src/interfaces/dict.jl index db79bbf..f309905 100644 --- a/BaseInterfaces/src/interfaces/dict.jl +++ b/BaseInterfaces/src/interfaces/dict.jl @@ -1,5 +1,5 @@ -@interface DictInterface <: Union{IterationInterface{(:reverse,)}} AbstractDict ( # <: CollectionInterface +@interface DictInterface <: IterationInterface{(:reverse,)} AbstractDict ( # <: CollectionInterface mandatory = (; iterate = "AbstractDict follows the IterationInterface" => a -> Interfaces.test(IterationInterface, a.d; show=false) && first(iterate(a.d)) isa Pair, eltype = "eltype is a Pair" => a -> eltype(a.d) <: Pair, From d8dcbb176fe6cf4f3c1769ccab3039071fc48acc Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 3 Mar 2024 12:03:17 +0100 Subject: [PATCH 6/7] no assum_effects --- src/implements.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/implements.jl b/src/implements.jl index 35792b3..9822d76 100644 --- a/src/implements.jl +++ b/src/implements.jl @@ -47,7 +47,7 @@ inherited_type(::Type{<:Interface{<:Any,Inherits}}) where Inherits = Inherits inherited_basetype(::Type{T}) where T = basetypeof(inherited_type(T)) inherited_optional_keys(::Type{<:Interface{Optional}}) where Optional = Optional -Base.@assume_effects :foldable function inherited_optional_keys(::Type{T}) where T<:Union +function inherited_optional_keys(::Type{T}) where T<:Union map(propertynames(T)) do pn inherited_optional_keys(getproperty(T, pn)) end @@ -109,7 +109,7 @@ _as_tuple(x) = (x,) struct Implemented{T<:Interface} end struct NotImplemented{T<:Interface} end -Base.@assume_effects :foldable function basetypeof(::Type{T}) where T +function basetypeof(::Type{T}) where T if T isa Union types = map(propertynames(T)) do pn t = getproperty(T, pn) From 692b95ba8a1106b2c985d601838185bd54c09bee Mon Sep 17 00:00:00 2001 From: rafaqz Date: Sun, 3 Mar 2024 12:26:52 +0100 Subject: [PATCH 7/7] fix all the tests --- BaseInterfaces/test/runtests.jl | 2 +- src/implements.jl | 3 --- src/interface.jl | 5 ----- src/test.jl | 2 +- 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/BaseInterfaces/test/runtests.jl b/BaseInterfaces/test/runtests.jl index d1e87e5..81bdeeb 100644 --- a/BaseInterfaces/test/runtests.jl +++ b/BaseInterfaces/test/runtests.jl @@ -6,7 +6,7 @@ using Test @implements SetInterface{(:empty,:emptymutable,:hasfastin,:intersect,:union,:sizehint!)} Test.GenericSet [Test.GenericSet(Set((1, 2)))] @implements DictInterface Test.GenericDict [Arguments(d=Test.GenericDict(Dict(:a => 1, :b => 2)), k=:c, v=3)] -@test "inheritance" begin +@testset "inheritance" begin # Inherited interfaces are stored in the second parameter of the supertype @test supertype(ArrayInterface) <: Interfaces.Interface{<:Any,IterationInterface{(:reverse, :indexing)}} @test supertype(DictInterface) <: Interfaces.Interface{<:Any,IterationInterface{(:reverse,)}} diff --git a/src/implements.jl b/src/implements.jl index 9822d76..54436f6 100644 --- a/src/implements.jl +++ b/src/implements.jl @@ -103,9 +103,6 @@ _user_optional_keys(::Type{<:Interface}) = () _all_in(items::Tuple, collection) = all(map(in(collection), items)) _all_in(item::Symbol, collection) = in(item, collection) -_as_tuple(xs::Tuple) = xs -_as_tuple(x) = (x,) - struct Implemented{T<:Interface} end struct NotImplemented{T<:Interface} end diff --git a/src/interface.jl b/src/interface.jl index fee6115..d89c17c 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -30,17 +30,12 @@ function _flatten_inheritance(::Type{T}) where T else T end - @show T t - println() - println() return t end function _flatten_inheritance( ::Type{T} ) where T<:Interface{Options,Inherited} where {Options,Inherited} t = Inherited <: Nothing ? T : Union{T,Inherited} - @show T t - println() return t end diff --git a/src/test.jl b/src/test.jl index 063d333..f1bdb0a 100644 --- a/src/test.jl +++ b/src/test.jl @@ -144,7 +144,7 @@ function test(::Type{T}; show=true, kw...) where T results = map(methodlist) do m t = m.sig.parameters[2].var.ub t isa UnionAll || return true - interface = t.body.name.wrapper + interface = t.body.body.name.wrapper # If T implements it, test that if implements(interface, T) interface, test(interface, T; show, kw...)