Skip to content

Commit

Permalink
Merge branch 'main' into docs/link-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Oct 31, 2023
2 parents 8c3b706 + 34aa98c commit 1e0e1bb
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 9 deletions.
91 changes: 91 additions & 0 deletions docs/userguides/networks.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,94 @@ from ape import chain
block = chain.provider.get_block("latest")
```

## Provider Context Manager

Use the [ProviderContextManager](../methoddocs/api.html#ape.api.networks.ProviderContextManager) to change the network-context in Python.
When entering a network for the first time, it will connect to that network.
**You do not need to call `.connect()` or `.disconnect()` manually**.

For example, if you are using a script with a default network connection, you can change connection in the middle of the script by using the provider context manager:

```python
from ape import chain, networks
def main():
start_provider = chain.provider.name
with networks.ethereum.mainnet.use_provider("geth") as provider:
# We are using a different provider than the one we started with.
assert start_provider != provider.name
```

Jump between networks to simulate multi-chain behavior.

```python
import click
from ape import networks
@click.command()
def cli():
with networks.polygon.mainnet.use_provider("geth"):
...
with networks.ethereum.mainnet.use_provider("geth"):
...
```

The argument to [use_provider()](../methoddocs/api.html#ape.api.networks.NetworkAPI.use_provider) is the name of the provider you want to use.
You can also tell Ape to use the default provider by calling method [use_default_provider()](../methoddocs/api.html#ape.api.networks.NetworkAPI.use_default_provider) instead.
This will use whatever provider is set as default for your ecosystem / network combination (via one of your `ape-config.yaml` files).

For example, let's say I have a default provider set like this:

```yaml
arbitrum:
mainnet:
default_provider: alchemy
```

```python
import ape
# Use the provider configured as the default for the arbitrum::mainnet network.
# In this case, it will use the "alchemy" provider.
with ape.networks.arbitrum.mainnet.use_default_provider():
...
```

You can also use the [parse_network_choice()](../methoddocs/managers.html#ape.managers.networks.NetworkManager.parse_network_choice) method when working with network choice strings:

```python
from ape import networks
# Same as doing `networks.ethereum.local.use_provider("test")`.
with networks.parse_network_choice("ethereum:local:test") as provider:
print(provider)
```
**A note about disconnect**: Providers do not disconnect until the very end of your Python session.
This is so you can easily switch network contexts in a bridge or multi-chain environment, which happens in fixtures and other sessions out of Ape's control.
However, sometimes you may definitely want your temporary network session to end before continuing, in which case you can use the `disconnect_after=True` kwarg:

```python
from ape import networks
with networks.parse_network_choice("ethereum:local:foundry", disconnect_after=True) as provider:
print(provider)
```

### Forked Context

Using the `networks.fork()` method, you can achieve similar effects to using a forked network with `disconnect_after=True`.
For example, let's say we are running the following script on the network `ethereum:mainnet`.
We can switch to a forked network by doing this:

```python
from ape import networks
def main():
with networks.fork("foundry"):
...
# Do stuff on a local, forked version of mainnet
# Switch back to mainnet.
```
5 changes: 5 additions & 0 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,11 @@ class ProviderContextManager(ManagerAccessMixin):
mainnet = networks.ethereum.mainnet # An instance of NetworkAPI
with mainnet.use_provider("infura"):
...
# Or, using choice-strings:
with networks.parse_network_choice("ethereum:local:test"):
...
"""

connected_providers: Dict[str, "ProviderAPI"] = {}
Expand Down
30 changes: 21 additions & 9 deletions src/ape/pytest/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest

from ape import networks, project
from ape.exceptions import ConfigError
from ape.logging import LogLevel, logger
from ape.pytest.config import ConfigWrapper
from ape.pytest.coverage import CoverageTracker
Expand All @@ -14,33 +15,44 @@


def pytest_addoption(parser):
parser.addoption(
"--showinternal",
action="store_true",
)
parser.addoption(
def add_option(*names, **kwargs):
try:
parser.addoption(*names, **kwargs)
except ValueError as err:
name_str = ", ".join(names)
if "already added" in str(err):
raise ConfigError(
f"Another pytest plugin besides `ape_test` uses an option with "
f"one of '{name_str}'. Note that Ape does not support being "
f"installed alongside Brownie; please use separate environments!"
)

raise ConfigError(f"Failed adding option {name_str}: {err}") from err

add_option("--showinternal", action="store_true")
add_option(
"--network",
action="store",
default=networks.default_ecosystem.name,
help="Override the default network and provider (see ``ape networks list`` for options).",
)
parser.addoption(
add_option(
"--interactive",
"-I",
action="store_true",
help="Open an interactive console each time a test fails.",
)
parser.addoption(
add_option(
"--disable-isolation",
action="store_true",
help="Disable test and fixture isolation (see provider for info on snapshot availability).",
)
parser.addoption(
add_option(
"--gas",
action="store_true",
help="Show a transaction gas report at the end of the test session.",
)
parser.addoption(
add_option(
"--gas-exclude",
action="store",
help="A comma-separated list of contract:method-name glob-patterns to ignore.",
Expand Down

0 comments on commit 1e0e1bb

Please sign in to comment.