From bc1e67b08e80f83114ad712952d3d885606cb082 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Fri, 5 Feb 2021 20:58:27 -0500 Subject: [PATCH 01/11] Comment broken tests --- test/runtests.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 1cdedd4..dbdbb3c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -86,6 +86,9 @@ f(x::Int; y=3) = x + y g(; b, c, a) = a + b + c h(x::String; a, kwargs...) = x * a +#= +# MethodError: no method matching max_world(::Method) + @testset "hasmethod" begin @test hasmethod(f, typeof(ftuple(1, y=2))) @test hasmethod(f, typeof(ftuple(1))) # Agreement with using a plain Tuple @@ -100,3 +103,4 @@ h(x::String; a, kwargs...) = x * a @test !hasmethod(f, FrankenTuple{Tuple{Int},(:y,)}, world=typemin(UInt)) end +=# From ebc3a71837b6272d5dbb09657527757cc39170cc Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Fri, 5 Feb 2021 21:02:06 -0500 Subject: [PATCH 02/11] Define and test `Base.map` --- src/FrankenTuples.jl | 7 +++++++ test/runtests.jl | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/src/FrankenTuples.jl b/src/FrankenTuples.jl index 19d3ed9..caad4ad 100644 --- a/src/FrankenTuples.jl +++ b/src/FrankenTuples.jl @@ -421,4 +421,11 @@ julia> ftcall(mapreduce, ftuple(abs2, -, 1:4; init=0)) ftcall(f::Function, ft::FrankenTuple) = f(Tuple(ft)...; NamedTuple(ft)...) ftcall(f::Function, ft::FrankenTuple{Tuple{},(),Tuple{}}) = f() +# NOTE: this method signature makes sure we don't define map(f) +function Base.map(f, ft::FrankenTuple, fts::FrankenTuple...) + t = map(f, Tuple(ft), map(Tuple, fts)...) + nt = map(f, NamedTuple(ft), map(NamedTuple, fts)...) + FrankenTuple(t, nt) +end + end # module diff --git a/test/runtests.jl b/test/runtests.jl index dbdbb3c..ac67a65 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -104,3 +104,9 @@ h(x::String; a, kwargs...) = x * a @test !hasmethod(f, FrankenTuple{Tuple{Int},(:y,)}, world=typemin(UInt)) end =# + +@testset "map" begin + @test FrankenTuple((11,22), (x=33,y=44)) == map(+, FrankenTuple((1,2), (x=3,y=4)), FrankenTuple((10, 20), (x=30,y=40))) + @test_throws Exception map(+, FrankenTuple((1,2), (x=3,y=4)), FrankenTuple((10, 20), (x=30,))) + @test_throws Exception map(+, FrankenTuple((1,2), (x=3,y=4)), FrankenTuple((10,), (x=30,y=40))) +end From e241350d9d5eb978465ac790e92af8461d36c3af Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Sat, 6 Feb 2021 16:54:34 -0500 Subject: [PATCH 03/11] Remove type restriction `::Function` Any type can support the function call operation. --- src/FrankenTuples.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FrankenTuples.jl b/src/FrankenTuples.jl index caad4ad..0cede56 100644 --- a/src/FrankenTuples.jl +++ b/src/FrankenTuples.jl @@ -418,8 +418,8 @@ julia> ftcall(mapreduce, ftuple(abs2, -, 1:4; init=0)) -30 ``` """ -ftcall(f::Function, ft::FrankenTuple) = f(Tuple(ft)...; NamedTuple(ft)...) -ftcall(f::Function, ft::FrankenTuple{Tuple{},(),Tuple{}}) = f() +ftcall(f, ft::FrankenTuple) = f(Tuple(ft)...; NamedTuple(ft)...) +ftcall(f, ft::FrankenTuple{Tuple{},(),Tuple{}}) = f() # NOTE: this method signature makes sure we don't define map(f) function Base.map(f, ft::FrankenTuple, fts::FrankenTuple...) From c4ff1eff325181b386e0bec03c8a2df574ba96f2 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 16:35:24 -0500 Subject: [PATCH 04/11] Re-enable `hasmethod` functionality and tests Uses https://github.com/JuliaLang/julia/pull/30712 --- src/FrankenTuples.jl | 18 +----------------- test/runtests.jl | 4 ---- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/FrankenTuples.jl b/src/FrankenTuples.jl index 0cede56..f74e4e8 100644 --- a/src/FrankenTuples.jl +++ b/src/FrankenTuples.jl @@ -312,18 +312,7 @@ true function Base.hasmethod(f::Function, ::Type{FrankenTuple{T,names,NT}}; world=typemax(UInt)) where {T<:Tuple,names,NT<:Tuple} - hasmethod(f, T) || return false - m = which(f, T) - Base.max_world(m) <= world || return false - kws = Base.kwarg_decl(m, Core.kwftype(typeof(f))) - isempty(kws) === isempty(names) || return false - for (i, k) in enumerate(kws) - if endswith(String(k), "...") - deleteat!(kws, i) - return issubset(kws, names) - end - end - issubset(names, kws) + hasmethod(f, T, names; world=world) end function Base.hasmethod(f::Function, ::Type{FrankenTuple{T,names}}; @@ -331,11 +320,6 @@ function Base.hasmethod(f::Function, NT = Tuple{Iterators.repeated(Any, length(names))...} hasmethod(f, FrankenTuple{T,names,NT}; world=world) end -function Base.hasmethod(f::Function, - ::Type{FrankenTuple{T,(),Tuple{}}}; - world=typemax(UInt)) where {T<:Tuple} - hasmethod(f, T; world=world) -end """ ftuple(args...; kwargs...) diff --git a/test/runtests.jl b/test/runtests.jl index ac67a65..cc2bddb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -86,9 +86,6 @@ f(x::Int; y=3) = x + y g(; b, c, a) = a + b + c h(x::String; a, kwargs...) = x * a -#= -# MethodError: no method matching max_world(::Method) - @testset "hasmethod" begin @test hasmethod(f, typeof(ftuple(1, y=2))) @test hasmethod(f, typeof(ftuple(1))) # Agreement with using a plain Tuple @@ -103,7 +100,6 @@ h(x::String; a, kwargs...) = x * a @test !hasmethod(f, FrankenTuple{Tuple{Int},(:y,)}, world=typemin(UInt)) end -=# @testset "map" begin @test FrankenTuple((11,22), (x=33,y=44)) == map(+, FrankenTuple((1,2), (x=3,y=4)), FrankenTuple((10, 20), (x=30,y=40))) From 1c1633315fe6fa42e7f18f08caacb5d4791b6137 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 16:53:16 -0500 Subject: [PATCH 05/11] Copy template for Github Actions CI From https://discourse.julialang.org/t/easy-workflow-file-for-setting-up-github-actions-ci-for-your-julia-package/49765 --- .github/workflows/ci.yml | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..83c681d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +name: CI +on: + pull_request: + branches: + - master + push: + branches: + - master + tags: '*' +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - '1.3' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'. + - '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. + - 'nightly' + os: + - ubuntu-latest + arch: + - x64 + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: actions/cache@v1 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v1 + with: + file: lcov.info + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@v1 + with: + version: '1' + - run: | + julia --project=docs -e ' + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate()' + - run: | + julia --project=docs -e ' + using Documenter: doctest + using MYPACKAGE + doctest(MYPACKAGE)' # change MYPACKAGE to the name of your package + - run: julia --project=docs docs/make.jl + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} \ No newline at end of file From 40961d39d2aff0a234eaedd74dc0495ff9ecb191 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 16:57:33 -0500 Subject: [PATCH 06/11] Copy `ci.yml` from `FixArgs.jl` --- .github/workflows/ci.yml | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83c681d..9ee7e9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,22 +1,16 @@ name: CI on: - pull_request: - branches: - - master - push: - branches: - - master - tags: '*' + - push + - pull_request jobs: test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} runs-on: ${{ matrix.os }} strategy: - fail-fast: false matrix: version: - - '1.3' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'. - - '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. + - '1.2' + - '1.5' - 'nightly' os: - ubuntu-latest @@ -38,12 +32,12 @@ jobs: ${{ runner.os }}-test-${{ env.cache-name }}- ${{ runner.os }}-test- ${{ runner.os }}- - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 - with: - file: lcov.info + - uses: julia-actions/julia-uploadcodecov@latest + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} docs: name: Documentation runs-on: ubuntu-latest @@ -57,12 +51,6 @@ jobs: using Pkg Pkg.develop(PackageSpec(path=pwd())) Pkg.instantiate()' - - run: | - julia --project=docs -e ' - using Documenter: doctest - using MYPACKAGE - doctest(MYPACKAGE)' # change MYPACKAGE to the name of your package - run: julia --project=docs docs/make.jl env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} \ No newline at end of file From b94d7a2f49d4b960d5ba8ca720f348390f182c10 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 16:58:39 -0500 Subject: [PATCH 07/11] Restore some of original `ci.yml` --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ee7e9e..40936ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,13 +4,13 @@ on: - pull_request jobs: test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} strategy: matrix: version: - - '1.2' - - '1.5' + - '1.3' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'. + - '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. - 'nightly' os: - ubuntu-latest From 26fc307b772e8976a318df5a540fe7a72234cd08 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 17:27:16 -0500 Subject: [PATCH 08/11] Fix test in docstring --- src/FrankenTuples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FrankenTuples.jl b/src/FrankenTuples.jl index f74e4e8..c1542e6 100644 --- a/src/FrankenTuples.jl +++ b/src/FrankenTuples.jl @@ -300,7 +300,7 @@ julia> f(x::Int; y=3, z=4) = x + y + z; julia> hasmethod(f, FrankenTuple{Tuple{Int},(:y,)}) true -julia> hasmethod(f, FrankenTuple{Tuple{Int},(:a,)) # no keyword `a` +julia> hasmethod(f, FrankenTuple{Tuple{Int},(:a,)}) # no keyword `a` false julia> g(; a, b, kwargs...) = +(a, b, kwargs...); From e31680d925fc5790bff456f46fcff13c7b0115f7 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 17:32:57 -0500 Subject: [PATCH 09/11] Prevent doctests from breaking once 1.6 is released --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40936ba..9dee302 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@v1 with: - version: '1' + version: '1.5' # 1.6 will break doctests due to type aliases, until the tests are updated - run: | julia --project=docs -e ' using Pkg From ffb20c69eb88cddc3d4f15be2df677d7b8ac2c6a Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 17:38:14 -0500 Subject: [PATCH 10/11] Update docs --- docs/src/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/index.md b/docs/src/index.md index ea85ef1..1bde669 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -39,6 +39,7 @@ Base.first Base.tail Base.empty Base.eltype +Base.map ``` ## Additional Methods @@ -46,7 +47,6 @@ Base.eltype These are some additional ways to use `FrankenTuple`s. The most interesting of these is perhaps `hasmethod`, which permits looking for methods that have particular keyword arguments. -This is not currently possible with the generic method in Base. ```@docs Base.hasmethod From 6cc32fd462b54248fd49cb64f2f6fb1507201781 Mon Sep 17 00:00:00 2001 From: Gustavo Goretkin Date: Wed, 10 Feb 2021 17:39:14 -0500 Subject: [PATCH 11/11] Add compat bound and test minimum version Commit c4ff1e introduces a dependency on Julia 1.2 --- .github/workflows/ci.yml | 2 +- Project.toml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9dee302..2684571 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: version: - - '1.3' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'. + - '1.2' # minimum Julia version that the package supports. - '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia. - 'nightly' os: diff --git a/Project.toml b/Project.toml index 629a076..285e9d5 100644 --- a/Project.toml +++ b/Project.toml @@ -2,6 +2,9 @@ name = "FrankenTuples" uuid = "7e584817-dab4-53a9-9a51-4037a36b0ad0" version = "0.0.1" +[compat] +julia = "1.2" + [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"