From 52e3448c3c24c6c4f841bc3d6e5259a8c8362678 Mon Sep 17 00:00:00 2001 From: iamdefinitelyahuman Date: Tue, 31 Dec 2019 01:54:40 +0200 Subject: [PATCH 1/5] remove old code --- solcx/utils/types.py | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/solcx/utils/types.py b/solcx/utils/types.py index 0c76845..c7dfe53 100644 --- a/solcx/utils/types.py +++ b/solcx/utils/types.py @@ -1,34 +1,21 @@ -import sys import numbers from collections import abc -if sys.version_info.major == 2: - integer_types = (int, long) # noqa: F821 - bytes_types = (bytes, bytearray) - text_types = (unicode,) # noqa: F821 - string_types = (basestring, bytearray) # noqa: F821 -else: - integer_types = (int,) - bytes_types = (bytes, bytearray) - text_types = (str,) - string_types = (bytes, str, bytearray) - - def is_integer(value): - return isinstance(value, integer_types) and not isinstance(value, bool) + return isinstance(value, int) and not isinstance(value, bool) def is_bytes(value): - return isinstance(value, bytes_types) + return isinstance(value, (bytes, bytearray)) def is_text(value): - return isinstance(value, text_types) + return isinstance(value, str) def is_string(value): - return isinstance(value, string_types) + return isinstance(value, (bytes, str, bytearray)) def is_boolean(value): From 947384e0ae217ecda9db50857f0c1e1cf965f977 Mon Sep 17 00:00:00 2001 From: iamdefinitelyahuman Date: Tue, 31 Dec 2019 01:55:12 +0200 Subject: [PATCH 2/5] show progress bar during solc installation if tqdm is installed --- requirements-dev.txt | 1 + solcx/install.py | 51 +++++++++++++++++++++++++++++-------------- tests/test_install.py | 4 ++++ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index a2e16a9..3fb965b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,5 +2,6 @@ coveralls==1.9.2 pytest>=5.0.0 pytest-cov>=2.7.1 semantic_version>=2.8.1,<3 +tqdm==4.41.0 twine==1.13.0 requests>=2.19.0,<3 diff --git a/solcx/install.py b/solcx/install.py index 0c329ce..7f71dc9 100644 --- a/solcx/install.py +++ b/solcx/install.py @@ -25,6 +25,12 @@ get_process_lock ) +try: + from tqdm import tqdm +except ImportError: + tqdm = None + + DOWNLOAD_BASE = "https://github.com/ethereum/solidity/releases/download/{}/{}" ALL_RELEASES = "https://api.github.com/repos/ethereum/solidity/releases?per_page=100" @@ -139,7 +145,7 @@ def set_solc_version_pragma(pragma_string, silent=False, check_new=False): LOGGER.info("Newer compatible solc version exists: {}".format(latest)) -def install_solc_pragma(pragma_string, install=True): +def install_solc_pragma(pragma_string, install=True, show_progress=False): version = _select_pragma_version( pragma_string, [Version(i[1:]) for i in get_available_solc_versions()] @@ -147,7 +153,7 @@ def install_solc_pragma(pragma_string, install=True): if not version: raise ValueError("Compatible solc version does not exist") if install: - install_solc(version) + install_solc(version, show_progress=show_progress) return version @@ -198,7 +204,7 @@ def get_installed_solc_versions(): return sorted(i.name[5:] for i in get_solc_folder().glob('solc-v*')) -def install_solc(version, allow_osx=False): +def install_solc(version, allow_osx=False, show_progress=False): platform = _get_platform() version = _check_version(version) @@ -211,11 +217,11 @@ def install_solc(version, allow_osx=False): try: if platform == 'linux': - _install_solc_linux(version) + _install_solc_linux(version, show_progress) elif platform == 'darwin': - _install_solc_osx(version, allow_osx) + _install_solc_osx(version, allow_osx, show_progress) elif platform == 'win32': - _install_solc_windows(version) + _install_solc_windows(version, show_progress) binary_path = get_executable(version) _check_subprocess_call( [binary_path, '--version'], @@ -267,8 +273,21 @@ def _get_temp_folder(): return path -def _download_solc(url): - response = requests.get(url) +def _download_solc(url, show_progress): + if not show_progress: + response = requests.get(url) + content = response.content + else: + response = requests.get(url, stream=True) + total_size = int(response.headers.get('content-length', 0)) + progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True) + content = bytes() + + for data in response.iter_content(1024, decode_unicode=True): + progress_bar.update(len(data)) + content += data + progress_bar.close() + if response.status_code != 200: raise DownloadError( "Received status code {} when attempting to download from {}".format( @@ -276,33 +295,33 @@ def _download_solc(url): url ) ) - return response.content + return content -def _install_solc_linux(version): +def _install_solc_linux(version, show_progress): download = DOWNLOAD_BASE.format(version, "solc-static-linux") - binary_path = _check_for_installed_version(version) + binary_path = _check_for_installed_version(version, show_progress) if binary_path: LOGGER.info("Downloading solc {} from {}".format(version, download)) - content = _download_solc(download) + content = _download_solc(download, show_progress) with open(binary_path, 'wb') as fp: fp.write(content) _chmod_plus_x(binary_path) -def _install_solc_windows(version): +def _install_solc_windows(version, show_progress): download = DOWNLOAD_BASE.format(version, "solidity-windows.zip") install_folder = _check_for_installed_version(version) if install_folder: temp_path = _get_temp_folder() - content = _download_solc(download) + content = _download_solc(download, show_progress) with zipfile.ZipFile(BytesIO(content)) as zf: zf.extractall(str(temp_path)) install_folder = get_solc_folder().joinpath("solc-" + version) temp_path.rename(install_folder) -def _install_solc_osx(version, allow_osx): +def _install_solc_osx(version, allow_osx, show_progress): if version.startswith("v0.4") and not allow_osx: raise ValueError( "Py-solc-x cannot build solc versions 0.4.x on OSX. If you install solc 0.4.x " @@ -316,7 +335,7 @@ def _install_solc_osx(version, allow_osx): if not binary_path: return - content = _download_solc(download) + content = _download_solc(download, show_progress) with tarfile.open(fileobj=BytesIO(content)) as tar: tar.extractall(temp_path) temp_path = temp_path.joinpath('solidity_{}'.format(version[1:])) diff --git a/tests/test_install.py b/tests/test_install.py index 4baa4ec..dbb6d14 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -44,3 +44,7 @@ def test_install_osx(): solcx.install_solc('0.4.25') solcx.install_solc('0.4.25', allow_osx=True) solcx.install_solc('0.5.4') + + +def test_progress_bar(nosolc): + solcx.install_solc('0.6.0', show_progress=True) From 28e4509b5fe43d7ef24621ff1fe92afd189484e5 Mon Sep 17 00:00:00 2001 From: iamdefinitelyahuman Date: Tue, 31 Dec 2019 02:12:04 +0200 Subject: [PATCH 3/5] update readme and changelog --- CHANGELOG | 1 + README.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 540cd1f..c17f406 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ - Store solc binaries at $HOME/.solcx - Add locks for thread and multiprocessing safety + - Show progress bar during installation if `tqdm` is installed 0.6.1 ----- diff --git a/README.md b/README.md index 387f33b..ab2c454 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ pip install py-solc-x ## Installing the `solc` Executable -The first time py-solc-x is imported it will automatically check for an installed version of solc on your system. If none is found, you must manually install via `solcx.install_solc` +The first time py-solc-x is imported it will automatically check for an installed version of solc on your system. If none is found, you must manually install via `solcx.install_solc`: ```python >>> from solcx import install_solc @@ -39,7 +39,7 @@ The first time py-solc-x is imported it will automatically check for an installe Or via the command line: ```bash -$ python -m solcx.install v0.4.25 +python -m solcx.install v0.4.25 ``` Py-solc-x defaults to the most recent installed version set as the active one. To check or modify the active version: @@ -185,7 +185,7 @@ Py-solc-x is tested on Linux and Windows with solc versions ``>=0.4.11``. To run the test suite: ```bash -$ pytest tests/ +pytest tests/ ``` ## License From 2f440b460f3c98f1fb639c494c795eb087f22e09 Mon Sep 17 00:00:00 2001 From: iamdefinitelyahuman Date: Tue, 31 Dec 2019 02:19:38 +0200 Subject: [PATCH 4/5] bugfixes --- solcx/install.py | 2 +- tests/conftest.py | 3 ++- tests/test_locks.py | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/solcx/install.py b/solcx/install.py index 7f71dc9..405e07a 100644 --- a/solcx/install.py +++ b/solcx/install.py @@ -300,7 +300,7 @@ def _download_solc(url, show_progress): def _install_solc_linux(version, show_progress): download = DOWNLOAD_BASE.format(version, "solc-static-linux") - binary_path = _check_for_installed_version(version, show_progress) + binary_path = _check_for_installed_version(version) if binary_path: LOGGER.info("Downloading solc {} from {}".format(version, download)) content = _download_solc(download, show_progress) diff --git a/tests/conftest.py b/tests/conftest.py index e753f67..a7c2357 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -45,7 +45,8 @@ def nosolc(): temp_path = path.parent.joinpath('.temp') path.rename(temp_path) yield - shutil.rmtree(path) + if path.exists(): + shutil.rmtree(path) temp_path.rename(path) diff --git a/tests/test_locks.py b/tests/test_locks.py index c2b5274..8e044f7 100644 --- a/tests/test_locks.py +++ b/tests/test_locks.py @@ -32,8 +32,9 @@ def test_threadlock(nosolc): def test_processlock(nosolc): - mp.set_start_method('spawn') - threads = [mp.Process(target=solcx.install_solc, args=('0.5.0',),) for i in range(4)] + # have to use a context here to prevent a conflict with tqdm + ctx = mp.get_context('spawn') + threads = [ctx.Process(target=solcx.install_solc, args=('0.5.0',),) for i in range(4)] for t in threads: t.start() solcx.install_solc('0.5.0') From daecfbb8c73521ed8571863bf2b30b25a3603614 Mon Sep 17 00:00:00 2001 From: iamdefinitelyahuman Date: Tue, 31 Dec 2019 03:18:50 +0200 Subject: [PATCH 5/5] changelog, bumpversion --- CHANGELOG | 2 +- Makefile | 44 -------------------------------------------- setup.py | 2 +- 3 files changed, 2 insertions(+), 46 deletions(-) delete mode 100644 Makefile diff --git a/CHANGELOG b/CHANGELOG index c17f406..872f0ec 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -0.7.0 (unreleased) +0.7.0 ----- - Store solc binaries at $HOME/.solcx diff --git a/Makefile b/Makefile deleted file mode 100644 index cb16864..0000000 --- a/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -.PHONY: clean-pyc clean-build - -help: - @echo "clean-build - remove build artifacts" - @echo "clean-pyc - remove Python file artifacts" - @echo "lint - check style with flake8" - @echo "test - run tests quickly with the default Python" - @echo "testall - run tests on every Python version with tox" - @echo "release - package and upload a release" - @echo "sdist - package" - -clean: clean-build clean-pyc - -clean-build: - rm -fr build/ - rm -fr dist/ - rm -fr *.egg-info - -clean-pyc: - find . -name '*.pyc' -exec rm -f {} + - find . -name '*.pyo' -exec rm -f {} + - find . -name '*~' -exec rm -f {} + - -lint: - flake8 solc - -test: - py.test tests - -test-all: - tox - -release: clean - CURRENT_SIGN_SETTING=$(git config commit.gpgSign) - git config commit.gpgSign true - bumpversion $(bump) - git push upstream && git push upstream --tags - python setup.py sdist bdist_wheel - twine upload dist/* - git config commit.gpgSign "$(CURRENT_SIGN_SETTING)" - -sdist: clean - python setup.py sdist bdist_wheel - ls -l dist diff --git a/setup.py b/setup.py index 52e956e..fc5ef68 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='py-solc-x', - version='0.6.1', + version='0.7.0', description="""Python wrapper around the solc binary with 0.5.x and 0.6.x support""", long_description_markdown_filename='README.md', author='Ben Hauser (forked from py-solc by Piper Merriam)',