-
Notifications
You must be signed in to change notification settings - Fork 763
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
RFC: Fix #2615 by relaxing the type check in extract_sequence. #2620
Conversation
After staring at this for a bit longer, I noticed that neither |
ad841d8
to
39c990b
Compare
I think a nice and simple way could be to test this in the This of course still leaves the question open whether we want extraction to be as relaxed as this PR would make, i.e. not checking for sequences at all but using anything that can be turned into an iterator? |
Sorry for the long delay in reply. Been swamped IRL and just not had a chance to get my head into this one. It seems ok to add As for relaxing the type check this far... I'm a little unsure, though in practice this is likely to match what the previous implementation did? I am tempted to look at what |
From a quick glance, they are doing what we did before 0.17.0, i.e. they check for a sequence (but not str or bytes) and then iterate to fill a So this would correspond to the first commit pushed here (modulo the extra check for bytes which we lack). So should I drop the second commit and try to add a pytest based on NumPy? And maybe also add the check to not extract bytes into a Personally, I am sort of endeared with the generic version with the reasoning that the Rust is the one that fixes the types and the Python side is the malleable one that tries to fit in. Meaning if the Rust side asks for a #[derive(FromPyObject)]
enum StringOrChars {
String(PyString),
Chars(Vec<char>),
} which should work even if At least I don't really have an example I mind where making the extraction fail on the Rust side would make something possible that would not be if it succeeded. But then again, that explicit check for str probably had a rationale that I just cannot remember ATM. |
So by now, I found #2342 and #2500 and I think even here I would argue that the idiomatic Python solution if isinstance(strings, str):
strings = [strings] could be turned into #[derive(FromPyObject)]
enum OneOrMany<'a> {
One(&'a PyString),
Many(Vec<&'a PyString>),
}
impl Into<Vec<&'a PyString>> for OneOrMany {
fn into(self) -> Vec<&'a PyString> {
match self {
Self::One(one) => vec![one],
Self::Many(many) => many,
}
}
} |
39c990b
to
ebac9f5
Compare
Added the pytest and verified that both commits would make it green. |
56022a2
to
cdff4bb
Compare
There are no binary wheels for NumPy at least on Windows/PyPy, so I restricted that test case to Linux/CPython since one combination should be enough to test this particular functionality. |
This allows us to handle types like one-dimensional NumPy arrays which implement just enough of the sequence protocol to support the extract_sequence function but are not an instance of the sequence ABC.
…:iter actually need the sequence protocol.
cdff4bb
to
c2f1810
Compare
Sorry to have been so slow to reply here. Been busy IRL and needed some time to mull this over.
I think I'm coming round to this argument too. I am flip-flopping on whether #2500 was a mistake. If we revert it, I guess we have to wait until 0.18? I was thinking about releasing 0.17.2, so should we split this fix in two pieces:
That way I can cherry pick just the first change for 0.17.2. I'm still a bit murky on whether that's definitely correct, as it'd be nice to get the I think the main thing we lost from the 0.17 change was accepting |
Since the change is already split into multiple commits here, I think we could already cherry-pick the second commit which basically restores pre-0.17 behaviour for The second commit then further relaxes To make things less messy, I will open up two new PR, one containing the test and the first change. And another one containing the second commit and a removal of the |
I am somewhat at a loss on how to properly test this without adding NumPy as a Python-side dependency and would be grateful for any advice here? (Maybe writing a custom Python class that implements only
PySequence_Length
andPySequence_Length
andPyObject_GetIter
?)I am also not sure whether
PyMapping
needs a similar treatment but the conversions forHashMap
seem to go throughPyDict
instead?