class PytestBinary(object): """A `py.test` PEX binary with an embedded default (empty) `pytest.ini` config file.""" _COVERAGE_PLUGIN_MODULE_NAME = '__{}__'.format(__name__.replace('.', '_')) def __init__(self, interpreter, pex): # Here we hack around `coverage.cmdline` nuking the 0th element of `sys.path` (our root pex) # by ensuring, the root pex is on the sys.path twice. # See: https://github.com/nedbat/coveragepy/issues/715 pex_path = pex.path() pex_info = PexInfo.from_pex(pex_path) pex_info.merge_pex_path(pex_path) # We're now on the sys.path twice. PEXBuilder(pex_path, interpreter=interpreter, pex_info=pex_info).freeze() self._pex = PEX(pex=pex_path, interpreter=interpreter) self._interpreter = interpreter @property def pex(self): """Return the loose-source py.test binary PEX. :rtype: :class:`pex.pex.PEX` """ return self._pex @property def interpreter(self): """Return the interpreter used to build this PEX. :rtype: :class:`pex.interpreter.PythonInterpreter` """ return self._interpreter @property def config_path(self): """Return the absolute path of the `pytest.ini` config file in this py.test binary. :rtype: str """ return os.path.join(self._pex.path(), 'pytest.ini') @classmethod def coverage_plugin_module(cls): """Return the name of the coverage plugin module embedded in this py.test binary. :rtype: str """ return cls._COVERAGE_PLUGIN_MODULE_NAME