Skip to content

Commit

Permalink
Merge pull request #35 from iamdefinitelyahuman/tqdm
Browse files Browse the repository at this point in the history
v0.7.0
  • Loading branch information
iamdefinitelyahuman authored Dec 31, 2019
2 parents 94a1357 + daecfbb commit 28b7110
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 84 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
0.7.0 (unreleased)
0.7.0
-----

- 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
-----
Expand Down
44 changes: 0 additions & 44 deletions Makefile

This file was deleted.

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)',
Expand Down
49 changes: 34 additions & 15 deletions solcx/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -139,15 +145,15 @@ 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()]
)
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


Expand Down Expand Up @@ -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)

Expand All @@ -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'],
Expand Down Expand Up @@ -267,42 +273,55 @@ 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(
response.status_code,
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)
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 "
Expand All @@ -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:]))
Expand Down
21 changes: 4 additions & 17 deletions solcx/utils/types.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down
3 changes: 2 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
4 changes: 4 additions & 0 deletions tests/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
5 changes: 3 additions & 2 deletions tests/test_locks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down

0 comments on commit 28b7110

Please sign in to comment.