Skip to content

Commit f51f9b5

Browse files
authored
Merge pull request #95 from JuliaArrays/teh/disable_convert_error
For now, disable the distinction between coercion and conversion
2 parents f10500a + 272d795 commit f51f9b5

File tree

4 files changed

+38
-83
lines changed

4 files changed

+38
-83
lines changed

READMEOLD.md

Lines changed: 0 additions & 63 deletions
This file was deleted.

docs/src/internals.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ julia> oa2[ax2[2]]
106106
```
107107

108108
`IdOffsetRange`s apply the offset both to the values and the indices of the range, and otherwise preserve the parent range.
109+
110+
!!! warning
111+
112+
There are circumstances where constructing a specific type of `IdOffsetRange` cannot be supported without changing the axes of the range (see [`OffsetArrays.IdOffsetRange`](@ref).)
113+
In the future, this package will distinguish between *construction* and *conversion*:
114+
115+
- construction (aka, *coercion*) will always succeed, even if it has to change the axes of the result (Examples: `RangeType(rng)`, `typeof(rng1)(rng2)`)
116+
- conversion will succeed only if it can preserve both the values and the axes (Examples: `convert(RangeType, rng)`, `oftype(rng1, rng2)`)
117+
118+
While these behave equivalently now (conversion currently performs coercion), developers are encouraged to "future-proof" their code by choosing the behavior appropriate for each usage.

src/axes.jl

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,25 @@ has `r[3] == 3` and `r[4] == 4`, and `r[1]` would throw a `BoundsError`.
5353
In this latter case, a shift in the axes was needed because `Base.OneTo` ranges
5454
must start with value 1.
5555
56-
In contrast, *conversion* preserves both the values and the indices, throwing an error
57-
when this is not achievable. For instance,
56+
!!! warning
5857
59-
r = convert(OffsetArrays.IdOffsetRange{Int,UnitRange{Int}}, 3:4)
58+
In the future, *conversion* will preserve both the values and
59+
the indices, throwing an error when this is not achievable. For instance,
6060
61-
has `r[1] == 3` and `r[2] == 4` and would satisfy `r == 3:4`, whereas
61+
r = convert(OffsetArrays.IdOffsetRange{Int,UnitRange{Int}}, 3:4)
6262
63-
```jldoctest; setup=:(import OffsetArrays)
64-
julia> convert(OffsetArrays.IdOffsetRange{Int,Base.OneTo{Int}}, 3:4)
65-
ERROR: ArgumentError: first element must be 1, got 3
66-
```
63+
has `r[1] == 3` and `r[2] == 4` and would satisfy `r == 3:4`, whereas
64+
65+
```
66+
julia> convert(OffsetArrays.IdOffsetRange{Int,Base.OneTo{Int}}, 3:4) # future behavior, not present behavior
67+
ERROR: ArgumentError: first element must be 1, got 3
68+
```
6769
68-
where the error arises because the result could not have the same axes as the input.
70+
where the error will arise because the result could not have the same axes as the input.
6971
70-
An important corollary is that `typeof(r1)(r2)` and `oftype(r1, r2)` behave differently:
71-
the first coerces `r2` to be of the type of `r1`, whereas the second converts.
72+
An important corollary is that `typeof(r1)(r2)` and `oftype(r1, r2)` will behave differently:
73+
the first coerces `r2` to be of the type of `r1`, whereas the second converts.
74+
Developers are urged to future-proof their code by choosing the behavior appropriate for each usage.
7275
"""
7376
struct IdOffsetRange{T<:Integer,I<:AbstractUnitRange{T}} <: AbstractUnitRange{T}
7477
parent::I
@@ -100,13 +103,14 @@ function IdOffsetRange{T}(r::IdOffsetRange) where T<:Integer
100103
end
101104
IdOffsetRange(r::IdOffsetRange) = r
102105

103-
# Conversion preserves both the values and the indexes, throwing an InexactError if this
104-
# is not possible.
105-
Base.convert(::Type{IdOffsetRange{T,I}}, r::IdOffsetRange{T,I}) where {T<:Integer,I<:AbstractUnitRange{T}} = r
106-
Base.convert(::Type{IdOffsetRange{T,I}}, r::IdOffsetRange) where {T<:Integer,I<:AbstractUnitRange{T}} =
107-
IdOffsetRange{T,I}(convert(I, r.parent), r.offset)
108-
Base.convert(::Type{IdOffsetRange{T,I}}, r::AbstractUnitRange) where {T<:Integer,I<:AbstractUnitRange{T}} =
109-
IdOffsetRange{T,I}(convert(I, r), 0)
106+
# TODO: uncomment these when Julia is ready
107+
# # Conversion preserves both the values and the indexes, throwing an InexactError if this
108+
# # is not possible.
109+
# Base.convert(::Type{IdOffsetRange{T,I}}, r::IdOffsetRange{T,I}) where {T<:Integer,I<:AbstractUnitRange{T}} = r
110+
# Base.convert(::Type{IdOffsetRange{T,I}}, r::IdOffsetRange) where {T<:Integer,I<:AbstractUnitRange{T}} =
111+
# IdOffsetRange{T,I}(convert(I, r.parent), r.offset)
112+
# Base.convert(::Type{IdOffsetRange{T,I}}, r::AbstractUnitRange) where {T<:Integer,I<:AbstractUnitRange{T}} =
113+
# IdOffsetRange{T,I}(convert(I, r), 0)
110114

111115
offset_coerce(::Type{Base.OneTo{T}}, r::Base.OneTo) where T<:Integer = convert(Base.OneTo{T}, r), 0
112116
function offset_coerce(::Type{Base.OneTo{T}}, r::AbstractUnitRange) where T<:Integer

test/runtests.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,14 @@ using CatIndices: BidirectionalVector
6363
@test typeof(r2) === typeof(rs)
6464
@test same_value(r2, 1:3)
6565
check_indexed_by(r2, 1:3)
66-
@test_throws ArgumentError oftype(ro, rs)
66+
# These two broken tests can be fixed by uncommenting the `convert` definitions
67+
# in axes.jl, but unfortunately Julia may not quite be ready for this. (E.g. `reinterpretarray.jl`)
68+
@test_broken try oftype(ro, rs); false catch err true end # replace with line below
69+
# @test_throws ArgumentError oftype(ro, rs)
6770
@test @inferred(oftype(ro, Base.OneTo(2))) === OffsetArrays.IdOffsetRange(Base.OneTo(2))
6871
@test @inferred(oftype(ro, 1:2)) === OffsetArrays.IdOffsetRange(Base.OneTo(2))
69-
@test_throws ArgumentError oftype(ro, 3:4)
72+
@test_broken try oftype(ro, 3:4); false catch err true end
73+
# @test_throws ArgumentError oftype(ro, 3:4)
7074
end
7175

7276
@testset "Single-entry arrays in dims 0:5" begin

0 commit comments

Comments
 (0)