Skip to content

Commit

Permalink
Merge pull request #154 from iamdefinitelyahuman/v1.0.0b10
Browse files Browse the repository at this point in the history
V1.0.0b10
  • Loading branch information
iamdefinitelyahuman committed Jul 20, 2019
2 parents 6dc29de + 4025bb5 commit e91a0ae
Show file tree
Hide file tree
Showing 105 changed files with 3,651 additions and 3,331 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
1.0.0b10
--------

- Use pytest for unit testing
- remove check module, add check.equals comparison logic to ReturnValue
- Modify coverage evaluation to work with pytest
- remove brownie.types package, move classes to related modules
- replace wei function with Wei class, expand functionality
- add EthAddress and HexString helper classes
- improved formatting for tx.traceback and tx.call_trace

1.0.0b9
-------

Expand Down
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Brownie

[![Pypi Status](https://img.shields.io/pypi/v/eth-brownie.svg)](https://pypi.org/project/eth-brownie/) [![Build Status](https://img.shields.io/travis/com/HyperLink-Technology/brownie.svg)](https://travis-ci.com/HyperLink-Technology/brownie) [![Docs Status](https://readthedocs.org/projects/eth-brownie/badge/?version=latest)](https://eth-brownie.readthedocs.io/en/latest/) [![Coverage Status](https://coveralls.io/repos/github/HyperLink-Technology/brownie/badge.svg?branch=master)](https://coveralls.io/github/HyperLink-Technology/brownie?branch=master)
[![Pypi Status](https://img.shields.io/pypi/v/eth-brownie.svg)](https://pypi.org/project/eth-brownie/) [![Build Status](https://img.shields.io/travis/com/iamdefinitelyahuman/brownie.svg)](https://travis-ci.com/iamdefinitelyahuman/brownie) [![Docs Status](https://readthedocs.org/projects/eth-brownie/badge/?version=latest)](https://eth-brownie.readthedocs.io/en/latest/) [![Coverage Status](https://coveralls.io/repos/github/iamdefinitelyahuman/brownie/badge.svg?branch=master)](https://coveralls.io/github/iamdefinitelyahuman/brownie?branch=master)

Brownie is a Python framework for deploying, testing and interacting with Ethereum smart contracts.

Expand Down Expand Up @@ -50,15 +50,11 @@ To run the tests, first install the developer dependencies:
$ pip install -r requirements-dev.txt
```

Then use ``tox`` to run the complete suite against the full set of build targets, or ``py.test`` to run specific tests against a specific version of Python.
Then use ``tox`` to run the complete suite against the full set of build targets, or ``pytest`` to run tests against a specific version of Python. If you are using ``pytest`` you must include the ``-p no:pytest-brownie`` flag to prevent it from loading the Brownie plugin.

## Contributing

Help is always appreciated! In particular, Brownie needs work in the following areas before we can comfortably take it out of beta:

* More tests

Feel free to open an issue if you find a problem, or a pull request if you've solved an issue.
Help is always appreciated! Feel free to open an issue if you find a problem, or a pull request if you've solved an issue.

## License

Expand Down
8 changes: 4 additions & 4 deletions brownie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
)
from .project import (
compile_source,
run,
__brownie_import_all__
)
from brownie.gui import Gui
from brownie.test import check
from brownie._config import CONFIG as config
from brownie.types.convert import wei
from brownie.convert import Wei

__all__ = [
'accounts',
Expand All @@ -25,9 +25,9 @@
'web3',
'project',
'__brownie_import_all__',
'check',
'compile_source',
'wei',
'run',
'Wei',
'config',
'Gui'
]
72 changes: 48 additions & 24 deletions brownie/_config.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,58 @@
#!/usr/bin/python3

from collections import defaultdict
import json
from pathlib import Path
import shutil
import sys

from brownie.types.types import (
FalseyDict,
StrictDict,
_Singleton
)
from brownie._singleton import _Singleton


REPLACE = ['active_network', 'networks']
IGNORE = ['active_network', 'folders', 'logging']
IGNORE = ['active_network', 'folders']


class ConfigDict(dict):
'''Dict subclass that prevents adding new keys when locked'''

def __init__(self, values={}):
self._locked = False
super().__init__()
self.update(values)

def __setitem__(self, key, value):
if self._locked and key not in self:
raise KeyError(f"{key} is not a known config setting")
if type(value) is dict:
value = ConfigDict(value)
super().__setitem__(key, value)

def update(self, arg):
for k, v in arg.items():
self.__setitem__(k, v)

def _lock(self):
'''Locks the dict so that new keys cannot be added'''
for v in [i for i in self.values() if type(i) is ConfigDict]:
v._lock()
self._locked = True

def _unlock(self):
'''Unlocks the dict so that new keys can be added'''
for v in [i for i in self.values() if type(i) is ConfigDict]:
v._unlock()
self._locked = False


def _load_default_config():
'''Loads the default configuration settings from brownie/data/config.json'''
with Path(__file__).parent.joinpath("data/config.json").open() as f:
config = _Singleton("Config", (StrictDict,), {})(json.load(f))
with Path(__file__).parent.joinpath("data/config.json").open() as fp:
config = _Singleton("Config", (ConfigDict,), {})(json.load(fp))
config['folders'] = {
'brownie': str(Path(__file__).parent),
'project': None
}
config['active_network'] = {'name': None}
# set logging
try:
config['logging'] = config['logging'][sys.argv[1]]
config['logging'].setdefault('tx', 0)
config['logging'].setdefault('exc', 0)
for k, v in [(k, v) for k, v in config['logging'].items() if type(v) is list]:
config['logging'][k] = v[1 if '--verbose' in sys.argv else 0]
except Exception:
config['logging'] = {"tx": 1, "exc": 1}
return config


Expand All @@ -45,8 +65,8 @@ def load_project_config(project_path):
CONFIG['folders']['project'] = str(project_path)
config_path = project_path.joinpath("brownie-config.json")
try:
with config_path.open() as f:
_recursive_update(CONFIG, json.load(f), [])
with config_path.open() as fp:
_recursive_update(CONFIG, json.load(fp), [])
except FileNotFoundError:
shutil.copy(
str(Path(CONFIG['folders']['brownie']).joinpath("data/config.json")),
Expand Down Expand Up @@ -75,7 +95,7 @@ def modify_network_config(network=None):
if not CONFIG['active_network']['broadcast_reverting_tx']:
print("WARNING: Reverting transactions will NOT be broadcasted.")
except KeyError:
raise KeyError("Network '{}' is not defined in config.json".format(network))
raise KeyError(f"Network '{network}' is not defined in config.json")
finally:
CONFIG._lock()

Expand All @@ -91,13 +111,17 @@ def _recursive_update(original, new, base):
original[k] = new[k]
for k in [i for i in original if i not in new and not set(base+[i]).intersection(IGNORE)]:
print(
"WARNING: Value '{}' not found in the config file for this project."
" The default setting has been used.".format(".".join(base+[k]))
f"WARNING: '{'.'.join(base+[k])}' not found in the config file for this project."
" The default setting has been used."
)


def update_argv_from_docopt(args):
ARGV.update(dict((k.lstrip("-"), v) for k, v in args.items()))


# create argv object
ARGV = _Singleton("Argv", (FalseyDict,), {})()
ARGV = _Singleton("Argv", (defaultdict,), {})(lambda: None)

# load config
CONFIG = _load_default_config()
11 changes: 11 additions & 0 deletions brownie/_singleton.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/python3


class _Singleton(type):

_instances = {}

def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
3 changes: 1 addition & 2 deletions brownie/cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from brownie.exceptions import ProjectNotFound
from brownie._config import ARGV

__version__ = "1.0.0b9" # did you change this in docs/conf.py as well?
__version__ = "1.0.0b10" # did you change this in docs/conf.py as well?

__doc__ = """Usage: brownie <command> [<args>...] [options <args>]
Expand All @@ -21,7 +21,6 @@
gui Load the GUI to view opcodes and test coverage
init Initialize a new brownie project
run Run a script in the /scripts folder
test Run test scripts in the /tests folder
Options:
--help -h Display this message
Expand Down
2 changes: 1 addition & 1 deletion brownie/cli/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ def main():
if args['--all']:
shutil.rmtree(build_path, ignore_errors=True)
project.load(project_path)
print("Brownie project has been compiled at {}".format(build_path))
print(f"Brownie project has been compiled at {build_path}")
4 changes: 2 additions & 2 deletions brownie/cli/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from brownie import network, project
from brownie.cli.utils.console import Console
from brownie._config import ARGV, CONFIG
from brownie._config import ARGV, CONFIG, update_argv_from_docopt


__doc__ = f"""Usage: brownie console [options]
Expand All @@ -21,7 +21,7 @@

def main():
args = docopt(__doc__)
ARGV._update_from_args(args)
update_argv_from_docopt(args)

project.load()
network.connect(ARGV['network'])
Expand Down
16 changes: 7 additions & 9 deletions brownie/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,30 @@

from docopt import docopt

from brownie import network, project, run
from brownie._config import ARGV, CONFIG, update_argv_from_docopt

from brownie import network, project
from brownie.test.main import run_script
from brownie._config import ARGV, CONFIG


__doc__ = """Usage: brownie run <filename> [<function>] [options]
__doc__ = f"""Usage: brownie run <filename> [<function>] [options]
Arguments:
<filename> The name of the script to run
[<function>] The function to call (default is main)
Options:
--network [name] Use a specific network (default {})
--network [name] Use a specific network (default {CONFIG['network_defaults']['name']})
--gas -g Display gas profile for function calls
--verbose -v Enable verbose reporting
--tb -t Show entire python traceback on exceptions
--help -h Display this message
Use run to execute scripts for contract deployment, to automate common
interactions, or for gas profiling.""".format(CONFIG['network_defaults']['name'])
interactions, or for gas profiling."""


def main():
args = docopt(__doc__)
ARGV._update_from_args(args)
update_argv_from_docopt(args)
project.load()
network.connect(ARGV['network'])
run_script(args['<filename>'], args['<function>'] or "main", gas_profile=ARGV['gas'])
run(args['<filename>'], args['<function>'] or "main", gas_profile=ARGV['gas'])
37 changes: 0 additions & 37 deletions brownie/cli/test.py

This file was deleted.

9 changes: 3 additions & 6 deletions brownie/cli/utils/console.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#!/usr/bin/python3

import atexit
import builtins
import code
from pathlib import Path
import sys

import brownie
from brownie.test.main import run_script
from . import color
from brownie._config import CONFIG

Expand All @@ -22,10 +20,9 @@ class Console(code.InteractiveConsole):

def __init__(self):
locals_dict = dict((i, getattr(brownie, i)) for i in brownie.__all__)
locals_dict['run'] = run_script
locals_dict['dir'] = self._dir
del locals_dict['project']

builtins.dir = self._dir
self._stdout_write = sys.stdout.write
sys.stdout.write = self._console_write

Expand All @@ -37,7 +34,7 @@ def __init__(self):
pass
super().__init__(locals_dict)

# replaces builtin dir method, for simplified and colorful output
# console dir method, for simplified and colorful output
def _dir(self, obj=None):
if obj is None:
results = [(k, v) for k, v in self.locals.items() if not k.startswith('_')]
Expand All @@ -55,7 +52,7 @@ def _console_write(self, text):
text = color.pretty_dict(obj)
elif obj and type(obj) in (tuple, list, set):
text = color.pretty_list(obj)
except SyntaxError:
except (SyntaxError, NameError):
pass
return self._stdout_write(text)

Expand Down

0 comments on commit e91a0ae

Please sign in to comment.