From 770c678fbb7f41fa51d77f5b7d39f833add04142 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Wed, 13 Jan 2021 12:55:35 +0100 Subject: [PATCH 1/8] Add range(start, stop) and range(start, stop, length) --- NEWS.md | 1 + base/range.jl | 22 +++++++++------------- test/ranges.jl | 6 ++++-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/NEWS.md b/NEWS.md index e4c88c5b25177..37849117223a8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -40,6 +40,7 @@ Standard library changes ------------------------ * `count` and `findall` now accept an `AbstractChar` argument to search for a character in a string ([#38675]). +* `range` now supports the `range(start, stop)` and `range(start, stop, length)` methods ([#????]). * `range` now supports `start` as an optional keyword argument ([#38041]). * `islowercase` and `isuppercase` are now compliant with the Unicode lower/uppercase categories ([#38574]). * `iseven` and `isodd` functions now support non-`Integer` numeric types ([#38976]). diff --git a/base/range.jl b/base/range.jl index 6e5a86f9c863f..471458892a640 100644 --- a/base/range.jl +++ b/base/range.jl @@ -47,6 +47,7 @@ function _colon(start::T, step, stop::T) where T end """ + range(start, stop, length) range(start, stop; length, step) range(start; length, stop, step) range(;start, length, stop, step) @@ -97,33 +98,28 @@ Special care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the [`LinRange`](@ref) constructor. Both `start` and `stop` may be specified as either a positional or keyword arguments. -If both are specified as positional arguments, one of `step` or `length` must also be provided. !!! compat "Julia 1.1" `stop` as a positional argument requires at least Julia 1.1. !!! compat "Julia 1.7" `start` as a keyword argument requires at least Julia 1.7. + +!!! compat "Julia 1.7" + the versions without keyword arguments require at least Julia 1.7. """ function range end range(start; stop=nothing, length::Union{Integer,Nothing}=nothing, step=nothing) = _range(start, step, stop, length) - +range(start, stop, length::Integer) = _range(start, nothing, stop, length) function range(start, stop; length::Union{Integer,Nothing}=nothing, step=nothing) - # For code clarity, the user must pass step or length - # See https://github.com/JuliaLang/julia/pull/28708#issuecomment-420034562 - if step === length === nothing - msg = """ - Neither `step` nor `length` was provided. To fix this do one of the following: - * Pass one of them - * Use `$(start):$(stop)` - * Use `range($start, stop=$stop)` - """ - throw(ArgumentError(msg)) + if length === nothing && step === nothing + step = 1 end - _range(start, step, stop, length) + range(start, step, stop, length) end +range(start, stop) = _range(start, 1, stop, nothing) range(;start=nothing, stop=nothing, length::Union{Integer, Nothing}=nothing, step=nothing) = _range(start, step, stop, length) diff --git a/test/ranges.jl b/test/ranges.jl index b9f77f211193d..aec80519f35f7 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -14,9 +14,11 @@ r = 4:9 @test r === range(start=first(r), stop=last(r) ) @test r === range(start=first(r), length=length(r)) - # the next one uses ==, because it changes the eltype - @test r == range(start=first(r), stop=last(r), length=length(r)) @test r === range( stop=last(r), length=length(r)) + @test r === range(first(r), last(r)) + # the next ones use ==, because it changes the eltype + @test r == range(first(r), last(r), length(r)) + @test r == range(start=first(r), stop=last(r), length=length(r)) end end From 5167671b2e8bd2fb31371e3fa177358d47d90353 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Wed, 13 Jan 2021 13:01:29 +0100 Subject: [PATCH 2/8] Remove confusing comment --- base/range.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/base/range.jl b/base/range.jl index 471458892a640..2b0a3aea32782 100644 --- a/base/range.jl +++ b/base/range.jl @@ -97,8 +97,6 @@ julia> range(1, 3.5, step=2) Special care is taken to ensure intermediate values are computed rationally. To avoid this induced overhead, see the [`LinRange`](@ref) constructor. -Both `start` and `stop` may be specified as either a positional or keyword arguments. - !!! compat "Julia 1.1" `stop` as a positional argument requires at least Julia 1.1. From 7241fdaa13a8028c86d125afb1901aaeea1e0396 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Wed, 13 Jan 2021 15:35:32 +0100 Subject: [PATCH 3/8] review --- NEWS.md | 2 +- base/range.jl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 37849117223a8..e3e5cac05755e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -40,7 +40,7 @@ Standard library changes ------------------------ * `count` and `findall` now accept an `AbstractChar` argument to search for a character in a string ([#38675]). -* `range` now supports the `range(start, stop)` and `range(start, stop, length)` methods ([#????]). +* `range` now supports the `range(start, stop)` and `range(start, stop, length)` methods ([#39228]). * `range` now supports `start` as an optional keyword argument ([#38041]). * `islowercase` and `isuppercase` are now compliant with the Unicode lower/uppercase categories ([#38574]). * `iseven` and `isodd` functions now support non-`Integer` numeric types ([#38976]). diff --git a/base/range.jl b/base/range.jl index 2b0a3aea32782..4f4d85a6edcbb 100644 --- a/base/range.jl +++ b/base/range.jl @@ -117,7 +117,6 @@ function range(start, stop; length::Union{Integer,Nothing}=nothing, step=nothing end range(start, step, stop, length) end -range(start, stop) = _range(start, 1, stop, nothing) range(;start=nothing, stop=nothing, length::Union{Integer, Nothing}=nothing, step=nothing) = _range(start, step, stop, length) From c2cb8d0f896ee8ea53e099318376d65710ca25c2 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Wed, 13 Jan 2021 15:38:12 +0100 Subject: [PATCH 4/8] review --- base/range.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/range.jl b/base/range.jl index 4f4d85a6edcbb..a5e49b5a4665e 100644 --- a/base/range.jl +++ b/base/range.jl @@ -115,7 +115,7 @@ function range(start, stop; length::Union{Integer,Nothing}=nothing, step=nothing if length === nothing && step === nothing step = 1 end - range(start, step, stop, length) + _range(start, step, stop, length) end range(;start=nothing, stop=nothing, length::Union{Integer, Nothing}=nothing, step=nothing) = From fc6d219232d89d87d9c11f17a91455d37d4f993f Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Wed, 13 Jan 2021 15:40:29 +0100 Subject: [PATCH 5/8] review --- base/range.jl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/base/range.jl b/base/range.jl index a5e49b5a4665e..97bc6da2fb572 100644 --- a/base/range.jl +++ b/base/range.jl @@ -110,13 +110,8 @@ function range end range(start; stop=nothing, length::Union{Integer,Nothing}=nothing, step=nothing) = _range(start, step, stop, length) +range(start, stop; length::Union{Integer,Nothing}=nothing, step=nothing) = _range(start, step, stop, length) range(start, stop, length::Integer) = _range(start, nothing, stop, length) -function range(start, stop; length::Union{Integer,Nothing}=nothing, step=nothing) - if length === nothing && step === nothing - step = 1 - end - _range(start, step, stop, length) -end range(;start=nothing, stop=nothing, length::Union{Integer, Nothing}=nothing, step=nothing) = _range(start, step, stop, length) From 5a7e6edc1bec9d8dfa2cb33b4e0c4219ce515877 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Wed, 13 Jan 2021 16:39:09 +0100 Subject: [PATCH 6/8] review --- base/range.jl | 6 ++---- test/ranges.jl | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/base/range.jl b/base/range.jl index 97bc6da2fb572..8ca2a0d9bb2a6 100644 --- a/base/range.jl +++ b/base/range.jl @@ -101,10 +101,8 @@ To avoid this induced overhead, see the [`LinRange`](@ref) constructor. `stop` as a positional argument requires at least Julia 1.1. !!! compat "Julia 1.7" - `start` as a keyword argument requires at least Julia 1.7. - -!!! compat "Julia 1.7" - the versions without keyword arguments require at least Julia 1.7. + The versions without keyword arguments and `start` as a keyword argument + require at least Julia 1.7. """ function range end diff --git a/test/ranges.jl b/test/ranges.jl index aec80519f35f7..df2b8e820454d 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1628,8 +1628,6 @@ end end end end - # require a keyword arg - @test_throws ArgumentError range(1, 100) end @testset "Reverse empty ranges" begin From 0e41a9e2cc53dace5ea1df2c67d33dbf742bac96 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Sat, 16 Jan 2021 10:16:51 +0100 Subject: [PATCH 7/8] whitespace --- test/ranges.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ranges.jl b/test/ranges.jl index df2b8e820454d..674a0b2765e40 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -15,10 +15,10 @@ @test r === range(start=first(r), stop=last(r) ) @test r === range(start=first(r), length=length(r)) @test r === range( stop=last(r), length=length(r)) - @test r === range(first(r), last(r)) + @test r === range(first(r), last(r) ) # the next ones use ==, because it changes the eltype - @test r == range(first(r), last(r), length(r)) - @test r == range(start=first(r), stop=last(r), length=length(r)) + @test r == range(first(r), last(r), length(r) ) + @test r == range(start=first(r), stop=last(r), length=length(r)) end end From 770a02b9dce33207eab24ff52a4d5599723c39f7 Mon Sep 17 00:00:00 2001 From: Antoine Levitt Date: Mon, 18 Jan 2021 14:22:24 +0100 Subject: [PATCH 8/8] testset --- test/ranges.jl | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/test/ranges.jl b/test/ranges.jl index 674a0b2765e40..59005013324b1 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1,25 +1,23 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license @testset "range construction" begin - @testset "range(;kw...)" begin - @test_throws ArgumentError range(start=1, step=1, stop=2, length=10) - @test_throws ArgumentError range(start=1, step=1, stop=10, length=11) - - r = 3.0:2:11 - @test r == range(start=first(r), step=step(r), stop=last(r) ) - @test r == range(start=first(r), step=step(r), length=length(r)) - @test r == range(start=first(r), stop=last(r), length=length(r)) - @test r == range( step=step(r), stop=last(r), length=length(r)) - - r = 4:9 - @test r === range(start=first(r), stop=last(r) ) - @test r === range(start=first(r), length=length(r)) - @test r === range( stop=last(r), length=length(r)) - @test r === range(first(r), last(r) ) - # the next ones use ==, because it changes the eltype - @test r == range(first(r), last(r), length(r) ) - @test r == range(start=first(r), stop=last(r), length=length(r)) - end + @test_throws ArgumentError range(start=1, step=1, stop=2, length=10) + @test_throws ArgumentError range(start=1, step=1, stop=10, length=11) + + r = 3.0:2:11 + @test r == range(start=first(r), step=step(r), stop=last(r) ) + @test r == range(start=first(r), step=step(r), length=length(r)) + @test r == range(start=first(r), stop=last(r), length=length(r)) + @test r == range( step=step(r), stop=last(r), length=length(r)) + + r = 4:9 + @test r === range(start=first(r), stop=last(r) ) + @test r === range(start=first(r), length=length(r)) + @test r === range( stop=last(r), length=length(r)) + @test r === range(first(r), last(r) ) + # the next ones use ==, because it changes the eltype + @test r == range(first(r), last(r), length(r) ) + @test r == range(start=first(r), stop=last(r), length=length(r)) end using Dates, Random