ctypes._CData.from_buffer does not inherit _b_base_
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 77.2k
- Fork
- 35.9k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
Continuing work from #135669, I have noticed another inconsistency.
This method returns a ctypes instance that shares the buffer of the source object.
The _b_base_ read-only member is the root ctypes object that owns the memory block.
So, I assumed that, when passing a ctypes object as source to from_buffer, the _b_base_ from the resulting ctypes object would be inherited from source, however that is not the case.
To better visualize the issue, lets consider this code:
import ctypes
bindata = bytearray([
0, 0, # [0].offset
2, 0, # [0].variant
8, 0, # [1].offset
1, 0, # [1].variant
# dynamic_part
1, 2, 3, 4,
5, 6,
0, 0,
9, 8, 7, 6,
])
class A(ctypes.Structure):
_fields_ = [
("foo", ctypes.c_int),
]
class B(ctypes.Structure):
_fields_ = [
("bar", ctypes.c_byte * 6),
]
class Message(ctypes.Structure):
_fields_ = [
("offset", ctypes.c_uint16),
("variant", ctypes.c_uint16),
]
variants = {
1: A,
2: B,
}
def get(self):
root = self._b_base_._b_base_
_type = self.variants[self.variant]
try:
return _type.from_buffer(root.dynamic_part, self.offset)
except ValueError as e:
e.add_note(f"Invalid data offset={self.offset} variant={self.variant}")
raise
class FinalData(ctypes.Structure):
_fields_ = [
("messages", Message * 2),
("dynamic_part", ctypes.c_ubyte * 12),
]
x = FinalData.from_buffer(bindata)
print(x)
print(x.dynamic_part._b_base_)
a = x.messages[1].get()
b = x.messages[0].get()
print(a)
print(a._b_base_)
print(b)
print(b._b_base_)
I expected the a._b_base_ and b._b_base_ would be <__main__.FinalData object at 0x7fbee293d3d0>, like x.dynamic_part._b_base_, instead it is None.
Linked PRs
- gh-152706
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia esaminando la PR collegata gh-152706 ed eseguendo il riproduttore ctypes fornito. Poi esamina l’implementazione alla base di _CData.from_buffer e i test esistenti; il lavoro è completo quando la catena di ownership b_base dell’oggetto risultante corrisponde al comportamento documentato di ownership del buffer.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- backend
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 35/100