Problem with time.time() standing still
Hi all, I've been a long time user of Python and written many extensions but this problem has me stumped. I've written a straight forward extension that wraps a vendors SDK for a video capture card. All works well except that in the Python thread on which I call the extension, after certain calls that I believe are using DirectShow, time stands still. The thread returns fine as the extension does its stuff in its own threads. In all other respects the Python thread seems unaffected but calls to time.time() always return the same time which is usually several seconds in the past or future and always has no fractional part. If I leave it long enough time will suddently jump forward after a few minutes, then again after a few minutes more. I've never encountered this behaviour before and can't understand what on earth is going on. If I call the 'C' time() function just the other side of my call to the extension the time is ticking along fine. It's just the one Python thread that is affected. If I call from the main thread then the main thread is affected. The calling program I've used to test this is just a few lines long. I believe the time function is a thin wrapper over the 'C' runtime so its very odd that time only stands still on the Python side but not on the 'C' side. As time is built in I've not looked at the code as its not in the distribution. Don't know if it would help to do that. This also can affect the time.sleep() function making it return immediately but that only seems to happen in my full application. Any ideas would be very greatly received. Bob -- http://mail.python.org/mailman/listinfo/python-list
Re: Problem with time.time() standing still
Thanks Daniel, that's interesting. Unfortunately there is no sensible code I can post because this only happens when I make a specific call into the vendors SDK. I can exercise my own code in the extension without a problem. The python test calling code is doing practically nothing. I make 3 calls to the extension to set things going and then loop every 5 seconds and print the time. I know Pythons own threading model is cooperative because of the GIL and therefore one thread can hog the show but I've never had issues with threads running in a C extension messing up a Python thread. I really need to understand what mechanism is at play here rather than work around it. Bob The time.clock() function does increment correctly. CPU is around 30% On 05/05/2012 21:17, Danyel Lawson wrote: > Add a time.sleep(0) call to all your loops. Multithreading in Python > is a cooperative cross platform threading simulation if you have tight > loops Python won't task switch until you make a system call. > Potentially preventing internal library variables from being updated. > > Your five minute interval may be almost exactly how long it takes to > process a flooded queue in a tight loop in your program and it may be > why it continues to happen as the queue waits to fill again while > processing happens. > > You can simulate the progression of time by overriding the time.time > function by simply setting it to a function that just increments a > module level or function property variable. You can also override the > time.time function to return the posix time function's value to maybe > get around whatever optimization is happening in the time.time > function to pass back the same value. > > If you post your sample code that exhibits the same behavior it may be > obvious to someone on the list as to what is the problem. > > > > On Sat, May 5, 2012 at 3:33 PM, Bob Cowdery wrote: >> Hi all, >> >> I've been a long time user of Python and written many extensions but >> this problem has me stumped. >> >> I've written a straight forward extension that wraps a vendors SDK for a >> video capture card. All works well except that in the Python thread on >> which I call the extension, after certain calls that I believe are using >> DirectShow, time stands still. The thread returns fine as the extension >> does its stuff in its own threads. In all other respects the Python >> thread seems unaffected but calls to time.time() always return the same >> time which is usually several seconds in the past or future and always >> has no fractional part. If I leave it long enough time will suddently >> jump forward after a few minutes, then again after a few minutes more. >> >> I've never encountered this behaviour before and can't understand what >> on earth is going on. If I call the 'C' time() function just the other >> side of my call to the extension the time is ticking along fine. It's >> just the one Python thread that is affected. If I call from the main >> thread then the main thread is affected. The calling program I've used >> to test this is just a few lines long. >> >> I believe the time function is a thin wrapper over the 'C' runtime so >> its very odd that time only stands still on the Python side but not on >> the 'C' side. As time is built in I've not looked at the code as its not >> in the distribution. Don't know if it would help to do that. >> >> This also can affect the time.sleep() function making it return >> immediately but that only seems to happen in my full application. >> >> Any ideas would be very greatly received. >> >> Bob >> -- >> http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Problem with time.time() standing still
On 05/05/2012 23:05, Cameron Simpson wrote: > On 05May2012 20:33, Bob Cowdery wrote: > | I've written a straight forward extension that wraps a vendors SDK for a > | video capture card. All works well except that in the Python thread on > | which I call the extension, after certain calls that I believe are using > | DirectShow, time stands still. The thread returns fine as the extension > | does its stuff in its own threads. In all other respects the Python > | thread seems unaffected but calls to time.time() always return the same > | time which is usually several seconds in the past or future and always > | has no fractional part. > > Thought #1: you are calling time.time() and haven't unfortunately > renamed it? (I doubt this scenario, though the lack of fractional part > is interesting.) Not sure what you mean by renamed it. I also tried datetime and that had the same behaviour. > > | If I leave it long enough time will suddently > | jump forward after a few minutes, then again after a few minutes more. > | > | I've never encountered this behaviour before and can't understand what > | on earth is going on. If I call the 'C' time() function just the other > | side of my call to the extension the time is ticking along fine. It's > | just the one Python thread that is affected. > [...] > > Thought #2: On a UNIX system I'd be running the process under strace (or > dtrace or ktrace depending on flavour) to see what actual OS system calls are > being made during this behaviour. Is this feasible for you? I'm on Windows for this particular part of the application. The video SDK is Windows only. But debugging into this is probably the only way. I looked at the built-in time module. As far as I can tell it just calls the underlying C time() function as an extension. This is more mystifying as that is pretty much what I'm doing by checking the time in my own extension module where it ticks along fine. I have another scenario using a different part of their SDK where the time does still tick but the fractional part is frozen, not 0 but frozen. I'd dearly love to know what's going on here. I thought about extracting the time module, building it, calling it something else and seeing if it behaves the same. All time consuming unfortunately when I have a deadline. > > Cheers, -- http://mail.python.org/mailman/listinfo/python-list
Re: Problem with time.time() standing still
On 06/05/2012 00:11, Chris Angelico wrote: > On Sun, May 6, 2012 at 6:51 AM, Bob Cowdery wrote: >> The time.clock() function does increment correctly. CPU is around 30% > 30% of how many cores? If that's a quad-core processor, that could > indicate one core completely pegged plus a little usage elsewhere. It is a quad core but no CPU is pegged as there are a number of threads running in C. It's reasonably well spread. > > ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Problem with time.time() standing still
On 06/05/2012 09:24, Chris Angelico wrote: > On Sun, May 6, 2012 at 6:18 PM, Bob Cowdery wrote: >> On 05/05/2012 23:05, Cameron Simpson wrote: >>> Thought #1: you are calling time.time() and haven't unfortunately >>> renamed it? (I doubt this scenario, though the lack of fractional part >>> is interesting.) >> Not sure what you mean by renamed it. I also tried datetime and that had >> the same behaviour. > In Python, names are nothing special, so you could do something like: > > time.time = lambda: 142857 > > which means that time.time() will forever return that constant. > > Take a snapshot of time.time early in your code somewhere, and try > using that instead, just in case. It's a long shot but might save you > some insanity! Thanks. I will try that. Away now until Monday when the battle will resume. Bob > ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Problem with time.time() standing still
On 06/05/2012 09:49, Cameron Simpson wrote: > On 06May2012 09:18, Bob Cowdery wrote: > | On 05/05/2012 23:05, Cameron Simpson wrote: > | > On 05May2012 20:33, Bob Cowdery wrote: > | > | [...] calls to time.time() always return the same > | > | time which is usually several seconds in the past or future and always > | > | has no fractional part. > | > > | > Thought #1: you are calling time.time() and haven't unfortunately > | > renamed it? (I doubt this scenario, though the lack of fractional part > | > is interesting.) > | > | Not sure what you mean by renamed it. > > Like this: > > from time import time > [...] > time = some_unfortunate_other_function > [...] > now = time() # calls wrong function > > It seems unlikely, but possible. > > | I also tried datetime and that had > | the same behaviour. > > Makes my suggestion even less likely unless the time module itself gets > monkeypatched (i.e. "time.time = bad_function" somewhere). I don't think the function is subverted unless there is some way inside the vendor SDK or even DirectShow (the SDK uses this as a COM object) which can somehow hijack it. It does catch up every few minutes so there has to be a clue there. > | > | If I leave it long enough time will suddently > | > | jump forward after a few minutes, then again after a few minutes more. > | > | > | > | I've never encountered this behaviour before and can't understand what > | > | on earth is going on. If I call the 'C' time() function just the other > | > | side of my call to the extension the time is ticking along fine. It's > | > | just the one Python thread that is affected. > | > [...] > | > > | > Thought #2: On a UNIX system I'd be running the process under strace (or > | > dtrace or ktrace depending on flavour) to see what actual OS system calls > are > | > being made during this behaviour. Is this feasible for you? > | > | I'm on Windows for this particular part of the application. > > I'd guessed so. I've no Windows programming background; I was wondering > if there was something like this you had to hand on windows. Maybe, but not that I know of. > | [...] But debugging into this is probably the only way. I > | looked at the built-in time module. As far as I can tell it just calls > | the underlying C time() function as an extension. This is more > | mystifying as that is pretty much what I'm doing by checking the time in > | my own extension module where it ticks along fine. > > Hmm. A C extension I presume? How about writing a little pure Python > thread to call time.time(), and spin it off parallel to the rest of the > app; does it also get bad time.time() behaviour? I've tried that. It's only the Python thread (or Python main thread) that calls the extension that behaves like this. Other Python threads tick along fine with the correct time including a fractional part. > | I have another > | scenario using a different part of their SDK where the time does still > | tick but the fractional part is frozen, not 0 but frozen. > > Curiouser and curiouser. Indeed. Away now but battle will resume on Tuesday. Bob -- http://mail.python.org/mailman/listinfo/python-list
Re: Problem with time.time() standing still
Can anyone make sense of this. I've looked over the Python timemodule.c again and it uses one of gettimeofday(), ftime() or time(). The gettimeofday() is not available on Windows so its going to use ftime() or time(). As time() only has a resolution of 1 second and returns a long and I know Python time.time() has a ms resolution it must be using ftime(). After going round the houses - a lot. I've made a trivially simple extension that goes wrong. I can only think I must be doing something incredibly stupid. Perhaps someone can put me out of my misery. In the full app what happens is that it reports the correct time as given by time() by gets the ms from somewhere also. When it goes wrong it reports the same time as ftime(). Bob >>> import mytime >>> mytime.doTime() TIME : 1336474857 FTIME secs 1336474880.00 FTIME ms 0.601000 FTIME secs+ms 1336474880.601000 0 >>> mytime.doTime() TIME : 1336474871 FTIME secs 1336474880.00 FTIME ms 0.548000 FTIME secs+ms 1336474880.548000 0 >>> mytime.doTime() TIME : 1336474897 FTIME secs 1336474880.00 FTIME ms 0.007000 FTIME secs+ms 1336474880.007000 0 The extension just prints out the time as got from time() and ftime(). For a start the two do not agree on what the time is. Secondly ftime() stops incrementing while the python session is running. If I start a new session it will have incremented. >>> import mytime >>> mytime.doTime() TIME : 1336475029 FTIME secs 1336475008.00 FTIME ms 0.265000 FTIME secs+ms 1336475008.265000 0 Code and build file #include "Python.h" #include #include #include #include static struct timeb t; static float secs = 0.0; static float ms = 0.0; static float both = 0.0; static PyObject *doTime( PyObject *self, PyObject *args) { time_t seconds; seconds = time (NULL); printf ("TIME : %ld\n", seconds); ftime(&t); secs = (float)t.time; ms = (float)((float)t.millitm * 0.001); printf("FTIME secs+ms %f\n", secs + ms); return PyInt_FromLong((long)0); } static PyMethodDef pyInst_Methods[] = { {"doTime", doTime, METH_VARARGS}, {NULL, NULL, 0, NULL} }; #ifndef PyMODINIT_FUNC #define PyMODINIT_FUNC void #endif /* PyMODINIT_FUNC */ PyMODINIT_FUNC initmytime(void) { PyObject *module; module = Py_InitModule3("mytime", pyInst_Methods,"Time module"); if (!module) return; } Build file import os from distutils.core import setup from distutils.extension import Extension if os.path.exists('C:\\Program Files (x86)'): # 64 bit ProgramFiles = 'Program Files (x86)' else: # 32 bit ProgramFiles = 'Program Files' setup( name='Time Test', author='Bob Cowdery', ext_modules = [ Extension('mytime', ['pytime.cpp'], include_dirs = ['C:\\' + ProgramFiles + '\\Microsoft SDKs\\Windows\\v7.0A\\Include', 'C:\\Python26\\include'], #define_macros = [("_AFXDLL", None)], library_dirs = ['C:\\' + ProgramFiles + '\\Microsoft SDKs\\Windows\\v7.0A\\Lib', 'C:\\Python26\\libs'], libraries = ['User32', 'Gdi32', 'python26', 'odbc32', 'odbccp32'] ) ] ) On 06/05/2012 10:19, Bob Cowdery wrote: On 06/05/2012 09:49, Cameron Simpson wrote: On 06May2012 09:18, Bob Cowdery wrote: | On 05/05/2012 23:05, Cameron Simpson wrote: |> On 05May2012 20:33, Bob Cowdery wrote: |> | [...] calls to time.time() always return the same |> | time which is usually several seconds in the past or future and always |> | has no fractional part. |> |> Thought #1: you are calling time.time() and haven't unfortunately |> renamed it? (I doubt this scenario, though the lack of fractional part |> is interesting.) | | Not sure what you mean by renamed it. Like this: from time import time [...] time = some_unfortunate_other_function [...] now = time() # calls wrong function It seems unlikely, but possible. | I also tried datetime and that had | the same behaviour. Makes my suggestion even less likely unless the time module itself gets monkeypatched (i.e. "time.time = bad_function" somewhere). I don't think the function is subverted unless there is some way inside the vendor SDK or even DirectShow (the SDK uses this as a COM object) which can somehow hijack it. It does catch up every few minutes so there has to be a clue there. |> | If I leave it long enough time will suddently |> | jump forward after a few minutes, then again after a few minutes more. |> | |> | I
Re: Problem with time.time() standing still
Hopefully somebody can add the last piece of this puzzle. My code didn't work because I did make a silly mistake. The number of seconds since EPOC is a large number but it also needs a high precision. Attempting to put this value into a 32 bit float corrupts the least significant part because 24 bits cannot hold that precision. Now Python floats are C doubles and the calculation in timemodule.c is in doubles right back to Python. Normally this retains the precision. For some inexplicable reason when I make certain calls into this vendors SDK, ftime() is getting precision problems and appears to be frozen as a result. C, only supporting early binding cannot change the function referenced at runtime so how the devil is it managing to do this. On 08/05/2012 12:17, Bob Cowdery wrote: Can anyone make sense of this. I've looked over the Python timemodule.c again and it uses one of gettimeofday(), ftime() or time(). The gettimeofday() is not available on Windows so its going to use ftime() or time(). As time() only has a resolution of 1 second and returns a long and I know Python time.time() has a ms resolution it must be using ftime(). After going round the houses - a lot. I've made a trivially simple extension that goes wrong. I can only think I must be doing something incredibly stupid. Perhaps someone can put me out of my misery. In the full app what happens is that it reports the correct time as given by time() by gets the ms from somewhere also. When it goes wrong it reports the same time as ftime(). Bob >>> import mytime >>> mytime.doTime() TIME : 1336474857 FTIME secs 1336474880.00 FTIME ms 0.601000 FTIME secs+ms 1336474880.601000 0 >>> mytime.doTime() TIME : 1336474871 FTIME secs 1336474880.00 FTIME ms 0.548000 FTIME secs+ms 1336474880.548000 0 >>> mytime.doTime() TIME : 1336474897 FTIME secs 1336474880.00 FTIME ms 0.007000 FTIME secs+ms 1336474880.007000 0 The extension just prints out the time as got from time() and ftime(). For a start the two do not agree on what the time is. Secondly ftime() stops incrementing while the python session is running. If I start a new session it will have incremented. >>> import mytime >>> mytime.doTime() TIME : 1336475029 FTIME secs 1336475008.00 FTIME ms 0.265000 FTIME secs+ms 1336475008.265000 0 Code and build file #include "Python.h" #include #include #include #include static struct timeb t; static float secs = 0.0; static float ms = 0.0; static float both = 0.0; static PyObject *doTime( PyObject *self, PyObject *args) { time_t seconds; seconds = time (NULL); printf ("TIME : %ld\n", seconds); ftime(&t); secs = (float)t.time; ms = (float)((float)t.millitm * 0.001); printf("FTIME secs+ms %f\n", secs + ms); return PyInt_FromLong((long)0); } static PyMethodDef pyInst_Methods[] = { {"doTime", doTime, METH_VARARGS}, {NULL, NULL, 0, NULL} }; #ifndef PyMODINIT_FUNC #define PyMODINIT_FUNC void #endif /* PyMODINIT_FUNC */ PyMODINIT_FUNC initmytime(void) { PyObject *module; module = Py_InitModule3("mytime", pyInst_Methods,"Time module"); if (!module) return; } Build file import os from distutils.core import setup from distutils.extension import Extension if os.path.exists('C:\\Program Files (x86)'): # 64 bit ProgramFiles = 'Program Files (x86)' else: # 32 bit ProgramFiles = 'Program Files' setup( name='Time Test', author='Bob Cowdery', ext_modules = [ Extension('mytime', ['pytime.cpp'], include_dirs = ['C:\\' + ProgramFiles + '\\Microsoft SDKs\\Windows\\v7.0A\\Include', 'C:\\Python26\\include'], #define_macros = [("_AFXDLL", None)], library_dirs = ['C:\\' + ProgramFiles + '\\Microsoft SDKs\\Windows\\v7.0A\\Lib', 'C:\\Python26\\libs'], libraries = ['User32', 'Gdi32', 'python26', 'odbc32', 'odbccp32'] ) ] ) On 06/05/2012 10:19, Bob Cowdery wrote: On 06/05/2012 09:49, Cameron Simpson wrote: On 06May2012 09:18, Bob Cowdery wrote: | On 05/05/2012 23:05, Cameron Simpson wrote: |> On 05May2012 20:33, Bob Cowdery wrote: |> | [...] calls to time.time() always return the same |> | time which is usually several seconds in the past or future and always |> | has no fractional part. |> |> Thought #1: you are calling time.time() and haven't unfortunately |> renamed it? (I doubt this scenario, though the lack of fractional part |> is interest
Re: Problem with time.time() standing still
Hi Roel "Our problem turned out to be caused by a loss of precision in an application of ours, caused by Direct3D. The solution for us was to include the flag D3DCREATE_FPU_PRESERVE in CreateDevice(). The documentation seems to imply that the lower precision only has effect in the Direct3D code, but in reality it lowers precision in the rest of the code too (the whole process or the whole thread, I'm not sure). " That is spot on and very likely the cause. Thanks very much for responding. I do have some control over the vendor and have passed that information on to them. Hopefully they will investigate and fix the problem. Bob -- http://mail.python.org/mailman/listinfo/python-list
Metaclasses
Title: Message Hi I am trying to build a capability based API. That is, an instance of the api will reflect the capabilities of some underlying services. I could have several different instances of the api concurrently running against different back end services. A ui applet will bind to an api instance. I want to make this easy to use from the ui perspective so I envisage exposing a number of properties as the variable part can be represented by properties. I want a property to exist only if a capability is available so it is easily tested. I have tried using Property and Metaclasses to do this and although both work I can't figure out how to make multiple different instances as both get executed on 'import' and thus only one instance can be created. Inside the metaclass I have to get hold of the capability map I want to build the instance against. The only way I can see to do this at the moment is to have a metaclass for each capability type and hardcode the type inside it, then pick the appropriate metaclass when I build the implementation class. Regards Bob Bob Cowdery CGI Senior Technical Architect +44(0)1438 791517 Mobile: +44(0)7771 532138 [EMAIL PROTECTED] *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to notify the sender by reply email. -- http://mail.python.org/mailman/listinfo/python-list
RE: Metaclasses
Title: RE: Metaclasses Robert Yes you understand exectly what I am trying to do, my test code was not much more than you show. You are right that to do the simple thing of adding attributes I can do that in-line as it were but there may be other customisations that I want to do. I am probably just not understanding the process here but in both the examples you give the code is executed on 'import' so I end up with a class that has fixed function depending on what capability it picked up at 'import' time. What I want to do is when class API(object): __metaclass__ = MetaAPI is created that MetaAPI generates attributes from a given capability map and not the one it picked up on 'import'. Does that make any sense? Bob -Original Message- From: Robert Brewer [mailto:[EMAIL PROTECTED]] Sent: 22 December 2004 17:01 To: [EMAIL PROTECTED]; python-list@python.org Subject: RE: Metaclasses Bob Cowdery wrote: > I am trying to build a capability based API. That is, > an instance of the api will reflect the capabilities > of some underlying services. I could have several > different instances of the api concurrently running > against different back end services. A ui applet will > bind to an api instance. I want to make this easy to > use from the ui perspective so I envisage exposing a > number of properties as the variable part can be > represented by properties. I want a property to exist > only if a capability is available so it is easily tested. > I have tried using Property and Metaclasses to do this > and although both work I can't figure out how to make multiple > different instances as both get executed on 'import' and thus only one > instance can be created. Inside the metaclass I have to get hold of > the capability map I want to build the instance against. The only way > I can see to do this at the moment is to have a metaclass > for each capability type and hardcode the type inside it, > then pick the appropriate metaclass when I build the > implementation class. I was with you until the last couple of sentences. :) I *think* you're trying to write something like this: class MetaAPI(type): def __init__(cls, name, bases, dct): for name, method in capabilities.iteritems(): setattr(cls, name, method) class API(object): __metaclass__ = MetaAPI ...where all capable behaviors are attached to the API _class_. But then you start talking about "instances", and I'm not sure whether you mean instances of the API class or not, because the metaclass doesn't have much to do with that. If you want to conditionally attach methods to instances of API, then just do it in API.__init__(): class API(object): def __init__(self, keyring): for name, method in capabilities(keyring).iteritems(): setattr(self, name, method) Can you show us some code? <:) Robert Brewer MIS Amor Ministries [EMAIL PROTECTED] *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to notify the sender by reply email. -- http://mail.python.org/mailman/listinfo/python-list
RE: Metaclasses
Title: RE: Metaclasses Robert Brewer wrote: >Okay. It depends on where you're getting that capability information from, but the simplest approach I can > >think of would be to stick it in the class: > >class API(object): > __metaclass__ = MetaAPI > > capmap = global_map_getter(usercontext_or_keyring) > >...then "capmap" should be available within MetaAPI.__init__: > >class MetaAPI(type): > def __init__(cls, name, bases, dct): > for name, method in dct['capmap']: > setattr(cls, name, method) > >Of course, all of this could be done without using a metaclass--just call setattr as needed right after your >class is defined. Another option would be to immediately follow your API class definition with a call like: > >from myframework import captools > >class API(object): > def foo(): > pass> > >captools.enable(API) > > >...the choice comes down IMO to what you think will be the most usable/maintainable by those who follow you. Thanks for your help Robert. I'm still not understanding what I am seeing. I've forgotten about the objective for the moment. I just want to understand metaclasses. The code I have is below, in 3 separate files, the capability, the metaclass and the API class. Sorry it's a bit rubbish at the moment. When I run this I get: >>> import api {'_API__cap': {'MyRig': ['mode', 'mute'], 'SDR1000': ['mode', 'blanker', 'mute'], 'YourRig': ['mode', 'blanker']}, 'radio': 'SDR1000', '__module__': 'api', '__metaclass__': } Set property SDR1000 mode Set property SDR1000 blanker Set property SDR1000 mute >>> a = api.API() >>> a.mode Traceback (most recent call last): File "", line 1, in ? a.mode AttributeError: 'API' object has no attribute 'mode' >>> a.mode = 10 >>> a.mode 10 >>> Two things I don't understand. __init__ gets called when I import api, not when I create an instance of API so the capability is set in stone on the import and I can't change it. Second when I try to read attribute 'mode' (or any other valid attribute) I get an error. If I set it to some value and read it it's there. I know I am not actually using the capability out of the dict at the moment because I just haven't looked to see how to dig it out yet but it is passed in because it prints out ok. Regards Bob Capability class ... class Capability(object): global m_radio m_radio = '' m_cap = { 'SDR1000': ['mode','blanker','mute'], 'MyRig': ['mode','mute'], 'YourRig': ['mode', 'blanker'] } def setRadio(radio): global m_radio m_radio = radio def getRadio(): global m_radio return m_radio setRadio = staticmethod(setRadio) getRadio = staticmethod(getRadio) Metaclass class ... import capability class autoprop(type): def __init__(cls, name, bases, dict): super(autoprop, cls).__init__(name, bases, dict) print dict def _get_mode(self): return self.__mode def _set_mode(self, mode): self.__mode = mode def _get_blanker(self): return self.__blanker def _set_blanker(self, blanker): self.__blanker = blanker def _get_mute(self): return self.__mute def _set_mute(self, mute): self.__mute = mute # need to dig this out the dict radio = capability.Capability.getRadio() __cap = capability.Capability.m_cap # set capability as properties for i in range(len(__cap[radio])): if __cap[radio][i] == 'mode': print 'Set property ', radio, 'mode' mode = property (eval('_get_'+__cap[radio][i]), eval('_set_'+__cap[radio][i])) elif __cap[radio][i] == 'blanker': print 'Set property ', radio, 'blanker' blanker = property (eval('_get_'+__cap[radio][i]), eval('_set_'+__cap[radio][i])) elif __cap[radio][i] == 'mute': print 'Set property ', radio, 'mute' mute = property (eval('_get_'+__cap[radio][i]), eval('_set_'+__cap[radio][i])) Api class ... import meta import capability capability.Capability.setRadio('SDR1000') class API(object): __metaclass__ = meta.autoprop # Get the capability context radio = capability.Capability.getRadio() __cap = capability.Capability.m_cap Robert Brewer MIS Amor Ministries [EMAIL PROTECTED] *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to no
RE: Metaclasses
Title: RE: Metaclasses Shalabh Yes I am realising there are variaous ways to achieve the same end. I guess I am in research mode at the moment and understanding what metaclasses can do is important even if I end up not using them. There is another thread on this question where I am trying to fill in the gaps in my understanding. Regards Bob -Original Message- From: Shalabh Chaturvedi [mailto:[EMAIL PROTECTED]] Sent: 22 December 2004 23:44 To: python-list@python.org Subject: Re: Metaclasses [EMAIL PROTECTED] wrote: > I am trying to build a capability based API. That is, an instance of > the api will reflect the capabilities of some underlying services. The question I'd ask at this point is - does the term 'instance of the API' correspond to a Python class, or an instance of the class that you define? In case you want to have one class per API, you'd have multiple classes in which case metaclasses *may* be useful (but still not required). In case you want to have one instance per API such that each instance has a different set of methods, you don't need metaclasses at all. -- Shalabh -- http://mail.python.org/mailman/listinfo/python-list *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to notify the sender by reply email. -- http://mail.python.org/mailman/listinfo/python-list
built-in 'property'
Title: Message Hi Can any one explain how property works. It seems to be fine if executed on import i.e. if the property statement is at class scope. If I put the statement inside __init__() then it appears to work ok but when I try to access the property by e.g. klass.x it just tells me it is a property object. Is this statement only designed to work at class scope? I really want to set these properties per instance. Thanks Bob Bob Cowdery CGI Senior Technical Architect +44(0)1438 791517 Mobile: +44(0)7771 532138 [EMAIL PROTECTED] *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to notify the sender by reply email. -- http://mail.python.org/mailman/listinfo/python-list
RE: built-in 'property'
Title: RE: built-in 'property' What I want to achieve is a class whereby I can set the property access per instance so the user can test if a property is present using hasattr(klass,'prop') such that the instance has a given capability that can easily be tested by the user. The actual get/set must also be implemented by functions as there is work to do on property get/set. This snippet explains. class OK(object): def __init__(self): self.__x = 0 def getx(self): return self.__x - 5 def setx(self, value): self.__x = value + 10 def delx(self): del self.__x x = property(getx, setx, delx, "I'm the 'x' property.") class NOTOK(object): def __init__(self): self.__x = 0 self.x = property(self.getx, self.setx, self.delx, "I'm the 'x' property.") def getx(self): return self.__x - 5 def setx(self, value): self.__x = value + 10 def delx(self): del self.__x >>> reload(prop) >>> ok=prop.OK() >>> ok.x -5 >>> ok.x=10 >>> ok.x 15 >>> notok=prop.NOTOK() >>> notok.x >>> notok.x=10 >>> notok.x 10 The OK example has the property and it clearly goes through the get/set methods. The NOTOK example creates a property object for x. When I set x it creates a new property x which clearly does not invoke the get/set methods. Am I doing something stupid here? Regards Bob -Original Message- From: Shalabh Chaturvedi [mailto:[EMAIL PROTECTED]] Sent: 28 December 2004 01:11 To: [EMAIL PROTECTED] Subject: Re: built-in 'property' [EMAIL PROTECTED] wrote: > > Hi > > Can any one explain how property works. It seems to be fine if > executed > on import i.e. if the property statement is at class scope. Properties are meant to be used at the class scope. A property is a kind of descriptor. See http://users.rcn.com/python/download/Descriptor.htm for details of descriptors. > If I put the > statement inside __init__() then it appears to work ok but when I try to > access the property by e.g. klass.x it just tells me it is a property > object. Please show us the code of what you are doing and describe what you are trying to do. There are a lot many things one could do with a property in __init__(). Mostly properties are just defined at the class scope. And rarely would you access klass.x (where x is a property object), mostly you would do instance.x. > Is this statement only designed to work at class scope? I really > want to set these properties per instance. Again, what exactly are you trying to do? The link above has some simple examples of how to use properties. -- Shalabh *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to notify the sender by reply email. -- http://mail.python.org/mailman/listinfo/python-list
RE: built-in 'property'
Title: RE: built-in 'property' Thanks to everyone that has helped on this. What I am trying to do is create a capability based api that I can build to order. This is as far as I get at the moment. Each of the first three classes represents some function I can do to a radio, there would be many of these in practice. The next class is the API. I figure I have to include all the possible radio function classes in this as I can't figure out how to make the classes I include per instance. When I create the API object I pass in a capability array as in the last class. I use these classes as follows. >>> import capability as c >>> import radioapi as r >>> caps = c.Capability() >>> cap = caps.getCaps('SDR1000') >>> cap ['mode', 'freq', 'blanker'] >>> api = r.API(cap) >>> r.caps ['mode', 'freq', 'blanker'] >>> api.mode Retrieving mode var "mode" 'lsb' >>> api.freq Retrieving freq var "freq" 7.0801 >>> api.blanker Retrieving blanker var "blanker" 1 >>> hasattr(api, 'monitor') 0 This is the behaviour I want, each class responds if it is in the capability array. The user can test attributes with hasattr(klass, 'att') to see if it is supported. I can create another instance with a different radio and it will respond accordingly. The problem of course is that in class API, caps is global so as soon as I create another instance the first starts responding to the new capability. If I try to make caps per instance I get into all sorts of trouble with recursion. Does anyone have an idea how to fix this or is it just impossible to make this work. Regards Bob class Mode(object): def __init__(self, initval=None, name='var'): self.val = initval self.name = name def __get__(self, obj, objtype): print 'Retrieving mode', self.name return self.val def __set__(self, obj, val): print 'Updating mode' , self.name self.val = val import capability class Freq(object): def __init__(self, initval=None, name='var'): self.val = initval self.name = name def __get__(self, obj, objtype): print 'Retrieving freq', self.name return self.val def __set__(self, obj, val): print 'Updating freq' , self.name self.val = val class Blanker(object): def __init__(self, initval=None, name='var'): self.val = initval self.name = name def __get__(self, obj, objtype): print 'Retrieving blanker', self.name return self.val def __set__(self, obj, val): print 'Updating blanker' , self.name self.val = val class API(object): # create all possible radio classes mode=Mode('lsb', 'var "mode"') freq=Freq(7.080, 'var "freq"') blanker=Blanker(True, 'var "blanker"') global caps caps = [] def __init__(self, pcaps): global caps caps = pcaps def __getattribute__(self, key): global caps if (key in caps) or (key == 'caps'): obj = object.__getattribute__(self, key) if hasattr(obj, "__get__"): return obj.__get__() return obj else: raise AttributeError, "unreadable attribute" class Capability(object): m_cap = { 'SDR1000': ['mode','freq','blanker'], 'MyRig': ['mode','freq'], 'YourRig': ['mode', 'blanker'] } def getCaps(self, radio): return self.m_cap[radio] *** Confidentiality Notice *** Proprietary/ConfidentialInformation belonging to CGI Group Inc. and its affiliatesmay be contained in this message. If you are not a recipientindicated or intended in this message (or responsible fordelivery of this message to such person), or you think forany reason that this message may have been addressed to youin error, you may not use or copy or deliver this messageto anyone else. In such case, you should destroy thismessage and are asked to notify the sender by reply email. -- http://mail.python.org/mailman/listinfo/python-list