<commit_before>import contextlib
import functools

import click

from pygeth import (
    DevGethProcess,
    InterceptedStreamsMixin,
    LoggingMixin,
)
from populus.utils.filesystem import (
    remove_file_if_exists,
    remove_dir_if_exists,
    get_blockchains_dir,
    tempdir,
)
from populus.utils.chain import (
    get_chaindata_dir,
    get_dapp_dir,
    get_nodekey_path,
    get_geth_ipc_path,
    get_geth_logfile_path,
)


def reset_chain(data_dir):
    chaindata_dir = get_chaindata_dir(data_dir)
    remove_dir_if_exists(chaindata_dir)

    dapp_dir = get_dapp_dir(data_dir)
    remove_dir_if_exists(dapp_dir)

    nodekey_path = get_nodekey_path(data_dir)
    remove_file_if_exists(nodekey_path)

    geth_ipc_path = get_geth_ipc_path(data_dir)
    remove_file_if_exists(geth_ipc_path)


class LocalChainGethProcess(InterceptedStreamsMixin, DevGethProcess):
    def __init__(self, *args, **kwargs):
        super(LocalChainGethProcess, self).__init__(*args, **kwargs)
        self.register_stdout_callback(click.echo)
        self.register_stderr_callback(functools.partial(click.echo, err=True))


@contextlib.contextmanager
def dev_geth_process(project_dir, chain_name):
    blockchains_dir = get_blockchains_dir(project_dir)
    with LocalChainGethProcess(chain_name=chain_name, base_dir=blockchains_dir) as geth:
        yield geth


class TestingGethProcess(LoggingMixin, DevGethProcess):
    pass


