Skip to content

Commit f31cd07

Browse files
gaftermcmcgrath13
andauthored
Add compat version of the macro (needed for rai) (#50)
Version 2.1.0 Co-authored-by: Mary McGrath <[email protected]>
1 parent 0a1e379 commit f31cd07

File tree

8 files changed

+95
-102
lines changed

8 files changed

+95
-102
lines changed

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
The AutoHashEquals.jl package is licensed under the MIT "Expat" License:
44

5-
Copyright (c) 2015-2023: andrew cooke, RelationalAI, Inc, and contributors.
5+
Copyright (c) 2015-2023: Neal Gafter, Andrew Cooke, RelationalAI, Inc, and contributors.
66

77
Permission is hereby granted, free of charge, to any person obtaining a copy
88
of this software and associated documentation files (the "Software"), to deal

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "AutoHashEquals"
22
uuid = "15f4f7f2-30c1-5605-9d31-71845cf9641f"
33
authors = ["Neal Gafter <[email protected]>", "andrew cooke <[email protected]>"]
4-
version = "2.0.0"
4+
version = "2.1.0"
55

66
[deps]
77
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,10 @@ end
214214
@assert Box891(missing) != Box891(1)
215215
@assert !isequal(Box891(missing), Box891(1))
216216
```
217+
218+
If you need compatibility mode always and don't want to have to specify the mode on each invocation,
219+
you can instead import the compatibility version of the macro, which defaults to `compat1=true':
220+
221+
```julia
222+
using AutoHashEquals.Compat
223+
```

src/AutoHashEquals.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export @auto_hash_equals
66

77
include("type_seed.jl")
88
include("impl.jl")
9+
include("compat.jl")
910

1011
"""
1112
@auto_hash_equals [options] struct Foo ... end

src/compat.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module Compat
2+
3+
using AutoHashEquals: AutoHashEquals
4+
5+
export @auto_hash_equals
6+
7+
"""
8+
@auto_hash_equals [options] struct Foo ... end
9+
10+
Generate `Base.hash`, `Base.isequal`, and `Base.==` methods for `Foo`.
11+
12+
Options:
13+
14+
* `cache=true|false` whether or not to generate an extra cache field to store the precomputed hash value. Default: `false`.
15+
* `hashfn=myhash` the hash function to use. Default: `Base.hash`.
16+
* `fields=a,b,c` the fields to use for hashing and equality. Default: all fields.
17+
* `typearg=true|false` whether or not to make type arguments significant. Default: `false`.
18+
* `typeseed=e` Use `e` (or `e(type)` if `typearg=true`) as the seed for hashing type arguments.
19+
* `compat1=true` To have `==` defined by using `isequal`. Default: `true`.
20+
"""
21+
macro auto_hash_equals(args...)
22+
esc(:($AutoHashEquals.@auto_hash_equals(compat1=true, $(args...))))
23+
end
24+
25+
end

src/impl.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ function auto_hash_equals_impl(__source__, struct_decl, fields, cache::Bool, has
234234
if typearg
235235
:($type_seed($full_type_name))
236236
else
237-
Base.hash(type_name)
237+
:($hashfn($(QuoteNode(type_name))))
238238
end
239239
else
240240
if typearg
@@ -275,11 +275,11 @@ function auto_hash_equals_impl(__source__, struct_decl, fields, cache::Bool, has
275275
if typearg
276276
:($type_seed($full_type_name, h))
277277
else
278-
:($(Base.hash)($(QuoteNode(type_name)), h))
278+
:($hashfn($(QuoteNode(type_name)), h))
279279
end
280280
else
281281
if typearg
282-
:(h + UInt($typeseed($full_type_name)))
282+
:(UInt($typeseed($full_type_name, h)))
283283
else
284284
:(h + UInt($typeseed))
285285
end
@@ -360,9 +360,6 @@ function auto_hash_equals_impl(__source__, struct_decl, fields, cache::Bool, has
360360
equality_impl = :(a === b || $equality_impl)
361361
end
362362
else
363-
# Julia library defines `isequal` in terms of `==`.
364-
compat1 && continue
365-
366363
# Here we have a more complicated implementation in order to handle missings correctly.
367364
# If any field comparison is false, we return false (even if some return missing).
368365
# If no field comparisons are false, but one comparison missing, then we return missing.

test/compat.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module compat
2+
3+
using AutoHashEquals.Compat: @auto_hash_equals
4+
using Test
5+
6+
@testset "test the compat macro" begin
7+
@auto_hash_equals struct Box851{T}
8+
x::T
9+
end
10+
@test Box851(missing) == Box851(missing)
11+
@test isequal(Box851(missing), Box851(missing))
12+
@test Box851(missing) != Box851(1)
13+
@test !isequal(Box851(missing), Box851(1))
14+
end
15+
16+
end

test/runtests.jl

Lines changed: 41 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# SPDX-License-Identifier: MIT
22

3+
include("compat.jl")
4+
35
module runtests
46

5-
using AutoHashEquals: @auto_hash_equals
7+
using AutoHashEquals: AutoHashEquals, @auto_hash_equals
68
using Markdown: plain
79
using Match: Match, @match, MatchFailure
810
using Random
@@ -23,15 +25,6 @@ macro noop(x)
2325
esc(x)
2426
end
2527

26-
macro _const(x)
27-
# const fields were introduced in Julia 1.8
28-
if VERSION >= v"1.8"
29-
esc(Expr(:const , x))
30-
else
31-
esc(x)
32-
end
33-
end
34-
3528
"""
3629
@auto_hash_equals_cached struct Foo ... end
3730
@@ -114,14 +107,12 @@ abstract type B{T} end
114107
end
115108

116109
@testset "the macro sees through `const`" begin
117-
if VERSION >= v"1.8"
118-
T33 = eval(:(@auto_hash_equals mutable struct T33
119-
@_const x
120-
end))
121-
@test T33(1) == T33(1)
122-
@test hash(T33(1)) == hash(T33(1))
123-
@test hash(T33(1)) != hash(T33(2))
124-
end
110+
T33 = eval(:(@auto_hash_equals mutable struct T33
111+
const x
112+
end))
113+
@test T33(1) == T33(1)
114+
@test hash(T33(1)) == hash(T33(1))
115+
@test hash(T33(1)) != hash(T33(2))
125116
end
126117

127118
@testset "misuse of the macro" begin
@@ -288,12 +279,7 @@ abstract type B{T} end
288279
end
289280

290281
# @test_throws requires a type before v1.8.
291-
internal_constructor_error =
292-
if VERSION >= v"1.7"
293-
ErrorException
294-
else
295-
LoadError
296-
end
282+
internal_constructor_error = ErrorException
297283

298284
@testset "give an error if the struct contains internal constructors 1" begin
299285
@test_throws internal_constructor_error begin
@@ -663,89 +649,49 @@ abstract type B{T} end
663649
x
664650
end
665651

666-
if VERSION < v"1.7"
667-
@test 0x67d66c8ebce604c4 === hash(Box1(1))
668-
@test 0x57ce10fa6d65774c === hash(Box1(:x))
669-
@test 0x7951851906420162 === hash(Box1("a"))
670-
@test 0x6a46c6ef41c6b97d === hash(Box1(1), UInt(1))
671-
@test 0x0ef668a2dd4500a0 === hash(Box1(:x), UInt(1))
672-
@test 0x7398684da66deba5 === hash(Box1("a"), UInt(1))
673-
else
674-
@test 0x05014b35fc91d289 === hash(Box1(1))
675-
@test 0x91d7652c7a24efb3 === hash(Box1(:x))
676-
@test 0x1d9ac96f957cc50a === hash(Box1("a"))
677-
@test 0x6e0378444e962be8 === hash(Box1(1), UInt(1))
678-
@test 0xa31a1cd3c72d944c === hash(Box1(:x), UInt(1))
679-
@test 0xe563b59c847e3d2f === hash(Box1("a"), UInt(1))
680-
end
652+
@test 0x05014b35fc91d289 === hash(Box1(1))
653+
@test 0x91d7652c7a24efb3 === hash(Box1(:x))
654+
@test 0x1d9ac96f957cc50a === hash(Box1("a"))
655+
@test 0x6e0378444e962be8 === hash(Box1(1), UInt(1))
656+
@test 0xa31a1cd3c72d944c === hash(Box1(:x), UInt(1))
657+
@test 0xe563b59c847e3d2f === hash(Box1("a"), UInt(1))
681658

682659
@auto_hash_equals struct Box2{T}
683660
x::T
684661
end
685662

686-
if VERSION < v"1.7"
687-
@test 0x97e8e85cce6400e5 === hash(Box2(1))
688-
@test 0x97e8e85cce6400e5 === hash(Box2{Any}(1))
689-
@test 0x95c1c5ce8a9d4310 === hash(Box2(:x))
690-
@test 0x9424a3ad9ea0312c === hash(Box2("a"))
691-
@test 0xd7caed9a4e280b13 === hash(Box2(1), UInt(1))
692-
@test 0xd7caed9a4e280b13 === hash(Box2{Any}(1), UInt(1))
693-
@test 0x3c6236446852acfb === hash(Box2(:x), UInt(1))
694-
@test 0x08aaed0ddd68f482 === hash(Box2("a"), UInt(1))
695-
else
696-
@test 0xfddfe30b106aa2f0 === hash(Box2(1))
697-
@test 0xfddfe30b106aa2f0 === hash(Box2{Any}(1))
698-
@test 0xb9abdfa5883b32bb === hash(Box2(:x))
699-
@test 0x6c49b14653a071c6 === hash(Box2("a"))
700-
@test 0x451b0ebf9ee0f99c === hash(Box2(1), UInt(1))
701-
@test 0x451b0ebf9ee0f99c === hash(Box2{Any}(1), UInt(1))
702-
@test 0x175e9079609f34c5 === hash(Box2(:x), UInt(1))
703-
@test 0x77cf64ab93060d1e === hash(Box2("a"), UInt(1))
704-
end
663+
@test 0xfddfe30b106aa2f0 === hash(Box2(1))
664+
@test 0xfddfe30b106aa2f0 === hash(Box2{Any}(1))
665+
@test 0xb9abdfa5883b32bb === hash(Box2(:x))
666+
@test 0x6c49b14653a071c6 === hash(Box2("a"))
667+
@test 0x451b0ebf9ee0f99c === hash(Box2(1), UInt(1))
668+
@test 0x451b0ebf9ee0f99c === hash(Box2{Any}(1), UInt(1))
669+
@test 0x175e9079609f34c5 === hash(Box2(:x), UInt(1))
670+
@test 0x77cf64ab93060d1e === hash(Box2("a"), UInt(1))
705671

706672
@auto_hash_equals struct Box3
707673
x
708674
end
709675

710-
if VERSION < v"1.7"
711-
@test 0xa28c5530534e00ff === hash(Box3(1))
712-
@test 0xbd098dc8d84b2b3c === hash(Box3(:x))
713-
@test 0x306232d62b351152 === hash(Box3("a"))
714-
@test 0xd4f16da2b818329f === hash(Box3(1), UInt(1))
715-
@test 0xbc02b85a84d59f22 === hash(Box3(:x), UInt(1))
716-
@test 0xf3298984f3d3f10e === hash(Box3("a"), UInt(1))
717-
else
718-
@test 0x6c8a62ecebe7d0ce === hash(Box3(1))
719-
@test 0xb3dc0f774c8dbf65 === hash(Box3(:x))
720-
@test 0x18c77bdc2543b944 === hash(Box3("a"))
721-
@test 0x1fe5e7cdd29edab1 === hash(Box3(1), UInt(1))
722-
@test 0x55e8647bf53d5ecd === hash(Box3(:x), UInt(1))
723-
@test 0xf556f204c1f1bc53 === hash(Box3("a"), UInt(1))
724-
end
676+
@test 0x6c8a62ecebe7d0ce === hash(Box3(1))
677+
@test 0xb3dc0f774c8dbf65 === hash(Box3(:x))
678+
@test 0x18c77bdc2543b944 === hash(Box3("a"))
679+
@test 0x1fe5e7cdd29edab1 === hash(Box3(1), UInt(1))
680+
@test 0x55e8647bf53d5ecd === hash(Box3(:x), UInt(1))
681+
@test 0xf556f204c1f1bc53 === hash(Box3("a"), UInt(1))
725682

726683
@auto_hash_equals struct Box4{T}
727684
x::T
728685
end
729686

730-
if VERSION < v"1.7"
731-
@test 0xa0164c66e926af40 === hash(Box4(1))
732-
@test 0xa0164c66e926af40 === hash(Box4{Any}(1))
733-
@test 0xcb0ce1b2da05840b === hash(Box4(:x))
734-
@test 0xc10479084e27e5db === hash(Box4("a"))
735-
@test 0xdbc4ab0260836c4a === hash(Box4(1), UInt(1))
736-
@test 0xdbc4ab0260836c4a === hash(Box4{Any}(1), UInt(1))
737-
@test 0x485f0ce7fd57b390 === hash(Box4(:x), UInt(1))
738-
@test 0xaff3b9595e40223d === hash(Box4("a"), UInt(1))
739-
else
740-
@test 0x98dc0cd9a86cbdee === hash(Box4(1))
741-
@test 0x98dc0cd9a86cbdee === hash(Box4{Any}(1))
742-
@test 0x3dbd99c859966133 === hash(Box4(:x))
743-
@test 0xa7d6e8579ef5a8cd === hash(Box4("a"))
744-
@test 0x44ac08ef000cb686 === hash(Box4(1), UInt(1))
745-
@test 0x44ac08ef000cb686 === hash(Box4{Any}(1), UInt(1))
746-
@test 0xc7dc8347992b452d === hash(Box4(:x), UInt(1))
747-
@test 0x3dcb6b6168a2c18d === hash(Box4("a"), UInt(1))
748-
end
687+
@test 0x98dc0cd9a86cbdee === hash(Box4(1))
688+
@test 0x98dc0cd9a86cbdee === hash(Box4{Any}(1))
689+
@test 0x3dbd99c859966133 === hash(Box4(:x))
690+
@test 0xa7d6e8579ef5a8cd === hash(Box4("a"))
691+
@test 0x44ac08ef000cb686 === hash(Box4(1), UInt(1))
692+
@test 0x44ac08ef000cb686 === hash(Box4{Any}(1), UInt(1))
693+
@test 0xc7dc8347992b452d === hash(Box4(:x), UInt(1))
694+
@test 0x3dcb6b6168a2c18d === hash(Box4("a"), UInt(1))
749695

750696
end
751697

@@ -806,7 +752,7 @@ abstract type B{T} end
806752
w::T
807753
end
808754
@test hash(S640{Int}(1)) == hash(1, hash(S640{Int}))
809-
@test hash(S640{Int}(1), UInt(2)) == hash(1, UInt(2) + hash(S640{Int}))
755+
@test hash(S640{Int}(1), UInt(2)) == hash(1, hash(S640{Int}, UInt(2)))
810756
end
811757

812758
@testset "test typearg=false typeseed=K generic type" begin
@@ -822,7 +768,7 @@ abstract type B{T} end
822768
w
823769
end
824770
@test hash(S650(1)) == hash(1, hash(S650))
825-
@test hash(S650(1), UInt(2)) == hash(1, UInt(2) + hash(S650))
771+
@test hash(S650(1), UInt(2)) == hash(1, hash(S650, UInt(2)))
826772
end
827773

828774
@testset "test typearg=false typeseed=e non-generic type" begin
@@ -902,6 +848,7 @@ abstract type B{T} end
902848
@test Box891(missing) != Box891(1)
903849
@test !isequal(Box891(missing), Box891(1))
904850
end
851+
905852
end
906853
end
907854

0 commit comments

Comments
 (0)