mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-23 01:33:06 +00:00
libdrgn/python: allow specifying Object value positionally
It's annoying to have to do value= when creating objects, especially in interactive mode. Let's allow passing in the value positionally so that `Object(prog, "int", value=0)` becomes `Object(prog, "int", 0)`. It's clear enough that this is creating an int with value 0.
This commit is contained in:
parent
1cc771605d
commit
ab876f3dbd
10
_drgn.pyi
10
_drgn.pyi
@ -611,14 +611,14 @@ class Object:
|
|||||||
language. For example, adding two objects from a program written in C
|
language. For example, adding two objects from a program written in C
|
||||||
results in an object with a type and value according to the rules of C:
|
results in an object with a type and value according to the rules of C:
|
||||||
|
|
||||||
>>> Object(prog, 'unsigned long', value=2**64 - 1) + Object(prog, 'int', value=1)
|
>>> Object(prog, 'unsigned long', 2**64 - 1) + Object(prog, 'int', 1)
|
||||||
Object(prog, 'unsigned long', value=0)
|
Object(prog, 'unsigned long', value=0)
|
||||||
|
|
||||||
If only one operand to a binary operator is an object, the other operand
|
If only one operand to a binary operator is an object, the other operand
|
||||||
will be converted to an object according to the language's rules for
|
will be converted to an object according to the language's rules for
|
||||||
literals:
|
literals:
|
||||||
|
|
||||||
>>> Object(prog, 'char', value=0) - 1
|
>>> Object(prog, 'char', 0) - 1
|
||||||
Object(prog, 'int', value=-1)
|
Object(prog, 'int', value=-1)
|
||||||
|
|
||||||
The standard :class:`int() <int>`, :class:`float() <float>`, and
|
The standard :class:`int() <int>`, :class:`float() <float>`, and
|
||||||
@ -640,9 +640,9 @@ class Object:
|
|||||||
:param prog: The program to create this object in.
|
:param prog: The program to create this object in.
|
||||||
:param type: The type of the object. If omitted, this is deduced from
|
:param type: The type of the object. If omitted, this is deduced from
|
||||||
*value* according to the language's rules for literals.
|
*value* according to the language's rules for literals.
|
||||||
|
:param value: The value of this object. See :meth:`value_()`.
|
||||||
:param address: The address of this object in the program. Either this or
|
:param address: The address of this object in the program. Either this or
|
||||||
*value* must be given, but not both.
|
*value* must be given, but not both.
|
||||||
:param value: The value of this object. See :meth:`value_()`.
|
|
||||||
:param byteorder: Byte order of the object. This should be ``'little'`` or
|
:param byteorder: Byte order of the object. This should be ``'little'`` or
|
||||||
``'big'``. The default is ``None``, which indicates the program byte
|
``'big'``. The default is ``None``, which indicates the program byte
|
||||||
order. This must be ``None`` for primitive values.
|
order. This must be ``None`` for primitive values.
|
||||||
@ -657,9 +657,9 @@ class Object:
|
|||||||
self,
|
self,
|
||||||
prog: Program,
|
prog: Program,
|
||||||
type: Union[str, Type, None] = None,
|
type: Union[str, Type, None] = None,
|
||||||
|
value: Any = None,
|
||||||
*,
|
*,
|
||||||
address: Optional[int] = None,
|
address: Optional[int] = None,
|
||||||
value: Any = None,
|
|
||||||
byteorder: Optional[str] = None,
|
byteorder: Optional[str] = None,
|
||||||
bit_offset: Optional[int] = None,
|
bit_offset: Optional[int] = None,
|
||||||
bit_field_size: Optional[int] = None,
|
bit_field_size: Optional[int] = None,
|
||||||
@ -935,7 +935,7 @@ def NULL(prog: Program, type: Union[str, Type]) -> Object:
|
|||||||
"""
|
"""
|
||||||
Get an object representing ``NULL`` casted to the given type.
|
Get an object representing ``NULL`` casted to the given type.
|
||||||
|
|
||||||
This is equivalent to ``Object(prog, type, value=0)``.
|
This is equivalent to ``Object(prog, type, 0)``.
|
||||||
|
|
||||||
:param prog: The program.
|
:param prog: The program.
|
||||||
:param type: The type.
|
:param type: The type.
|
||||||
|
@ -412,7 +412,7 @@ static int DrgnObject_init(DrgnObject *self, PyObject *args, PyObject *kwds)
|
|||||||
struct index_arg bit_field_size = { .allow_none = true, .is_none = true };
|
struct index_arg bit_field_size = { .allow_none = true, .is_none = true };
|
||||||
struct drgn_qualified_type qualified_type;
|
struct drgn_qualified_type qualified_type;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O$OO&O&O&O&:Object",
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|OO$O&O&O&O&:Object",
|
||||||
keywords, &Program_type, &prog,
|
keywords, &Program_type, &prog,
|
||||||
&type_obj, &value_obj, index_converter,
|
&type_obj, &value_obj, index_converter,
|
||||||
&address, byteorder_converter,
|
&address, byteorder_converter,
|
||||||
|
@ -80,6 +80,15 @@ class TestInit(ObjectTestCase):
|
|||||||
self.prog,
|
self.prog,
|
||||||
"int",
|
"int",
|
||||||
)
|
)
|
||||||
|
self.assertRaisesRegex(
|
||||||
|
ValueError,
|
||||||
|
"object cannot have address and value",
|
||||||
|
Object,
|
||||||
|
self.prog,
|
||||||
|
"int",
|
||||||
|
0,
|
||||||
|
address=0,
|
||||||
|
)
|
||||||
self.assertRaisesRegex(
|
self.assertRaisesRegex(
|
||||||
ValueError,
|
ValueError,
|
||||||
"object cannot have address and value",
|
"object cannot have address and value",
|
||||||
@ -373,6 +382,9 @@ class TestReference(ObjectTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestValue(ObjectTestCase):
|
class TestValue(ObjectTestCase):
|
||||||
|
def test_positional(self):
|
||||||
|
self.assertEqual(Object(self.prog, "int", 1), Object(self.prog, "int", value=1))
|
||||||
|
|
||||||
def test_signed(self):
|
def test_signed(self):
|
||||||
obj = Object(self.prog, "int", value=-4)
|
obj = Object(self.prog, "int", value=-4)
|
||||||
self.assertIs(obj.prog_, self.prog)
|
self.assertIs(obj.prog_, self.prog)
|
||||||
|
Loading…
Reference in New Issue
Block a user