Skip to content

Commit 38458ef

Browse files
committed
Implement __hash__ for all classes
1 parent 71419d5 commit 38458ef

5 files changed

Lines changed: 44 additions & 15 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rlbot-flatbuffers-py"
3-
version = "0.3.4"
3+
version = "0.3.5"
44
edition = "2021"
55
description = "A Python module implemented in Rust for serializing and deserializing RLBot's flatbuffers"
66
repository = "https://github.com/VirxEC/rlbot-flatbuffers-py"

build.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,12 @@ impl PythonBindGenerator {
11381138
self.write_str(" }");
11391139
}
11401140

1141+
fn generate_enum_hash_method(&mut self) {
1142+
self.write_str(" pub fn __hash__(&self) -> u64 {");
1143+
self.write_str(" crate::hash_u64(*self as u64)");
1144+
self.write_str(" }");
1145+
}
1146+
11411147
fn generate_py_methods(&mut self) {
11421148
self.write_str("#[pymethods]");
11431149
self.write_string(format!("impl {} {{", self.struct_name));
@@ -1148,6 +1154,11 @@ impl PythonBindGenerator {
11481154
self.write_str("");
11491155
self.generate_repr_method();
11501156

1157+
if self.bind_type == PythonBindType::Enum {
1158+
self.write_str("");
1159+
self.generate_enum_hash_method();
1160+
}
1161+
11511162
if self.bind_type != PythonBindType::Union {
11521163
self.write_str("");
11531164
self.generate_pack_method();
@@ -1358,7 +1369,9 @@ fn pyi_generator(type_data: &[(String, String, Vec<Vec<String>>)]) -> io::Result
13581369
if is_enum {
13591370
file_contents.push(Cow::Borrowed(" def __init__(self, value: int = 0):"));
13601371
file_contents.push(Cow::Borrowed(" \"\"\""));
1361-
file_contents.push(Cow::Borrowed(" :raises ValueError: If the `value` is not a valid enum value"));
1372+
file_contents.push(Cow::Borrowed(
1373+
" :raises ValueError: If the `value` is not a valid enum value",
1374+
));
13621375
file_contents.push(Cow::Borrowed(" \"\"\""));
13631376
} else {
13641377
file_contents.push(Cow::Borrowed(" def __init__("));
@@ -1405,6 +1418,7 @@ fn pyi_generator(type_data: &[(String, String, Vec<Vec<String>>)]) -> io::Result
14051418

14061419
file_contents.push(Cow::Borrowed(" def __str__(self) -> str: ..."));
14071420
file_contents.push(Cow::Borrowed(" def __repr__(self) -> str: ..."));
1421+
file_contents.push(Cow::Borrowed(" def __hash__(self) -> str: ..."));
14081422

14091423
if is_enum {
14101424
file_contents.push(Cow::Borrowed(" def __int__(self) -> int: ..."));

pytest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def __add__(self, other):
1414
print(vec1 + vec2)
1515

1616
ready_message = ReadyMessage(True, wants_game_messages=True)
17+
print(hash(ready_message))
1718
print(repr(ready_message))
1819
print(ready_message)
1920
eval(repr(ready_message))
@@ -27,6 +28,7 @@ def __add__(self, other):
2728
dgs.console_commands = [ConsoleCommand("dump_items")]
2829
dgs.ball_state = DesiredBallState()
2930

31+
print(hash(dgs))
3032
print(repr(dgs))
3133
print(dgs)
3234
eval(repr(dgs))
@@ -40,18 +42,22 @@ def __add__(self, other):
4042
else:
4143
raise ValueError("Expected Line3D")
4244

45+
print(hash(render_type))
4346
print(repr(render_type))
4447
print(render_type)
4548
eval(repr(render_type))
4649
print()
4750

4851
comm = MatchComm(3, 1, False, "Ready!", b"Hello, world!")
52+
print(hash(comm))
4953
print(repr(comm))
5054
print(comm)
5155
eval(repr(comm))
5256
print(comm.content.decode("utf-8"))
5357
print()
5458

59+
print(hash(AirState.Dodging))
60+
5561
try:
5662
AirState(8)
5763
except ValueError as e:

src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ mod python;
1414

1515
use pyo3::{create_exception, exceptions::PyValueError, prelude::*, types::PyBytes, PyClass};
1616
use python::*;
17-
use std::panic::Location;
17+
use std::{
18+
hash::{DefaultHasher, Hash, Hasher},
19+
panic::Location,
20+
};
1821

1922
create_exception!(rlbot_flatbuffers, InvalidFlatbuffer, PyValueError, "Invalid FlatBuffer");
2023

@@ -25,6 +28,12 @@ pub fn flat_err_to_py(err: flatbuffers::InvalidFlatbuffer) -> PyErr {
2528
InvalidFlatbuffer::new_err(err_msg)
2629
}
2730

31+
pub fn hash_u64(num: u64) -> u64 {
32+
let mut hasher = DefaultHasher::new();
33+
num.hash(&mut hasher);
34+
hasher.finish()
35+
}
36+
2837
pub trait FromGil<T> {
2938
fn from_gil(py: Python, obj: T) -> Self;
3039
}

0 commit comments

Comments
 (0)