Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
gencache.py800 linesDownload Raw Back to client
1"""Manages the cache of generated Python code.2 3Description4  This file manages the cache of generated Python code.  When run from the5  command line, it also provides a number of options for managing that cache.6 7Implementation8  Each typelib is generated into a filename of format "{guid}x{lcid}x{major}x{minor}.py"9 10  An external persistant dictionary maps from all known IIDs in all known type libraries11  to the type library itself.12 13  Thus, whenever Python code knows the IID of an object, it can find the IID, LCID and version of14  the type library which supports it.  Given this information, it can find the Python module15  with the support.16 17  If necessary, this support can be generated on the fly.18 19Hacks, to do, etc20  Currently just uses a pickled dictionary, but should used some sort of indexed file.21  Maybe an OLE2 compound file, or a bsddb file?22"""23import glob24import os25import sys26from importlib import reload27 28import pythoncom29import pywintypes30import win32com31import win32com.client32 33from . import CLSIDToClass34 35bForDemandDefault = 0  # Default value of bForDemand - toggle this to change the world - see also makepy.py36 37# The global dictionary38clsidToTypelib = {}39 40# If we have a different version of the typelib generated, this41# maps the "requested version" to the "generated version".42versionRedirectMap = {}43 44# There is no reason we *must* be readonly in a .zip, but we are now,45# Rather than check for ".zip" or other tricks, PEP302 defines46# a "__loader__" attribute, so we use that.47# (Later, it may become necessary to check if the __loader__ can update files,48# as a .zip loader potentially could - but punt all that until a need arises)49is_readonly = is_zip = hasattr(win32com, "__loader__") and hasattr(50    win32com.__loader__, "archive"51)52 53# A dictionary of ITypeLibrary objects for demand generation explicitly handed to us54# Keyed by usual clsid, lcid, major, minor55demandGeneratedTypeLibraries = {}56 57import pickle as pickle58 59 60def __init__():61    # Initialize the module.  Called once explicitly at module import below.62    try:63        _LoadDicts()64    except IOError:65        Rebuild()66 67 68pickleVersion = 169 70 71def _SaveDicts():72    if is_readonly:73        raise RuntimeError(74            "Trying to write to a readonly gencache ('%s')!" % win32com.__gen_path__75        )76    f = open(os.path.join(GetGeneratePath(), "dicts.dat"), "wb")77    try:78        p = pickle.Pickler(f)79        p.dump(pickleVersion)80        p.dump(clsidToTypelib)81    finally:82        f.close()83 84 85def _LoadDicts():86    # Load the dictionary from a .zip file if that is where we live.87    if is_zip:88        import io as io89 90        loader = win32com.__loader__91        arc_path = loader.archive92        dicts_path = os.path.join(win32com.__gen_path__, "dicts.dat")93        if dicts_path.startswith(arc_path):94            dicts_path = dicts_path[len(arc_path) + 1 :]95        else:96            # Hm. See below.97            return98        try:99            data = loader.get_data(dicts_path)100        except AttributeError:101            # The __loader__ has no get_data method.  See below.102            return103        except IOError:104            # Our gencache is in a .zip file (and almost certainly readonly)105            # but no dicts file.  That actually needn't be fatal for a frozen106            # application.  Assuming they call "EnsureModule" with the same107            # typelib IDs they have been frozen with, that EnsureModule will108            # correctly re-build the dicts on the fly.  However, objects that109            # rely on the gencache but have not done an EnsureModule will110            # fail (but their apps are likely to fail running from source111            # with a clean gencache anyway, as then they would be getting112            # Dynamic objects until the cache is built - so the best answer113            # for these apps is to call EnsureModule, rather than freezing114            # the dict)115            return116        f = io.BytesIO(data)117    else:118        # NOTE: IOError on file open must be caught by caller.119        f = open(os.path.join(win32com.__gen_path__, "dicts.dat"), "rb")120    try:121        p = pickle.Unpickler(f)122        version = p.load()123        global clsidToTypelib124        clsidToTypelib = p.load()125        versionRedirectMap.clear()126    finally:127        f.close()128 129 130def GetGeneratedFileName(clsid, lcid, major, minor):131    """Given the clsid, lcid, major and  minor for a type lib, return132    the file name (no extension) providing this support.133    """134    return str(clsid).upper()[1:-1] + "x%sx%sx%s" % (lcid, major, minor)135 136 137def SplitGeneratedFileName(fname):138    """Reverse of GetGeneratedFileName()"""139    return tuple(fname.split("x", 4))140 141 142def GetGeneratePath():143    """Returns the name of the path to generate to.144    Checks the directory is OK.145    """146    assert not is_readonly, "Why do you want the genpath for a readonly store?"147    try:148        os.makedirs(win32com.__gen_path__)149        # os.mkdir(win32com.__gen_path__)150    except os.error:151        pass152    try:153        fname = os.path.join(win32com.__gen_path__, "__init__.py")154        os.stat(fname)155    except os.error:156        f = open(fname, "w")157        f.write(158            "# Generated file - this directory may be deleted to reset the COM cache...\n"159        )160        f.write("import win32com\n")161        f.write(162            "if __path__[:-1] != win32com.__gen_path__: __path__.append(win32com.__gen_path__)\n"163        )164        f.close()165 166    return win32com.__gen_path__167 168 169#170# The helpers for win32com.client.Dispatch and OCX clients.171#172def GetClassForProgID(progid):173    """Get a Python class for a Program ID174 175    Given a Program ID, return a Python class which wraps the COM object176 177    Returns the Python class, or None if no module is available.178 179    Params180    progid -- A COM ProgramID or IID (eg, "Word.Application")181    """182    clsid = pywintypes.IID(progid)  # This auto-converts named to IDs.183    return GetClassForCLSID(clsid)184 185 186def GetClassForCLSID(clsid):187    """Get a Python class for a CLSID188 189    Given a CLSID, return a Python class which wraps the COM object190 191    Returns the Python class, or None if no module is available.192 193    Params194    clsid -- A COM CLSID (or string repr of one)195    """196    # first, take a short-cut - we may already have generated support ready-to-roll.197    clsid = str(clsid)198    if CLSIDToClass.HasClass(clsid):199        return CLSIDToClass.GetClass(clsid)200    mod = GetModuleForCLSID(clsid)201    if mod is None:202        return None203    try:204        return CLSIDToClass.GetClass(clsid)205    except KeyError:206        return None207 208 209def GetModuleForProgID(progid):210    """Get a Python module for a Program ID211 212    Given a Program ID, return a Python module which contains the213    class which wraps the COM object.214 215    Returns the Python module, or None if no module is available.216 217    Params218    progid -- A COM ProgramID or IID (eg, "Word.Application")219    """220    try:221        iid = pywintypes.IID(progid)222    except pywintypes.com_error:223        return None224    return GetModuleForCLSID(iid)225 226 227def GetModuleForCLSID(clsid):228    """Get a Python module for a CLSID229 230    Given a CLSID, return a Python module which contains the231    class which wraps the COM object.232 233    Returns the Python module, or None if no module is available.234 235    Params236    progid -- A COM CLSID (ie, not the description)237    """238    clsid_str = str(clsid)239    try:240        typelibCLSID, lcid, major, minor = clsidToTypelib[clsid_str]241    except KeyError:242        return None243 244    try:245        mod = GetModuleForTypelib(typelibCLSID, lcid, major, minor)246    except ImportError:247        mod = None248    if mod is not None:249        sub_mod = mod.CLSIDToPackageMap.get(clsid_str)250        if sub_mod is None:251            sub_mod = mod.VTablesToPackageMap.get(clsid_str)252        if sub_mod is not None:253            sub_mod_name = mod.__name__ + "." + sub_mod254            try:255                __import__(sub_mod_name)256            except ImportError:257                info = typelibCLSID, lcid, major, minor258                # Force the generation.  If this typelibrary has explicitly been added,259                # use it (it may not be registered, causing a lookup by clsid to fail)260                if info in demandGeneratedTypeLibraries:261                    info = demandGeneratedTypeLibraries[info]262                from . import makepy263 264                makepy.GenerateChildFromTypeLibSpec(sub_mod, info)265                # Generate does an import...266            mod = sys.modules[sub_mod_name]267    return mod268 269 270def GetModuleForTypelib(typelibCLSID, lcid, major, minor):271    """Get a Python module for a type library ID272 273    Given the CLSID of a typelibrary, return an imported Python module,274    else None275 276    Params277    typelibCLSID -- IID of the type library.278    major -- Integer major version.279    minor -- Integer minor version280    lcid -- Integer LCID for the library.281    """282    modName = GetGeneratedFileName(typelibCLSID, lcid, major, minor)283    mod = _GetModule(modName)284    # If the import worked, it doesn't mean we have actually added this285    # module to our cache though - check that here.286    if "_in_gencache_" not in mod.__dict__:287        AddModuleToCache(typelibCLSID, lcid, major, minor)288        assert "_in_gencache_" in mod.__dict__289    return mod290 291 292def MakeModuleForTypelib(293    typelibCLSID,294    lcid,295    major,296    minor,297    progressInstance=None,298    bForDemand=bForDemandDefault,299    bBuildHidden=1,300):301    """Generate support for a type library.302 303    Given the IID, LCID and version information for a type library, generate304    and import the necessary support files.305 306    Returns the Python module.  No exceptions are caught.307 308    Params309    typelibCLSID -- IID of the type library.310    major -- Integer major version.311    minor -- Integer minor version.312    lcid -- Integer LCID for the library.313    progressInstance -- Instance to use as progress indicator, or None to314                        use the GUI progress bar.315    """316    from . import makepy317 318    makepy.GenerateFromTypeLibSpec(319        (typelibCLSID, lcid, major, minor),320        progressInstance=progressInstance,321        bForDemand=bForDemand,322        bBuildHidden=bBuildHidden,323    )324    return GetModuleForTypelib(typelibCLSID, lcid, major, minor)325 326 327def MakeModuleForTypelibInterface(328    typelib_ob, progressInstance=None, bForDemand=bForDemandDefault, bBuildHidden=1329):330    """Generate support for a type library.331 332    Given a PyITypeLib interface generate and import the necessary support files.  This is useful333    for getting makepy support for a typelibrary that is not registered - the caller can locate334    and load the type library itself, rather than relying on COM to find it.335 336    Returns the Python module.337 338    Params339    typelib_ob -- The type library itself340    progressInstance -- Instance to use as progress indicator, or None to341                        use the GUI progress bar.342    """343    from . import makepy344 345    try:346        makepy.GenerateFromTypeLibSpec(347            typelib_ob,348            progressInstance=progressInstance,349            bForDemand=bForDemandDefault,350            bBuildHidden=bBuildHidden,351        )352    except pywintypes.com_error:353        return None354    tla = typelib_ob.GetLibAttr()355    guid = tla[0]356    lcid = tla[1]357    major = tla[3]358    minor = tla[4]359    return GetModuleForTypelib(guid, lcid, major, minor)360 361 362def EnsureModuleForTypelibInterface(363    typelib_ob, progressInstance=None, bForDemand=bForDemandDefault, bBuildHidden=1364):365    """Check we have support for a type library, generating if not.366 367    Given a PyITypeLib interface generate and import the necessary368    support files if necessary. This is useful for getting makepy support369    for a typelibrary that is not registered - the caller can locate and370    load the type library itself, rather than relying on COM to find it.371 372    Returns the Python module.373 374    Params375    typelib_ob -- The type library itself376    progressInstance -- Instance to use as progress indicator, or None to377                        use the GUI progress bar.378    """379    tla = typelib_ob.GetLibAttr()380    guid = tla[0]381    lcid = tla[1]382    major = tla[3]383    minor = tla[4]384 385    # If demand generated, save the typelib interface away for later use386    if bForDemand:387        demandGeneratedTypeLibraries[(str(guid), lcid, major, minor)] = typelib_ob388 389    try:390        return GetModuleForTypelib(guid, lcid, major, minor)391    except ImportError:392        pass393    # Generate it.394    return MakeModuleForTypelibInterface(395        typelib_ob, progressInstance, bForDemand, bBuildHidden396    )397 398 399def ForgetAboutTypelibInterface(typelib_ob):400    """Drop any references to a typelib previously added with EnsureModuleForTypelibInterface and forDemand"""401    tla = typelib_ob.GetLibAttr()402    guid = tla[0]403    lcid = tla[1]404    major = tla[3]405    minor = tla[4]406    info = str(guid), lcid, major, minor407    try:408        del demandGeneratedTypeLibraries[info]409    except KeyError:410        # Not worth raising an exception - maybe they dont know we only remember for demand generated, etc.411        print(412            "ForgetAboutTypelibInterface:: Warning - type library with info %s is not being remembered!"413            % (info,)414        )415    # and drop any version redirects to it416    for key, val in list(versionRedirectMap.items()):417        if val == info:418            del versionRedirectMap[key]419 420 421def EnsureModule(422    typelibCLSID,423    lcid,424    major,425    minor,426    progressInstance=None,427    bValidateFile=not is_readonly,428    bForDemand=bForDemandDefault,429    bBuildHidden=1,430):431    """Ensure Python support is loaded for a type library, generating if necessary.432 433    Given the IID, LCID and version information for a type library, check and if434    necessary (re)generate, then import the necessary support files. If we regenerate the file, there435    is no way to totally snuff out all instances of the old module in Python, and thus we will regenerate the file more than necessary,436    unless makepy/genpy is modified accordingly.437 438 439    Returns the Python module.  No exceptions are caught during the generate process.440 441    Params442    typelibCLSID -- IID of the type library.443    major -- Integer major version.444    minor -- Integer minor version445    lcid -- Integer LCID for the library.446    progressInstance -- Instance to use as progress indicator, or None to447                        use the GUI progress bar.448    bValidateFile -- Whether or not to perform cache validation or not449    bForDemand -- Should a complete generation happen now, or on demand?450    bBuildHidden -- Should hidden members/attributes etc be generated?451    """452    bReloadNeeded = 0453    try:454        try:455            module = GetModuleForTypelib(typelibCLSID, lcid, major, minor)456        except ImportError:457            # If we get an ImportError458            # We may still find a valid cache file under a different MinorVersion #459            # (which windows will search out for us)460            # print "Loading reg typelib", typelibCLSID, major, minor, lcid461            module = None462            try:463                tlbAttr = pythoncom.LoadRegTypeLib(464                    typelibCLSID, major, minor, lcid465                ).GetLibAttr()466                # if the above line doesn't throw a pythoncom.com_error, check if467                # it is actually a different lib than we requested, and if so, suck it in468                if tlbAttr[1] != lcid or tlbAttr[4] != minor:469                    # print "Trying 2nd minor #", tlbAttr[1], tlbAttr[3], tlbAttr[4]470                    try:471                        module = GetModuleForTypelib(472                            typelibCLSID, tlbAttr[1], tlbAttr[3], tlbAttr[4]473                        )474                    except ImportError:475                        # We don't have a module, but we do have a better minor476                        # version - remember that.477                        minor = tlbAttr[4]478                # else module remains None479            except pythoncom.com_error:480                # couldn't load any typelib - mod remains None481                pass482        if module is not None and bValidateFile:483            assert not is_readonly, "Can't validate in a read-only gencache"484            try:485                typLibPath = pythoncom.QueryPathOfRegTypeLib(486                    typelibCLSID, major, minor, lcid487                )488                # windows seems to add an extra \0 (via the underlying BSTR)489                # The mainwin toolkit does not add this erroneous \0490                if typLibPath[-1] == "\0":491                    typLibPath = typLibPath[:-1]492                suf = getattr(os.path, "supports_unicode_filenames", 0)493                if not suf:494                    # can't pass unicode filenames directly - convert495                    try:496                        typLibPath = typLibPath.encode(sys.getfilesystemencoding())497                    except AttributeError:  # no sys.getfilesystemencoding498                        typLibPath = str(typLibPath)499                tlbAttributes = pythoncom.LoadRegTypeLib(500                    typelibCLSID, major, minor, lcid501                ).GetLibAttr()502            except pythoncom.com_error:503                # We have a module, but no type lib - we should still504                # run with what we have though - the typelib may not be505                # deployed here.506                bValidateFile = 0507        if module is not None and bValidateFile:508            assert not is_readonly, "Can't validate in a read-only gencache"509            filePathPrefix = "%s\\%s" % (510                GetGeneratePath(),511                GetGeneratedFileName(typelibCLSID, lcid, major, minor),512            )513            filePath = filePathPrefix + ".py"514            filePathPyc = filePathPrefix + ".py"515            if __debug__:516                filePathPyc = filePathPyc + "c"517            else:518                filePathPyc = filePathPyc + "o"519            # Verify that type library is up to date.520            # If we have a differing MinorVersion or genpy has bumped versions, update the file521            from . import genpy522 523            if (524                module.MinorVersion != tlbAttributes[4]525                or genpy.makepy_version != module.makepy_version526            ):527                # print "Version skew: %d, %d" % (module.MinorVersion, tlbAttributes[4])528                # try to erase the bad file from the cache529                try:530                    os.unlink(filePath)531                except os.error:532                    pass533                try:534                    os.unlink(filePathPyc)535                except os.error:536                    pass537                if os.path.isdir(filePathPrefix):538                    import shutil539 540                    shutil.rmtree(filePathPrefix)541                minor = tlbAttributes[4]542                module = None543                bReloadNeeded = 1544            else:545                minor = module.MinorVersion546                filePathPrefix = "%s\\%s" % (547                    GetGeneratePath(),548                    GetGeneratedFileName(typelibCLSID, lcid, major, minor),549                )550                filePath = filePathPrefix + ".py"551                filePathPyc = filePathPrefix + ".pyc"552                # print "Trying py stat: ", filePath553                fModTimeSet = 0554                try:555                    pyModTime = os.stat(filePath)[8]556                    fModTimeSet = 1557                except os.error as e:558                    # If .py file fails, try .pyc file559                    # print "Trying pyc stat", filePathPyc560                    try:561                        pyModTime = os.stat(filePathPyc)[8]562                        fModTimeSet = 1563                    except os.error as e:564                        pass565                # print "Trying stat typelib", pyModTime566                # print str(typLibPath)567                typLibModTime = os.stat(typLibPath)[8]568                if fModTimeSet and (typLibModTime > pyModTime):569                    bReloadNeeded = 1570                    module = None571    except (ImportError, os.error):572        module = None573    if module is None:574        # We need to build an item.  If we are in a read-only cache, we575        # can't/don't want to do this - so before giving up, check for576        # a different minor version in our cache - according to COM, this is OK577        if is_readonly:578            key = str(typelibCLSID), lcid, major, minor579            # If we have been asked before, get last result.580            try:581                return versionRedirectMap[key]582            except KeyError:583                pass584            # Find other candidates.585            items = []586            for desc in GetGeneratedInfos():587                if key[0] == desc[0] and key[1] == desc[1] and key[2] == desc[2]:588                    items.append(desc)589            if items:590                # Items are all identical, except for last tuple element591                # We want the latest minor version we have - so just sort and grab last592                items.sort()593                new_minor = items[-1][3]594                ret = GetModuleForTypelib(typelibCLSID, lcid, major, new_minor)595            else:596                ret = None597            # remember and return598            versionRedirectMap[key] = ret599            return ret600        # print "Rebuilding: ", major, minor601        module = MakeModuleForTypelib(602            typelibCLSID,603            lcid,604            major,605            minor,606            progressInstance,607            bForDemand=bForDemand,608            bBuildHidden=bBuildHidden,609        )610        # If we replaced something, reload it611        if bReloadNeeded:612            module = reload(module)613            AddModuleToCache(typelibCLSID, lcid, major, minor)614    return module615 616 617def EnsureDispatch(618    prog_id, bForDemand=1619):  # New fn, so we default the new demand feature to on!620    """Given a COM prog_id, return an object that is using makepy support, building if necessary"""621    disp = win32com.client.Dispatch(prog_id)622    if not disp.__dict__.get("CLSID"):  # Eeek - no makepy support - try and build it.623        try:624            ti = disp._oleobj_.GetTypeInfo()625            disp_clsid = ti.GetTypeAttr()[0]626            tlb, index = ti.GetContainingTypeLib()627            tla = tlb.GetLibAttr()628            mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)629            GetModuleForCLSID(disp_clsid)630            # Get the class from the module.631            from . import CLSIDToClass632 633            disp_class = CLSIDToClass.GetClass(str(disp_clsid))634            disp = disp_class(disp._oleobj_)635        except pythoncom.com_error:636            raise TypeError(637                "This COM object can not automate the makepy process - please run makepy manually for this object"638            )639    return disp640 641 642def AddModuleToCache(643    typelibclsid, lcid, major, minor, verbose=1, bFlushNow=not is_readonly644):645    """Add a newly generated file to the cache dictionary."""646    fname = GetGeneratedFileName(typelibclsid, lcid, major, minor)647    mod = _GetModule(fname)648    # if mod._in_gencache_ is already true, then we are reloading this649    # module - this doesn't mean anything special though!650    mod._in_gencache_ = 1651    info = str(typelibclsid), lcid, major, minor652    dict_modified = False653 654    def SetTypelibForAllClsids(dict):655        nonlocal dict_modified656        for clsid, cls in dict.items():657            if clsidToTypelib.get(clsid) != info:658                clsidToTypelib[clsid] = info659                dict_modified = True660 661    SetTypelibForAllClsids(mod.CLSIDToClassMap)662    SetTypelibForAllClsids(mod.CLSIDToPackageMap)663    SetTypelibForAllClsids(mod.VTablesToClassMap)664    SetTypelibForAllClsids(mod.VTablesToPackageMap)665 666    # If this lib was previously redirected, drop it667    if info in versionRedirectMap:668        del versionRedirectMap[info]669    if bFlushNow and dict_modified:670        _SaveDicts()671 672 673def GetGeneratedInfos():674    zip_pos = win32com.__gen_path__.find(".zip\\")675    if zip_pos >= 0:676        import zipfile677 678        zip_file = win32com.__gen_path__[: zip_pos + 4]679        zip_path = win32com.__gen_path__[zip_pos + 5 :].replace("\\", "/")680        zf = zipfile.ZipFile(zip_file)681        infos = {}682        for n in zf.namelist():683            if not n.startswith(zip_path):684                continue685            base = n[len(zip_path) + 1 :].split("/")[0]686            try:687                iid, lcid, major, minor = base.split("x")688                lcid = int(lcid)689                major = int(major)690                minor = int(minor)691                iid = pywintypes.IID("{" + iid + "}")692            except ValueError:693                continue694            except pywintypes.com_error:695                # invalid IID696                continue697            infos[(iid, lcid, major, minor)] = 1698        zf.close()699        return list(infos.keys())700    else:701        # on the file system702        files = glob.glob(win32com.__gen_path__ + "\\*")703        ret = []704        for file in files:705            if not os.path.isdir(file) and not os.path.splitext(file)[1] == ".py":706                continue707            name = os.path.splitext(os.path.split(file)[1])[0]708            try:709                iid, lcid, major, minor = name.split("x")710                iid = pywintypes.IID("{" + iid + "}")711                lcid = int(lcid)712                major = int(major)713                minor = int(minor)714            except ValueError:715                continue716            except pywintypes.com_error:717                # invalid IID718                continue719            ret.append((iid, lcid, major, minor))720        return ret721 722 723def _GetModule(fname):724    """Given the name of a module in the gen_py directory, import and return it."""725    mod_name = "win32com.gen_py.%s" % fname726    mod = __import__(mod_name)727    return sys.modules[mod_name]728 729 730def Rebuild(verbose=1):731    """Rebuild the cache indexes from the file system."""732    clsidToTypelib.clear()733    infos = GetGeneratedInfos()734    if verbose and len(infos):  # Dont bother reporting this when directory is empty!735        print("Rebuilding cache of generated files for COM support...")736    for info in infos:737        iid, lcid, major, minor = info738        if verbose:739            print("Checking", GetGeneratedFileName(*info))740        try:741            AddModuleToCache(iid, lcid, major, minor, verbose, 0)742        except:743            print(744                "Could not add module %s - %s: %s"745                % (info, sys.exc_info()[0], sys.exc_info()[1])746            )747    if verbose and len(infos):  # Dont bother reporting this when directory is empty!748        print("Done.")749    _SaveDicts()750 751 752def _Dump():753    print("Cache is in directory", win32com.__gen_path__)754    # Build a unique dir755    d = {}756    for clsid, (typelibCLSID, lcid, major, minor) in clsidToTypelib.items():757        d[typelibCLSID, lcid, major, minor] = None758    for typelibCLSID, lcid, major, minor in d.keys():759        mod = GetModuleForTypelib(typelibCLSID, lcid, major, minor)760        print("%s - %s" % (mod.__doc__, typelibCLSID))761 762 763# Boot up764__init__()765 766 767def usage():768    usageString = """\769	  Usage: gencache [-q] [-d] [-r]770 771			 -q         - Quiet772			 -d         - Dump the cache (typelibrary description and filename).773			 -r         - Rebuild the cache dictionary from the existing .py files774	"""775    print(usageString)776    sys.exit(1)777 778 779if __name__ == "__main__":780    import getopt781 782    try:783        opts, args = getopt.getopt(sys.argv[1:], "qrd")784    except getopt.error as message:785        print(message)786        usage()787 788    # we only have options - complain about real args, or none at all!789    if len(sys.argv) == 1 or args:790        print(usage())791 792    verbose = 1793    for opt, val in opts:794        if opt == "-d":  # Dump795            _Dump()796        if opt == "-r":797            Rebuild(verbose)798        if opt == "-q":799            verbose = 0800 
codekingpro/portable-devtools · Team Ai