makepy.py :  » Windows » pyExcelerator » pywin32-214 » com » win32com » client » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Windows » pyExcelerator 
pyExcelerator » pywin32 214 » com » win32com » client » makepy.py
# Originally written by Curt Hagenlocher, and various bits
# and pieces by Mark Hammond (and now Greg Stein has had
# a go too :-)

# Note that the main worker code has been moved to genpy.py
# As this is normally run from the command line, it reparses the code each time.  
# Now this is nothing more than the command line handler and public interface.

# XXX - TO DO
# XXX - Greg and Mark have some ideas for a revamp - just no
#       time - if you want to help, contact us for details.
#       Main idea is to drop the classes exported and move to a more
#       traditional data driven model.

"""Generate a .py file from an OLE TypeLibrary file.


 This module is concerned only with the actual writing of
 a .py file.  It draws on the @build@ module, which builds 
 the knowledge of a COM interface.
 
"""
usageHelp = """ \

Usage:

  makepy.py [-i] [-v|q] [-h] [-u] [-o output_file] [-d] [typelib, ...]
  
  -i    -- Show information for the specified typelib.
  
  -v    -- Verbose output.
  
  -q    -- Quiet output.
  
  -h    -- Do not generate hidden methods.
  
  -u    -- Python 1.5 and earlier: Do NOT convert all Unicode objects to 
           strings.
                                   
           Python 1.6 and later: Convert all Unicode objects to strings.
  
  -o    -- Create output in a specified output file.  If the path leading
           to the file does not exist, any missing directories will be
           created.
           NOTE: -o cannot be used with -d.  This will generate an error.
  
  -d    -- Generate the base code now and the class code on demand.
           Recommended for large type libraries.
           
  typelib -- A TLB, DLL, OCX or anything containing COM type information.
             If a typelib is not specified, a window containing a textbox
             will open from which you can select a registered type
             library.
               
Examples:

  makepy.py -d
  
    Presents a list of registered type libraries from which you can make
    a selection.
    
  makepy.py -d "Microsoft Excel 8.0 Object Library"
  
    Generate support for the type library with the specified description
    (in this case, the MS Excel object model).

"""

import sys, os, pythoncom
from win32com.client import genpy,selecttlb,gencache
from win32com.client import Dispatch

bForDemandDefault = 0 # Default value of bForDemand - toggle this to change the world - see also gencache.py

error = "makepy.error"

def usage():
  sys.stderr.write (usageHelp)
  sys.exit(2)

def ShowInfo(spec):
  if not spec:
    tlbSpec = selecttlb.SelectTlb(excludeFlags=selecttlb.FLAG_HIDDEN)
    if tlbSpec is None:
      return
    try:
      tlb = pythoncom.LoadRegTypeLib(tlbSpec.clsid, tlbSpec.major, tlbSpec.minor, tlbSpec.lcid)
    except pythoncom.com_error: # May be badly registered.
      sys.stderr.write("Warning - could not load registered typelib '%s'\n" % (tlbSpec.clsid))
      tlb = None
    
    infos = [(tlb, tlbSpec)]
  else:
    infos = GetTypeLibsForSpec(spec)
  for (tlb, tlbSpec) in infos:
    desc = tlbSpec.desc
    if desc is None:
      if tlb is None:
        desc = "<Could not load typelib %s>" % (tlbSpec.dll)
      else:
        desc = tlb.GetDocumentation(-1)[0]
    print desc
    print " %s, lcid=%s, major=%s, minor=%s" % (tlbSpec.clsid, tlbSpec.lcid, tlbSpec.major, tlbSpec.minor)
    print " >>> # Use these commands in Python code to auto generate .py support"
    print " >>> from win32com.client import gencache"
    print " >>> gencache.EnsureModule('%s', %s, %s, %s)" % (tlbSpec.clsid, tlbSpec.lcid, tlbSpec.major, tlbSpec.minor)

class SimpleProgress(genpy.GeneratorProgress):
  """A simple progress class prints its output to stderr
  """
  def __init__(self, verboseLevel):
    self.verboseLevel = verboseLevel
  def Close(self):
    pass
  def Finished(self):
    if self.verboseLevel>1:
      sys.stderr.write("Generation complete..\n")
  def SetDescription(self, desc, maxticks = None):
    if self.verboseLevel:
      sys.stderr.write(desc + "\n")
  def Tick(self, desc = None):
    pass

  def VerboseProgress(self, desc, verboseLevel = 2):
    if self.verboseLevel >= verboseLevel:
      sys.stderr.write(desc + "\n")

  def LogBeginGenerate(self, filename):
    self.VerboseProgress("Generating to %s" % filename, 1)
  
  def LogWarning(self, desc):
    self.VerboseProgress("WARNING: " + desc, 1)

