ctypes._CData.from_buffer does not inherit _b_base_
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
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
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par examiner la PR liée gh-152706 et exécuter le reproducteur ctypes fourni. Inspectez ensuite l’implémentation derrière _CData.from_buffer et ses tests existants ; le travail est considéré comme terminé lorsque la chaîne de possession b_base de l’objet obtenu correspond au comportement documenté de possession du buffer.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 35/100