From 2af7bb036ea9d42992a5eca644f02146b5f12d61 Mon Sep 17 00:00:00 2001 From: Paul Peregud Date: Mon, 27 Feb 2017 15:48:57 +0100 Subject: [PATCH 1/6] for win32 IPC use win32file pipe --- web3/providers/ipc.py | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py index 02d6a80..2e40d21 100644 --- a/web3/providers/ipc.py +++ b/web3/providers/ipc.py @@ -25,14 +25,32 @@ from .base import JSONBaseProvider @contextlib.contextmanager def get_ipc_socket(ipc_path, timeout=0.1): - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect(ipc_path) - sock.settimeout(timeout) - - yield sock - - sock.close() - + # is_linux = sys.platform.startswith('linux') + # is_darwin = sys.platform == 'darwin' + is_win32 = sys.platform == 'win32' + if is_win32: + import win32file + sock = win32file.CreateFile(ipc_path, + win32file.win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, None, + win32file.OPEN_EXISTING, 0, None) + def recv(self, max_length): + data = win32file.ReadFile(self, max_length) + if data[0] == 0: + return data[1] + return "" + sock.recv = recv + def sendall(data): + return win32file.WriteFile(self, data) + sock.sendall = sendall + yield sock + sock + else: + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.connect(ipc_path) + sock.settimeout(timeout) + yield sock + sock.close() def get_default_ipc_path(testnet=False): if testnet: @@ -56,12 +74,7 @@ def get_default_ipc_path(testnet=False): "geth.ipc", )) elif sys.platform == 'win32': - return os.path.expanduser(os.path.join( - "~", - "AppData", - "Roaming", - "Ethereum", - )) + return "\\\\.\\pipe\\geth.ipc", else: raise ValueError( "Unsupported platform '{0}'. Only darwin/linux2/win32 are " From 186280e7066438a8a8a6d758223621d501ca6012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 27 Feb 2017 16:42:47 +0100 Subject: [PATCH 2/6] Fix IPC via named pipe on Windows --- web3/providers/ipc.py | 52 ++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py index 2e40d21..1c8ab36 100644 --- a/web3/providers/ipc.py +++ b/web3/providers/ipc.py @@ -25,26 +25,37 @@ from .base import JSONBaseProvider @contextlib.contextmanager def get_ipc_socket(ipc_path, timeout=0.1): - # is_linux = sys.platform.startswith('linux') - # is_darwin = sys.platform == 'darwin' - is_win32 = sys.platform == 'win32' - if is_win32: + + # On Windows named pipe is used. Simulate socket with it. + if sys.platform == 'win32': import win32file - sock = win32file.CreateFile(ipc_path, - win32file.win32file.GENERIC_READ | win32file.GENERIC_WRITE, - 0, None, - win32file.OPEN_EXISTING, 0, None) - def recv(self, max_length): - data = win32file.ReadFile(self, max_length) - if data[0] == 0: - return data[1] - return "" - sock.recv = recv - def sendall(data): - return win32file.WriteFile(self, data) - sock.sendall = sendall - yield sock - sock + import pywintypes + + class NamedPipe(object): + def __init__(self, ipc_path): + try: + self.handle = win32file.CreateFile( + ipc_path, win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, None, win32file.OPEN_EXISTING, 0, None) + except pywintypes.error as err: + raise IOError(err) + + def recv(self, max_length): + (err, data) = win32file.ReadFile(self.handle, max_length) + if err: + raise IOError(err) + return data + + def sendall(self, data): + return win32file.WriteFile(self.handle, data) + + def close(self): + self.handle.close() + + pipe = NamedPipe(ipc_path) + yield pipe + pipe.close() + else: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(ipc_path) @@ -52,6 +63,7 @@ def get_ipc_socket(ipc_path, timeout=0.1): yield sock sock.close() + def get_default_ipc_path(testnet=False): if testnet: testnet = "testnet" @@ -74,7 +86,7 @@ def get_default_ipc_path(testnet=False): "geth.ipc", )) elif sys.platform == 'win32': - return "\\\\.\\pipe\\geth.ipc", + return "\\\\.\\pipe\\geth.ipc" else: raise ValueError( "Unsupported platform '{0}'. Only darwin/linux2/win32 are " From a53c0e562823fc7de6a719df6bbcb9a3cff43949 Mon Sep 17 00:00:00 2001 From: Paul Peregud Date: Mon, 27 Feb 2017 16:44:15 +0100 Subject: [PATCH 3/6] add pypiwin32 dependency for win32 --- setup.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 308db01..08f0c88 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,17 @@ DIR = os.path.dirname(os.path.abspath(__file__)) readme = open(os.path.join(DIR, 'README.md')).read() +install_requires=[ + "ethereum-abi-utils>=0.4.0", + "ethereum-utils>=0.2.0", + "pylru>=1.0.9", + "pysha3>=0.3", + "requests>=2.12.4", + "rlp>=0.4.6,<0.4.7", +], +import sys +if sys.platform == 'win32': + install_requires.append('pypiwin32') setup( name='web3', @@ -23,14 +34,7 @@ setup( author_email='pipermerriam@gmail.com', url='https://github.com/pipermerriam/web3.py', include_package_data=True, - install_requires=[ - "ethereum-abi-utils>=0.4.0", - "ethereum-utils>=0.2.0", - "pylru>=1.0.9", - "pysha3>=0.3", - "requests>=2.12.4", - "rlp>=0.4.6,<0.4.7", - ], + install_requires=install_requires, extras_require={ 'Tester': ["eth-testrpc>=1.1.0"], 'tester': ["eth-testrpc>=1.1.0"], From f18b784845eb03bcf1b98486dc7a13dd744e6478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 27 Feb 2017 16:50:42 +0100 Subject: [PATCH 4/6] Fix changes in setup.py --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 08f0c88..69a7802 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- import os +import sys from setuptools import ( setup, @@ -20,8 +21,8 @@ install_requires=[ "pysha3>=0.3", "requests>=2.12.4", "rlp>=0.4.6,<0.4.7", -], -import sys +] + if sys.platform == 'win32': install_requires.append('pypiwin32') From 9fa2c9e9aa3cd71efafbc3ff4d6b0a9e733ec41f Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Mon, 27 Feb 2017 09:32:28 -0700 Subject: [PATCH 5/6] Speed up travis builds by removing sudo requirement --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 511f715..f63627c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,6 @@ language: python python: - "3.5" dist: trusty -sudo: required -before_install: - - travis_retry sudo add-apt-repository -y ppa:ethereum/ethereum - - travis_retry sudo apt-get update env: matrix: - TOX_ENV=py27-stdlib From 0c22eb8d1c9c0d30e67708dc8cd462a271e9a03a Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Mon, 27 Feb 2017 09:33:20 -0700 Subject: [PATCH 6/6] re-organize windows named pipe code --- web3/providers/ipc.py | 36 ++++++------------------------------ web3/utils/windows.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 web3/utils/windows.py diff --git a/web3/providers/ipc.py b/web3/providers/ipc.py index 1c8ab36..dec7daa 100644 --- a/web3/providers/ipc.py +++ b/web3/providers/ipc.py @@ -25,43 +25,19 @@ from .base import JSONBaseProvider @contextlib.contextmanager def get_ipc_socket(ipc_path, timeout=0.1): - - # On Windows named pipe is used. Simulate socket with it. if sys.platform == 'win32': - import win32file - import pywintypes - - class NamedPipe(object): - def __init__(self, ipc_path): - try: - self.handle = win32file.CreateFile( - ipc_path, win32file.GENERIC_READ | win32file.GENERIC_WRITE, - 0, None, win32file.OPEN_EXISTING, 0, None) - except pywintypes.error as err: - raise IOError(err) - - def recv(self, max_length): - (err, data) = win32file.ReadFile(self.handle, max_length) - if err: - raise IOError(err) - return data - - def sendall(self, data): - return win32file.WriteFile(self.handle, data) - - def close(self): - self.handle.close() + # On Windows named pipe is used. Simulate socket with it. + from web3.utils.windows import NamedPipe pipe = NamedPipe(ipc_path) - yield pipe - pipe.close() - + with contextlib.closing(pipe): + yield pipe else: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(ipc_path) sock.settimeout(timeout) - yield sock - sock.close() + with contextlib.closing(sock): + yield sock def get_default_ipc_path(testnet=False): diff --git a/web3/utils/windows.py b/web3/utils/windows.py new file mode 100644 index 0000000..0a7c861 --- /dev/null +++ b/web3/utils/windows.py @@ -0,0 +1,31 @@ +import sys + + +if sys.platform != 'win32': + raise ImportError("This module should not be imported on non `win32` platforms") + + +import win32file # noqa: E402 +import pywintypes # noqa: E402 + + +class NamedPipe(object): + def __init__(self, ipc_path): + try: + self.handle = win32file.CreateFile( + ipc_path, win32file.GENERIC_READ | win32file.GENERIC_WRITE, + 0, None, win32file.OPEN_EXISTING, 0, None) + except pywintypes.error as err: + raise IOError(err) + + def recv(self, max_length): + (err, data) = win32file.ReadFile(self.handle, max_length) + if err: + raise IOError(err) + return data + + def sendall(self, data): + return win32file.WriteFile(self.handle, data) + + def close(self): + self.handle.close()