class GUIProgress(SimpleProgress):
  def __init__(self, verboseLevel):
    # Import some modules we need to we can trap failure now.
    import win32ui, pywin
    SimpleProgress.__init__(self, verboseLevel)
    self.dialog = None
    
  def Close(self):
    if self.dialog is not None:
      self.dialog.Close()
      self.dialog = None

  def Starting(self, tlb_desc):
    SimpleProgress.Starting(self, tlb_desc)
    if self.dialog is None:
      from pywin.dialogs import status
      self.dialog=status.ThreadedStatusProgressDialog(tlb_desc)
    else:
      self.dialog.SetTitle(tlb_desc)
    
  def SetDescription(self, desc, maxticks = None):
    self.dialog.SetText(desc)
    if maxticks:
      self.dialog.SetMaxTicks(maxticks)

  def Tick(self, desc = None):
    self.dialog.Tick()
    if desc is not None:
      self.dialog.SetText(desc)

def GetTypeLibsForSpec(arg):
  """Given an argument on the command line (either a file name, library
  description, or ProgID of an object) return a list of actual typelibs
  to use. """
  typelibs = []
  try:
    try:
      tlb = pythoncom.LoadTypeLib(arg)
      spec = selecttlb.TypelibSpec(None, 0,0,0)
      spec.FromTypelib(tlb, arg)
      typelibs.append((tlb, spec))
    except pythoncom.com_error:
      # See if it is a description
      tlbs = selecttlb.FindTlbsWithDescription(arg)
      if len(tlbs)==0:
        # Maybe it is the name of a COM object?
        try:
          ob = Dispatch(arg)
          # and if so, it must support typelib info
          tlb, index = ob._oleobj_.GetTypeInfo().GetContainingTypeLib()
          spec = selecttlb.TypelibSpec(None, 0,0,0)
          spec.FromTypelib(tlb)
          tlbs.append(spec)
        except pythoncom.com_error:
          pass
      if len(tlbs)==0:
        print "Could not locate a type library matching '%s'" % (arg)
      for spec in tlbs:
        # Version numbers not always reliable if enumerated from registry.
        # (as some libs use hex, other's dont.  Both examples from MS, of course.)
        if spec.dll is None:
          tlb = pythoncom.LoadRegTypeLib(spec.clsid, spec.major, spec.minor, spec.lcid)
        else:
          tlb = pythoncom.LoadTypeLib(spec.dll)
        
        # We have a typelib, but it may not be exactly what we specified
        # (due to automatic version matching of COM).  So we query what we really have!
        attr = tlb.GetLibAttr()
        spec.major = attr[3]
        spec.minor = attr[4]
        spec.lcid = attr[1]
        typelibs.append((tlb, spec))
    return typelibs
  except pythoncom.com_error:
    t,v,tb=sys.exc_info()
    sys.stderr.write ("Unable to load type library from '%s' - %s\n" % (arg, v))
    tb = None # Storing tb in a local is a cycle!
    sys.exit(1)

def GenerateFromTypeLibSpec(typelibInfo, file = None, verboseLevel = None, progressInstance = None, bUnicodeToString=None, bForDemand = bForDemandDefault, bBuildHidden = 1):
  assert bUnicodeToString is None, "this is deprecated and will go away"
  if verboseLevel is None:
    verboseLevel = 0 # By default, we use no gui and no verbose level!

  if bForDemand and file is not None:
    raise RuntimeError("You can only perform a demand-build when the output goes to the gen_py directory")
  if isinstance(typelibInfo, tuple):
    # Tuple
    typelibCLSID, lcid, major, minor  = typelibInfo
    tlb = pythoncom.LoadRegTypeLib(typelibCLSID, major, minor, lcid)
    spec = selecttlb.TypelibSpec(typelibCLSID, lcid, major, minor)
    spec.FromTypelib(tlb, str(typelibCLSID))
    typelibs = [(tlb, spec)]
  elif isinstance(typelibInfo, selecttlb.TypelibSpec):
    if typelibInfo.dll is None:
      # Version numbers not always reliable if enumerated from registry.
      tlb = pythoncom.LoadRegTypeLib(typelibInfo.clsid, typelibInfo.major, typelibInfo.minor, typelibInfo.lcid)
    else:
      tlb = pythoncom.LoadTypeLib(typelibInfo.dll)
    typelibs = [(tlb, typelibInfo)]
  elif hasattr(typelibInfo, "GetLibAttr"):
    # A real typelib object!
    # Could also use isinstance(typelibInfo, PyITypeLib) instead, but PyITypeLib is not directly exposed by pythoncom.
    #  pythoncom.TypeIIDs[pythoncom.IID_ITypeLib] seems to work
    tla = typelibInfo.GetLibAttr()
    guid = tla[0]
    lcid = tla[1]
    major = tla[3]
    minor = tla[4]
    spec = selecttlb.TypelibSpec(guid, lcid, major, minor)
    typelibs = [(typelibInfo, spec)]
  else:
    typelibs = GetTypeLibsForSpec(typelibInfo)

  if progressInstance is None:
    progressInstance = SimpleProgress(verboseLevel)
  progress = progressInstance

  bToGenDir = (file is None)

  for typelib, info in typelibs:
    gen = genpy.Generator(typelib, info.dll, progress, bBuildHidden=bBuildHidden)

    if file is None:
      this_name = gencache.GetGeneratedFileName(info.clsid, info.lcid, info.major, info.minor)
      full_name = os.path.join(gencache.GetGeneratePath(), this_name)
      if bForDemand:
        try: os.unlink(full_name + ".py")
        except os.error: pass
        try: os.unlink(full_name + ".pyc")
        except os.error: pass
        try: os.unlink(full_name + ".pyo")
        except os.error: pass
        if not os.path.isdir(full_name):
          os.mkdir(full_name)
        outputName = os.path.join(full_name, "__init__.py")
      else:
        outputName = full_name + ".py"
      fileUse = gen.open_writer(outputName)
      progress.LogBeginGenerate(outputName)
    else:
      fileUse = file

    worked = False
    try:
      gen.generate(fileUse, bForDemand)
      worked = True
    finally:
      if file is None:
        gen.finish_writer(outputName, fileUse, worked)
    if bToGenDir:
      progress.SetDescription("Importing module")
      gencache.AddModuleToCache(info.clsid, info.lcid, info.major, info.minor)

  progress.Close()

