RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hello all,

I'm trying to make a few changes to the PWM module of RPi.GPIO 0.7.0, and  
have a couple of questions:

1) Inside "PyMODINIT_FUNC PyInit__GPIO(void)" :

// Add PWM class
if (PWM_init_PWMType() == NULL)
...
Py_INCREF(&PWMType);
PyModule_AddObject(module, "PWM", (PyObject*)&PWMType);

Is there any reason (technical or otherwise) why the last two lines are not  
part of the "PWM_init_PWMType()" function just above it ?    Somehow I  
regard that function as the initialisator of the PWM class.

2) Inside "PyTypeObject *PWM_init_PWMType(void)":

PWMType.tp_new = PyType_GenericNew;

Is there a (technical or otherwise) reason to why the "PyTypeObject PWMType  
=" structure (just above the call) does not not just contain  
"PyType_GenericNew" as the relevant element ?


Yes, I could just make the changes and do a few tests if the result will  
still work (I have the feeling it will), but I can't test everything and  
perhaps there are some design/readability considerations involved too. Hence  
the post. :-)

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
declaimed the following:

Quoted text here. Click to load it
    I'm not going to crawl through the code and Python embedding/extension
manuals... But I will comment that, in Python, instantiating a class object
invokes two functions

__new__()
__init__()

    The first is responsible for allocating the space for the object (and
possibly setting up special conditions), the second is responsible for
initializing the allocated object.

    My suspicion is that the two functions you mention are C-level
equivalents of new and init (though with confusing names). The
"if(...NULL)" confirms that the object space was created, then the
initialization takes place.


--  
    Wulfraed                 Dennis Lee Bieber         AF6VN
     snipped-for-privacy@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Dennis,
Quoted text here. Click to load it
...

Hmmm...  Those names do not make it easier for me to keep the  
possibility-to-instanciate and the actual instanciation initialisations  
apart I'm afraid.

As far as I can tell the functions I referred to are related to the first  
(the contents of the table (mentioned it the second part) are used at actual  
instanciation).

But .... as a newbie in this regard I could easily be wrong there. :-|

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

PWM_init_PWMType sets up the type (someting that doesn?t need to know
about any module it may end up in), PyModule_AddObject gives the type a
name in a module. They?re logically quite separate operations.

Quoted text here. Click to load it

There?s no technical reason. The idiom and the associated comment is
widespread so I expect that whatever material the author learn the API
from had it.

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

Quoted text here. Click to load it

True.    But somehow I have the strong urge to place both in a single  
function, and place it inside the PWM api sourcefile, py_pwm.c.  The reason  
for that ?    The PyModule_AddObject() function call gets two arguments,  
"PWM" and PWMType, which the main module, py_gpio.c, doesn't need to know  
anything about and should correlate with other data in the py_pwm.c file.  
In short, it looks cleaner to me that way.

Quoted text here. Click to load it

I thought so too, but have started to doubt myself :

As far as I can (now) tell, the "PWMType.tp_new = PyType_GenericNew;" line  
creates a single instance and stores it, which than is referenced in all  
further access thru the "tp_new" field - instead of creating a new instance  
of it every time that that field is referenced, which is what I think would  
happen if the PyType_GenericNew is placed in the table itself.    Does that  
make any sense ?

Quoted text here. Click to load it

:-)  That is what I assumed at first..

Regards,
Rudy Wieser  



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

You?re welcome to your opinion and your urges, but most programmers
would see your version as wrong due to its mixing of separate concerns.
I would reject it in a PR.

Quoted text here. Click to load it

It makes no sense at all. Both approaches behave the same, ending up
with the tp_new member set to PyType_GenericNew.

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

Quoted text here. Click to load it

Which is exactly what I see in the current way its done ...   :-\

But yes, that "what is the custom?" is the second part of my question.

Quoted text here. Click to load it

Thank you for confirming it.

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

To clarify:

Quoted text here. Click to load it

That sounds quite logical.

Quoted text here. Click to load it

That commands last argument reaches into the PWM module, which goes against  
what you mentioned above, and which is what I tried to refer to: The main  
module should also not need to know anything about the PWM one, but for how  
to call its class initialisator - which, I could imagine, might have a  
strictly defined name.

But as I have no reason (yet) to go against conventions I've choosen to  
slightly alter the main modules PWM modules initializing code:

// Add PWM class
if (( pwmtype = PWM_init_PWMType()) == NULL)
...
Py_INCREF(pwmtype);
PyModule_AddObject(module, "PWM", (PyObject*)pwmtype);

This way the main module also doesn't know anything about the PWM modules  
internal data (als have removed the PWMType declaration from the PWM modules  
header file)

Any objections or other remarks ?

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

The relevant module is RPi._GPIO. That?s what PyInit__GPIO is setting
up. PyModule_AddObject gives the type defined in C by PWMType the name
?PWM? in that module. If you don?t believe me then consult the Python C
API documentation. RPi._GPIO only ?knows? about its own module
namespace, it doesn?t know about the internals of PWMType, so it seems
to me that your preferences about who knows what are already met.

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

Quoted text here. Click to load it

That is not the part I have been talking about.

Quoted text here. Click to load it

Neither is that

Quoted text here. Click to load it

You're playing games, implicitily declaring the PWMType object itself as not  
being internal to the PWM module/sourcefile.  I'm afraid that that doesn't  
quite work for me.

Thanks for the respons though.

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