@contextlib.contextmanager
def testing_geth_process(project_dir, test_name):
    """A content manager to launch a new local Geth process for running tests.

    A fresh run in a new environment may need up to 10 minutes to
    generate DAG files.

    * See https://github.com/ethereum/wiki/wiki/Ethash-DAG

    * These are shared across all Ethereum nodes and live in
      ``$(HOME)/.ethash/`` folder

    Example:

    .. code-block:: python

        import pytest

        from web3 import Web3, RPCProvider
        from populus.chain import testing_geth_process


        @pytest.yield_fixture(scope="session")
        def web3(request, client_mode, client_credentials) -> Web3:
            '''A py.test fixture to get a Web3 interface to locally launched geth.

            This is session scoped fixture.
            Geth is launched only once during the beginning of the test run.

            Geth will have huge instant balance on its coinbase account.
            Geth will also mine our transactions on artificially
            low difficulty level.
            '''

            # Ramp up a local geth server, store blockchain files in the
            # current working directory
            with testing_geth_process(project_dir=os.getcwd(), test_name="test") as geth_proc:
                # Launched in port 8080
                web3 = Web3(RPCProvider(host="127.0.0.1", port="8545"))

                # Allow access to sendTransaction() to use coinbase balance
                # to deploy contracts. Password is from py-geth
                # default_blockchain_password file. Assume we don't
                # run tests for more than 9999 seconds
                coinbase = web3.eth.coinbase
                success = web3.personal.unlockAccount(
                    coinbase,
                    passphrase="<PASSWORD>",
                    duration=9999)

                assert success, "Could not unlock test geth coinbase account"

                yield web3


        @pytest.fixture(scope="session")
        def coinbase(web3) -> str:
            '''Get coinbase address of locally running geth.'''
            return web3.eth.coinbase


    :param project_dir: Directory where chain files and log files are stored
    :param test_name: An identifier that llows separatation log files for each test
    :return: :class:`populus.chain.TestingGethProcess`
    """
    with tempdir() as tmp_project_dir:
        blockchains_dir = get_blockchains_dir(tmp_project_dir)
        geth = TestingGethProcess(
            chain_name='tmp-chain',<commit_msg>Update how to pass port from geth_proc to RPC.<commit_after>import contextlib
import functools

import click

from pygeth import (
    DevGethProcess,
    InterceptedStreamsMixin,
    LoggingMixin,
)
from populus.utils.filesystem import (
    remove_file_if_exists,
    remove_dir_if_exists,
    get_blockchains_dir,
    tempdir,
)
from populus.utils.chain import (
    get_chaindata_dir,
    get_dapp_dir,
    get_nodekey_path,
    get_geth_ipc_path,
    get_geth_logfile_path,
)


def reset_chain(data_dir):
    chaindata_dir = get_chaindata_dir(data_dir)
    remove_dir_if_exists(chaindata_dir)

    dapp_dir = get_dapp_dir(data_dir)
    remove_dir_if_exists(dapp_dir)

    nodekey_path = get_nodekey_path(data_dir)
    remove_file_if_exists(nodekey_path)

    geth_ipc_path = get_geth_ipc_path(data_dir)
    remove_file_if_exists(geth_ipc_path)


class LocalChainGethProcess(InterceptedStreamsMixin, DevGethProcess):
    def __init__(self, *args, **kwargs):
        super(LocalChainGethProcess, self).__init__(*args, **kwargs)
        self.register_stdout_callback(click.echo)
        self.register_stderr_callback(functools.partial(click.echo, err=True))


@contextlib.contextmanager
def dev_geth_process(project_dir, chain_name):
    blockchains_dir = get_blockchains_dir(project_dir)
    with LocalChainGethProcess(chain_name=chain_name, base_dir=blockchains_dir) as geth:
        yield geth


class TestingGethProcess(LoggingMixin, DevGethProcess):
    pass


@contextlib.contextmanager
def testing_geth_process(project_dir, test_name):
    """A content manager to launch a new local Geth process for running tests.

    A fresh run in a new environment may need up to 10 minutes to
    generate DAG files.

    * See https://github.com/ethereum/wiki/wiki/Ethash-DAG

    * These are shared across all Ethereum nodes and live in
      ``$(HOME)/.ethash/`` folder

    Example:

    .. code-block:: python

        import pytest

        from web3 import Web3, RPCProvider
        from populus.chain import testing_geth_process


        @pytest.yield_fixture(scope="session")
        def web3(request, client_mode, client_credentials) -> Web3:
            '''A py.test fixture to get a Web3 interface to locally launched geth.

            This is session scoped fixture.
            Geth is launched only once during the beginning of the test run.

            Geth will have huge instant balance on its coinbase account.
            Geth will also mine our transactions on artificially
            low difficulty level.
            '''

            # Ramp up a local geth server, store blockchain files in the
            # current working directory
            with testing_geth_process(project_dir=os.getcwd(), test_name="test") as geth_proc:
                # Launched in port 8080
                web3 = Web3(RPCProvider(host="127.0.0.1", port=geth_proc.rpc_port))

                # Allow access to sendTransaction() to use coinbase balance
                # to deploy contracts. Password is from py-geth
                # default_blockchain_password file. Assume we don't
                # run tests for more than 9999 seconds
                coinbase = web3.eth.coinbase
                success = web3.personal.unlockAccount(
                    coinbase,
                    passphrase="<PASSWORD>",
                    duration=9999)

                assert success, "Could not unlock test geth coinbase account"

                yield web3


        @pytest.fixture(scope="session")
        def coinbase(web3) -> str:
            '''Get coinbase address of locally running geth.'''
            return web3.eth.coinbase


    :param project_dir: Directory where chain files and log files are stored
    :param test_name: An identifier that llows separatation log files for each test
    :return: :class:`populus.chain.TestingGethProcess`
    """
    with tempdir() as tmp_project_dir:
        blockchains_dir = get_blockchains_dir(tmp_project_dir)
        geth = TestingGethProcess(
            chain_name='tmp-chain',
{'fraction_non_alphanumeric': 0.06875077842819778, 'fraction_numerical': 0.008469298791879437, 'mean_word_length': 2.7823834196891193, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7102198', 'n_tokens_mistral': 2467, 'n_tokens_neox': 2330, 'n_words': 621}