Search code examples
pythonpy2exereview-board

Py2Exe and pkg_resources.iter_entry_points()


I'm attempting to use Py2Exe to build a Windows executable from ReviewBoard's postreview.py, so my users don't need to install Python in order to post review requests.

I'm running up against a problem in which the compiled version can't find any registered SCM clients. I've tracked this down to the following line in the code:

for ep in pkg_resources.iter_entry_points(group='rbtools_scm_clients'):

These entry points are listed in the RBTools egg in EGG-INFO\entry_points.txt. In the compiled exe, the iter_entry_points() function returns an empty list.

Is there any way through Py2Exe to make the compiled exe aware of these entry points? Or am I stuck customizing postreview (essentially hard-coding the entry points) to get this to work?

Thanks for any tips!


Solution

  • In case anyone else comes across this looking for an answer, I got it to work by hard-coding the entry points. I had to update the load_scmclients() function in rbtools/clients/__init__.py as follows:

    import imp
    def main_is_frozen():
        return (hasattr(sys, "frozen") or # new py2exe
                hasattr(sys, "importers") # old py2exe
                or imp.is_frozen("__main__")) # tools/freeze
    
    from rbtools.clients.svn import SVNClient
    from rbtools.clients.git import GitClient
    from rbtools.clients.mercurial import MercurialClient
    from rbtools.clients.cvs import CVSClient
    from rbtools.clients.perforce import PerforceClient
    from rbtools.clients.plastic import PlasticClient
    from rbtools.clients.clearcase import ClearCaseClient
    from rbtools.clients.bazaar import BazaarClient
    def load_scmclients(options):
        global SCMCLIENTS
    
        SCMCLIENTS = {}
    
        if not main_is_frozen():
            for ep in pkg_resources.iter_entry_points(group='rbtools_scm_clients'):
                try:
                    SCMCLIENTS[ep.name] = ep.load()(options=options)
                except Exception, e:
                    logging.error('Could not load SCM Client "%s": %s' % (ep.name, e))
        else:
            temp_clients = {}
            temp_clients['svn'] = SVNClient
            temp_clients['git'] = GitClient
            temp_clients['mercurial'] = MercurialClient
            temp_clients['cvs'] = CVSClient
            temp_clients['perforce'] = PerforceClient
            temp_clients['plastic'] = PlasticClient
            temp_clients['clearcase'] = ClearCaseClient
            temp_clients['bazaar'] = BazaarClient
            for ep in temp_clients:
                try:
                    SCMCLIENTS[ep] = temp_clients[ep](options=options)
                except Exception, e:
                    logging.error('Could not load SCM Client "%s": %s' % (str(ep), e))