I?ve no idea what you think the game is. I?ve been assuming throughout
that ?module? meant a Python module, since we?ve been talking about a
Python module, rather than a C source file. If you want to use one word
to mean two quite different things, without even clarifying what you
mean, then I don?t think you get to tell other people that they are
playing games when they don?t realise you?re being ambiguous.

Based on your last code fragment it looks like all you?re now arguing
about is what name the type object should be referred to by when adding
it to the module, rather than where the PyModule_AddObject call is. That
falls into the ?don?t care? camp for me (which is why I didn?t respond
to that bit).

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
declaimed the following:

Quoted text here. Click to load it

    Neither... cf: https://docs.python.org/3/c-api/type.html (and related)
"""
 newfunc PyTypeObject.tp_new

    An optional pointer to an instance creation function.
"""
"""
PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject
*kwds)
    Return value: New reference.

    Generic handler for the tp_new slot of a type object. Create a new
instance using the type?s tp_alloc slot.
"""

    It appears to be saving "genericnew" AS the function to be used later
when the instance is actually created. Somewhere (possibly in the C
extension API itself) PWMType.tp_new needs to be called (with arguments) to
actually make the object.




--  
    Wulfraed                 Dennis Lee Bieber         AF6VN
     snipped-for-privacy@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Dennis,

Quoted text here. Click to load it

That part I understood (from the fields name).

My doubt was/is if the current way its done would perhaps result in a (sort  
of) singleton, and moving the "PyType_GenericNew" reference into the table  
itself would possibly cause multiple instances to be created.

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

Both strategies still have the same behavior. The choice of assignment vs
initialisation does not make any difference here. It certainly isn?t
going to cause the function to be called different numbers of times at
some point in the future; if you think that it is then you need to
revisit your mental model of what is going on here.

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

Quoted text here. Click to load it

Are you sure ?

1) The "PWMType.tp_new = PyType_GenericNew;" inside the "PWM_init_PWMType"  
function is called exactly /once/ when the GPIO module is loaded..

2)AFAIK the "tp_new" function is called /every time/ you instanciate the PWM  
class on a selected pin.

So yes, AFAIKS there are different call numbers.

That means that in the origional code I see a single PyType_GenericNew  
instance being created before any PWM class instanciation is done and (thus)  
shared between all PWM class instanciations. (with the "tp_new" call just  
incrementing the reference count)

Moving the "PyType_GenericNew" into the table means that every time a PWM  
class is instanciated (and its "tp_new" member is called) a new  
PyType_GenericNew is instanciated too.

Quoted text here. Click to load it

I did.   And the above is, after careful consideration, what I now have.

If you know where my above "mental model" goes wrong than please do tell, as  
I'm now in a state of confusion: my assumption/knowledge of what is going on  
there does not stroke with your assurance that that is not what happens -  
and I have no idea why.

Regards,
Rudy Wieser



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

No function is called in that line.

Quoted text here. Click to load it

Yes. tp_new, and therefore PyType_GenericNew, are called precisely as
many times as you create a PWM instance. No more, no less.  

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

Quoted text here. Click to load it

Re-read please.   I did not say it was a function that got called, I said  
that its called INSIDE a function - which name I only mentioned so you could  
easily find it back.

Quoted text here. Click to load it

Am I speaking some foreign language perhaps ?   I really thought that my  
English/American wasn't /that/ bad.    'Cause no matter how I say it you do  
not seem to understand what I'm trying to explain (you just repeat the same  
phrase over-and-over again) :-(

According to me line "PWMType.tp_new = PyType_GenericNew;" creates a single  
instance, and than (one of the methods of) that instance is called thru  
accessing the tables "tp_new" field

But if-and-when you put the "PyType_GenericNew" into the table itself you  
will, as far as I can tell, create a new instance every time (yes ?  no?).

Thats a BIG difference.    Care to explain how that /doesn't/ happen ?

In short, the ammount of calls does not interest me in the slightest.   What  
/does/ is the AMMOUNT OF INSTANCES that either of the described methods will  
result in, preferrably accompanied by some explanation pointing out where my  
train of thoughts goes amiss.

Regards,
Rudy Wieser.



Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
On 16/12/2019 11:12, R.Wieser wrote:

Quoted text here. Click to load it
OK I haven't programmed C for a quarter of a century, but isn't that  
just assigning a function pointer to a field. As I recall C doesn't have  
function "objects" so it doesn't instantiate an object for a function  
pointer, a function pointer is just a pointer to the function.

Please ignore me if I have totally missed the point.





Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Quoted text here. Click to load it

You don?t seem to be paying attention to the answers.

Quoted text here. Click to load it

It doesn?t create an instance of anything. It just sets tp_new to
PyType_GenericNew.

Quoted text here. Click to load it

Instances of the PWM type are created by calling tp_new with &PWMType as
is first argument (plus some other details). In both cases, tp_new is
set to PyType_GenericNew. The number of instances of the PWM type
created is the same as the number of calls.

Quoted text here. Click to load it

Neither way of setting tp_new creates anything. They both just set the
value of tp_new to PyType_GenericNew. I have no idea why you think it
does anything else.

Quoted text here. Click to load it

The number of calls through tp_new is precisely the same as the number
of PWM instances created.

--  
https://www.greenend.org.uk/rjk/

Re: RPi.GPIO-0.7.0 - a few questions about how it adds the PWM class
Richard,

Quoted text here. Click to load it

Yep, there's the repeat again :-(((

I'm sorry, but I do not understand you there.   That also means that  
explanation below it fully meaningless to me (doesn't have any soldid  
ground).

Regards,
Rudy Wieser



Site Timeline