[ty] Format conflicting types as an enumeration (#18956)

## Summary

Format conflicting declared types as
```
`str`, `int` and `bytes`
```

Thanks to @AlexWaygood for the initial draft.

@dcreager, looking forward to your one-character follow-up PR.
This commit is contained in:
David Peter 2025-06-26 14:29:33 +02:00 committed by GitHub
parent c0beb3412f
commit 86fd9b634e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 90 additions and 83 deletions

View file

@ -1,5 +1,6 @@
use crate::{Db, Program, PythonVersionWithSource};
use ruff_db::diagnostic::{Annotation, Diagnostic, Severity, SubDiagnostic};
use std::fmt::Write;
/// Add a subdiagnostic to `diagnostic` that explains why a certain Python version was inferred.
///
@ -87,3 +88,27 @@ pub fn add_inferred_python_version_hint_to_diagnostic(
}
}
}
/// Format a list of elements as a human-readable enumeration.
///
/// Encloses every element in backticks (`1`, `2` and `3`).
pub(crate) fn format_enumeration<I, IT, D>(elements: I) -> String
where
I: IntoIterator<IntoIter = IT>,
IT: ExactSizeIterator<Item = D> + DoubleEndedIterator,
D: std::fmt::Display,
{
let mut elements = elements.into_iter();
debug_assert!(elements.len() >= 2);
let final_element = elements.next_back().unwrap();
let penultimate_element = elements.next_back().unwrap();
let mut buffer = String::new();
for element in elements {
write!(&mut buffer, "`{element}`, ").ok();
}
write!(&mut buffer, "`{penultimate_element}` and `{final_element}`").ok();
buffer
}