Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Python] All Union cases across all union types return the same Hash Code #3640

Closed
HLWeil opened this issue Dec 4, 2023 · 0 comments · Fixed by #3644
Closed

[Python] All Union cases across all union types return the same Hash Code #3640

HLWeil opened this issue Dec 4, 2023 · 0 comments · Fixed by #3644

Comments

@HLWeil
Copy link

HLWeil commented Dec 4, 2023

Description

For union cases always the same hash value 2654435761 is returned.

Repro code

test.fsx

type X =
    | A of int
    | B of string

let x = A 1
let y = B "hello"

x.GetHashCode() = y.GetHashCode

test.cmd

dotnet fable . --lang python
python test.py

Expected and actual results

Expected result: false

Actual result: true

Debugging

In python, the function safe_hash is called on the object
-> this calls number-hash on the result of ObjectRef.id

ObjectRef.id always returns 1, so the resulting hash of safe_hash is always 2654435761

For reference, this is the source code in util.py

class ObjectRef:
    id_map: dict[int, int] = dict()
    count = 0

    @staticmethod
    def id(o: Any) -> int:
        _id = id(o)
        if _id not in ObjectRef.id_map:
            count = ObjectRef.count + 1
            ObjectRef.id_map[_id] = count

        return ObjectRef.id_map[_id]


def safe_hash(x: Any) -> int:
    return 0 if x is None else x.GetHashCode() if is_hashable(x) else number_hash(ObjectRef.id(x))


def string_hash(s: str) -> int:
    h = 5381
    for c in s:
        h = (h * 33) ^ ord(c)

    return h


def number_hash(x: int) -> int:
    return x * 2654435761 | 0

Related information

  • dotnet fable --version: 4.5.0
  • dotnet tool list/update/install: 4.6.0
  • Windows11

@Freymaurer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant