From mateusz at loskot.net Thu Jul 5 13:42:17 2012 From: mateusz at loskot.net (Mateusz Loskot) Date: Thu, 5 Jul 2012 12:42:17 +0100 Subject: [capi-sig] Modify tp_getset or PyGetSetDef entries in run-time Message-ID: Hi, I have a type object implemented using plain Python 3 C API. The type has number of attributes - tp_getset slot set with typical table of geters and seters. I'd like to find out best way to make certain attributes read-only at run-time. The table I assign to tp_getset looks like this: PyGetSetDef Foo_getseters[] = { {"text", (getter)Foo_get_text, (setter)Foo_set_text, PyDoc_STR("Foo text"), NULL }, {NULL} }; Now, at some point at run-time, I'd like to disallow assignment to .text property Obvious way to do that is to check desired condition in Foo_set_text() and set AttributeError. I wonder if it would be possible and sensible to modify the tp_getset slot and simply set the Foo_set_text entry in Foo_getseters to NULL. Is it possible? Is there any better way to make an attribute read-only at run-time? Best regards, -- Mateusz Loskot, http://mateusz.loskot.net From mateusz at loskot.net Fri Jul 6 14:24:35 2012 From: mateusz at loskot.net (Mateusz Loskot) Date: Fri, 6 Jul 2012 13:24:35 +0100 Subject: [capi-sig] How to pass arguments to tp_new and tp_init from subtypes? Message-ID: Hi, I'm reading the PEP 253 [1] on subtyping and there are plenty of good recommendations on how to structure the types, call tp_new and tp_init slots, etc. But, it lacks an important note on passing arguments from sub to super type. It seems the PEP is unfinished as per the note: (XXX There should be a paragraph or two about argument passing here.) So, I'm trying to extrapolate some strategies well known from the Python classes [2] subtyping, especially techniques that each level strips-off arguments, etc. I'm looking for techniques to achieve similar effect to this, but in using plain Python C API (3.x): class Shape: def __init__(self, shapename, **kwds): self.shapename = shapename super().__init__(**kwds) class ColoredShape(Shape): def __init__(self, color, **kwds): self.color = color super().__init__(**kwds) What would be the equivalent in C API? Also, how to deal with similar situation but with arguments specific to derived class expected in different order, it is given at the end of the args tuple (or kwds dict, I assume principle would be same). Here is some (pseudo-)code that illustrates the situation: class Base: def __init__(self, x, y, z): self.x = x self.y = y self.z = z class Derived(Base): def __init__(self, x, y, a): self.a = a super().__init__(x, y, None): Note, if the 'a' was expected first: Derived.__init__(self, a, x, y) it would be similar situation to the Shape and ColoredShape above. It would be easier to deal with, I assume. [1] http://www.python.org/dev/peps/pep-0253/ [2] http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ Best regards, -- Mateusz Loskot, http://mateusz.loskot.net From ideasman42 at gmail.com Fri Jul 6 14:35:29 2012 From: ideasman42 at gmail.com (Campbell Barton) Date: Fri, 6 Jul 2012 14:35:29 +0200 Subject: [capi-sig] Modify tp_getset or PyGetSetDef entries in run-time In-Reply-To: References: Message-ID: While this isnt impossible - its definetly not intended, when python runs PyType_Ready() it converts the PyGetSetDef's into PyObject's attribute descriptors which are stored in the PyType's dictionary. so strongly advice against trying to manipulate that data at low level... some alternatives could be.... - define pygetattro and manage the lookups on each call - typical way to handle such cases. - you could look at assigning properties to a class as can be done in python... MyClass.foo = property(getx, setx, delx, "This is a property") ... doing in C will be more verbose of course but it should work fine. On Thu, Jul 5, 2012 at 1:42 PM, Mateusz Loskot wrote: > Hi, > > I have a type object implemented using plain Python 3 C API. > The type has number of attributes - tp_getset slot set with typical > table of geters and seters. > I'd like to find out best way to make certain attributes read-only at run-time. > > The table I assign to tp_getset looks like this: > > PyGetSetDef Foo_getseters[] = > { > {"text", (getter)Foo_get_text, (setter)Foo_set_text, > PyDoc_STR("Foo text"), NULL }, > {NULL} > }; > > Now, at some point at run-time, I'd like to disallow assignment to > .text property > Obvious way to do that is to check desired condition in Foo_set_text() > and set AttributeError. > > I wonder if it would be possible and sensible to modify the tp_getset slot and > simply set the Foo_set_text entry in Foo_getseters to NULL. > > Is it possible? > Is there any better way to make an attribute read-only at run-time? > > Best regards, > -- > Mateusz Loskot, http://mateusz.loskot.net > _______________________________________________ > capi-sig mailing list > capi-sig at python.org > http://mail.python.org/mailman/listinfo/capi-sig -- - Campbell From mateusz at loskot.net Fri Jul 6 14:40:51 2012 From: mateusz at loskot.net (Mateusz Loskot) Date: Fri, 6 Jul 2012 13:40:51 +0100 Subject: [capi-sig] Modify tp_getset or PyGetSetDef entries in run-time In-Reply-To: References: Message-ID: On 6 July 2012 13:35, Campbell Barton wrote: > While this isnt impossible - its definetly not intended, when python > runs PyType_Ready() it converts the PyGetSetDef's into PyObject's > attribute descriptors which are stored in the PyType's dictionary. > so strongly advice against trying to manipulate that data at low > level... Campbell, That's what I thought indeed. > - you could look at assigning properties to a class as can be done in python... > > MyClass.foo = property(getx, setx, delx, "This is a property") > > ... doing in C will be more verbose of course but it should work fine. It is a very interesting option, though I'm running out of either C API fu or imagination how to make such thing at C API level...without fiddling with PyGetSetDef table. If Python sources make use of it, I could grasp it easily, but what to look there at? Would you mind pointing where to learn some details? Best regards, -- Mateusz Loskot, http://mateusz.loskot.net