def GenerateChildFromTypeLibSpec(child, typelibInfo, verboseLevel = None, progressInstance = None, bUnicodeToString=None):
  assert bUnicodeToString is None, "this is deprecated and will go away"
  if verboseLevel is None:
    verboseLevel = 0 # By default, we use no gui, and no verbose level for the children.
  if type(typelibInfo)==type(()):
    typelibCLSID, lcid, major, minor  = typelibInfo
    tlb = pythoncom.LoadRegTypeLib(typelibCLSID, major, minor, lcid)
  else:
    tlb = typelibInfo
    tla = typelibInfo.GetLibAttr()
    typelibCLSID = tla[0]
    lcid = tla[1]
    major = tla[3]
    minor = tla[4]
  spec = selecttlb.TypelibSpec(typelibCLSID, lcid, major, minor)
  spec.FromTypelib(tlb, str(typelibCLSID))
  typelibs = [(tlb, spec)]

  if progressInstance is None:
    progressInstance = SimpleProgress(verboseLevel)
  progress = progressInstance

  for typelib, info in typelibs:
    dir_name = gencache.GetGeneratedFileName(info.clsid, info.lcid, info.major, info.minor)
    dir_path_name = os.path.join(gencache.GetGeneratePath(), dir_name)
    progress.LogBeginGenerate(dir_path_name)

    gen = genpy.Generator(typelib, info.dll, progress)
    gen.generate_child(child, dir_path_name)
    progress.SetDescription("Importing module")
    __import__("win32com.gen_py." + dir_name + "." + child)
  progress.Close()

def main():
  import getopt
  hiddenSpec = 1
  outputName = None
  verboseLevel = 1
  doit = 1
  bForDemand = bForDemandDefault
  try:
    opts, args = getopt.getopt(sys.argv[1:], 'vo:huiqd')
    for o,v in opts:
      if o=='-h':
        hiddenSpec = 0
      elif o=='-o':
        outputName = v
      elif o=='-v':
        verboseLevel = verboseLevel + 1
      elif o=='-q':
        verboseLevel = verboseLevel - 1
      elif o=='-i':
        if len(args)==0:
          ShowInfo(None)
        else:
          for arg in args:
            ShowInfo(arg)
        doit = 0
      elif o=='-d':
        bForDemand = not bForDemand

  except (getopt.error, error), msg:
    sys.stderr.write (str(msg) + "\n")
    usage()

  if bForDemand and outputName is not None:
    sys.stderr.write("Can not use -d and -o together\n")
    usage()

  if not doit:
    return 0    
  if len(args)==0:
    rc = selecttlb.SelectTlb()
    if rc is None:
      sys.exit(1)
    args = [ rc ]

  if outputName is not None:
    path = os.path.dirname(outputName)
    if path is not '' and not os.path.exists(path):
      os.makedirs(path)
    f = open(outputName, "w")
  else:
    f = None

  for arg in args:
    GenerateFromTypeLibSpec(arg, f, verboseLevel = verboseLevel, bForDemand = bForDemand, bBuildHidden = hiddenSpec)

  if f:  
    f.close()


if __name__=='__main__':
  rc = main()
  if rc:
    sys.exit(rc)
  sys.exit(0)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.