PyXR

c:\python24\lib\site-packages\win32 \ com \ client \ makepy.py



0001 # Originally written by Curt Hagenlocher, and various bits
0002 # and pieces by Mark Hammond (and now Greg Stein has had
0003 # a go too :-)
0004 
0005 # Note that the main worker code has been moved to genpy.py
0006 # As this is normally run from the command line, it reparses the code each time.  
0007 # Now this is nothing more than the command line handler and public interface.
0008 
0009 # XXX - TO DO
0010 # XXX - Greg and Mark have some ideas for a revamp - just no
0011 #       time - if you want to help, contact us for details.
0012 #       Main idea is to drop the classes exported and move to a more
0013 #       traditional data driven model.
0014 
0015 """Generate a .py file from an OLE TypeLibrary file.
0016 
0017 
0018  This module is concerned only with the actual writing of
0019  a .py file.  It draws on the @build@ module, which builds 
0020  the knowledge of a COM interface.
0021  
0022 """
0023 usageHelp = """ \
0024 Usage:
0025 
0026   makepy.py [-h] [-x0|1] [-u] [-o filename] [-d] [typelib, ...]
0027   
0028   typelib -- A TLB, DLL, OCX, Description, or possibly something else.
0029   -h    -- Do not generate hidden methods.
0030   -u    -- Python 1.5 and earlier: Do not convert all Unicode objects to strings.
0031            Python 1.6 and later: Do convert all Unicode objects to strings.
0032   -o outputFile -- Generate to named file - dont generate to standard directory.
0033   -i [typelib] -- Show info for specified typelib, or select the typelib if not specified.
0034   -v    -- Verbose output
0035   -q    -- Quiet output
0036   -d    -- Generate the base code now and classes code on demand
0037   
0038 Examples:
0039   makepy.py
0040     Present a list of type libraries.
0041     
0042   makepy.py "Microsoft Excel 8.0 Object Library"
0043     Generate support for the typelibrary with the specified description
0044     (in this case, MS Excel object model)
0045 
0046 """
0047 
0048 import genpy, string, sys, os, types, pythoncom
0049 import selecttlb
0050 import gencache
0051 from win32com.client import NeedUnicodeConversions
0052 
0053 bForDemandDefault = 0 # Default value of bForDemand - toggle this to change the world - see also gencache.py
0054 
0055 error = "makepy.error"
0056 
0057 def usage():
0058         sys.stderr.write (usageHelp)
0059         sys.exit(2)
0060 
0061 def ShowInfo(spec):
0062         if not spec:
0063                 tlbSpec = selecttlb.SelectTlb(excludeFlags=selecttlb.FLAG_HIDDEN)
0064                 if tlbSpec is None:
0065                         return
0066                 try:
0067                         tlb = pythoncom.LoadRegTypeLib(tlbSpec.clsid, tlbSpec.major, tlbSpec.minor, tlbSpec.lcid)
0068                 except pythoncom.com_error: # May be badly registered.
0069                         sys.stderr.write("Warning - could not load registered typelib '%s'\n" % (tlbSpec.clsid))
0070                         tlb = None
0071                 
0072                 infos = [(tlb, tlbSpec)]
0073         else:
0074                 infos = GetTypeLibsForSpec(spec)
0075         for (tlb, tlbSpec) in infos:
0076                 desc = tlbSpec.desc
0077                 if desc is None:
0078                         if tlb is None:
0079                                 desc = "<Could not load typelib %s>" % (tlbSpec.dll)
0080                         else:
0081                                 desc = tlb.GetDocumentation(-1)[0]
0082                 print desc
0083                 print " %s, lcid=%s, major=%s, minor=%s" % (tlbSpec.clsid, tlbSpec.lcid, tlbSpec.major, tlbSpec.minor)
0084                 print " >>> # Use these commands in Python code to auto generate .py support"
0085                 print " >>> from win32com.client import gencache"
0086                 print " >>> gencache.EnsureModule('%s', %s, %s, %s)" % (tlbSpec.clsid, tlbSpec.lcid, tlbSpec.major, tlbSpec.minor)
0087 
0088 class SimpleProgress(genpy.GeneratorProgress):
0089         """A simple progress class prints its output to stderr
0090         """
0091         def __init__(self, verboseLevel):
0092                 self.verboseLevel = verboseLevel
0093         def Close(self):
0094                 pass
0095         def Finished(self):
0096                 if self.verboseLevel>1:
0097                         sys.stderr.write("Generation complete..\n")
0098         def SetDescription(self, desc, maxticks = None):
0099                 if self.verboseLevel:
0100                         sys.stderr.write(desc + "\n")
0101         def Tick(self, desc = None):
0102                 pass
0103 
0104         def VerboseProgress(self, desc, verboseLevel = 2):
0105                 if self.verboseLevel >= verboseLevel:
0106                         sys.stderr.write(desc + "\n")
0107 
0108         def LogBeginGenerate(self, filename):
0109                 self.VerboseProgress("Generating to %s" % filename, 1)
0110         
0111         def LogWarning(self, desc):
0112                 self.VerboseProgress("WARNING: " + desc, 1)
0113 
0114 class GUIProgress(SimpleProgress):
0115         def __init__(self, verboseLevel):
0116                 # Import some modules we need to we can trap failure now.
0117                 import win32ui, pywin
0118                 SimpleProgress.__init__(self, verboseLevel)
0119                 self.dialog = None
0120                 
0121         def Close(self):
0122                 if self.dialog is not None:
0123                         self.dialog.Close()
0124                         self.dialog = None
0125 
0126         def Starting(self, tlb_desc):
0127                 SimpleProgress.Starting(self, tlb_desc)
0128                 if self.dialog is None:
0129                         from pywin.dialogs import status
0130                         self.dialog=status.ThreadedStatusProgressDialog(tlb_desc)
0131                 else:
0132                         self.dialog.SetTitle(tlb_desc)
0133                 
0134         def SetDescription(self, desc, maxticks = None):
0135                 self.dialog.SetText(desc)
0136                 if maxticks:
0137                         self.dialog.SetMaxTicks(maxticks)
0138 
0139         def Tick(self, desc = None):
0140                 self.dialog.Tick()
0141                 if desc is not None:
0142                         self.dialog.SetText(desc)
0143 
0144 def GetTypeLibsForSpec(arg):
0145         """Given an argument on the command line (either a file name or a library description)
0146         return a list of actual typelibs to use.
0147         """
0148         typelibs = []
0149         try:
0150                 try:
0151                         tlb = pythoncom.LoadTypeLib(arg)
0152                         spec = selecttlb.TypelibSpec(None, 0,0,0)
0153                         spec.FromTypelib(tlb, arg)
0154                         typelibs.append((tlb, spec))
0155                 except pythoncom.com_error:
0156                         # See if it is a description
0157                         tlbs = selecttlb.FindTlbsWithDescription(arg)
0158                         if len(tlbs)==0:
0159                                 print "Could not locate a type library matching '%s'" % (arg)
0160                         for spec in tlbs:
0161                                 # Version numbers not always reliable if enumerated from registry.
0162                                 # (as some libs use hex, other's dont.  Both examples from MS, of course.)
0163                                 if spec.dll is None:
0164                                         tlb = pythoncom.LoadRegTypeLib(spec.clsid, spec.major, spec.minor, spec.lcid)
0165                                 else:
0166                                         tlb = pythoncom.LoadTypeLib(spec.dll)
0167                                 
0168                                 # We have a typelib, but it may not be exactly what we specified
0169                                 # (due to automatic version matching of COM).  So we query what we really have!
0170                                 attr = tlb.GetLibAttr()
0171                                 spec.major = attr[3]
0172                                 spec.minor = attr[4]
0173                                 spec.lcid = attr[1]
0174                                 typelibs.append((tlb, spec))
0175                 return typelibs
0176         except pythoncom.com_error:
0177                 t,v,tb=sys.exc_info()
0178                 sys.stderr.write ("Unable to load type library from '%s' - %s\n" % (arg, v))
0179                 tb = None # Storing tb in a local is a cycle!
0180                 sys.exit(1)
0181 
0182 def GenerateFromTypeLibSpec(typelibInfo, file = None, verboseLevel = None, progressInstance = None, bUnicodeToString=NeedUnicodeConversions, bQuiet = None, bGUIProgress = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
0183         if bQuiet is not None or bGUIProgress is not None:
0184                 print "Please dont use the bQuiet or bGUIProgress params"
0185                 print "use the 'verboseLevel', and 'progressClass' params"
0186         if verboseLevel is None:
0187                 verboseLevel = 0 # By default, we use a gui, and no verbose level!
0188 
0189         if bForDemand and file is not None:
0190                 raise RuntimeError, "You can only perform a demand-build when the output goes to the gen_py directory"
0191         if type(typelibInfo)==type(()):
0192                 # Tuple
0193                 typelibCLSID, lcid, major, minor  = typelibInfo
0194                 tlb = pythoncom.LoadRegTypeLib(typelibCLSID, major, minor, lcid)
0195                 spec = selecttlb.TypelibSpec(typelibCLSID, lcid, major, minor)
0196                 spec.FromTypelib(tlb, str(typelibCLSID))
0197                 typelibs = [(tlb, spec)]
0198         elif type(typelibInfo)==types.InstanceType:
0199                 if typelibInfo.dll is None:
0200                         # Version numbers not always reliable if enumerated from registry.
0201                         tlb = pythoncom.LoadRegTypeLib(typelibInfo.clsid, typelibInfo.major, typelibInfo.minor, typelibInfo.lcid)
0202                 else:
0203                         tlb = pythoncom.LoadTypeLib(typelibInfo.dll)
0204                 typelibs = [(tlb, typelibInfo)]
0205         elif hasattr(typelibInfo, "GetLibAttr"):
0206                 # A real typelib object!
0207                 tla = typelibInfo.GetLibAttr()
0208                 guid = tla[0]
0209                 lcid = tla[1]
0210                 major = tla[3]
0211                 minor = tla[4]
0212                 spec = selecttlb.TypelibSpec(guid, lcid, major, minor)
0213                 typelibs = [(typelibInfo, spec)]
0214         else:
0215                 typelibs = GetTypeLibsForSpec(typelibInfo)
0216 
0217         if progressInstance is None:
0218                 try:
0219                         if not bForDemand: # Only go for GUI progress if not doing a demand-import
0220                                 # Win9x console programs don't seem to like our GUI!
0221                                 # (Actually, NT/2k wouldnt object to having them threaded - later!)
0222                                 import win32api, win32con
0223                                 if win32api.GetVersionEx()[3]==win32con.VER_PLATFORM_WIN32_NT:
0224                                         bMakeGuiProgress = 1
0225                                 else:
0226                                         try:
0227                                                 win32api.GetConsoleTitle()
0228                                                 # Have a console - can't handle GUI
0229                                                 bMakeGuiProgress = 0
0230                                         except win32api.error:
0231                                                 # no console - we can have a GUI
0232                                                 bMakeGuiProgress = 1
0233                                 if bMakeGuiProgress:
0234                                         progressInstance = GUIProgress(verboseLevel)
0235                 except ImportError: # No Pythonwin GUI around.
0236                         pass
0237         if progressInstance is None:
0238                 progressInstance = SimpleProgress(verboseLevel)
0239         progress = progressInstance
0240 
0241         bToGenDir = (file is None)
0242 
0243         for typelib, info in typelibs:
0244                 if file is None:
0245                         this_name = gencache.GetGeneratedFileName(info.clsid, info.lcid, info.major, info.minor)
0246                         full_name = os.path.join(gencache.GetGeneratePath(), this_name)
0247                         if bForDemand:
0248                                 try: os.unlink(full_name + ".py")
0249                                 except os.error: pass
0250                                 try: os.unlink(full_name + ".pyc")
0251                                 except os.error: pass
0252                                 try: os.unlink(full_name + ".pyo")
0253                                 except os.error: pass
0254                                 if not os.path.isdir(full_name):
0255                                         os.mkdir(full_name)
0256                                 outputName = os.path.join(full_name, "__init__.py")
0257                         else:
0258                                 outputName = full_name + ".py"
0259                         fileUse = open(outputName, "wt")
0260                         progress.LogBeginGenerate(outputName)
0261                 else:
0262                         fileUse = file
0263 
0264                 gen = genpy.Generator(typelib, info.dll, progress, bUnicodeToString=bUnicodeToString, bBuildHidden=bBuildHidden)
0265 
0266                 gen.generate(fileUse, bForDemand)
0267                 
0268                 if file is None:
0269                         fileUse.close()
0270                 
0271                 if bToGenDir:
0272                         progress.SetDescription("Importing module")
0273                         gencache.AddModuleToCache(info.clsid, info.lcid, info.major, info.minor)
0274 
0275         progress.Close()
0276 
0277 def GenerateChildFromTypeLibSpec(child, typelibInfo, verboseLevel = None, progressInstance = None, bUnicodeToString=NeedUnicodeConversions):
0278         if verboseLevel is None:
0279                 verboseLevel = 0 # By default, we use no gui, and no verbose level for the children.
0280         if type(typelibInfo)==type(()):
0281                 typelibCLSID, lcid, major, minor  = typelibInfo
0282                 tlb = pythoncom.LoadRegTypeLib(typelibCLSID, major, minor, lcid)
0283         else:
0284                 tlb = typelibInfo
0285                 tla = typelibInfo.GetLibAttr()
0286                 typelibCLSID = tla[0]
0287                 lcid = tla[1]
0288                 major = tla[3]
0289                 minor = tla[4]
0290         spec = selecttlb.TypelibSpec(typelibCLSID, lcid, major, minor)
0291         spec.FromTypelib(tlb, str(typelibCLSID))
0292         typelibs = [(tlb, spec)]
0293 
0294         if progressInstance is None:
0295                 progressInstance = SimpleProgress(verboseLevel)
0296         progress = progressInstance
0297 
0298         for typelib, info in typelibs:
0299                 dir_name = gencache.GetGeneratedFileName(info.clsid, info.lcid, info.major, info.minor)
0300                 dir_path_name = os.path.join(gencache.GetGeneratePath(), dir_name)
0301                 progress.LogBeginGenerate(dir_path_name)
0302 
0303                 gen = genpy.Generator(typelib, info.dll, progress, bUnicodeToString=bUnicodeToString)
0304                 gen.generate_child(child, dir_path_name)
0305                 progress.SetDescription("Importing module")
0306                 __import__("win32com.gen_py." + dir_name + "." + child)
0307         progress.Close()
0308 
0309 def main():
0310         import getopt
0311         hiddenSpec = 1
0312         bUnicodeToString = NeedUnicodeConversions
0313         outputName = None
0314         verboseLevel = 1
0315         doit = 1
0316         bForDemand = bForDemandDefault
0317         try:
0318                 opts, args = getopt.getopt(sys.argv[1:], 'vo:huiqd')
0319                 for o,v in opts:
0320                         if o=='-h':
0321                                 hiddenSpec = 0
0322                         elif o=='-u':
0323                                 bUnicodeToString = not NeedUnicodeConversions
0324                         elif o=='-o':
0325                                 outputName = v
0326                         elif o=='-v':
0327                                 verboseLevel = verboseLevel + 1
0328                         elif o=='-q':
0329                                 verboseLevel = verboseLevel - 1
0330                         elif o=='-i':
0331                                 if len(args)==0:
0332                                         ShowInfo(None)
0333                                 else:
0334                                         for arg in args:
0335                                                 ShowInfo(arg)
0336                                 doit = 0
0337                         elif o=='-d':
0338                                 bForDemand = not bForDemand
0339 
0340         except (getopt.error, error), msg:
0341                 sys.stderr.write (str(msg) + "\n")
0342                 usage()
0343 
0344         if bForDemand and outputName is not None:
0345                 sys.stderr.write("Can not use -d and -o together\n")
0346                 usage()
0347 
0348         if not doit:
0349                 return 0                
0350         if len(args)==0:
0351                 rc = selecttlb.SelectTlb()
0352                 if rc is None:
0353                         sys.exit(1)
0354                 args = [ rc ]
0355 
0356         if outputName is not None:
0357                 f = open(outputName, "w")
0358         else:
0359                 f = None
0360 
0361         for arg in args:
0362                 GenerateFromTypeLibSpec(arg, f, verboseLevel = verboseLevel, bForDemand = bForDemand, bBuildHidden = hiddenSpec)
0363 
0364         if f:        
0365                 f.close()
0366 
0367 
0368 if __name__=='__main__':
0369         rc = main()
0370         if rc:
0371                 sys.exit(rc)
0372         sys.exit(0)
0373 

Generated by PyXR 0.9.4
SourceForge.net Logo