rlbot-flatbuffers 0.13.0__tar.gz → 0.13.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/Cargo.lock +7 -7
  2. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/Cargo.toml +4 -1
  3. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/PKG-INFO +1 -1
  4. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/main.rs +3 -3
  5. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/structs.rs +177 -352
  6. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/unions.rs +23 -72
  7. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/src/lib.rs +39 -15
  8. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/LICENSE +0 -0
  9. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/README.md +0 -0
  10. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/class_inject.rs +0 -0
  11. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/enums.rs +0 -0
  12. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/generator.rs +0 -0
  13. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/codegen/pyi.rs +0 -0
  14. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/FLATBUFFERS-LICENSE +0 -0
  15. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/README.md +0 -0
  16. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/comms.fbs +0 -0
  17. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/flatc +0 -0
  18. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/flatc.exe +0 -0
  19. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/gamedata.fbs +0 -0
  20. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/gamestatemanip.fbs +0 -0
  21. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/matchconfig.fbs +0 -0
  22. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/rendering.fbs +0 -0
  23. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/flatbuffers-schema/rlbot.fbs +0 -0
  24. {rlbot_flatbuffers-0.13.0 → rlbot_flatbuffers-0.13.2}/pyproject.toml +0 -0
@@ -279,7 +279,7 @@ dependencies = [
279
279
 
280
280
  [[package]]
281
281
  name = "rlbot_flatbuffers"
282
- version = "0.13.0"
282
+ version = "0.13.2"
283
283
  dependencies = [
284
284
  "flatbuffers",
285
285
  "get-size",
@@ -298,9 +298,9 @@ dependencies = [
298
298
 
299
299
  [[package]]
300
300
  name = "semver"
301
- version = "1.0.24"
301
+ version = "1.0.25"
302
302
  source = "registry+https://github.com/rust-lang/crates.io-index"
303
- checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
303
+ checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
304
304
 
305
305
  [[package]]
306
306
  name = "serde"
@@ -330,9 +330,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
330
330
 
331
331
  [[package]]
332
332
  name = "syn"
333
- version = "2.0.96"
333
+ version = "2.0.98"
334
334
  source = "registry+https://github.com/rust-lang/crates.io-index"
335
- checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
335
+ checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
336
336
  dependencies = [
337
337
  "proc-macro2",
338
338
  "quote",
@@ -347,9 +347,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
347
347
 
348
348
  [[package]]
349
349
  name = "unicode-ident"
350
- version = "1.0.14"
350
+ version = "1.0.16"
351
351
  source = "registry+https://github.com/rust-lang/crates.io-index"
352
- checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
352
+ checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
353
353
 
354
354
  [[package]]
355
355
  name = "unindent"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rlbot_flatbuffers"
3
- version = "0.13.0"
3
+ version = "0.13.2"
4
4
  edition = "2021"
5
5
  description = "A Python module implemented in Rust for serializing and deserializing RLBot's flatbuffers"
6
6
  repository = "https://github.com/VirxEC/rlbot_flatbuffers_py"
@@ -25,6 +25,9 @@ flatbuffers = "=24.12.23"
25
25
  # forked and updated deps
26
26
  get-size = { git = "https://github.com/VirxEC/get-size", branch = "update", features = ["derive"] }
27
27
 
28
+ [profile.dev]
29
+ opt-level = 2
30
+
28
31
  [profile.release]
29
32
  lto = true
30
33
  strip = true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rlbot_flatbuffers
3
- Version: 0.13.0
3
+ Version: 0.13.2
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -27,7 +27,7 @@ pub enum PythonBindType {
27
27
 
28
28
  impl PythonBindType {
29
29
  pub const BASE_TYPES: [&'static str; 6] = ["bool", "i32", "u32", "f32", "String", "u8"];
30
- pub const FROZEN_TYPES: [&'static str; 19] = [
30
+ pub const FROZEN_TYPES: [&'static str; 21] = [
31
31
  "GoalInfo",
32
32
  "GamePacket",
33
33
  "PlayerInfo",
@@ -47,9 +47,9 @@ impl PythonBindType {
47
47
  "ControllableTeamInfo",
48
48
  "BoostPad",
49
49
  "PredictionSlice",
50
+ "FieldInfo",
51
+ "BallPrediction",
50
52
  ];
51
- pub const SEMI_FROZEN_TYPES: [&'static str; 2] = ["FieldInfo", "BallPrediction"];
52
- pub const FROZEN_NEEDS_PY: [&'static str; 3] = ["GamePacket", "BallInfo", "CollisionShape"];
53
53
  pub const UNIONS: [&'static str; 4] = [
54
54
  "PlayerClass",
55
55
  "CollisionShape",
@@ -39,7 +39,6 @@ pub struct CustomType {
39
39
  pub raw_type: String,
40
40
  pub rust_type: RustType,
41
41
  pub is_frozen: bool,
42
- pub frozen_needs_py: bool,
43
42
  pub is_special_base: Option<SpecialBase>,
44
43
  pub snake_case_name: String,
45
44
  pub doc_str: Option<Vec<String>>,
@@ -53,10 +52,7 @@ pub struct StructBindGenerator {
53
52
  pub types: Vec<CustomType>,
54
53
  file_contents: Vec<Cow<'static, str>>,
55
54
  has_complex_pack: bool,
56
- is_all_base_types: bool,
57
55
  is_frozen: bool,
58
- frozen_needs_py: bool,
59
- is_semi_frozen: bool,
60
56
  }
61
57
 
62
58
  macro_rules! write_str {
@@ -81,26 +77,17 @@ impl StructBindGenerator {
81
77
  types: Vec<CustomType>,
82
78
  ) -> Option<Self> {
83
79
  let is_frozen = PythonBindType::FROZEN_TYPES.contains(&struct_name.as_str());
84
- let frozen_needs_py =
85
- is_frozen && PythonBindType::FROZEN_NEEDS_PY.contains(&struct_name.as_str());
86
- let is_semi_frozen =
87
- !is_frozen && PythonBindType::SEMI_FROZEN_TYPES.contains(&struct_name.as_str());
88
80
 
89
- let is_all_base_types = types
90
- .iter()
91
- .all(|t| matches!(t.rust_type, RustType::Base(_)));
92
81
  let has_complex_pack =
93
82
  contents.contains("pub fn pack<'b, A: flatbuffers::Allocator + 'b>(");
94
83
 
95
84
  let mut file_contents = vec![];
96
85
 
97
- file_contents.push(Cow::Borrowed(
98
- if (is_frozen && !frozen_needs_py) || is_all_base_types || types.is_empty() {
99
- "use crate::{flat_err_to_py, generated::rlbot::flat, FromGil};"
100
- } else {
101
- "use crate::{flat_err_to_py, generated::rlbot::flat, FromGil, IntoGil, PyDefault};"
102
- },
103
- ));
86
+ file_contents.push(Cow::Borrowed(if types.is_empty() {
87
+ "use crate::{flat_err_to_py, generated::rlbot::flat, FromGil};"
88
+ } else {
89
+ "use crate::{flat_err_to_py, generated::rlbot::flat, FromGil, IntoGil, PyDefault};"
90
+ }));
104
91
 
105
92
  if has_complex_pack {
106
93
  file_contents.push(Cow::Borrowed("use flatbuffers::{root, FlatBufferBuilder};"));
@@ -109,12 +96,7 @@ impl StructBindGenerator {
109
96
  file_contents.push(Cow::Borrowed("use flatbuffers::root;"));
110
97
  }
111
98
 
112
- file_contents.push(Cow::Borrowed(if is_frozen {
113
- "use pyo3::{pyclass, pymethods, types::PyBytes, Bound, PyResult, Python};"
114
- } else {
115
- "use pyo3::{pyclass, pymethods, types::{PyAnyMethods, PyBytes, PyList, PyListMethods}, Bound, Py, PyResult, Python};"
116
- }));
117
-
99
+ file_contents.push(Cow::Borrowed("use pyo3::{prelude::*, types::*};"));
118
100
  file_contents.push(Cow::Borrowed(""));
119
101
 
120
102
  Some(Self {
@@ -125,10 +107,7 @@ impl StructBindGenerator {
125
107
  types,
126
108
  file_contents,
127
109
  has_complex_pack,
128
- is_all_base_types,
129
110
  is_frozen,
130
- frozen_needs_py,
131
- is_semi_frozen,
132
111
  })
133
112
  }
134
113
 
@@ -269,30 +248,26 @@ impl StructBindGenerator {
269
248
  (RustType::Other(raw_type.to_string()), Some(raw_type))
270
249
  };
271
250
 
272
- let (is_frozen, frozen_needs_py, is_special_base) =
273
- if let Some(inner_type) = inner_type {
274
- let is_frozen = PythonBindType::FROZEN_TYPES.contains(&inner_type);
275
- let frozen_needs_py =
276
- is_frozen && PythonBindType::FROZEN_NEEDS_PY.contains(&inner_type);
277
- let is_special_base = if inner_type == "Float" {
278
- Some(SpecialBase::FloatT)
279
- } else if inner_type == "Bool" {
280
- Some(SpecialBase::BoolT)
281
- } else {
282
- None
283
- };
284
-
285
- (is_frozen, frozen_needs_py, is_special_base)
251
+ let (is_frozen, is_special_base) = if let Some(inner_type) = inner_type {
252
+ let is_frozen = PythonBindType::FROZEN_TYPES.contains(&inner_type);
253
+ let is_special_base = if inner_type == "Float" {
254
+ Some(SpecialBase::FloatT)
255
+ } else if inner_type == "Bool" {
256
+ Some(SpecialBase::BoolT)
286
257
  } else {
287
- (false, false, None)
258
+ None
288
259
  };
289
260
 
261
+ (is_frozen, is_special_base)
262
+ } else {
263
+ (false, None)
264
+ };
265
+
290
266
  CustomType {
291
267
  name: name.to_string(),
292
268
  raw_type: raw_type.to_string(),
293
269
  rust_type,
294
270
  is_frozen,
295
- frozen_needs_py,
296
271
  is_special_base,
297
272
  snake_case_name: String::new(),
298
273
  doc_str,
@@ -326,28 +301,24 @@ impl StructBindGenerator {
326
301
  format!("{variable_name}=None")
327
302
  }
328
303
  RustType::Union(_) => {
329
- if !self.is_frozen {
330
- needs_python = true;
331
- }
332
-
304
+ needs_python = true;
333
305
  format!("{variable_name}=None")
334
306
  }
335
307
  RustType::Box(_) | RustType::Custom(_) => {
336
- if self.is_frozen {
337
- format!("{variable_name}=Default::default()")
338
- } else {
339
- needs_python = !self.is_frozen;
340
- format!("{variable_name}=None")
341
- }
342
- }
343
- RustType::Vec(InnerVecType::U8) => {
344
308
  needs_python = true;
345
309
  format!("{variable_name}=None")
346
310
  }
347
- RustType::Vec(InnerVecType::Custom(_)) if !self.is_frozen => {
311
+ RustType::Vec(InnerVecType::U8) | RustType::Vec(InnerVecType::Custom(_)) => {
348
312
  needs_python = true;
349
- format!("{variable_name}=Vec::new()")
313
+ format!("{variable_name}=None")
350
314
  }
315
+ RustType::Base(inner_type) => match inner_type.as_str() {
316
+ "f32" => {
317
+ needs_python = true;
318
+ format!("{variable_name}=Default::default()")
319
+ }
320
+ _ => format!("{variable_name}=Default::default()"),
321
+ },
351
322
  _ => {
352
323
  format!("{variable_name}=Default::default()")
353
324
  }
@@ -376,44 +347,39 @@ impl StructBindGenerator {
376
347
  let variable_name = variable_info.name.as_str();
377
348
 
378
349
  let variable_type = match &variable_info.rust_type {
379
- RustType::Vec(InnerVecType::Custom(inner_type)) => Cow::Owned(if self.is_frozen {
380
- format!("Vec<super::{inner_type}>")
381
- } else {
382
- format!("Vec<Py<super::{inner_type}>>")
383
- }),
350
+ RustType::Vec(InnerVecType::Custom(_)) => Cow::Borrowed("Option<Py<PyList>>"),
384
351
  RustType::Vec(InnerVecType::Base(inner_type)) => {
385
352
  Cow::Owned(format!("Vec<{}>", inner_type))
386
353
  }
387
354
  RustType::Vec(InnerVecType::String) => Cow::Borrowed("Vec<String>"),
388
355
  RustType::Vec(InnerVecType::U8) => Cow::Borrowed("Option<Py<PyBytes>>"),
389
- RustType::Box(inner_type) => Cow::Owned(if self.is_frozen {
390
- format!("super::{inner_type}")
391
- } else {
392
- format!("Option<Py<super::{inner_type}>>")
393
- }),
394
- RustType::Option(InnerOptionType::BaseType, inner_type)
395
- | RustType::Option(InnerOptionType::String, inner_type) => {
356
+ RustType::Box(inner_type) => Cow::Owned(format!("Option<Py<super::{inner_type}>>")),
357
+ RustType::Option(InnerOptionType::BaseType, inner_type) => {
396
358
  Cow::Owned(format!("Option<{inner_type}>"))
397
359
  }
398
- RustType::Option(_, inner_type) => Cow::Owned(if inner_type == "Float" {
399
- String::from("Option<crate::Floats>")
400
- } else if inner_type == "Bool" {
401
- String::from("Option<crate::Bools>")
402
- } else if self.is_frozen {
403
- format!("Option<super::{inner_type}>")
404
- } else {
405
- format!("Option<Py<super::{inner_type}>>")
360
+ RustType::Option(InnerOptionType::String, _) => {
361
+ Cow::Borrowed("Option<Py<PyString>>")
362
+ }
363
+ RustType::Option(_, inner_type) => {
364
+ if inner_type == "Float" {
365
+ Cow::Borrowed("Option<crate::PartFloats>")
366
+ } else if inner_type == "Bool" {
367
+ Cow::Borrowed("Option<crate::PartBools>")
368
+ } else {
369
+ Cow::Owned(format!("Option<Py<super::{inner_type}>>"))
370
+ }
371
+ }
372
+ RustType::Base(inner_type) => Cow::Borrowed(match inner_type.as_str() {
373
+ "f32" => "f64",
374
+ item => item,
406
375
  }),
407
- RustType::Base(inner_type) => Cow::Borrowed(inner_type.as_str()),
408
376
  RustType::String => Cow::Borrowed("String"),
409
377
  RustType::Union(inner_type) => {
410
378
  Cow::Owned(format!("Option<super::{inner_type}Union>"))
411
379
  }
412
- RustType::Custom(inner_type) => Cow::Owned(if self.is_frozen {
413
- format!("super::{inner_type}")
414
- } else {
415
- format!("Option<Py<super::{inner_type}>>")
416
- }),
380
+ RustType::Custom(inner_type) => {
381
+ Cow::Owned(format!("Option<Py<super::{inner_type}>>"))
382
+ }
417
383
  RustType::Other(inner_type) => Cow::Owned(format!("super::{inner_type}")),
418
384
  };
419
385
 
@@ -436,21 +402,13 @@ impl StructBindGenerator {
436
402
 
437
403
  match &variable_info.rust_type {
438
404
  RustType::Union(inner_type) => {
439
- if self.is_frozen {
440
- write_fmt!(
441
- self,
442
- " {variable_name}: super::{}::new({variable_name}),",
443
- inner_type
444
- );
445
- } else {
446
- write_fmt!(
447
- self,
448
- " {variable_name}: Py::new(py, super::{}::new({variable_name})).unwrap(),",
449
- inner_type
450
- );
451
- }
405
+ write_fmt!(
406
+ self,
407
+ " {variable_name}: Py::new(py, super::{}::new({variable_name})).unwrap(),",
408
+ inner_type
409
+ );
452
410
  }
453
- RustType::Box(inner_type) | RustType::Custom(inner_type) if !self.is_frozen => {
411
+ RustType::Box(inner_type) | RustType::Custom(inner_type) => {
454
412
  write_fmt!(self, " {variable_name}: {variable_name}.unwrap_or_else(|| super::{inner_type}::py_default(py)),",);
455
413
  }
456
414
  RustType::Vec(InnerVecType::U8) => {
@@ -459,12 +417,19 @@ impl StructBindGenerator {
459
417
  " {variable_name}: {variable_name}.unwrap_or_else(|| PyBytes::new(py, &[]).unbind()),"
460
418
  );
461
419
  }
462
- RustType::Vec(InnerVecType::Custom(_)) if !self.is_frozen => {
420
+ RustType::Vec(InnerVecType::Custom(_)) => {
463
421
  write_fmt!(
464
422
  self,
465
- " {variable_name}: PyList::new(py, {variable_name}).unwrap().unbind(),"
423
+ " {variable_name}: {variable_name}.unwrap_or_else(|| PyList::empty(py).unbind()),"
466
424
  );
467
425
  }
426
+ RustType::Base(inner_type) => match inner_type.as_str() {
427
+ "f32" => write_fmt!(
428
+ self,
429
+ " {variable_name}: PyFloat::new(py, {variable_name}).unbind(),"
430
+ ),
431
+ _ => write_fmt!(self, " {variable_name},"),
432
+ },
468
433
  _ => write_fmt!(self, " {variable_name},"),
469
434
  }
470
435
  }
@@ -487,10 +452,7 @@ impl StructBindGenerator {
487
452
  return;
488
453
  }
489
454
 
490
- if !self.frozen_needs_py {
491
- write_str!(self, " #[allow(unused_variables)]");
492
- }
493
-
455
+ write_str!(self, " #[allow(unused_variables)]");
494
456
  write_str!(self, " pub fn __repr__(&self, py: Python) -> String {");
495
457
  write_str!(self, " format!(");
496
458
 
@@ -536,16 +498,9 @@ impl StructBindGenerator {
536
498
  write_str!(self, " .map(ToString::to_string)");
537
499
  }
538
500
  InnerVecType::Custom(type_name) => {
539
- if !self.is_frozen {
540
- write_str!(self, " .bind_borrowed(py)");
541
- }
542
-
501
+ write_str!(self, " .bind_borrowed(py)");
543
502
  write_str!(self, " .iter()");
544
- if self.is_frozen {
545
- write_str!(self, " .map(|x| x.__repr__(py))");
546
- } else {
547
- write_fmt!(self, " .map(|x| x.downcast_into::<super::{type_name}>().unwrap().borrow().__repr__(py))");
548
- }
503
+ write_fmt!(self, " .map(|x| x.downcast_into::<super::{type_name}>().unwrap().borrow().__repr__(py))");
549
504
  }
550
505
  }
551
506
  write_str!(self, " .collect::<Vec<String>>()");
@@ -556,40 +511,30 @@ impl StructBindGenerator {
556
511
  write_str!(self, " .as_ref()");
557
512
 
558
513
  match inner_type {
559
- InnerOptionType::BaseType | InnerOptionType::String => {
514
+ InnerOptionType::BaseType => {
560
515
  write_str!(self, " .map(|i| format!(\"{i:?}\"))");
561
516
  }
517
+ InnerOptionType::String => {
518
+ write_str!(self, " .map(|i| format!(\"{:?}\", i.to_str(py).unwrap().to_string()))");
519
+ }
562
520
  _ => {
563
- write_str!(
564
- self,
565
- if self.is_frozen {
566
- " .map(|x| x.__repr__(py))"
567
- } else {
568
- " .map(|x| x.borrow(py).__repr__(py))"
569
- }
570
- );
521
+ write_str!(self, " .map(|x| x.borrow(py).__repr__(py))");
571
522
  }
572
523
  }
573
524
 
574
525
  write_str!(self, " .unwrap_or_else(crate::none_str),");
575
526
  }
576
527
  RustType::Union(_) => {
577
- let repr_str = if self.is_frozen {
578
- ".inner_repr(py)"
579
- } else {
580
- ".borrow(py).inner_repr(py)"
581
- };
582
-
583
- write_fmt!(self, " self.{variable_name}{repr_str},");
528
+ write_fmt!(
529
+ self,
530
+ " self.{variable_name}.borrow(py).inner_repr(py),"
531
+ );
584
532
  }
585
533
  RustType::Box(_) | RustType::Custom(_) => {
586
- let repr_str = if self.is_frozen {
587
- ".__repr__(py)"
588
- } else {
589
- ".borrow(py).__repr__(py)"
590
- };
591
-
592
- write_fmt!(self, " self.{variable_name}{repr_str},");
534
+ write_fmt!(
535
+ self,
536
+ " self.{variable_name}.borrow(py).__repr__(py),"
537
+ );
593
538
  }
594
539
  RustType::Base(inner_type) => {
595
540
  if inner_type == "bool" {
@@ -614,45 +559,53 @@ impl StructBindGenerator {
614
559
  write_str!(self, " }");
615
560
  }
616
561
 
617
- fn generate_long_match_args(&mut self) {
618
- write_str!(self, " #[classattr]");
619
- write_str!(
620
- self,
621
- " fn __match_args__(py: Python) -> Bound<pyo3::types::PyTuple> {"
622
- );
623
- write_str!(self, " pyo3::types::PyTuple::new(py, [");
562
+ fn generate_long_args(&mut self) {
563
+ let funcs = ["match_args", "slots"];
624
564
 
625
- for variable_info in &self.types {
626
- write_fmt!(self, " \"{}\",", variable_info.name);
627
- }
565
+ for func in funcs {
566
+ write_str!(self, " #[classattr]");
567
+ write_fmt!(
568
+ self,
569
+ " fn __{func}__(py: Python) -> Bound<pyo3::types::PyTuple> {{"
570
+ );
571
+ write_str!(self, " pyo3::types::PyTuple::new(py, [");
628
572
 
629
- write_str!(self, " ]).unwrap()");
630
- write_str!(self, " }");
573
+ for variable_info in &self.types {
574
+ write_fmt!(self, " \"{}\",", variable_info.name);
575
+ }
576
+
577
+ write_str!(self, " ]).unwrap()");
578
+ write_str!(self, " }\n");
579
+ }
631
580
  }
632
581
 
633
- fn generate_match_args(&mut self) {
582
+ fn generate_args(&mut self) {
634
583
  if self.types.is_empty() {
635
584
  return;
636
585
  }
637
586
 
638
587
  if self.types.len() > 12 {
639
- self.generate_long_match_args();
588
+ self.generate_long_args();
640
589
  return;
641
590
  }
642
591
 
643
592
  let sig_parts: Vec<_> = repeat("&'static str").take(self.types.len()).collect();
644
593
  let sig = sig_parts.join(", ");
645
594
 
646
- write_str!(self, " #[classattr]");
647
- write_fmt!(self, " fn __match_args__() -> ({sig},) {{",);
648
- write_str!(self, " (");
595
+ let funcs = ["match_args", "slots"];
649
596
 
650
- for variable_info in &self.types {
651
- write_fmt!(self, " \"{}\",", variable_info.name);
652
- }
597
+ for func in funcs {
598
+ write_str!(self, " #[classattr]");
599
+ write_fmt!(self, " fn __{func}__() -> ({sig},) {{",);
600
+ write_str!(self, " (");
653
601
 
654
- write_str!(self, " )");
655
- write_str!(self, " }");
602
+ for variable_info in &self.types {
603
+ write_fmt!(self, " \"{}\",", variable_info.name);
604
+ }
605
+
606
+ write_str!(self, " )");
607
+ write_str!(self, " }\n");
608
+ }
656
609
  }
657
610
 
658
611
  fn generate_pack_method(&mut self) {
@@ -692,9 +645,7 @@ impl StructBindGenerator {
692
645
  fn generate_unpack_method(&mut self) {
693
646
  write_str!(self, " #[staticmethod]");
694
647
 
695
- let (py_arg, return_val, out_map) = if self.frozen_needs_py {
696
- ("py: Python, ", "Self", "flat_t.unpack().into_gil(py)")
697
- } else if self.is_frozen {
648
+ let (py_arg, return_val, out_map) = if false {
698
649
  ("", "Self", "flat_t.unpack().into()")
699
650
  } else {
700
651
  (
@@ -764,8 +715,6 @@ impl Generator for StructBindGenerator {
764
715
  self,
765
716
  if self.is_frozen {
766
717
  "#[pyclass(module = \"rlbot_flatbuffers\", subclass, get_all, frozen)]"
767
- } else if self.is_semi_frozen {
768
- "#[pyclass(module = \"rlbot_flatbuffers\", subclass, get_all)]"
769
718
  } else if self.types.is_empty() {
770
719
  "#[pyclass(module = \"rlbot_flatbuffers\", subclass, frozen)]"
771
720
  } else {
@@ -774,26 +723,12 @@ impl Generator for StructBindGenerator {
774
723
  );
775
724
 
776
725
  if self.types.is_empty() {
777
- write_str!(self, "#[derive(Debug, Default, Clone, Copy)]");
726
+ write_str!(self, "#[derive(Default)]");
778
727
  write_fmt!(self, "pub struct {} {{}}", self.struct_name);
779
728
  write_str!(self, "");
780
729
  return;
781
730
  }
782
731
 
783
- write_str!(
784
- self,
785
- if self.is_frozen || self.is_all_base_types {
786
- if !self.is_all_base_types
787
- || self.types.iter().any(|t| t.rust_type == RustType::String)
788
- {
789
- "#[derive(Debug, Default, Clone)]"
790
- } else {
791
- "#[derive(Debug, Default, Clone, Copy)]"
792
- }
793
- } else {
794
- "#[derive(Debug)]"
795
- }
796
- );
797
732
  write_fmt!(self, "pub struct {} {{", self.struct_name);
798
733
 
799
734
  for variable_info in &self.types {
@@ -803,39 +738,22 @@ impl Generator for StructBindGenerator {
803
738
  RustType::Vec(InnerVecType::U8) => String::from("Py<PyBytes>"),
804
739
  RustType::Vec(InnerVecType::String) => String::from("Vec<String>"),
805
740
  RustType::Vec(InnerVecType::Base(inner_type)) => format!("Vec<{}>", inner_type),
806
- RustType::Vec(InnerVecType::Custom(inner_type)) => {
807
- if self.is_frozen {
808
- format!("Vec<super::{inner_type}>")
809
- } else {
810
- String::from("Py<PyList>")
811
- }
741
+ RustType::Vec(InnerVecType::Custom(_)) => String::from("Py<PyList>"),
742
+ RustType::Box(inner_type) => format!("Py<super::{inner_type}>"),
743
+ RustType::Option(InnerOptionType::BaseType, inner_type) => {
744
+ format!("Option<Py<{inner_type}>>")
812
745
  }
813
- RustType::Box(inner_type) => {
814
- if self.is_frozen {
815
- format!("super::{inner_type}")
816
- } else {
817
- format!("Py<super::{inner_type}>")
818
- }
819
- }
820
- RustType::Option(InnerOptionType::BaseType, inner_type)
821
- | RustType::Option(InnerOptionType::String, inner_type) => {
822
- format!("Option<{inner_type}>")
823
- }
824
- RustType::Option(_, inner_type) => {
825
- if self.is_frozen {
826
- format!("Option<super::{inner_type}>")
827
- } else {
828
- format!("Option<Py<super::{inner_type}>>")
829
- }
746
+ RustType::Option(InnerOptionType::String, _) => {
747
+ String::from("Option<Py<PyString>>")
830
748
  }
831
- RustType::Base(inner_type) => inner_type.clone(),
749
+ RustType::Option(_, inner_type) => format!("Option<Py<super::{inner_type}>>"),
750
+ RustType::Base(inner_type) => match inner_type.as_str() {
751
+ "f32" => String::from("Py<PyFloat>"),
752
+ _ => inner_type.clone(),
753
+ },
832
754
  RustType::String => String::from("String"),
833
755
  RustType::Union(inner_type) | RustType::Custom(inner_type) => {
834
- if self.is_frozen {
835
- format!("super::{inner_type}")
836
- } else {
837
- format!("Py<super::{inner_type}>")
838
- }
756
+ format!("Py<super::{inner_type}>")
839
757
  }
840
758
  RustType::Other(inner_type) => format!("super::{inner_type}"),
841
759
  };
@@ -846,14 +764,6 @@ impl Generator for StructBindGenerator {
846
764
  write_str!(self, "}");
847
765
  write_str!(self, "");
848
766
 
849
- if self.is_all_base_types {
850
- return;
851
- }
852
-
853
- if self.is_frozen {
854
- return;
855
- }
856
-
857
767
  write_fmt!(self, "impl crate::PyDefault for {} {{", self.struct_name);
858
768
  write_str!(self, " fn py_default(py: Python) -> Py<Self> {");
859
769
  write_str!(self, " Py::new(py, Self {");
@@ -863,7 +773,7 @@ impl Generator for StructBindGenerator {
863
773
 
864
774
  let end = match &variable_info.rust_type {
865
775
  RustType::Vec(InnerVecType::U8) => Cow::Borrowed("PyBytes::new(py, &[]).unbind()"),
866
- RustType::Vec(InnerVecType::Custom(_)) if !self.is_frozen => {
776
+ RustType::Vec(InnerVecType::Custom(_)) => {
867
777
  Cow::Borrowed("PyList::empty(py).unbind()")
868
778
  }
869
779
  RustType::Vec(_) => Cow::Borrowed("Vec::new()"),
@@ -873,20 +783,17 @@ impl Generator for StructBindGenerator {
873
783
  | RustType::Custom(inner_type) => {
874
784
  Cow::Owned(format!("super::{inner_type}::py_default(py)"))
875
785
  }
876
- RustType::String | RustType::Base(_) | RustType::Other(_) => {
877
- Cow::Borrowed("Default::default()")
878
- }
786
+ RustType::Base(inner_type) => Cow::Borrowed(match inner_type.as_str() {
787
+ "f32" => "crate::pyfloat_default(py)",
788
+ _ => "Default::default()",
789
+ }),
790
+ RustType::String | RustType::Other(_) => Cow::Borrowed("Default::default()"),
879
791
  };
880
792
 
881
793
  write_fmt!(self, " {variable_name}: {end},");
882
794
  }
883
795
 
884
- if self.is_frozen {
885
- write_str!(self, " }");
886
- } else {
887
- write_str!(self, " }).unwrap()");
888
- }
889
-
796
+ write_str!(self, " }).unwrap()");
890
797
  write_str!(self, " }");
891
798
  write_str!(self, "}");
892
799
  write_str!(self, "");
@@ -905,26 +812,16 @@ impl Generator for StructBindGenerator {
905
812
  return;
906
813
  }
907
814
 
908
- let (is_simple, trait_name, fn_name, python_arg) =
909
- if (self.is_frozen && !self.frozen_needs_py) || self.is_all_base_types {
910
- (true, "From", "from", "")
911
- } else {
912
- (false, "FromGil", "from_gil", "py: Python, ")
913
- };
914
-
915
815
  write_fmt!(
916
816
  self,
917
- "impl {trait_name}<{impl_type}> for {} {{",
817
+ "impl FromGil<{impl_type}> for {} {{",
918
818
  self.struct_name
919
819
  );
920
820
 
921
- if !is_simple {
922
- write_str!(self, " #[allow(unused_variables)]")
923
- }
924
-
821
+ write_str!(self, " #[allow(unused_variables)]");
925
822
  write_fmt!(
926
823
  self,
927
- " fn {fn_name}({python_arg}flat_t: {impl_type}) -> Self {{"
824
+ " fn from_gil(py: Python, flat_t: {impl_type}) -> Self {{"
928
825
  );
929
826
  write_fmt!(self, " {} {{", self.struct_name);
930
827
 
@@ -942,38 +839,19 @@ impl Generator for StructBindGenerator {
942
839
  write_fmt!(self, " {variable_name}: flat_t.{variable_name},")
943
840
  }
944
841
  RustType::Vec(InnerVecType::Custom(type_name)) => {
945
- if self.is_frozen {
946
- let map_out = if variable_info.frozen_needs_py {
947
- "|x| x.into_gil(py)"
948
- } else {
949
- "Into::into"
950
- };
951
-
952
- write_fmt!(
953
- self,
954
- " {variable_name}: flat_t.{variable_name}.into_iter().map({map_out}).collect(),"
955
- )
956
- } else {
957
- write_fmt!(
958
- self,
959
- " {variable_name}: PyList::new(py, flat_t.{variable_name}.into_iter().map(|x| crate::into_py_from::<_, super::{type_name}>(py, x))).unwrap().unbind(),",
960
- )
961
- }
842
+ write_fmt!(
843
+ self,
844
+ " {variable_name}: PyList::new(py, flat_t.{variable_name}.into_iter().map(|x| crate::into_py_from::<_, super::{type_name}>(py, x))).unwrap().unbind(),",
845
+ )
962
846
  }
963
847
  RustType::Option(InnerOptionType::Box, _) => {
964
- let inner = if self.is_frozen {
965
- "(*x).into()"
966
- } else {
967
- "crate::into_py_from(py, *x)"
968
- };
969
-
970
848
  write_fmt!(
971
849
  self,
972
- " {variable_name}: flat_t.{variable_name}.map(|x| {inner}),"
850
+ " {variable_name}: flat_t.{variable_name}.map(|x| crate::into_py_from(py, *x)),"
973
851
  );
974
852
  }
975
853
  RustType::Option(InnerOptionType::String, _) => {
976
- write_fmt!(self, " {variable_name}: flat_t.{variable_name},");
854
+ write_fmt!(self, " {variable_name}: flat_t.{variable_name}.map(|s| PyString::new(py, &s).unbind()),");
977
855
  }
978
856
  RustType::Option(_, _) => {
979
857
  write_fmt!(
@@ -982,33 +860,22 @@ impl Generator for StructBindGenerator {
982
860
  );
983
861
  }
984
862
  RustType::Box(_) => {
985
- let end = if self.is_frozen {
986
- if variable_info.frozen_needs_py {
987
- format!("(*flat_t.{variable_name}).into_gil(py)",)
988
- } else {
989
- format!("(*flat_t.{variable_name}).into()",)
990
- }
991
- } else {
992
- format!("crate::into_py_from(py, *flat_t.{variable_name})")
993
- };
994
- write_fmt!(self, " {variable_name}: {end},",);
863
+ write_fmt!(self, " {variable_name}: crate::into_py_from(py, *flat_t.{variable_name}),",);
995
864
  }
996
865
  RustType::Union(_) | RustType::Custom(_) => {
997
- let end = if self.is_frozen {
998
- if variable_info.frozen_needs_py {
999
- format!("flat_t.{variable_name}.into_gil(py)")
1000
- } else {
1001
- format!("flat_t.{variable_name}.into()")
1002
- }
1003
- } else {
1004
- format!("crate::into_py_from(py, flat_t.{variable_name})")
1005
- };
1006
-
1007
- write_fmt!(self, " {variable_name}: {end},",);
866
+ write_fmt!(self, " {variable_name}: crate::into_py_from(py, flat_t.{variable_name}),",);
1008
867
  }
1009
- RustType::Base(_) | RustType::String => {
868
+ RustType::String => {
1010
869
  write_fmt!(self, " {variable_name}: flat_t.{variable_name},");
1011
870
  }
871
+ RustType::Base(inner_type) => match inner_type.as_str() {
872
+ "f32" => {
873
+ write_fmt!(self, " {variable_name}: crate::float_to_py(py, flat_t.{variable_name}),");
874
+ }
875
+ _ => {
876
+ write_fmt!(self, " {variable_name}: flat_t.{variable_name},");
877
+ }
878
+ },
1012
879
  RustType::Other(_) => {
1013
880
  write_fmt!(
1014
881
  self,
@@ -1037,26 +904,16 @@ impl Generator for StructBindGenerator {
1037
904
  return;
1038
905
  }
1039
906
 
1040
- let (is_simple, trait_name, fn_name, python_arg) =
1041
- if (self.is_frozen && !self.frozen_needs_py) || self.is_all_base_types {
1042
- (true, "From", "from", "")
1043
- } else {
1044
- (false, "FromGil", "from_gil", "py: Python, ")
1045
- };
1046
-
1047
907
  write_fmt!(
1048
908
  self,
1049
- "impl {trait_name}<&{}> for {impl_type} {{",
909
+ "impl FromGil<&{}> for {impl_type} {{",
1050
910
  self.struct_name
1051
911
  );
1052
912
 
1053
- if !is_simple {
1054
- write_str!(self, " #[allow(unused_variables)]")
1055
- }
1056
-
913
+ write_str!(self, " #[allow(unused_variables)]");
1057
914
  write_fmt!(
1058
915
  self,
1059
- " fn {fn_name}({python_arg}py_type: &{}) -> Self {{",
916
+ " fn from_gil(py: Python, py_type: &{}) -> Self {{",
1060
917
  self.struct_name
1061
918
  );
1062
919
  write_str!(self, " Self {");
@@ -1078,40 +935,21 @@ impl Generator for StructBindGenerator {
1078
935
  )
1079
936
  }
1080
937
  RustType::Vec(InnerVecType::Custom(_)) => {
1081
- if self.is_frozen {
1082
- let map_out = if variable_info.frozen_needs_py {
1083
- "|x| x.into_gil(py)"
1084
- } else {
1085
- "Into::into"
1086
- };
1087
-
1088
- write_fmt!(
1089
- self,
1090
- " {variable_name}: py_type.{variable_name}.iter().map({map_out}).collect(),"
1091
- )
1092
- } else {
1093
- write_fmt!(
1094
- self,
1095
- " {variable_name}: py_type.{variable_name}.bind_borrowed(py).iter().map(|x| crate::from_pyany_into(py, x)).collect(),",
1096
- )
1097
- }
938
+ write_fmt!(
939
+ self,
940
+ " {variable_name}: py_type.{variable_name}.bind_borrowed(py).iter().map(|x| crate::from_pyany_into(py, x)).collect(),",
941
+ )
1098
942
  }
1099
943
  RustType::Option(InnerOptionType::Box, _) => {
1100
- let inner = if self.is_frozen {
1101
- "x.into()"
1102
- } else {
1103
- "crate::from_py_into(py, x)"
1104
- };
1105
-
1106
944
  write_fmt!(
1107
945
  self,
1108
- " {variable_name}: py_type.{variable_name}.as_ref().map(|x| Box::new({inner})),"
946
+ " {variable_name}: py_type.{variable_name}.as_ref().map(|x| Box::new(crate::from_py_into(py, x))),"
1109
947
  );
1110
948
  }
1111
949
  RustType::Option(InnerOptionType::String, _) => {
1112
950
  write_fmt!(
1113
951
  self,
1114
- " {variable_name}: py_type.{variable_name}.clone(),"
952
+ " {variable_name}: py_type.{variable_name}.as_ref().map(|s| s.to_str(py).unwrap().to_string()),"
1115
953
  );
1116
954
  }
1117
955
  RustType::Option(_, _) => {
@@ -1121,30 +959,10 @@ impl Generator for StructBindGenerator {
1121
959
  );
1122
960
  }
1123
961
  RustType::Box(_) => {
1124
- let var_name = if self.is_frozen {
1125
- if variable_info.frozen_needs_py {
1126
- format!("(&py_type.{variable_name}).into_gil(py)")
1127
- } else {
1128
- format!("(&py_type.{variable_name}).into()")
1129
- }
1130
- } else {
1131
- format!("crate::from_py_into(py, &py_type.{variable_name})")
1132
- };
1133
-
1134
- write_fmt!(self, " {variable_name}: Box::new({var_name}),",);
962
+ write_fmt!(self, " {variable_name}: Box::new(crate::from_py_into(py, &py_type.{variable_name})),",);
1135
963
  }
1136
964
  RustType::Union(_) | RustType::Custom(_) => {
1137
- let end = if self.is_frozen {
1138
- if variable_info.frozen_needs_py {
1139
- format!("(&py_type.{variable_name}).into_gil(py)")
1140
- } else {
1141
- format!("(&py_type.{variable_name}).into()")
1142
- }
1143
- } else {
1144
- format!("crate::from_py_into(py, &py_type.{variable_name})")
1145
- };
1146
-
1147
- write_fmt!(self, " {variable_name}: {end},",);
965
+ write_fmt!(self, " {variable_name}: crate::from_py_into(py, &py_type.{variable_name}),",);
1148
966
  }
1149
967
  RustType::String => {
1150
968
  write_fmt!(
@@ -1152,12 +970,20 @@ impl Generator for StructBindGenerator {
1152
970
  " {variable_name}: py_type.{variable_name}.clone(),",
1153
971
  );
1154
972
  }
1155
- RustType::Base(_) => {
1156
- write_fmt!(
1157
- self,
1158
- " {variable_name}: py_type.{variable_name},"
1159
- );
1160
- }
973
+ RustType::Base(inner_type) => match inner_type.as_str() {
974
+ "f32" => {
975
+ write_fmt!(
976
+ self,
977
+ " {variable_name}: crate::float_from_py(py, &py_type.{variable_name}),"
978
+ );
979
+ }
980
+ _ => {
981
+ write_fmt!(
982
+ self,
983
+ " {variable_name}: py_type.{variable_name},"
984
+ );
985
+ }
986
+ },
1161
987
  RustType::Other(_) => {
1162
988
  write_fmt!(
1163
989
  self,
@@ -1186,8 +1012,7 @@ impl Generator for StructBindGenerator {
1186
1012
  self.generate_repr_method();
1187
1013
  write_str!(self, "");
1188
1014
 
1189
- self.generate_match_args();
1190
- write_str!(self, "");
1015
+ self.generate_args();
1191
1016
 
1192
1017
  self.generate_pack_method();
1193
1018
  write_str!(self, "");
@@ -50,12 +50,6 @@ impl UnionBindGenerator {
50
50
  fn generate_new_method(&mut self) {
51
51
  assert!(u8::try_from(self.types.len()).is_ok());
52
52
 
53
- let item_str = if self.is_frozen {
54
- "Bound::new(py, *item).unwrap().into_any()"
55
- } else {
56
- "item.clone_ref(py).into_any()"
57
- };
58
-
59
53
  write_str!(self, " #[new]");
60
54
  write_str!(self, " #[pyo3(signature = (item = None))]");
61
55
  write_fmt!(
@@ -68,17 +62,10 @@ impl UnionBindGenerator {
68
62
  write_str!(self, "");
69
63
  write_str!(self, " #[getter(item)]");
70
64
 
71
- if self.is_frozen {
72
- write_str!(
73
- self,
74
- " pub fn get<'a>(&self, py: Python<'a>) -> Option<Bound<'a, PyAny>> {"
75
- );
76
- } else {
77
- write_str!(
78
- self,
79
- " pub fn get(&self, py: Python) -> Option<Py<PyAny>> {"
80
- );
81
- }
65
+ write_str!(
66
+ self,
67
+ " pub fn get(&self, py: Python) -> Option<Py<PyAny>> {"
68
+ );
82
69
  write_str!(self, " match self.item.as_ref() {");
83
70
 
84
71
  for variable_info in &self.types {
@@ -89,7 +76,7 @@ impl UnionBindGenerator {
89
76
  } else {
90
77
  write_fmt!(
91
78
  self,
92
- " Some({}Union::{variable_name}(item)) => Some({item_str}),",
79
+ " Some({}Union::{variable_name}(item)) => Some(item.clone_ref(py).into_any()),",
93
80
  self.struct_name
94
81
  );
95
82
  }
@@ -109,15 +96,13 @@ impl UnionBindGenerator {
109
96
  write_str!(self, " pub fn inner_repr(&self, py: Python) -> String {");
110
97
  write_str!(self, " match self.item.as_ref() {");
111
98
 
112
- let borrow_str = if self.is_frozen { "" } else { ".borrow(py)" };
113
-
114
99
  for variable_info in &self.types {
115
100
  let variable_name = variable_info.name.as_str();
116
101
 
117
102
  if variable_info.value.is_some() {
118
103
  write_fmt!(
119
104
  self,
120
- " Some({}Union::{variable_name}(item)) => item{borrow_str}.__repr__(py),",
105
+ " Some({}Union::{variable_name}(item)) => item.borrow(py).__repr__(py),",
121
106
  self.struct_name
122
107
  );
123
108
  } else {
@@ -133,15 +118,13 @@ impl UnionBindGenerator {
133
118
  write_str!(self, " pub fn __repr__(&self, py: Python) -> String {");
134
119
  write_str!(self, " match self.item.as_ref() {");
135
120
 
136
- let borrow_str = if self.is_frozen { "" } else { ".borrow(py)" };
137
-
138
121
  for variable_info in &self.types {
139
122
  let variable_name = variable_info.name.as_str();
140
123
 
141
124
  if variable_info.value.is_some() {
142
125
  write_fmt!(
143
126
  self,
144
- " Some({}Union::{variable_name}(item)) => format!(\"{}({{}})\", item{borrow_str}.__repr__(py)),",
127
+ " Some({}Union::{variable_name}(item)) => format!(\"{}({{}})\", item.borrow(py).__repr__(py)),",
145
128
  self.struct_name,
146
129
  self.struct_name
147
130
  );
@@ -194,18 +177,13 @@ impl Generator for UnionBindGenerator {
194
177
  }
195
178
 
196
179
  fn generate_definition(&mut self) {
197
- let clone_str = if self.is_frozen { ", Clone" } else { "" };
198
- write_fmt!(self, "#[derive(Debug{clone_str}, pyo3::FromPyObject)]");
180
+ write_fmt!(self, "#[derive(Debug, pyo3::FromPyObject)]");
199
181
  write_fmt!(self, "pub enum {}Union {{", self.struct_name);
200
182
 
201
183
  for variable_info in self.types.iter().skip(1) {
202
184
  let variable_name = variable_info.name.as_str();
203
185
 
204
- if self.is_frozen {
205
- write_fmt!(self, " {variable_name}(super::{variable_name}),");
206
- } else {
207
- write_fmt!(self, " {variable_name}(Py<super::{variable_name}>),");
208
- }
186
+ write_fmt!(self, " {variable_name}(Py<super::{variable_name}>),");
209
187
  }
210
188
 
211
189
  write_str!(self, "}");
@@ -217,7 +195,7 @@ impl Generator for UnionBindGenerator {
217
195
  write_str!(self, "#[pyclass(module = \"rlbot_flatbuffers\")]");
218
196
  }
219
197
 
220
- write_fmt!(self, "#[derive(Debug, Default{clone_str})]");
198
+ write_fmt!(self, "#[derive(Debug, Default)]");
221
199
  write_fmt!(self, "pub struct {} {{", self.struct_name);
222
200
 
223
201
  if !self.is_frozen {
@@ -230,21 +208,15 @@ impl Generator for UnionBindGenerator {
230
208
  }
231
209
 
232
210
  fn generate_from_flat_impls(&mut self) {
233
- let (trait_name, fn_name, python_arg) = if self.is_frozen {
234
- ("From", "from", "")
235
- } else {
236
- ("FromGil", "from_gil", "py: Python, ")
237
- };
238
-
239
211
  write_fmt!(
240
212
  self,
241
- "impl {trait_name}<flat::{}> for {} {{",
213
+ "impl FromGil<flat::{}> for {} {{",
242
214
  self.struct_t_name,
243
215
  self.struct_name
244
216
  );
245
217
  write_fmt!(
246
218
  self,
247
- " fn {fn_name}({python_arg}flat_t: flat::{}) -> Self {{",
219
+ " fn from_gil(py: Python, flat_t: flat::{}) -> Self {{",
248
220
  self.struct_t_name
249
221
  );
250
222
 
@@ -274,17 +246,10 @@ impl Generator for UnionBindGenerator {
274
246
  self.struct_name
275
247
  );
276
248
 
277
- if self.is_frozen {
278
- write_fmt!(
279
- self,
280
- " super::{variable_name}::from(*item),"
281
- );
282
- } else {
283
- write_fmt!(
284
- self,
285
- " Py::new(py, super::{variable_name}::from_gil(py, *item)).unwrap(),"
286
- );
287
- }
249
+ write_fmt!(
250
+ self,
251
+ " Py::new(py, super::{variable_name}::from_gil(py, *item)).unwrap(),"
252
+ );
288
253
 
289
254
  write_fmt!(self, " )),");
290
255
  write_fmt!(self, " }},");
@@ -298,21 +263,15 @@ impl Generator for UnionBindGenerator {
298
263
  }
299
264
 
300
265
  fn generate_to_flat_impls(&mut self) {
301
- let (trait_name, fn_name, python_arg) = if self.is_frozen {
302
- ("From", "from", "")
303
- } else {
304
- ("FromGil", "from_gil", "py: Python, ")
305
- };
306
-
307
266
  write_fmt!(
308
267
  self,
309
- "impl {trait_name}<&{}> for flat::{} {{",
268
+ "impl FromGil<&{}> for flat::{} {{",
310
269
  self.struct_name,
311
270
  self.struct_t_name
312
271
  );
313
272
  write_fmt!(
314
273
  self,
315
- " fn {fn_name}({python_arg}py_type: &{}) -> Self {{",
274
+ " fn from_gil(py: Python, py_type: &{}) -> Self {{",
316
275
  self.struct_name
317
276
  );
318
277
 
@@ -328,19 +287,11 @@ impl Generator for UnionBindGenerator {
328
287
  self.struct_name,
329
288
  );
330
289
 
331
- if self.is_frozen {
332
- write_fmt!(
333
- self,
334
- " flat::{}::{variable_name}(Box::new(item.into()))",
335
- self.struct_t_name
336
- );
337
- } else {
338
- write_fmt!(
339
- self,
340
- " flat::{}::{variable_name}(Box::new(crate::from_py_into(py, item)))",
341
- self.struct_t_name
342
- );
343
- }
290
+ write_fmt!(
291
+ self,
292
+ " flat::{}::{variable_name}(Box::new(crate::from_py_into(py, item)))",
293
+ self.struct_t_name
294
+ );
344
295
 
345
296
  write_str!(self, " },");
346
297
  } else {
@@ -14,7 +14,7 @@ pub mod generated;
14
14
  #[allow(clippy::enum_variant_names, clippy::useless_conversion, unused_imports)]
15
15
  mod python;
16
16
 
17
- use pyo3::{create_exception, exceptions::PyValueError, prelude::*, PyClass};
17
+ use pyo3::{create_exception, exceptions::PyValueError, prelude::*, types::*, PyClass};
18
18
  use python::*;
19
19
  use std::{panic::Location, path::MAIN_SEPARATOR};
20
20
 
@@ -100,6 +100,24 @@ impl<T: Default + PyClass + Into<PyClassInitializer<T>>> PyDefault for T {
100
100
  }
101
101
  }
102
102
 
103
+ #[must_use]
104
+ #[inline(never)]
105
+ pub fn pyfloat_default(py: Python) -> Py<PyFloat> {
106
+ PyFloat::new(py, 0.0).unbind()
107
+ }
108
+
109
+ #[must_use]
110
+ #[inline(never)]
111
+ pub fn float_to_py(py: Python, num: f32) -> Py<PyFloat> {
112
+ PyFloat::new(py, num as f64).unbind()
113
+ }
114
+
115
+ #[must_use]
116
+ #[inline(never)]
117
+ pub fn float_from_py(py: Python, num: &Py<PyFloat>) -> f32 {
118
+ num.bind(py).value() as f32
119
+ }
120
+
103
121
  #[must_use]
104
122
  #[inline(never)]
105
123
  pub fn none_str() -> String {
@@ -116,32 +134,38 @@ pub const fn bool_to_str(b: bool) -> &'static str {
116
134
  }
117
135
  }
118
136
 
119
- #[derive(Debug, FromPyObject)]
120
- pub enum Floats {
121
- Num(f32),
137
+ #[derive(FromPyObject)]
138
+ pub enum PartFloats {
139
+ Float(f64),
122
140
  Flat(Py<Float>),
123
141
  }
124
142
 
125
- impl FromGil<Floats> for Py<Float> {
126
- fn from_gil(py: Python, floats: Floats) -> Self {
143
+ impl FromGil<PartFloats> for Py<Float> {
144
+ fn from_gil(py: Python, floats: PartFloats) -> Self {
127
145
  match floats {
128
- Floats::Flat(float) => float,
129
- Floats::Num(num) => Py::new(py, Float::new(num)).unwrap(),
146
+ PartFloats::Float(num) => Py::new(
147
+ py,
148
+ Float {
149
+ val: PyFloat::new(py, num).unbind(),
150
+ },
151
+ )
152
+ .unwrap(),
153
+ PartFloats::Flat(float) => float,
130
154
  }
131
155
  }
132
156
  }
133
157
 
134
- #[derive(Debug, FromPyObject)]
135
- pub enum Bools {
158
+ #[derive(FromPyObject)]
159
+ pub enum PartBools {
136
160
  Num(bool),
137
161
  Flat(Py<Bool>),
138
162
  }
139
163
 
140
- impl FromGil<Bools> for Py<Bool> {
141
- fn from_gil(py: Python, bools: Bools) -> Self {
164
+ impl FromGil<PartBools> for Py<Bool> {
165
+ fn from_gil(py: Python, bools: PartBools) -> Self {
142
166
  match bools {
143
- Bools::Flat(float) => float,
144
- Bools::Num(num) => Py::new(py, Bool::new(num)).unwrap(),
167
+ PartBools::Flat(float) => float,
168
+ PartBools::Num(num) => Py::new(py, Bool::new(num)).unwrap(),
145
169
  }
146
170
  }
147
171
  }
@@ -149,7 +173,7 @@ impl FromGil<Bools> for Py<Bool> {
149
173
  macro_rules! pynamedmodule {
150
174
  (doc: $doc:literal, name: $name:tt, classes: [$($class_name:ident),*], vars: [$(($var_name:literal, $value:expr)),*], exceptions: [$($except:expr),*]) => {
151
175
  #[doc = $doc]
152
- #[pymodule]
176
+ #[pymodule(gil_used = false)]
153
177
  #[allow(redundant_semicolons)]
154
178
  fn $name(py: Python, m: Bound<PyModule>) -> PyResult<()> {
155
179
  $(m.add_class::<$class_name>()?);*;