Re: [comtypes-users] generated modules
Anthony Tuininga schrieb: > Hi, > > In relation to the problem I have been experiencing I froze the script > I wrote (that accesses AutoCAD) and attempted to run that on the > machine that is not working properly. It still doesn't work but I > discovered something in doing so that may be of interest to this > group. > > It seems that if an application is frozen you have one of two choices: > > A) import the generated module yourself sometime before calling > something like GetActiveObject() that will generate it for you This is the approach that I would recommend. Normally my scripts contain code snippets like this one: """ if not hasattr(sys, "frozen"): from comtypes.client import GetModule GetModule(r"../../../include/SomeLib.tlb") GetModule(r"../../../include/SomeOtherLib.tlb") from comtypes.gen import SomeLibLib from comtypes.gen import SomeOtherLib """ which will generate the code when I start the script with Python, and which lets py2exe include the generated code into the exe. > B) accept the overhead of regenerating the generated modules > > Neither of those seems ideal. I tracked it down to the fact that > imp.find_module() is being used which doesn't understand zip files and AFAIK imp.find_module() DOES find modules in zipfiles. > the reason imp.find_module() is being used is because an attempt is > being made to find the file in which the module is located and > performing a "stat" on the file to determine if it is newer than the > type library in question. The assumption is that if the module is > older than the type library it must be up to date. Could someone > explain why the version alone is not sufficient to distinguish type > libraries? Are there vendors that ship type libraries with the same > major __AND__ minor version but the contents are different? On the > fact of it that would seem ludicrous but perhaps I am simply betraying > my ignorance here? Please advise. Thanks. Well, it may not be the recommended approach to develop but we (in our company) do not increment the typelib version numbers on each change we make to our idl files. OTOH, why do you care about the stat call? BTW: comtypes in SVN contains an important improvement: Code generated by a frozen script will be cached in the filesystem, so if the generated modules are not inside the frozen exe they will only have to be generated when the application is run for the first time. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
On Fri, Aug 22, 2008 at 1:58 AM, Thomas Heller <[EMAIL PROTECTED]> wrote: > Anthony Tuininga schrieb: >> Hi, >> >> In relation to the problem I have been experiencing I froze the script >> I wrote (that accesses AutoCAD) and attempted to run that on the >> machine that is not working properly. It still doesn't work but I >> discovered something in doing so that may be of interest to this >> group. >> >> It seems that if an application is frozen you have one of two choices: >> >> A) import the generated module yourself sometime before calling >> something like GetActiveObject() that will generate it for you > > This is the approach that I would recommend. Normally my scripts > contain code snippets like this one: > > """ > if not hasattr(sys, "frozen"): >from comtypes.client import GetModule >GetModule(r"../../../include/SomeLib.tlb") >GetModule(r"../../../include/SomeOtherLib.tlb") > > from comtypes.gen import SomeLibLib > from comtypes.gen import SomeOtherLib > """ > > which will generate the code when I start the script with Python, > and which lets py2exe include the generated code into the exe. Well, I don't like it much as it distracts from the program logic -- but it IS a solution and it has some merits. >> B) accept the overhead of regenerating the generated modules >> >> Neither of those seems ideal. I tracked it down to the fact that >> imp.find_module() is being used which doesn't understand zip files and > > AFAIK imp.find_module() DOES find modules in zipfiles. Definitely not. :-) I've just confirmed that again. Its annoying that imp.find_module() doesn't work for modules in zip files and I'm not sure if there is a good reason for that. I believe that imp is considered a deprecated module or at least devalued module and so no effort is put into enhancing it. The general suggestion is to use __import__(name) which works great for everything except when you want to know the location of the module without actually importing it, of course! >> the reason imp.find_module() is being used is because an attempt is >> being made to find the file in which the module is located and >> performing a "stat" on the file to determine if it is newer than the >> type library in question. The assumption is that if the module is >> older than the type library it must be up to date. Could someone >> explain why the version alone is not sufficient to distinguish type >> libraries? Are there vendors that ship type libraries with the same >> major __AND__ minor version but the contents are different? On the >> fact of it that would seem ludicrous but perhaps I am simply betraying >> my ignorance here? Please advise. Thanks. > > Well, it may not be the recommended approach to develop but we (in our > company) > do not increment the typelib version numbers on each change we make to our > idl files. OTOH, why do you care about the stat call? Well, its kind of hard to stat a module inside a zip file. :-) I can think of a few options to get around this. (1) attempt the import and if successful, use the module.__file__ attribute to determine the location. At that point you can check to see if the module exists in the filesystem and do the stat then; if it doesn't (its in a zip file) you can assume that its the one you want or perform a stat on the zip file itself (2) put the timestamp of the type library file itself in the generated file name. Do either of those options sound reasonable to you? I recognize you don't see any problem so I would be willing to develop the patch for whichever option you prefer it you wish. > BTW: comtypes in SVN contains an important improvement: Code generated by a > frozen > script will be cached in the filesystem, so if the generated modules are not > inside the frozen exe they will only have to be generated when the application > is run for the first time. Yes, I noticed that. That will be helpful for the situation where such generation is indeed necessary. In general a frozen application should have all of this taken care of beforehand if it at all possible, IMHO -- but if you forget or are performing dynamic COM stuff this will be very helpful. Anthony > -- > Thanks, > Thomas > > > - > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > ___ > comtypes-users mailing list > comtypes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/comtypes-users > - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand priz
Re: [comtypes-users] generated modules
Anthony Tuininga schrieb: > Hi, > > In relation to the problem I have been experiencing I froze the > script I wrote (that accesses AutoCAD) and attempted to run that on > the machine that is not working properly. It still doesn't work but I > discovered something in doing so that may be of interest to this > group. > > It seems that if an application is frozen you have one of two > choices: > > A) import the generated module yourself sometime before calling > something like GetActiveObject() that will generate it for you B) > accept the overhead of regenerating the generated modules Anthony, sorry that I didn't understand completely the first time what you were trying to say. The intent was that the import of the generated module was meant to instruct the freezer to include the imported module into the exe, independend from where this import statement occurs. This does indeed work. What does not work and you have discovered is that the import statement must be executed BEFORE the generated module is needed by a call to GetActiveObject() or CreateObject() - in a frozen script! > [...] I tracked it down to the fact that imp.find_module() is being > used which doesn't understand zip files and the reason > imp.find_module() is being used is because an attempt is being made > to find the file in which the module is located and performing a > "stat" on the file to determine if it is newer than the type library > in question. The assumption is that if the module is older than the > type library it must be up to date. [from your other post] > Well, its kind of hard to stat a module inside a zip file. :-) > > I can think of a few options to get around this. > > (1) attempt the import and if successful, use the module.__file__ > attribute to determine the location. At that point you can check to > see if the module exists in the filesystem and do the stat then; if > it doesn't (its in a zip file) you can assume that its the one you > want or perform a stat on the zip file itself > > (2) put the timestamp of the type library file itself in the > generated file name. > (2a) put the timestamp of the type library file itself in the generated code? > Do either of those options sound reasonable to you? I recognize you > don't see any problem so I would be willing to develop the patch for > whichever option you prefer it you wish. Well, I see the problem *now*. On first thought the first option looks more attractive to me but I have to think about that - which option would you prefer? >>> BTW: comtypes in SVN contains an important improvement: Code >>> generated by a frozen script will be cached in the filesystem, so >>> if the generated modules are not inside the frozen exe they will >>> only have to be generated when the application is run for the >>> first time. > > Yes, I noticed that. That will be helpful for the situation where > such generation is indeed necessary. In general a frozen application > should have all of this taken care of beforehand if it at all > possible, IMHO -- but if you forget or are performing dynamic COM > stuff this will be very helpful. My own recent impression on this new stuff (caching code generated from *frozen* scripts in the file system) isn't so good. The code generation is probably not robust enough for that - for example if the code generation is interrupted it may leave incomplete, broken stuff in the cache directory and the exe will fail miserably each time it is started. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
On Fri, Aug 29, 2008 at 3:37 PM, Thomas Heller <[EMAIL PROTECTED]> wrote: > Anthony Tuininga schrieb: >> Hi, >> >> In relation to the problem I have been experiencing I froze the >> script I wrote (that accesses AutoCAD) and attempted to run that on >> the machine that is not working properly. It still doesn't work but I >> discovered something in doing so that may be of interest to this >> group. >> >> It seems that if an application is frozen you have one of two >> choices: >> >> A) import the generated module yourself sometime before calling >> something like GetActiveObject() that will generate it for you B) >> accept the overhead of regenerating the generated modules > > Anthony, sorry that I didn't understand completely the first time > what you were trying to say. The intent was that the import of the > generated module was meant to instruct the freezer to include > the imported module into the exe, independend from where this > import statement occurs. This does indeed work. > > What does not work and you have discovered is that the import statement > must be executed BEFORE the generated module is needed by a call to > GetActiveObject() or CreateObject() - in a frozen script! True -- a limitation which could be documented, I suppose. Ideally, however, I was hoping that I could simply specify modules to include in a setup.py without having to include code snippets like the one you suggested in the right place. >> [...] I tracked it down to the fact that imp.find_module() is being >> used which doesn't understand zip files and the reason >> imp.find_module() is being used is because an attempt is being made >> to find the file in which the module is located and performing a >> "stat" on the file to determine if it is newer than the type library >> in question. The assumption is that if the module is older than the >> type library it must be up to date. > > > [from your other post] > >> Well, its kind of hard to stat a module inside a zip file. :-) >> >> I can think of a few options to get around this. >> >> (1) attempt the import and if successful, use the module.__file__ >> attribute to determine the location. At that point you can check to >> see if the module exists in the filesystem and do the stat then; if >> it doesn't (its in a zip file) you can assume that its the one you >> want or perform a stat on the zip file itself >> >> (2) put the timestamp of the type library file itself in the >> generated file name. >> > > (2a) put the timestamp of the type library file itself in the > generated code? > >> Do either of those options sound reasonable to you? I recognize you >> don't see any problem so I would be willing to develop the patch for >> whichever option you prefer it you wish. > > Well, I see the problem *now*. > > On first thought the first option looks more attractive to me but I have > to think about that - which option would you prefer? I could probably live with either. The timestamp of the generated module ought to be accurate since it was generated on the machine which has the type library. Once frozen, however, that zip file can be transported to any number of machines which leads to the following scenario: a module could be generated on a machine with timestamp 2008-09-01 referencing a type library with timestamp 2008-01-01. However, a new version of the type library is available with timestamp 2008-08-01 but is not currently installed on the machine which did the freezing. However, it is installed on the machine which is running the frozen binary. If we simply stat the zip file everything will appear to be in order -- when in fact it is not! So, my suggestion is to put the timestamp of the type library in the generated file name or, as you suggest, inside the generated code -- that should be free from such potential situations. Did you want me to come up with a patch for this or did you want to do this yourself? BTW: comtypes in SVN contains an important improvement: Code generated by a frozen script will be cached in the filesystem, so if the generated modules are not inside the frozen exe they will only have to be generated when the application is run for the first time. >> >> Yes, I noticed that. That will be helpful for the situation where >> such generation is indeed necessary. In general a frozen application >> should have all of this taken care of beforehand if it at all >> possible, IMHO -- but if you forget or are performing dynamic COM >> stuff this will be very helpful. > > My own recent impression on this new stuff (caching code generated from > *frozen* scripts > in the file system) isn't so good. The code generation is probably not robust > enough > for that - for example if the code generation is interrupted it may leave > incomplete, broken stuff > in the cache directory and the exe will fail miserably each time it is > started. To solve that problem you need to make sure that any partially generated code is not seen. One p
Re: [comtypes-users] generated modules
Anthony, I have, finally, come to the conclusion that you are absolutely right: it is fundamentally broken to make the generated modules dependent on timestamps. Whether a generated module is up to date or not should only depend on two things: - the version number of the type library (this is clear) - and the 'version number' of the comtypes codegenerator. The former is already taken care by the naming convention of the generated modules, the latter can probably be achived by generating a code snippet like this into the wrapper module itself: """ import comtypes.tools.codegenerator if comtypes.tools.codegenerator.version != 42: raise ImportError("wrong version") """ and then regenerating the wrapper code when the import fails. No longer fiddling with imp.find_module(), searching for type library files, fiddling with timestamps and so on. Ok? Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
Thomas Heller schrieb: > Whether a generated module is up to date or not should only depend on two > things: > > - the version number of the type library (this is clear) > - and the 'version number' of the comtypes codegenerator. > > The former is already taken care by the naming convention of the generated > modules, > the latter can probably be achived by generating a code snippet like this > into the wrapper module itself: > > """ > import comtypes.tools.codegenerator > if comtypes.tools.codegenerator.version != 42: > raise ImportError("wrong version") > """ > > and then regenerating the wrapper code when the import fails. No longer > fiddling with imp.find_module(), searching for type library files, fiddling > with timestamps and so on. I have comitted an implementation as svn revision 407. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
On Thu, Sep 4, 2008 at 2:03 PM, Thomas Heller <[EMAIL PROTECTED]> wrote: > Thomas Heller schrieb: >> Whether a generated module is up to date or not should only depend on two >> things: >> >> - the version number of the type library (this is clear) >> - and the 'version number' of the comtypes codegenerator. >> >> The former is already taken care by the naming convention of the generated >> modules, >> the latter can probably be achived by generating a code snippet like this >> into the wrapper module itself: >> >> """ >> import comtypes.tools.codegenerator >> if comtypes.tools.codegenerator.version != 42: >> raise ImportError("wrong version") >> """ >> >> and then regenerating the wrapper code when the import fails. No longer >> fiddling with imp.find_module(), searching for type library files, fiddling >> with timestamps and so on. > > I have comitted an implementation as svn revision 407. I took a look. Much better. :-) Just one further question: is there any reason why you have the code inside the generated module to raise an error if the generated number does not match when you are already performing that check after you import the module successfully? I think you can quite safely remove that code. In other words, all you want in the generated code is __codegen_version__ = 42 Then in the importing code module = __import__() if module.__codegen_version__ != comtypes.tools.codegenerator.version: raise ImportError("version mismatch") Or am I missing something here? Please be gentle if I am. :-) Anthony > -- > Thanks, > Thomas > > > - > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > ___ > comtypes-users mailing list > comtypes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/comtypes-users > - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
Anthony Tuininga schrieb: > On Thu, Sep 4, 2008 at 2:03 PM, Thomas Heller <[EMAIL PROTECTED]> wrote: >> Thomas Heller schrieb: >>> Whether a generated module is up to date or not should only depend on two >>> things: >>> >>> - the version number of the type library (this is clear) >>> - and the 'version number' of the comtypes codegenerator. >>> >>> The former is already taken care by the naming convention of the generated >>> modules, >>> the latter can probably be achived by generating a code snippet like this >>> into the wrapper module itself: >>> >>> """ >>> import comtypes.tools.codegenerator >>> if comtypes.tools.codegenerator.version != 42: >>> raise ImportError("wrong version") >>> """ >>> >>> and then regenerating the wrapper code when the import fails. No longer >>> fiddling with imp.find_module(), searching for type library files, fiddling >>> with timestamps and so on. >> >> I have comitted an implementation as svn revision 407. > > I took a look. Much better. :-) > > Just one further question: is there any reason why you have the code > inside the generated module to raise an error if the generated number > does not match when you are already performing that check after you > import the module successfully? I think you can quite safely remove > that code. In other words, all you want in the generated code is > > __codegen_version__ = 42 > > Then in the importing code > > module = __import__() > if module.__codegen_version__ != comtypes.tools.codegenerator.version: > raise ImportError("version mismatch") > I think that the version check inside the modules MUST be done. The only purpose of the version checks from outside, in comtypes.client._generate, is to catch cases where wrappers are already present in comtypes.gen, but from a previous version that has not inserted version checks into the modules. Since comtypes 0.5.1 will probably be the last release that does not generate version checks, this code can probably go. > Or am I missing something here? Please be gentle if I am. :-) The possibility exists that *I* did miss something ;-) Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
>>> I have comitted an implementation as svn revision 407. >> >> I took a look. Much better. :-) >> >> Just one further question: is there any reason why you have the code >> inside the generated module to raise an error if the generated number >> does not match when you are already performing that check after you >> import the module successfully? I think you can quite safely remove >> that code. In other words, all you want in the generated code is >> >> __codegen_version__ = 42 >> >> Then in the importing code >> >> module = __import__() >> if module.__codegen_version__ != comtypes.tools.codegenerator.version: >> raise ImportError("version mismatch") >> > > I think that the version check inside the modules MUST be done. > > The only purpose of the version checks from outside, in > comtypes.client._generate, > is to catch cases where wrappers are already present in comtypes.gen, but > from a previous > version that has not inserted version checks into the modules. Since > comtypes 0.5.1 will > probably be the last release that does not generate version checks, this code > can probably go. Ah, I see that you are intending to keep the code in the generated module and I was intending to keep the code outside the generated module. I think we both agree that only one check is needed. :-) The only reason I would keep the code outside the generated module is "safety" (that code is completely under your control) and "clarity" (the code that performs the check is "in your face" when you are looking at the code that does the import) -- but I have no difficulty with your plans either if you prefer. BTW, the code that checks for the existence of the __codegen_version__ attribute will already confirm anything earlier than 0.5.1 anyway since that attribute is new, right? >> Or am I missing something here? Please be gentle if I am. :-) > > The possibility exists that *I* did miss something ;-) Nope. Just misunderstanding and I think its cleared up now. :-) > Thomas > > > - > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > ___ > comtypes-users mailing list > comtypes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/comtypes-users > - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
I have comitted an implementation as svn revision 407. >>> >>> I took a look. Much better. :-) >>> >>> Just one further question: is there any reason why you have the code >>> inside the generated module to raise an error if the generated number >>> does not match when you are already performing that check after you >>> import the module successfully? I think you can quite safely remove >>> that code. In other words, all you want in the generated code is >>> >>> __codegen_version__ = 42 >>> >>> Then in the importing code >>> >>> module = __import__() >>> if module.__codegen_version__ != comtypes.tools.codegenerator.version: >>> raise ImportError("version mismatch") >>> >> >> I think that the version check inside the modules MUST be done. >> >> The only purpose of the version checks from outside, in >> comtypes.client._generate, >> is to catch cases where wrappers are already present in comtypes.gen, but >> from a previous >> version that has not inserted version checks into the modules. Since >> comtypes 0.5.1 will >> probably be the last release that does not generate version checks, this >> code can probably go. > > Ah, I see that you are intending to keep the code in the generated > module and I was intending to keep the code outside the generated > module. I think we both agree that only one check is needed. :-) The > only reason I would keep the code outside the generated module is > "safety" (that code is completely under your control) and "clarity" > (the code that performs the check is "in your face" when you are > looking at the code that does the import) -- but I have no difficulty > with your plans either if you prefer. I agree that version checking outside would be nicer. I tried to hack the comtypes.client._generate module and the codegenerator to implement this, but there is one place where an outside version check does not work. For example, the InternetExplorer typelib generated module contains this statement: import comtypes.gen._00020430___C000_0046_0_2_0 which imports the stdole2.tlb typelib wrapper code. So this import is not done with some code in the _generate module and cannot be checked from there. > BTW, the code that checks for the existence of the __codegen_version__ > attribute will already confirm anything earlier than 0.5.1 anyway > since that attribute is new, right? Yes (if I understand you correctly; I'm not a native english speaker) it would invalidate modules generated with earlier codegenerator versions. And this is the only place where an additional outside check makes sense when otherwise only inside checks were used. But this problem will go away after the next comtypes version anyway so maybe the check can be removed. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
On Tue, Sep 9, 2008 at 12:42 PM, Thomas Heller <[EMAIL PROTECTED]> wrote: > I have comitted an implementation as svn revision 407. I took a look. Much better. :-) Just one further question: is there any reason why you have the code inside the generated module to raise an error if the generated number does not match when you are already performing that check after you import the module successfully? I think you can quite safely remove that code. In other words, all you want in the generated code is __codegen_version__ = 42 Then in the importing code module = __import__() if module.__codegen_version__ != comtypes.tools.codegenerator.version: raise ImportError("version mismatch") >>> >>> I think that the version check inside the modules MUST be done. >>> >>> The only purpose of the version checks from outside, in >>> comtypes.client._generate, >>> is to catch cases where wrappers are already present in comtypes.gen, but >>> from a previous >>> version that has not inserted version checks into the modules. Since >>> comtypes 0.5.1 will >>> probably be the last release that does not generate version checks, this >>> code can probably go. >> >> Ah, I see that you are intending to keep the code in the generated >> module and I was intending to keep the code outside the generated >> module. I think we both agree that only one check is needed. :-) The >> only reason I would keep the code outside the generated module is >> "safety" (that code is completely under your control) and "clarity" >> (the code that performs the check is "in your face" when you are >> looking at the code that does the import) -- but I have no difficulty >> with your plans either if you prefer. > > I agree that version checking outside would be nicer. I tried to hack > the comtypes.client._generate module and the codegenerator to implement this, > but there is one place where an outside version check does not work. For > example, the InternetExplorer typelib generated module contains this > statement: > import comtypes.gen._00020430___C000_0046_0_2_0 > which imports the stdole2.tlb typelib wrapper code. So this import is not > done with some code in the _generate module and cannot be checked from there. Good point. So adding the code to the generated module makes the most sense. So I guess you'll remove the code outside of the module, then. >> BTW, the code that checks for the existence of the __codegen_version__ >> attribute will already confirm anything earlier than 0.5.1 anyway >> since that attribute is new, right? > > Yes (if I understand you correctly; I'm not a native english speaker) Really? I would never have guessed. Your English is perfectly understandable to me. > it would invalidate modules generated with earlier codegenerator versions. > And this is the only place where an additional outside check makes sense > when otherwise only inside checks were used. But this problem will > go away after the next comtypes version anyway so maybe the check > can be removed. Yes, it can be removed completely -- but only after this release is considered the baseline and support for all older versions is no longer being considered. So it may be there for a while > -- > Thanks, > Thomas > > > - > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > ___ > comtypes-users mailing list > comtypes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/comtypes-users > - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
>> I agree that version checking outside would be nicer. I tried to hack >> the comtypes.client._generate module and the codegenerator to implement this, >> but there is one place where an outside version check does not work. For >> example, the InternetExplorer typelib generated module contains this >> statement: >> import comtypes.gen._00020430___C000_0046_0_2_0 >> which imports the stdole2.tlb typelib wrapper code. So this import is not >> done with some code in the _generate module and cannot be checked from there. > > Good point. So adding the code to the generated module makes the most > sense. So I guess you'll remove the code outside of the module, then. Here's the next idea that I have for the version checking: Version check inside the generated modules, but using code outside: So, inside the generated module: ''' from comtypes import check_wrapper_version check_wrapper_version('42') ''' comtypes.check_wrapper_version() would compare against the code generator version, and in the simplest case raise an ImportError("version mismatch"). In a more sophisticated implementation it could regenerate and reload the module. But I have no time to implement this now. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
Thomas Heller schrieb: > Here's the next idea that I have for the version checking: Version check > inside > the generated modules, but using code outside: > > So, inside the generated module: > > ''' > from comtypes import check_wrapper_version > check_wrapper_version('42') > ''' > > comtypes.check_wrapper_version() would compare against the code generator > version, > and in the simplest case raise an ImportError("version mismatch"). In a more > sophisticated implementation it could regenerate and reload the module. > I have implemented this now; the code simply compares the actual and the required version and raises an ImportError if they are unequal. Also I must admit that I have reintroduced the os.stat() calls on the typelib files and the generated module files, this is too damn convenient for me. The code is much simpler now, and if the generated module's timestamp is less than the typelib's timestamp an ImportError is also raised. If any of the os.stat() calls fail then the import succeeds. I wonder if there should be a way in comtypes to enable/disable this timestamp check? Currently I've enabled this code only when a script is run, in other words only when hasattr(sys, "frozen") is False. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
On Thu, Sep 18, 2008 at 10:44 AM, Thomas Heller <[EMAIL PROTECTED]> wrote: > Thomas Heller schrieb: >> Here's the next idea that I have for the version checking: Version check >> inside >> the generated modules, but using code outside: >> >> So, inside the generated module: >> >> ''' >> from comtypes import check_wrapper_version >> check_wrapper_version('42') >> ''' >> >> comtypes.check_wrapper_version() would compare against the code generator >> version, >> and in the simplest case raise an ImportError("version mismatch"). In a more >> sophisticated implementation it could regenerate and reload the module. >> > > I have implemented this now; the code simply compares the actual and the > required > version and raises an ImportError if they are unequal. Looks good. > Also I must admit that I have reintroduced the os.stat() calls on the typelib > files > and the generated module files, this is too damn convenient for me. The code > is much > simpler now, and if the generated module's timestamp is less than the > typelib's timestamp > an ImportError is also raised. If any of the os.stat() calls fail then the > import succeeds. Hmm, you have added a "coder generator" version inside the generated module. Perhaps you could also add the "type library timestamp" inside the generated module as well and compare that with the os.stat() on the type library? The type library file should always exist, right? Its the module that may not exist or rather be buried inside a zip file. If you put the type library timestamp inside the generated module that would work in both the "script" and "frozen" situations. What do you think of that concept? > I wonder if there should be a way in comtypes to enable/disable this > timestamp check? > Currently I've enabled this code only when a script is run, in other words > only when > hasattr(sys, "frozen") is False. See above. > -- > Thanks, > Thomas > > > - > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > ___ > comtypes-users mailing list > comtypes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/comtypes-users > - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
[Resending, the first answer seemed to get lost somewhere] Anthony Tuininga schrieb: > > On Thu, Sep 18, 2008 at 10:44 AM, Thomas Heller <[EMAIL PROTECTED]> wrote: >> >> Thomas Heller schrieb: >>> >>> Here's the next idea that I have for the version checking: Version >>> >>> check inside >>> >>> the generated modules, but using code outside: >>> >>> >>> >>> So, inside the generated module: >>> >>> >>> >>> ''' >>> >>> from comtypes import check_wrapper_version >>> >>> check_wrapper_version('42') >>> >>> ''' >>> >>> >>> >>> comtypes.check_wrapper_version() would compare against the code >>> >>> generator version, >>> >>> and in the simplest case raise an ImportError("version mismatch"). In >>> >>> a more >>> >>> sophisticated implementation it could regenerate and reload the module. >>> >>> >> >> >> >> I have implemented this now; the code simply compares the actual and the >> >> required >> >> version and raises an ImportError if they are unequal. > > > > Looks good. > > >> >> Also I must admit that I have reintroduced the os.stat() calls on the >> >> typelib files >> >> and the generated module files, this is too damn convenient for me. The >> >> code is much >> >> simpler now, and if the generated module's timestamp is less than the >> >> typelib's timestamp >> >> an ImportError is also raised. If any of the os.stat() calls fail then >> >> the import succeeds. > > > > Hmm, you have added a "coder generator" version inside the generated > > module. Perhaps you could also add the "type library timestamp" inside > > the generated module as well and compare that with the os.stat() on > > the type library? The type library file should always exist, right? > > Its the module that may not exist or rather be buried inside a zip > > file. If you put the type library timestamp inside the generated > > module that would work in both the "script" and "frozen" situations. > > What do you think of that concept? To be honest, the current code does *exactly* what I want: """ def _check_version(actual): from comtypes.tools.codegenerator import version as required if actual != required: raise ImportError("Wrong version") if not hasattr(sys, "frozen"): g = sys._getframe(1).f_globals mod_path = g.get("__file__") tlb_path = g.get("typelib_path") try: mod_mtime = os.stat(mod_path).st_mtime tlib_mtime = os.stat(tlb_path).st_mtime except (WindowsError, TypeError): return if mod_mtime < tlib_mtime: raise ImportError("Typelib newer than module") """ On the development machine, the code running as Python script, 'hasattr(sys, "frozen")' is False, and the timestamps are checked. Regenerating a module because a typelib has been recompiled from idl - even if the version number has not changed - is what I want; this makes sure that the generated code is correct. On the end user machine my code runs from within py2exe, 'hasattr(sys, "frozen")' is True, and I do not want to regenerate the code because I trust the typelib version number in this case. The generated modules bundled within the executable should be used in this case. There are probably other possible ways to distinguish a developer and an end-user machine, if they are preferred. >> >> I wonder if there should be a way in comtypes to enable/disable this >> >> timestamp check? >> >> Currently I've enabled this code only when a script is run, in other >> >> words only when >> >> hasattr(sys, "frozen") is False. > > I was thinking of having a config variable in comtypes\__init__.py so that users (like you?) who would like to avoid the os.stat() calls, and who do not compile typelibaries themselves, would be able to skip this check completely by changing this variable. Maybe by editing a comtypes.cfg file somewhere, maybe programmatically. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
Actually, your further explanation makes sense and I'm happy enough with what you have written now. The further refinement I suggested is not needed. Thanks for taking the time to work this through with me, though. Anthony On Mon, Sep 22, 2008 at 12:49 AM, Thomas Heller <[EMAIL PROTECTED]> wrote: > [Resending, the first answer seemed to get lost somewhere] > > Anthony Tuininga schrieb: >> > On Thu, Sep 18, 2008 at 10:44 AM, Thomas Heller <[EMAIL PROTECTED]> wrote: >>> >> Thomas Heller schrieb: >>> Here's the next idea that I have for the version checking: Version >>> check inside >>> the generated modules, but using code outside: >>> >>> So, inside the generated module: >>> >>> ''' >>> from comtypes import check_wrapper_version >>> check_wrapper_version('42') >>> ''' >>> >>> comtypes.check_wrapper_version() would compare against the code >>> generator version, >>> and in the simplest case raise an ImportError("version mismatch"). In >>> a more >>> sophisticated implementation it could regenerate and reload the module. >>> >>> >> >>> >> I have implemented this now; the code simply compares the actual and the >>> >> required >>> >> version and raises an ImportError if they are unequal. >> > >> > Looks good. >> > >>> >> Also I must admit that I have reintroduced the os.stat() calls on the >>> >> typelib files >>> >> and the generated module files, this is too damn convenient for me. The >>> >> code is much >>> >> simpler now, and if the generated module's timestamp is less than the >>> >> typelib's timestamp >>> >> an ImportError is also raised. If any of the os.stat() calls fail then >>> >> the import succeeds. >> > >> > Hmm, you have added a "coder generator" version inside the generated >> > module. Perhaps you could also add the "type library timestamp" inside >> > the generated module as well and compare that with the os.stat() on >> > the type library? The type library file should always exist, right? >> > Its the module that may not exist or rather be buried inside a zip >> > file. If you put the type library timestamp inside the generated >> > module that would work in both the "script" and "frozen" situations. >> > What do you think of that concept? > > To be honest, the current code does *exactly* what I want: > > """ > def _check_version(actual): >from comtypes.tools.codegenerator import version as required >if actual != required: >raise ImportError("Wrong version") >if not hasattr(sys, "frozen"): >g = sys._getframe(1).f_globals >mod_path = g.get("__file__") >tlb_path = g.get("typelib_path") >try: >mod_mtime = os.stat(mod_path).st_mtime >tlib_mtime = os.stat(tlb_path).st_mtime >except (WindowsError, TypeError): >return >if mod_mtime < tlib_mtime: >raise ImportError("Typelib newer than module") > """ > > On the development machine, the code running as Python script, > 'hasattr(sys, "frozen")' is False, and the timestamps are checked. > Regenerating a module > because a typelib has been recompiled from idl - even if the version number > has not changed - > is what I want; this makes sure that the generated code is correct. > > On the end user machine my code runs from within py2exe, 'hasattr(sys, > "frozen")' is True, > and I do not want to regenerate the code because I trust the typelib version > number in this > case. The generated modules bundled within the executable should be used in > this case. > > There are probably other possible ways to distinguish a developer and an > end-user machine, > if they are preferred. > >>> >> I wonder if there should be a way in comtypes to enable/disable this >>> >> timestamp check? >>> >> Currently I've enabled this code only when a script is run, in other >>> >> words only when >>> >> hasattr(sys, "frozen") is False. >> > > > I was thinking of having a config variable in comtypes\__init__.py so that > users (like you?) > who would like to avoid the os.stat() calls, and who do not compile > typelibaries themselves, > would be able to skip this check completely by changing this variable. Maybe > by editing > a comtypes.cfg file somewhere, maybe programmatically. > > -- Thanks, Thomas > > - > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > ___ > comtypes-users mailing list > comtypes-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/comtypes-users > - This SF.Net email is sponsored b
Re: [comtypes-users] Generated modules folder mixup
Malte Skarupke schrieb: > OK so I got the following traceback: > > > > # Generating comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0 > # Generating comtypes.gen._00020430___C000_0046_0_2_0 > Traceback (most recent call last): [...] > ImportError: No module named _00020430___C000_0046_0_2_0 > > > > > In my effort to find out what is going on here, I added these lines to the > buggy method: > print "==" > print "_my_import(", fullname, ")" > print "comtypes.gen.__path__: ", comtypes.gen.__path__ > print "==" > > > > > And this is the output I got from that: > > > > > == > _my_import( comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0 ) > comtypes.gen.__path__: [u'C:\\Dokumente und > Einstellungen\\Mareike\\Anwendungsdaten\\Python\\Python25\\comtypes_cache'] > == > # Generating comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0 > == > _my_import( comtypes.gen._00020430___C000_0046_0_2_0 ) > comtypes.gen.__path__: [u'C:\\Dokumente und > Einstellungen\\Mareike\\Anwendungsdaten\\Python\\Python25\\comtypes_cache'] > == > # Generating comtypes.gen._00020430___C000_0046_0_2_0 > == > _my_import( comtypes.gen._00020430___C000_0046_0_2_0 ) > comtypes.gen.__path__: [u'C:\\Dokumente und > Einstellungen\\Mareike\\Anwendungsdaten\\Python\\Python25\\comtypes_cache'] > == > [... the same Traceback as above here...] > > > > > The folder, that comtypes.gen.__path__ is set to, contains two files: > _00020430___C000_0046_0_2_0.py and > _7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0.py. So most likely the > first two generates worked alright, and the third one now is buggy. Hm, which 'third one'? > I'm pretty new to Python, but I believe there is probably just a > missing reference here somewhere, that prevents the program from > finding the generated modules. > > > > When I run the same code from the Python console, it works fine. When > I copy the files generated from the Python console (those in > C.\Python25\Lib\...\gen) to the same folder, that this comtypes is > in, (C:\Programme\...\entities\common\Lib\site-packages\comtypes\gen) > it works fine. When I copy the files generated from the Python > console to the folder that comtypes.gen.__path__ (from the last > output) is set to, it does not work. I do not understand your setup. Why is the 'console' generating files in the C.\Python25\Lib\...\gen folder, and why is it in the other case comtypes in C:\Programme\...\entities\common\Lib\site-packages\comtypes\gen ? Do you have two comtypes installations? In different folders? -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Generated modules folder mixup
Malte Skarupke schrieb: > OK so I got the following traceback: > > > > # Generating comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0 > # Generating comtypes.gen._00020430___C000_0046_0_2_0 > Traceback (most recent call last): [...] > ImportError: No module named _00020430___C000_0046_0_2_0 > > > > > In my effort to find out what is going on here, I added these lines to the > buggy method: > print "==" > print "_my_import(", fullname, ")" > print "comtypes.gen.__path__: ", comtypes.gen.__path__ > print "==" > > > > > And this is the output I got from that: > > > > > == > _my_import( comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0 ) > comtypes.gen.__path__: [u'C:\\Dokumente und > Einstellungen\\Mareike\\Anwendungsdaten\\Python\\Python25\\comtypes_cache'] > == > # Generating comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0 > == > _my_import( comtypes.gen._00020430___C000_0046_0_2_0 ) > comtypes.gen.__path__: [u'C:\\Dokumente und > Einstellungen\\Mareike\\Anwendungsdaten\\Python\\Python25\\comtypes_cache'] > == > # Generating comtypes.gen._00020430___C000_0046_0_2_0 > == > _my_import( comtypes.gen._00020430___C000_0046_0_2_0 ) > comtypes.gen.__path__: [u'C:\\Dokumente und > Einstellungen\\Mareike\\Anwendungsdaten\\Python\\Python25\\comtypes_cache'] > == > [... the same Traceback as above here...] > > > > > The folder, that comtypes.gen.__path__ is set to, contains two files: > _00020430___C000_0046_0_2_0.py and > _7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0.py. So most likely the > first two generates worked alright, and the third one now is buggy. Hm, which 'third one'? > I'm pretty new to Python, but I believe there is probably just a > missing reference here somewhere, that prevents the program from > finding the generated modules. > > > > When I run the same code from the Python console, it works fine. When > I copy the files generated from the Python console (those in > C.\Python25\Lib\...\gen) to the same folder, that this comtypes is > in, (C:\Programme\...\entities\common\Lib\site-packages\comtypes\gen) > it works fine. When I copy the files generated from the Python > console to the folder that comtypes.gen.__path__ (from the last > output) is set to, it does not work. I do not understand your setup. Why is the 'console' generating files in the C.\Python25\Lib\...\gen folder, and why is it in the other case comtypes in C:\Programme\...\entities\common\Lib\site-packages\comtypes\gen ? Do you have two comtypes installations? In different folders? -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users