Runnable with both Python3 and Python2, with PyQt4 #2249

Open
kashikoibumi wants to merge 59 commits from kashikoibumi/py3 into v0.6
66 changed files with 211 additions and 193 deletions
Showing only changes of commit 4ee9986687 - Show all commits

View File

@ -2,7 +2,7 @@
import collectd import collectd
import json import json
import xmlrpclib from six.moves import xmlrpc_client as xmlrpclib
pybmurl = "" pybmurl = ""
api = "" api = ""

View File

@ -4,6 +4,7 @@ import os
import platform import platform
import shutil import shutil
import sys import sys
import six
from importlib import import_module from importlib import import_module
from setuptools import setup, Extension from setuptools import setup, Extension
@ -83,7 +84,7 @@ if __name__ == "__main__":
'images/kivy/text_images*.png' 'images/kivy/text_images*.png'
]} ]}
if sys.version_info[0] == 3: if six.PY3:
packages.extend( packages.extend(
[ [
'pybitmessage.bitmessagekivy', 'pybitmessage.bitmessagekivy',

View File

@ -70,6 +70,7 @@ from struct import pack, unpack
import six import six
from six.moves import configparser, http_client, xmlrpc_server from six.moves import configparser, http_client, xmlrpc_server
from six.moves.reprlib import repr
import helper_inbox import helper_inbox
import helper_sent import helper_sent

View File

@ -21,7 +21,8 @@ import os
import socket import socket
import sys import sys
import time import time
import xmlrpclib from six.moves import xmlrpc_client as xmlrpclib
from six.moves import input as raw_input
from bmconfigparser import config from bmconfigparser import config

View File

@ -10,13 +10,14 @@ Bitmessage commandline interface
# * python2-pythondialog # * python2-pythondialog
# * dialog # * dialog
import ConfigParser from six.moves import configparser
import curses import curses
import os import os
import sys import sys
import time import time
from textwrap import fill from textwrap import fill
from threading import Timer from threading import Timer
import six
from dialog import Dialog from dialog import Dialog
import helper_sent import helper_sent
@ -105,7 +106,7 @@ def ascii(s):
"""ASCII values""" """ASCII values"""
r = "" r = ""
for c in s: for c in s:
if ord(c) in range(128): if six.byte2int(c) in range(128):
r += c r += c
return r return r
@ -326,13 +327,13 @@ def handlech(c, stdscr):
if c != curses.ERR: if c != curses.ERR:
global inboxcur, addrcur, sentcur, subcur, abookcur, blackcur global inboxcur, addrcur, sentcur, subcur, abookcur, blackcur
if c in range(256): if c in range(256):
if chr(c) in '12345678': if six.int2byte(c) in '12345678':
global menutab global menutab
menutab = int(chr(c)) menutab = int(six.int2byte(c))
elif chr(c) == 'q': elif six.int2byte(c) == 'q':
global quit_ global quit_
quit_ = True quit_ = True
elif chr(c) == '\n': elif six.int2byte(c) == '\n':
curses.curs_set(1) curses.curs_set(1)
d = Dialog(dialog="dialog") d = Dialog(dialog="dialog")
if menutab == 1: if menutab == 1:
@ -672,7 +673,7 @@ def handlech(c, stdscr):
elif t == "2" and m is False: elif t == "2" and m is False:
try: try:
mn = config.get(a, "mailinglistname") mn = config.get(a, "mailinglistname")
except ConfigParser.NoOptionError: except configparser.NoOptionError:
mn = "" mn = ""
r, t = d.inputbox("Mailing list name", init=mn) r, t = d.inputbox("Mailing list name", init=mn)
if r == d.DIALOG_OK: if r == d.DIALOG_OK:

View File

@ -3,7 +3,7 @@ Core classes for loading images and converting them to a Texture.
The raw image data can be keep in memory for further access The raw image data can be keep in memory for further access
""" """
import hashlib import hashlib
from io import BytesIO from six import BytesIO
from PIL import Image from PIL import Image
from kivy.core.image import Image as CoreImage from kivy.core.image import Image as CoreImage

View File

@ -6,6 +6,7 @@ import os
import shutil import shutil
import tempfile import tempfile
from time import time, sleep from time import time, sleep
from six.moves import getcwdb
from telenium.tests import TeleniumTestCase from telenium.tests import TeleniumTestCase
from telenium.client import TeleniumHttpException from telenium.client import TeleniumHttpException
@ -32,7 +33,7 @@ def cleanup(files=_files):
class TeleniumTestProcess(TeleniumTestCase): class TeleniumTestProcess(TeleniumTestCase):
"""Setting Screen Functionality Testing""" """Setting Screen Functionality Testing"""
cmd_entrypoint = [os.path.join(os.path.abspath(os.getcwd()), 'src', 'mockbm', 'kivy_main.py')] cmd_entrypoint = [os.path.join(os.path.abspath(getcwdb()), 'src', 'mockbm', 'kivy_main.py')]
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):

View File

@ -14,8 +14,10 @@ import threading
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from sqlite3 import register_adapter from sqlite3 import register_adapter
import six
from six.moves import range as xrange
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.QtNetwork import QLocalSocket, QLocalServer from PyQt4.QtNetwork import QLocalSocket, QLocalServer
@ -469,7 +471,7 @@ class MyForm(settingsmixin.SMainWindow):
# add missing folders # add missing folders
if len(db[toAddress]) > 0: if len(db[toAddress]) > 0:
j = 0 j = 0
for f, c in db[toAddress].iteritems(): for f, c in six.iteritems(db[toAddress]):
try: try:
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count']) subwidget = Ui_FolderWidget(widget, j, toAddress, f, c['count'])
except KeyError: except KeyError:
@ -599,7 +601,7 @@ class MyForm(settingsmixin.SMainWindow):
# add missing folders # add missing folders
if len(db[toAddress]) > 0: if len(db[toAddress]) > 0:
j = 0 j = 0
for f, c in db[toAddress].iteritems(): for f, c in six.iteritems(db[toAddress]):
if toAddress is not None and tab == 'messages' and folder == "new": if toAddress is not None and tab == 'messages' and folder == "new":
continue continue
subwidget = Ui_FolderWidget(widget, j, toAddress, f, c) subwidget = Ui_FolderWidget(widget, j, toAddress, f, c)
@ -1076,15 +1078,15 @@ class MyForm(settingsmixin.SMainWindow):
for i in range(root.childCount()): for i in range(root.childCount()):
addressItem = root.child(i) addressItem = root.child(i)
if addressItem.type == AccountMixin.ALL: if addressItem.type == AccountMixin.ALL:
newCount = sum(totalUnread.itervalues()) newCount = sum(six.itervalues(totalUnread))
self.drawTrayIcon(self.currentTrayIconFileName, newCount) self.drawTrayIcon(self.currentTrayIconFileName, newCount)
else: else:
try: try:
newCount = sum(( newCount = sum(six.itervalues((
broadcastsUnread broadcastsUnread
if addressItem.type == AccountMixin.SUBSCRIPTION if addressItem.type == AccountMixin.SUBSCRIPTION
else normalUnread else normalUnread
)[addressItem.address].itervalues()) )[addressItem.address]))
except KeyError: except KeyError:
newCount = 0 newCount = 0
if newCount != addressItem.unreadCount: if newCount != addressItem.unreadCount:
@ -2872,7 +2874,7 @@ class MyForm(settingsmixin.SMainWindow):
QtCore.QEventLoop.AllEvents, 1000 QtCore.QEventLoop.AllEvents, 1000
) )
self.saveSettings() self.saveSettings()
for attr, obj in self.ui.__dict__.iteritems(): for attr, obj in six.iteritems(self.ui.__dict__):
if hasattr(obj, "__class__") \ if hasattr(obj, "__class__") \
and isinstance(obj, settingsmixin.SettingsMixin): and isinstance(obj, settingsmixin.SettingsMixin):
saveMethod = getattr(obj, "saveSettings", None) saveMethod = getattr(obj, "saveSettings", None)
@ -4210,7 +4212,7 @@ class MyForm(settingsmixin.SMainWindow):
def initSettings(self): def initSettings(self):
self.loadSettings() self.loadSettings()
for attr, obj in self.ui.__dict__.iteritems(): for attr, obj in six.iteritems(self.ui.__dict__):
if hasattr(obj, "__class__") and \ if hasattr(obj, "__class__") and \
isinstance(obj, settingsmixin.SettingsMixin): isinstance(obj, settingsmixin.SettingsMixin):
loadMethod = getattr(obj, "loadSettings", None) loadMethod = getattr(obj, "loadSettings", None)

View File

@ -14,7 +14,7 @@ import re
import sys import sys
import time import time
from ver import ustr from unqstr import ustr
from PyQt4 import QtGui from PyQt4 import QtGui
import queues import queues

View File

@ -5,7 +5,7 @@ Dialogs that work with BM address.
import hashlib import hashlib
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import queues import queues

View File

@ -3,9 +3,9 @@ Address validator module.
""" """
# pylint: disable=too-many-branches,too-many-arguments # pylint: disable=too-many-branches,too-many-arguments
from Queue import Empty from six.moves.queue import Empty
from ver import ustr from unqstr import ustr
from PyQt4 import QtGui from PyQt4 import QtGui
from addresses import decodeAddress, addBMIfNotPresent from addresses import decodeAddress, addBMIfNotPresent

View File

@ -1,4 +1,4 @@
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import widgets import widgets

View File

@ -2,7 +2,7 @@
Custom dialog classes Custom dialog classes
""" """
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
from ver import ustr from unqstr import ustr
from PyQt4 import QtGui from PyQt4 import QtGui
import paths import paths

View File

@ -6,7 +6,7 @@ Folder tree and messagelist widgets definitions.
from cgi import escape from cgi import escape
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from bmconfigparser import config from bmconfigparser import config

View File

@ -5,7 +5,7 @@ zoom and URL click warning popup
""" """
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from .safehtmlparser import SafeHTMLParser from .safehtmlparser import SafeHTMLParser

View File

@ -4,7 +4,7 @@ src/bitmessageqt/newchandialog.py
""" """
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from bitmessageqt import widgets from bitmessageqt import widgets

View File

@ -1,5 +1,6 @@
from os import path from os import path
from ver import ustr from unqstr import ustr
import six
from PyQt4 import QtGui from PyQt4 import QtGui
from debug import logger from debug import logger
from bitmessageqt import widgets from bitmessageqt import widgets
@ -8,7 +9,7 @@ class RetranslateMixin(object):
def retranslateUi(self): def retranslateUi(self):
defaults = QtGui.QWidget() defaults = QtGui.QWidget()
widgets.load(self.__class__.__name__.lower() + '.ui', defaults) widgets.load(self.__class__.__name__.lower() + '.ui', defaults)
for attr, value in defaults.__dict__.iteritems(): for attr, value in six.iteritems(defaults.__dict__):
setTextMethod = getattr(value, "setText", None) setTextMethod = getattr(value, "setText", None)
if callable(setTextMethod): if callable(setTextMethod):
getattr(self, attr).setText(ustr(getattr(defaults, attr).text())) getattr(self, attr).setText(ustr(getattr(defaults, attr).text()))

View File

@ -2,12 +2,11 @@
import inspect import inspect
import re import re
from HTMLParser import HTMLParser from six.moves.html_parser import HTMLParser
from urllib import quote_plus from six.moves.urllib.parse import quote_plus, urlparse
from urlparse import urlparse
from ver import ustr, unic from unqstr import ustr, unic
class SafeHTMLParser(HTMLParser): class SafeHTMLParser(HTMLParser):
"""HTML parser with sanitisation""" """HTML parser with sanitisation"""

View File

@ -1,13 +1,13 @@
""" """
This module setting file is for settings This module setting file is for settings
""" """
import ConfigParser from six.moves import configparser
import os import os
import sys import sys
import tempfile import tempfile
import six import six
from ver import ustr from unqstr import ustr
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import debug import debug
@ -30,9 +30,9 @@ from tr import _translate
def getSOCKSProxyType(config): def getSOCKSProxyType(config):
"""Get user socksproxytype setting from *config*""" """Get user socksproxytype setting from *config*"""
try: try:
result = ConfigParser.SafeConfigParser.get( result = configparser.SafeConfigParser.get(
config, 'bitmessagesettings', 'socksproxytype') config, 'bitmessagesettings', 'socksproxytype')
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): except (configparser.NoSectionError, configparser.NoOptionError):
return None return None
else: else:
if result.lower() in ('', 'none', 'false'): if result.lower() in ('', 'none', 'false'):

View File

@ -5,7 +5,7 @@ src/settingsmixin.py
""" """
from ver import ustr from unqstr import ustr
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui

View File

@ -6,7 +6,7 @@ import ssl
import sys import sys
import time import time
from ver import ustr, unic from unqstr import ustr, unic
from PyQt4 import QtCore from PyQt4 import QtCore
from bitmessageqt import account from bitmessageqt import account

View File

@ -1,6 +1,6 @@
"""Common definitions for bitmessageqt tests""" """Common definitions for bitmessageqt tests"""
import Queue from six.moves import queue as Queue
import sys import sys
import unittest import unittest

View File

@ -6,7 +6,7 @@ from shared import isAddressInMyAddressBook
from .main import TestBase from .main import TestBase
from ver import ustr from unqstr import ustr
class TestSupport(TestBase): class TestSupport(TestBase):

View File

@ -21,7 +21,7 @@ config_ready = Event()
class BMConfigParser(SafeConfigParser): class BMConfigParser(SafeConfigParser):
""" """
Singleton class inherited from :class:`ConfigParser.SafeConfigParser` Singleton class inherited from :class:`configparser.SafeConfigParser`
with additional methods specific to bitmessage config. with additional methods specific to bitmessage config.
""" """
# pylint: disable=too-many-ancestors # pylint: disable=too-many-ancestors

View File

@ -30,6 +30,7 @@ from bmconfigparser import config
from helper_sql import sqlExecute, sqlQuery from helper_sql import sqlExecute, sqlQuery
from network import knownnodes, StoppableThread from network import knownnodes, StoppableThread
from six.moves import configparser, queue from six.moves import configparser, queue
from six.moves.reprlib import repr
def sizeof_fmt(num, suffix='h/s'): def sizeof_fmt(num, suffix='h/s'):

View File

@ -4,9 +4,9 @@ SMTP client thread for delivering emails
# pylint: disable=unused-variable # pylint: disable=unused-variable
import smtplib import smtplib
import urlparse from six.moves.urllib import parse as urlparse
from email.header import Header from email.header import Header
from email.mime.text import MIMEText from six.moves import email_mime_text
import queues import queues
import state import state
@ -55,7 +55,7 @@ class smtpDeliver(StoppableThread):
u = urlparse.urlparse(dest) u = urlparse.urlparse(dest)
to = urlparse.parse_qs(u.query)['to'] to = urlparse.parse_qs(u.query)['to']
client = smtplib.SMTP(u.hostname, u.port) client = smtplib.SMTP(u.hostname, u.port)
msg = MIMEText(body, 'plain', 'utf-8') msg = email_mime_text(body, 'plain', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8') msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = fromAddress + '@' + SMTPDOMAIN msg['From'] = fromAddress + '@' + SMTPDOMAIN
toLabel = map( toLabel = map(

View File

@ -8,6 +8,7 @@ import sqlite3
import sys import sys
import threading import threading
import time import time
from six.moves.reprlib import repr
try: try:
import helper_sql import helper_sql

View File

@ -6,6 +6,7 @@ and suggest how it may be installed
import os import os
import re import re
import sys import sys
import six
# Only really old versions of Python don't have sys.hexversion. We don't # Only really old versions of Python don't have sys.hexversion. We don't
# support them. The logging module was introduced in Python 2.3 # support them. The logging module was introduced in Python 2.3
@ -452,7 +453,7 @@ def check_dependencies(verbose=False, optional=False):
'PyBitmessage requires Python 2.7.4 or greater' 'PyBitmessage requires Python 2.7.4 or greater'
' (but not Python 3+)') ' (but not Python 3+)')
has_all_dependencies = False has_all_dependencies = False
if sys.hexversion >= 0x3000000: if six.PY3:
logger.error( logger.error(
'PyBitmessage does not support Python 3+. Python 2.7.4' 'PyBitmessage does not support Python 3+. Python 2.7.4'
' or greater is required. Python 2.7.18 is recommended.') ' or greater is required. Python 2.7.18 is recommended.')

View File

@ -49,10 +49,11 @@ License: MIT
# pylint: disable=too-many-lines,too-many-branches,too-many-statements,global-statement,too-many-return-statements # pylint: disable=too-many-lines,too-many-branches,too-many-statements,global-statement,too-many-return-statements
# pylint: disable=unused-argument # pylint: disable=unused-argument
import collections from six.moves import collections_abc as collections
import io from six.moves import range as xrange
import struct import struct
import sys import sys
import six
__version__ = "2.4.1" __version__ = "2.4.1"
"Module version string" "Module version string"
@ -99,9 +100,9 @@ class Ext: # pylint: disable=old-style-class
if not isinstance(type, int) or not (type >= 0 and type <= 127): if not isinstance(type, int) or not (type >= 0 and type <= 127):
raise TypeError("ext type out of range") raise TypeError("ext type out of range")
# Check data is type bytes # Check data is type bytes
elif sys.version_info[0] == 3 and not isinstance(data, bytes): elif six.PY3 and not isinstance(data, bytes):
raise TypeError("ext data is not type \'bytes\'") raise TypeError("ext data is not type \'bytes\'")
elif sys.version_info[0] == 2 and not isinstance(data, str): elif six.PY2 and not isinstance(data, str):
raise TypeError("ext data is not type \'str\'") raise TypeError("ext data is not type \'str\'")
self.type = type self.type = type
self.data = data self.data = data
@ -125,7 +126,7 @@ class Ext: # pylint: disable=old-style-class
String representation of this Ext object. String representation of this Ext object.
""" """
s = "Ext Object (Type: 0x%02x, Data: " % self.type s = "Ext Object (Type: 0x%02x, Data: " % self.type
s += " ".join(["0x%02x" % ord(self.data[i:i + 1]) s += " ".join(["0x%02x" % six.byte2int(self.data[i:i + 1])
for i in xrange(min(len(self.data), 8))]) for i in xrange(min(len(self.data), 8))])
if len(self.data) > 8: if len(self.data) > 8:
s += " ..." s += " ..."
@ -549,7 +550,7 @@ def _packb2(obj, **options):
'\x82\xa7compact\xc3\xa6schema\x00' '\x82\xa7compact\xc3\xa6schema\x00'
>>> >>>
""" """
fp = io.BytesIO() fp = six.BytesIO()
_pack2(obj, fp, **options) _pack2(obj, fp, **options)
return fp.getvalue() return fp.getvalue()
@ -582,7 +583,7 @@ def _packb3(obj, **options):
b'\x82\xa7compact\xc3\xa6schema\x00' b'\x82\xa7compact\xc3\xa6schema\x00'
>>> >>>
""" """
fp = io.BytesIO() fp = six.BytesIO()
_pack3(obj, fp, **options) _pack3(obj, fp, **options)
return fp.getvalue() return fp.getvalue()
@ -599,7 +600,7 @@ def _read_except(fp, n):
def _unpack_integer(code, fp, options): def _unpack_integer(code, fp, options):
if (ord(code) & 0xe0) == 0xe0: if (six.byte2int(code) & 0xe0) == 0xe0:
return struct.unpack("b", code)[0] return struct.unpack("b", code)[0]
elif code == b'\xd0': elif code == b'\xd0':
return struct.unpack("b", _read_except(fp, 1))[0] return struct.unpack("b", _read_except(fp, 1))[0]
@ -609,7 +610,7 @@ def _unpack_integer(code, fp, options):
return struct.unpack(">i", _read_except(fp, 4))[0] return struct.unpack(">i", _read_except(fp, 4))[0]
elif code == b'\xd3': elif code == b'\xd3':
return struct.unpack(">q", _read_except(fp, 8))[0] return struct.unpack(">q", _read_except(fp, 8))[0]
elif (ord(code) & 0x80) == 0x00: elif (six.byte2int(code) & 0x80) == 0x00:
return struct.unpack("B", code)[0] return struct.unpack("B", code)[0]
elif code == b'\xcc': elif code == b'\xcc':
return struct.unpack("B", _read_except(fp, 1))[0] return struct.unpack("B", _read_except(fp, 1))[0]
@ -619,21 +620,21 @@ def _unpack_integer(code, fp, options):
return struct.unpack(">I", _read_except(fp, 4))[0] return struct.unpack(">I", _read_except(fp, 4))[0]
elif code == b'\xcf': elif code == b'\xcf':
return struct.unpack(">Q", _read_except(fp, 8))[0] return struct.unpack(">Q", _read_except(fp, 8))[0]
raise Exception("logic error, not int: 0x%02x" % ord(code)) raise Exception("logic error, not int: 0x%02x" % six.byte2int(code))
def _unpack_reserved(code, fp, options): def _unpack_reserved(code, fp, options):
if code == b'\xc1': if code == b'\xc1':
raise ReservedCodeException( raise ReservedCodeException(
"encountered reserved code: 0x%02x" % ord(code)) "encountered reserved code: 0x%02x" % six.byte2int(code))
raise Exception( raise Exception(
"logic error, not reserved code: 0x%02x" % ord(code)) "logic error, not reserved code: 0x%02x" % six.byte2int(code))
def _unpack_nil(code, fp, options): def _unpack_nil(code, fp, options):
if code == b'\xc0': if code == b'\xc0':
return None return None
raise Exception("logic error, not nil: 0x%02x" % ord(code)) raise Exception("logic error, not nil: 0x%02x" % six.byte2int(code))
def _unpack_boolean(code, fp, options): def _unpack_boolean(code, fp, options):
@ -641,7 +642,7 @@ def _unpack_boolean(code, fp, options):
return False return False
elif code == b'\xc3': elif code == b'\xc3':
return True return True
raise Exception("logic error, not boolean: 0x%02x" % ord(code)) raise Exception("logic error, not boolean: 0x%02x" % six.byte2int(code))
def _unpack_float(code, fp, options): def _unpack_float(code, fp, options):
@ -649,12 +650,12 @@ def _unpack_float(code, fp, options):
return struct.unpack(">f", _read_except(fp, 4))[0] return struct.unpack(">f", _read_except(fp, 4))[0]
elif code == b'\xcb': elif code == b'\xcb':
return struct.unpack(">d", _read_except(fp, 8))[0] return struct.unpack(">d", _read_except(fp, 8))[0]
raise Exception("logic error, not float: 0x%02x" % ord(code)) raise Exception("logic error, not float: 0x%02x" % six.byte2int(code))
def _unpack_string(code, fp, options): def _unpack_string(code, fp, options):
if (ord(code) & 0xe0) == 0xa0: if (six.byte2int(code) & 0xe0) == 0xa0:
length = ord(code) & ~0xe0 length = six.byte2int(code) & ~0xe0
elif code == b'\xd9': elif code == b'\xd9':
length = struct.unpack("B", _read_except(fp, 1))[0] length = struct.unpack("B", _read_except(fp, 1))[0]
elif code == b'\xda': elif code == b'\xda':
@ -662,7 +663,7 @@ def _unpack_string(code, fp, options):
elif code == b'\xdb': elif code == b'\xdb':
length = struct.unpack(">I", _read_except(fp, 4))[0] length = struct.unpack(">I", _read_except(fp, 4))[0]
else: else:
raise Exception("logic error, not string: 0x%02x" % ord(code)) raise Exception("logic error, not string: 0x%02x" % six.byte2int(code))
# Always return raw bytes in compatibility mode # Always return raw bytes in compatibility mode
global compatibility global compatibility
@ -686,7 +687,7 @@ def _unpack_binary(code, fp, options):
elif code == b'\xc6': elif code == b'\xc6':
length = struct.unpack(">I", _read_except(fp, 4))[0] length = struct.unpack(">I", _read_except(fp, 4))[0]
else: else:
raise Exception("logic error, not binary: 0x%02x" % ord(code)) raise Exception("logic error, not binary: 0x%02x" % six.byte2int(code))
return _read_except(fp, length) return _read_except(fp, length)
@ -709,9 +710,9 @@ def _unpack_ext(code, fp, options):
elif code == b'\xc9': elif code == b'\xc9':
length = struct.unpack(">I", _read_except(fp, 4))[0] length = struct.unpack(">I", _read_except(fp, 4))[0]
else: else:
raise Exception("logic error, not ext: 0x%02x" % ord(code)) raise Exception("logic error, not ext: 0x%02x" % six.byte2int(code))
ext = Ext(ord(_read_except(fp, 1)), _read_except(fp, length)) ext = Ext(six.byte2int(_read_except(fp, 1)), _read_except(fp, length))
# Unpack with ext handler, if we have one # Unpack with ext handler, if we have one
ext_handlers = options.get("ext_handlers") ext_handlers = options.get("ext_handlers")
@ -722,14 +723,14 @@ def _unpack_ext(code, fp, options):
def _unpack_array(code, fp, options): def _unpack_array(code, fp, options):
if (ord(code) & 0xf0) == 0x90: if (six.byte2int(code) & 0xf0) == 0x90:
length = (ord(code) & ~0xf0) length = (six.byte2int(code) & ~0xf0)
elif code == b'\xdc': elif code == b'\xdc':
length = struct.unpack(">H", _read_except(fp, 2))[0] length = struct.unpack(">H", _read_except(fp, 2))[0]
elif code == b'\xdd': elif code == b'\xdd':
length = struct.unpack(">I", _read_except(fp, 4))[0] length = struct.unpack(">I", _read_except(fp, 4))[0]
else: else:
raise Exception("logic error, not array: 0x%02x" % ord(code)) raise Exception("logic error, not array: 0x%02x" % six.byte2int(code))
return [_unpack(fp, options) for _ in xrange(length)] return [_unpack(fp, options) for _ in xrange(length)]
@ -741,14 +742,14 @@ def _deep_list_to_tuple(obj):
def _unpack_map(code, fp, options): def _unpack_map(code, fp, options):
if (ord(code) & 0xf0) == 0x80: if (six.byte2int(code) & 0xf0) == 0x80:
length = (ord(code) & ~0xf0) length = (six.byte2int(code) & ~0xf0)
elif code == b'\xde': elif code == b'\xde':
length = struct.unpack(">H", _read_except(fp, 2))[0] length = struct.unpack(">H", _read_except(fp, 2))[0]
elif code == b'\xdf': elif code == b'\xdf':
length = struct.unpack(">I", _read_except(fp, 4))[0] length = struct.unpack(">I", _read_except(fp, 4))[0]
else: else:
raise Exception("logic error, not map: 0x%02x" % ord(code)) raise Exception("logic error, not map: 0x%02x" % six.byte2int(code))
d = {} if not options.get('use_ordered_dict') \ d = {} if not options.get('use_ordered_dict') \
else collections.OrderedDict() else collections.OrderedDict()
@ -911,7 +912,7 @@ def _unpackb2(s, **options):
""" """
if not isinstance(s, (str, bytearray)): if not isinstance(s, (str, bytearray)):
raise TypeError("packed data must be type 'str' or 'bytearray'") raise TypeError("packed data must be type 'str' or 'bytearray'")
return _unpack(io.BytesIO(s), options) return _unpack(six.BytesIO(s), options)
# For Python 3, expects a bytes object # For Python 3, expects a bytes object
@ -957,7 +958,7 @@ def _unpackb3(s, **options):
""" """
if not isinstance(s, (bytes, bytearray)): if not isinstance(s, (bytes, bytearray)):
raise TypeError("packed data must be type 'bytes' or 'bytearray'") raise TypeError("packed data must be type 'bytes' or 'bytearray'")
return _unpack(io.BytesIO(s), options) return _unpack(six.BytesIO(s), options)
############################################################################# #############################################################################
# Module Initialization # Module Initialization
@ -990,7 +991,7 @@ def __init():
_float_precision = "single" _float_precision = "single"
# Map packb and unpackb to the appropriate version # Map packb and unpackb to the appropriate version
if sys.version_info[0] == 3: if six.PY3:
pack = _pack3 pack = _pack3
packb = _packb3 packb = _packb3
dump = _pack3 dump = _pack3

View File

@ -3,8 +3,8 @@
import logging import logging
import os import os
import re import re
import sys
import time import time
import six
from six.moves import range from six.moves import range
@ -61,7 +61,7 @@ if not re.search(r'\d', time.strftime(time_format)):
# It seems some systems lie about the encoding they use # It seems some systems lie about the encoding they use
# so we perform comprehensive decoding tests # so we perform comprehensive decoding tests
elif sys.version_info[0] == 2: elif six.PY2:
try: try:
# Check day names # Check day names
for i in range(7): for i in range(7):
@ -118,7 +118,7 @@ def formatTimestamp(timestamp=None):
except ValueError: except ValueError:
timestring = time.strftime(time_format) timestring = time.strftime(time_format)
if sys.version_info[0] == 2: if six.PY2:
return timestring.decode(encoding) return timestring.decode(encoding)
return timestring return timestring

View File

@ -3,7 +3,7 @@ A queue with multiple internal subqueues.
Elements are added into a random subqueue, and retrieval rotates Elements are added into a random subqueue, and retrieval rotates
""" """
from collections import deque from six.moves.collections_abc import deque
from six.moves import queue from six.moves import queue

View File

@ -4,7 +4,7 @@ Namecoin queries
# pylint: disable=too-many-branches,protected-access # pylint: disable=too-many-branches,protected-access
import base64 import base64
import httplib from six.moves import http_client as httplib
import json import json
import os import os
import socket import socket

View File

@ -18,6 +18,7 @@ from errno import (
ENOTCONN, ENOTSOCK, EPIPE, ESHUTDOWN, ETIMEDOUT, EWOULDBLOCK, errorcode ENOTCONN, ENOTSOCK, EPIPE, ESHUTDOWN, ETIMEDOUT, EWOULDBLOCK, errorcode
) )
from threading import current_thread from threading import current_thread
from six.moves.reprlib import repr
import helper_random import helper_random

View File

@ -6,6 +6,7 @@ from collections import namedtuple
from random import choice, expovariate, sample from random import choice, expovariate, sample
from threading import RLock from threading import RLock
from time import time from time import time
import six
from network import connectionpool from network import connectionpool
import state import state
@ -74,7 +75,7 @@ class Dandelion: # pylint: disable=old-style-class
if logger.isEnabledFor(logging.DEBUG): if logger.isEnabledFor(logging.DEBUG):
logger.debug( logger.debug(
'%s entering fluff mode due to %s.', '%s entering fluff mode due to %s.',
''.join('%02x' % ord(i) for i in hashId), reason) ''.join('%02x' % six.byte2int(i) for i in hashId), reason)
with self.lock: with self.lock:
try: try:
del self.hashMap[hashId] del self.hashMap[hashId]
@ -99,12 +100,12 @@ class Dandelion: # pylint: disable=old-style-class
with self.lock: with self.lock:
if len(self.stem) < MAX_STEMS: if len(self.stem) < MAX_STEMS:
self.stem.append(connection) self.stem.append(connection)
for k in (k for k, v in self.nodeMap.iteritems() if v is None): for k in (k for k, v in six.iteritems(self.nodeMap) if v is None):
self.nodeMap[k] = connection self.nodeMap[k] = connection
for k, v in { for k, v in six.iteritems({
k: v for k, v in self.hashMap.iteritems() k: v for k, v in six.iteritems(self.hashMap)
if v.child is None if v.child is None
}.iteritems(): }):
self.hashMap[k] = Stem( self.hashMap[k] = Stem(
connection, v.stream, self.poissonTimeout()) connection, v.stream, self.poissonTimeout())
invQueue.put((v.stream, k, v.child)) invQueue.put((v.stream, k, v.child))
@ -120,14 +121,14 @@ class Dandelion: # pylint: disable=old-style-class
self.stem.remove(connection) self.stem.remove(connection)
# active mappings to pointing to the removed node # active mappings to pointing to the removed node
for k in ( for k in (
k for k, v in self.nodeMap.iteritems() k for k, v in six.iteritems(self.nodeMap)
if v == connection if v == connection
): ):
self.nodeMap[k] = None self.nodeMap[k] = None
for k, v in { for k, v in six.iteritems({
k: v for k, v in self.hashMap.iteritems() k: v for k, v in six.iteritems(self.hashMap)
if v.child == connection if v.child == connection
}.iteritems(): }):
self.hashMap[k] = Stem( self.hashMap[k] = Stem(
None, v.stream, self.poissonTimeout()) None, v.stream, self.poissonTimeout())
@ -168,7 +169,7 @@ class Dandelion: # pylint: disable=old-style-class
with self.lock: with self.lock:
deadline = time() deadline = time()
toDelete = [ toDelete = [
[v.stream, k, v.child] for k, v in self.hashMap.iteritems() [v.stream, k, v.child] for k, v in six.iteritems(self.hashMap)
if v.timeout < deadline if v.timeout < deadline
] ]

View File

@ -3,6 +3,7 @@
""" """
import time import time
import state import state
import six
import addresses import addresses
import helper_random import helper_random
import protocol import protocol
@ -28,7 +29,7 @@ class DownloadThread(StoppableThread):
deadline = time.time() - self.requestExpires deadline = time.time() - self.requestExpires
try: try:
toDelete = [ toDelete = [
k for k, v in missingObjects.iteritems() k for k, v in six.iteritems(missingObjects)
if v < deadline] if v < deadline]
except RuntimeError: except RuntimeError:
pass pass

View File

@ -1,7 +1,7 @@
""" """
Thread to send inv annoucements Thread to send inv annoucements
""" """
import Queue from six.moves import queue as Queue
import random import random
from time import time from time import time

View File

@ -10,10 +10,8 @@ import os
import pickle # nosec B403 import pickle # nosec B403
import threading import threading
import time import time
try: from six.moves.collections_abc import Iterable
from collections.abc import Iterable import six
except ImportError:
from collections import Iterable
import state import state
from bmconfigparser import config from bmconfigparser import config
@ -54,8 +52,8 @@ def json_serialize_knownnodes(output):
Reorganize knownnodes dict and write it as JSON to output Reorganize knownnodes dict and write it as JSON to output
""" """
_serialized = [] _serialized = []
for stream, peers in knownNodes.iteritems(): for stream, peers in six.iteritems(knownNodes):
for peer, info in peers.iteritems(): for peer, info in six.iteritems(peers):
info.update(rating=round(info.get('rating', 0), 2)) info.update(rating=round(info.get('rating', 0), 2))
_serialized.append({ _serialized.append({
'stream': stream, 'peer': peer._asdict(), 'info': info 'stream': stream, 'peer': peer._asdict(), 'info': info
@ -87,7 +85,7 @@ def pickle_deserialize_old_knownnodes(source):
global knownNodes global knownNodes
knownNodes = pickle.load(source) # nosec B301 knownNodes = pickle.load(source) # nosec B301
for stream in knownNodes.keys(): for stream in knownNodes.keys():
for node, params in knownNodes[stream].iteritems(): for node, params in six.iteritems(knownNodes[stream]):
if isinstance(params, (float, int)): if isinstance(params, (float, int)):
addKnownNode(stream, node, params) addKnownNode(stream, node, params)

View File

@ -1,7 +1,7 @@
""" """
Named tuples representing the network peers Named tuples representing the network peers
""" """
import collections from six.moves import collections_abc as collections
Peer = collections.namedtuple('Peer', ['host', 'port']) Peer = collections.namedtuple('Peer', ['host', 'port'])
Node = collections.namedtuple('Node', ['services', 'host', 'port']) Node = collections.namedtuple('Node', ['services', 'host', 'port'])

View File

@ -3,6 +3,7 @@ Module for tracking objects
""" """
import time import time
from threading import RLock from threading import RLock
import six
import state import state
import network.connectionpool # use long name to address recursive import import network.connectionpool # use long name to address recursive import
@ -75,7 +76,7 @@ class ObjectTracker(object):
with self.objectsNewToThemLock: with self.objectsNewToThemLock:
self.objectsNewToThem = { self.objectsNewToThem = {
k: v k: v
for k, v in self.objectsNewToThem.iteritems() for k, v in six.iteritems(self.objectsNewToThem)
if v >= deadline} if v >= deadline}
self.lastCleaned = time.time() self.lastCleaned = time.time()

View File

@ -2,7 +2,7 @@
Process data incoming from network Process data incoming from network
""" """
import errno import errno
import Queue from six.moves import queue as Queue
import socket import socket
from network import connectionpool from network import connectionpool

View File

@ -5,6 +5,7 @@ SOCKS4a proxy module
import logging import logging
import socket import socket
import struct import struct
import six
from .proxy import GeneralProxyError, Proxy, ProxyError from .proxy import GeneralProxyError, Proxy, ProxyError
@ -39,16 +40,16 @@ class Socks4a(Proxy):
def state_pre_connect(self): def state_pre_connect(self):
"""Handle feedback from SOCKS4a while it is connecting on our behalf""" """Handle feedback from SOCKS4a while it is connecting on our behalf"""
# Get the response # Get the response
if self.read_buf[0:1] != chr(0x00).encode(): if self.read_buf[0:1] != six.int2byte(0x00).encode():
# bad data # bad data
self.close() self.close()
raise GeneralProxyError(1) raise GeneralProxyError(1)
elif self.read_buf[1:2] != chr(0x5A).encode(): elif self.read_buf[1:2] != six.int2byte(0x5A).encode():
# Connection failed # Connection failed
self.close() self.close()
if ord(self.read_buf[1:2]) in (91, 92, 93): if six.byte2int(self.read_buf[1:2]) in (91, 92, 93):
# socks 4 error # socks 4 error
raise Socks4aError(ord(self.read_buf[1:2]) - 90) raise Socks4aError(six.byte2int(self.read_buf[1:2]) - 90)
else: else:
raise Socks4aError(4) raise Socks4aError(4)
# Get the bound address/port # Get the bound address/port
@ -102,9 +103,9 @@ class Socks4aConnection(Socks4a):
self.append_write_buf(self.ipaddr) self.append_write_buf(self.ipaddr)
if self._auth: if self._auth:
self.append_write_buf(self._auth[0]) self.append_write_buf(self._auth[0])
self.append_write_buf(chr(0x00).encode()) self.append_write_buf(six.int2byte(0x00).encode())
if rmtrslv: if rmtrslv:
self.append_write_buf(self.destination[0] + chr(0x00).encode()) self.append_write_buf(self.destination[0] + six.int2byte(0x00).encode())
self.set_state("pre_connect", length=0, expectBytes=8) self.set_state("pre_connect", length=0, expectBytes=8)
return True return True
@ -132,8 +133,8 @@ class Socks4aResolver(Socks4a):
self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01)) self.append_write_buf(struct.pack("BBBB", 0x00, 0x00, 0x00, 0x01))
if self._auth: if self._auth:
self.append_write_buf(self._auth[0]) self.append_write_buf(self._auth[0])
self.append_write_buf(chr(0x00).encode()) self.append_write_buf(six.int2byte(0x00).encode())
self.append_write_buf(self.host + chr(0x00).encode()) self.append_write_buf(self.host + six.int2byte(0x00).encode())
self.set_state("pre_connect", length=0, expectBytes=8) self.set_state("pre_connect", length=0, expectBytes=8)
return True return True

View File

@ -6,6 +6,7 @@ SOCKS5 proxy module
import logging import logging
import socket import socket
import struct import struct
import six
from .node import Peer from .node import Peer
from .proxy import GeneralProxyError, Proxy, ProxyError from .proxy import GeneralProxyError, Proxy, ProxyError
@ -97,20 +98,20 @@ class Socks5(Proxy):
def state_pre_connect(self): def state_pre_connect(self):
"""Handle feedback from socks5 while it is connecting on our behalf.""" """Handle feedback from socks5 while it is connecting on our behalf."""
# Get the response # Get the response
if self.read_buf[0:1] != chr(0x05).encode(): if self.read_buf[0:1] != six.int2byte(0x05).encode():
self.close() self.close()
raise GeneralProxyError(1) raise GeneralProxyError(1)
elif self.read_buf[1:2] != chr(0x00).encode(): elif self.read_buf[1:2] != six.int2byte(0x00).encode():
# Connection failed # Connection failed
self.close() self.close()
if ord(self.read_buf[1:2]) <= 8: if six.byte2int(self.read_buf[1:2]) <= 8:
raise Socks5Error(ord(self.read_buf[1:2])) raise Socks5Error(six.byte2int(self.read_buf[1:2]))
else: else:
raise Socks5Error(9) raise Socks5Error(9)
# Get the bound address/port # Get the bound address/port
elif self.read_buf[3:4] == chr(0x01).encode(): elif self.read_buf[3:4] == six.int2byte(0x01).encode():
self.set_state("proxy_addr_1", length=4, expectBytes=4) self.set_state("proxy_addr_1", length=4, expectBytes=4)
elif self.read_buf[3:4] == chr(0x03).encode(): elif self.read_buf[3:4] == six.int2byte(0x03).encode():
self.set_state("proxy_addr_2_1", length=4, expectBytes=1) self.set_state("proxy_addr_2_1", length=4, expectBytes=1)
else: else:
self.close() self.close()
@ -129,7 +130,7 @@ class Socks5(Proxy):
(e.g. IPv6, onion, ...). This is part 1 which retrieves the (e.g. IPv6, onion, ...). This is part 1 which retrieves the
length of the data. length of the data.
""" """
self.address_length = ord(self.read_buf[0:1]) self.address_length = six.byte2int(self.read_buf[0:1])
self.set_state( self.set_state(
"proxy_addr_2_2", length=1, expectBytes=self.address_length) "proxy_addr_2_2", length=1, expectBytes=self.address_length)
return True return True
@ -171,19 +172,19 @@ class Socks5Connection(Socks5):
# use the IPv4 address request even if remote resolving was specified. # use the IPv4 address request even if remote resolving was specified.
try: try:
self.ipaddr = socket.inet_aton(self.destination[0]) self.ipaddr = socket.inet_aton(self.destination[0])
self.append_write_buf(chr(0x01).encode() + self.ipaddr) self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr)
except socket.error: # may be IPv6! except socket.error: # may be IPv6!
# Well it's not an IP number, so it's probably a DNS name. # Well it's not an IP number, so it's probably a DNS name.
if self._remote_dns: if self._remote_dns:
# Resolve remotely # Resolve remotely
self.ipaddr = None self.ipaddr = None
self.append_write_buf(chr(0x03).encode() + chr( self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte(
len(self.destination[0])).encode() + self.destination[0]) len(self.destination[0])).encode() + self.destination[0])
else: else:
# Resolve locally # Resolve locally
self.ipaddr = socket.inet_aton( self.ipaddr = socket.inet_aton(
socket.gethostbyname(self.destination[0])) socket.gethostbyname(self.destination[0]))
self.append_write_buf(chr(0x01).encode() + self.ipaddr) self.append_write_buf(six.int2byte(0x01).encode() + self.ipaddr)
self.append_write_buf(struct.pack(">H", self.destination[1])) self.append_write_buf(struct.pack(">H", self.destination[1]))
self.set_state("pre_connect", length=0, expectBytes=4) self.set_state("pre_connect", length=0, expectBytes=4)
return True return True
@ -208,7 +209,7 @@ class Socks5Resolver(Socks5):
"""Perform resolving""" """Perform resolving"""
# Now we can request the actual connection # Now we can request the actual connection
self.append_write_buf(struct.pack('BBB', 0x05, 0xF0, 0x00)) self.append_write_buf(struct.pack('BBB', 0x05, 0xF0, 0x00))
self.append_write_buf(chr(0x03).encode() + chr( self.append_write_buf(six.int2byte(0x03).encode() + six.int2byte(
len(self.host)).encode() + str(self.host)) len(self.host)).encode() + str(self.host))
self.append_write_buf(struct.pack(">H", self.port)) self.append_write_buf(struct.pack(">H", self.port))
self.set_state("pre_connect", length=0, expectBytes=4) self.set_state("pre_connect", length=0, expectBytes=4)

View File

@ -8,6 +8,7 @@ import math
import random import random
import socket import socket
import time import time
import six
# magic imports! # magic imports!
import addresses import addresses
@ -191,7 +192,7 @@ class TCPConnection(BMProto, TLSDispatcher):
# only if more recent than 3 hours # only if more recent than 3 hours
# and having positive or neutral rating # and having positive or neutral rating
filtered = [ filtered = [
(k, v) for k, v in nodes.iteritems() (k, v) for k, v in six.iteritems(nodes)
if v["lastseen"] > int(time.time()) if v["lastseen"] > int(time.time())
- maximumAgeOfNodesThatIAdvertiseToOthers - maximumAgeOfNodesThatIAdvertiseToOthers
and v["rating"] >= 0 and not k.host.endswith('.onion') and v["rating"] >= 0 and not k.host.endswith('.onion')

View File

@ -3,7 +3,7 @@
A menu plugin showing QR-Code for bitmessage address in modal dialog. A menu plugin showing QR-Code for bitmessage address in modal dialog.
""" """
import urllib from six.moves.urllib.parse import urlencode
import qrcode import qrcode
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -93,7 +93,7 @@ def connect_plugin(form):
return return
dialog.render( dialog.render(
'bitmessage:%s' % account.address + ( 'bitmessage:%s' % account.address + (
'?' + urllib.urlencode({'label': label.encode('utf-8')}) '?' + urlencode({'label': label.encode('utf-8')})
if label != account.address else '') if label != account.address else '')
) )
dialog.exec_() dialog.exec_()

View File

@ -12,6 +12,7 @@ import sys
import time import time
from binascii import hexlify from binascii import hexlify
from struct import Struct, pack, unpack from struct import Struct, pack, unpack
import six
import defaults import defaults
import highlevelcrypto import highlevelcrypto
@ -227,7 +228,7 @@ def checkIPv6Address(host, hostStandardFormat, private=False):
logger.debug('Ignoring loopback address: %s', hostStandardFormat) logger.debug('Ignoring loopback address: %s', hostStandardFormat)
return False return False
try: try:
host = [ord(c) for c in host[:2]] host = [six.byte2int(c) for c in host[:2]]
except TypeError: # python3 has ints already except TypeError: # python3 has ints already
pass pass
if host[0] == 0xfe and host[1] & 0xc0 == 0x80: if host[0] == 0xfe and host[1] & 0xc0 == 0x80:

View File

@ -3,6 +3,7 @@ Arithmetic Expressions
""" """
import hashlib import hashlib
import re import re
import six
P = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 P = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1
A = 0 A = 0
@ -34,7 +35,7 @@ def get_code_string(base):
return b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' return b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
if base == 256: if base == 256:
try: try:
return b''.join([chr(x) for x in range(256)]) return b''.join([six.int2byte(x) for x in range(256)])
except TypeError: except TypeError:
return bytes([x for x in range(256)]) return bytes([x for x in range(256)])

View File

@ -4,6 +4,8 @@ Wrappers for hash functions from OpenSSL.
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
# See LICENSE for details. # See LICENSE for details.
import six
from .openssl import OpenSSL from .openssl import OpenSSL
@ -22,7 +24,7 @@ def _equals_str(a, b):
return False return False
result = 0 result = 0
for x, y in zip(a, b): for x, y in zip(a, b):
result |= ord(x) ^ ord(y) result |= six.byte2int(x) ^ six.byte2int(y)
return result == 0 return result == 0

View File

@ -8,6 +8,7 @@ needed openssl functionality in class _OpenSSL.
""" """
import ctypes import ctypes
import sys import sys
import six
# pylint: disable=protected-access # pylint: disable=protected-access
@ -691,7 +692,7 @@ class _OpenSSL(object):
length = self.BN_num_bytes(x) length = self.BN_num_bytes(x)
data = self.malloc(0, length) data = self.malloc(0, length)
OpenSSL.BN_bn2bin(x, data) OpenSSL.BN_bn2bin(x, data)
return ord(data[length - 1]) & 1 return six.byte2int(data[length - 1]) & 1
def get_cipher(self, name): def get_cipher(self, name):
""" """
@ -745,7 +746,7 @@ class _OpenSSL(object):
""" """
buffer_ = None buffer_ = None
if data != 0: if data != 0:
if sys.version_info.major == 3 and isinstance(data, type('')): if six.PY3 and isinstance(data, type('')):
data = data.encode() data = data.encode()
buffer_ = self.create_string_buffer(data, size) buffer_ = self.create_string_buffer(data, size)
else: else:

View File

@ -14,6 +14,7 @@ import stat
import subprocess # nosec B404 import subprocess # nosec B404
import sys import sys
from binascii import hexlify from binascii import hexlify
from six.moves.reprlib import repr
# Project imports. # Project imports.
import highlevelcrypto import highlevelcrypto

View File

@ -4,10 +4,7 @@ Storing inventory items
from abc import abstractmethod from abc import abstractmethod
from collections import namedtuple from collections import namedtuple
try: from six.moves.collections_abc import MutableMapping # pylint: disable=deprecated-class
from collections import MutableMapping # pylint: disable=deprecated-class
except ImportError:
from collections.abc import MutableMapping
InventoryItem = namedtuple('InventoryItem', 'type stream payload expires tag') InventoryItem = namedtuple('InventoryItem', 'type stream payload expires tag')

View File

@ -1,7 +1,7 @@
import os import os
import sys
import time import time
import unittest import unittest
import six
_files = ( _files = (
@ -33,7 +33,7 @@ def checkup():
def skip_python3(): def skip_python3():
"""Raise unittest.SkipTest() if detected python3""" """Raise unittest.SkipTest() if detected python3"""
if sys.hexversion >= 0x3000000: if six.PY3:
raise unittest.SkipTest('Module is not ported to python3') raise unittest.SkipTest('Module is not ported to python3')

View File

@ -6,7 +6,7 @@ Tests for core and those that do not work outside
import atexit import atexit
import os import os
import pickle # nosec import pickle # nosec
import Queue from six.moves import queue as Queue
import random # nosec import random # nosec
import shutil import shutil
import socket import socket
@ -15,6 +15,7 @@ import sys
import threading import threading
import time import time
import unittest import unittest
import six
import protocol import protocol
import state import state
@ -137,8 +138,8 @@ class TestCore(unittest.TestCase):
@staticmethod @staticmethod
def _outdate_knownnodes(): def _outdate_knownnodes():
with knownnodes.knownNodesLock: with knownnodes.knownNodesLock:
for nodes in knownnodes.knownNodes.itervalues(): for nodes in six.itervalues(knownnodes.knownNodes):
for node in nodes.itervalues(): for node in six.itervalues(nodes):
node['lastseen'] -= 2419205 # older than 28 days node['lastseen'] -= 2419205 # older than 28 days
def test_knownnodes_pickle(self): def test_knownnodes_pickle(self):
@ -146,9 +147,9 @@ class TestCore(unittest.TestCase):
pickle_knownnodes() pickle_knownnodes()
self._wipe_knownnodes() self._wipe_knownnodes()
knownnodes.readKnownNodes() knownnodes.readKnownNodes()
for nodes in knownnodes.knownNodes.itervalues(): for nodes in six.itervalues(knownnodes.knownNodes):
self_count = n = 0 self_count = n = 0
for n, node in enumerate(nodes.itervalues()): for n, node in enumerate(six.itervalues(nodes)):
if node.get('self'): if node.get('self'):
self_count += 1 self_count += 1
self.assertEqual(n - self_count, 2) self.assertEqual(n - self_count, 2)
@ -202,7 +203,7 @@ class TestCore(unittest.TestCase):
while c > 0: while c > 0:
time.sleep(1) time.sleep(1)
c -= 2 c -= 2
for peer, con in connectionpool.pool.outboundConnections.iteritems(): for peer, con in six.iteritems(connectionpool.pool.outboundConnections):
if ( if (
peer.host.startswith('bootstrap') peer.host.startswith('bootstrap')
or peer.host == 'quzwelsuziwqgpt2.onion' or peer.host == 'quzwelsuziwqgpt2.onion'
@ -223,7 +224,7 @@ class TestCore(unittest.TestCase):
'Failed to connect during %.2f sec' % (time.time() - _started)) 'Failed to connect during %.2f sec' % (time.time() - _started))
def _check_knownnodes(self): def _check_knownnodes(self):
for stream in knownnodes.knownNodes.itervalues(): for stream in six.itervalues(knownnodes.knownNodes):
for peer in stream: for peer in stream:
if peer.host.startswith('bootstrap'): if peer.host.startswith('bootstrap'):
self.fail( self.fail(

View File

@ -3,6 +3,7 @@
import os import os
import sys import sys
import unittest import unittest
import six
from pybitmessage import pathmagic from pybitmessage import pathmagic
@ -22,7 +23,7 @@ class TestPartialRun(unittest.TestCase):
import state import state
from debug import logger # noqa:F401 pylint: disable=unused-variable from debug import logger # noqa:F401 pylint: disable=unused-variable
if sys.hexversion >= 0x3000000: if six.PY3:
# pylint: disable=no-name-in-module,relative-import # pylint: disable=no-name-in-module,relative-import
from mockbm import network as network_mock from mockbm import network as network_mock
import network import network

View File

@ -3,6 +3,7 @@
from binascii import unhexlify from binascii import unhexlify
from six.moves import queue from six.moves import queue
import six
from .partial import TestPartialRun from .partial import TestPartialRun
from .samples import ( from .samples import (
@ -91,8 +92,8 @@ class TestAddressGenerator(TestPartialRun):
self.command_queue.put(( self.command_queue.put((
'createRandomAddress', 4, 1, 'test_random', 1, '', False, 0, 0)) 'createRandomAddress', 4, 1, 'test_random', 1, '', False, 0, 0))
addr = self.return_queue.get() addr = self.return_queue.get()
self.assertRegexpMatches(addr, r'^BM-') six.assertRegex(self, addr, r'^BM-')
self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$') six.assertRegex(self, addr[3:], r'[a-zA-Z1-9]+$')
self.assertLessEqual(len(addr[3:]), 40) self.assertLessEqual(len(addr[3:]), 40)
self.assertEqual( self.assertEqual(

View File

@ -8,6 +8,7 @@ import time
from binascii import hexlify from binascii import hexlify
from six.moves import xmlrpc_client # nosec from six.moves import xmlrpc_client # nosec
import six
import psutil import psutil
@ -174,28 +175,28 @@ class TestAPI(TestAPIProto):
self.assertEqual( self.assertEqual(
self.api.getDeterministicAddress(self._seed, 3, 1), self.api.getDeterministicAddress(self._seed, 3, 1),
sample_deterministic_addr3) sample_deterministic_addr3)
self.assertRegexpMatches( six.assertRegex(self,
self.api.getDeterministicAddress(self._seed, 2, 1), self.api.getDeterministicAddress(self._seed, 2, 1),
r'^API Error 0002:') r'^API Error 0002:')
# This is here until the streams will be implemented # This is here until the streams will be implemented
self.assertRegexpMatches( six.assertRegex(self,
self.api.getDeterministicAddress(self._seed, 3, 2), self.api.getDeterministicAddress(self._seed, 3, 2),
r'API Error 0003:') r'API Error 0003:')
self.assertRegexpMatches( six.assertRegex(self,
self.api.createDeterministicAddresses(self._seed, 1, 4, 2), self.api.createDeterministicAddresses(self._seed, 1, 4, 2),
r'API Error 0003:') r'API Error 0003:')
self.assertRegexpMatches( six.assertRegex(self,
self.api.createDeterministicAddresses('', 1), self.api.createDeterministicAddresses('', 1),
r'API Error 0001:') r'API Error 0001:')
self.assertRegexpMatches( six.assertRegex(self,
self.api.createDeterministicAddresses(self._seed, 1, 2), self.api.createDeterministicAddresses(self._seed, 1, 2),
r'API Error 0002:') r'API Error 0002:')
self.assertRegexpMatches( six.assertRegex(self,
self.api.createDeterministicAddresses(self._seed, 0), self.api.createDeterministicAddresses(self._seed, 0),
r'API Error 0004:') r'API Error 0004:')
self.assertRegexpMatches( six.assertRegex(self,
self.api.createDeterministicAddresses(self._seed, 1000), self.api.createDeterministicAddresses(self._seed, 1000),
r'API Error 0005:') r'API Error 0005:')
@ -210,8 +211,8 @@ class TestAPI(TestAPIProto):
def test_create_random_address(self): def test_create_random_address(self):
"""API command 'createRandomAddress': basic BM-address validation""" """API command 'createRandomAddress': basic BM-address validation"""
addr = self._add_random_address('random_1') addr = self._add_random_address('random_1')
self.assertRegexpMatches(addr, r'^BM-') six.assertRegex(self, addr, r'^BM-')
self.assertRegexpMatches(addr[3:], r'[a-zA-Z1-9]+$') six.assertRegex(self, addr[3:], r'[a-zA-Z1-9]+$')
# Whitepaper says "around 36 character" # Whitepaper says "around 36 character"
self.assertLessEqual(len(addr[3:]), 40) self.assertLessEqual(len(addr[3:]), 40)
self.assertEqual(self.api.deleteAddress(addr), 'success') self.assertEqual(self.api.deleteAddress(addr), 'success')
@ -242,7 +243,7 @@ class TestAPI(TestAPIProto):
msg_subject = base64.encodestring('test_subject') msg_subject = base64.encodestring('test_subject')
result = self.api.sendMessage( result = self.api.sendMessage(
sample_deterministic_addr4, addr, msg_subject, msg) sample_deterministic_addr4, addr, msg_subject, msg)
self.assertNotRegexpMatches(result, r'^API Error') six.assertNotRegex(self, result, r'^API Error')
self.api.deleteAddress(addr) self.api.deleteAddress(addr)
# Remove known address # Remove known address
self.api.deleteAddressBookEntry(sample_deterministic_addr4) self.api.deleteAddressBookEntry(sample_deterministic_addr4)
@ -411,7 +412,7 @@ class TestAPI(TestAPIProto):
self.assertEqual(self.api.enableAddress(addr, False), 'success') self.assertEqual(self.api.enableAddress(addr, False), 'success')
result = self.api.sendBroadcast( result = self.api.sendBroadcast(
addr, base64.encodestring('test_subject'), msg) addr, base64.encodestring('test_subject'), msg)
self.assertRegexpMatches(result, r'^API Error 0014:') six.assertRegex(self, result, r'^API Error 0014:')
finally: finally:
self.assertEqual(self.api.deleteAddress(addr), 'success') self.assertEqual(self.api.deleteAddress(addr), 'success')
@ -420,7 +421,7 @@ class TestAPI(TestAPIProto):
result = self.api.sendBroadcast( result = self.api.sendBroadcast(
'BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw', 'BM-GtovgYdgs7qXPkoYaRgrLFuFKz1SFpsw',
base64.encodestring('test_subject'), msg) base64.encodestring('test_subject'), msg)
self.assertRegexpMatches(result, r'^API Error 0013:') six.assertRegex(self, result, r'^API Error 0013:')
def test_chan(self): def test_chan(self):
"""Testing chan creation/joining""" """Testing chan creation/joining"""
@ -435,7 +436,7 @@ class TestAPI(TestAPIProto):
self.assertEqual(self.api.joinChan(self._seed, addr), 'success') self.assertEqual(self.api.joinChan(self._seed, addr), 'success')
self.assertEqual(self.api.leaveChan(addr), 'success') self.assertEqual(self.api.leaveChan(addr), 'success')
# Joining with wrong address should fail # Joining with wrong address should fail
self.assertRegexpMatches( six.assertRegex(self,
self.api.joinChan(self._seed, 'BM-2cWzSnwjJ7yRP3nLEW'), self.api.joinChan(self._seed, 'BM-2cWzSnwjJ7yRP3nLEW'),
r'^API Error 0008:' r'^API Error 0008:'
) )

View File

@ -1,9 +1,9 @@
"""TestAPIThread class definition""" """TestAPIThread class definition"""
import sys
import time import time
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from struct import pack from struct import pack
import six
from six.moves import queue, xmlrpc_client from six.moves import queue, xmlrpc_client
@ -68,7 +68,7 @@ class TestAPIThread(TestPartialRun):
def test_client_status(self): def test_client_status(self):
"""Ensure the reply of clientStatus corresponds to mock""" """Ensure the reply of clientStatus corresponds to mock"""
status = self.api.clientStatus() status = self.api.clientStatus()
if sys.hexversion >= 0x3000000: if six.PY3:
self.assertEqual(status["networkConnections"], 4) self.assertEqual(status["networkConnections"], 4)
self.assertEqual(status["pendingDownload"], 0) self.assertEqual(status["pendingDownload"], 0)

View File

@ -6,6 +6,7 @@ import struct
import tempfile import tempfile
import time import time
import unittest import unittest
import six
from pybitmessage import highlevelcrypto from pybitmessage import highlevelcrypto
from pybitmessage.storage import storage from pybitmessage.storage import storage
@ -50,7 +51,7 @@ class TestStorageAbstract(unittest.TestCase):
def test_inventory_storage(self): def test_inventory_storage(self):
"""Check inherited abstract methods""" """Check inherited abstract methods"""
with self.assertRaisesRegexp( with six.assertRaisesRegex(self,
TypeError, "^Can't instantiate abstract class.*" TypeError, "^Can't instantiate abstract class.*"
"methods __contains__, __delitem__, __getitem__, __iter__," "methods __contains__, __delitem__, __getitem__, __iter__,"
" __len__, __setitem__" " __len__, __setitem__"

View File

@ -1,9 +1,9 @@
"""Tests for l10n module""" """Tests for l10n module"""
import re import re
import sys
import time import time
import unittest import unittest
import six
from pybitmessage import l10n from pybitmessage import l10n
@ -16,7 +16,7 @@ class TestL10n(unittest.TestCase):
self.assertFalse(re.search(r'\d', time.strftime("wrong"))) self.assertFalse(re.search(r'\d', time.strftime("wrong")))
timestring_type = type(time.strftime(l10n.DEFAULT_TIME_FORMAT)) timestring_type = type(time.strftime(l10n.DEFAULT_TIME_FORMAT))
self.assertEqual(timestring_type, str) self.assertEqual(timestring_type, str)
if sys.version_info[0] == 2: if six.PY2:
self.assertEqual(timestring_type, bytes) self.assertEqual(timestring_type, bytes)
def test_getWindowsLocale(self): def test_getWindowsLocale(self):

View File

@ -1,8 +1,8 @@
"""Tests for logging""" """Tests for logging"""
import subprocess import subprocess
import sys
import unittest import unittest
import six
from pybitmessage import proofofwork from pybitmessage import proofofwork
@ -11,7 +11,7 @@ class TestLog(unittest.TestCase):
"""A test case for logging""" """A test case for logging"""
@unittest.skipIf( @unittest.skipIf(
sys.hexversion < 0x3000000, 'assertLogs is new in version 3.4') six.PY2, 'assertLogs is new in version 3.4')
def test_LogOutput(self): def test_LogOutput(self):
"""Use proofofwork.LogOutput to log output of a shell command""" """Use proofofwork.LogOutput to log output of a shell command"""
with self.assertLogs('default') as cm: # pylint: disable=no-member with self.assertLogs('default') as cm: # pylint: disable=no-member

View File

@ -4,6 +4,7 @@ Testing the logger configuration
import os import os
import tempfile import tempfile
import six
from .test_process import TestProcessProto from .test_process import TestProcessProto
@ -52,5 +53,5 @@ handlers=default
self._stop_process() self._stop_process()
data = open(self.log_file).read() data = open(self.log_file).read()
self.assertRegexpMatches(data, self.pattern) six.assertRegex(self, data, self.pattern)
self.assertRegexpMatches(data, 'Loaded logger configuration') six.assertRegex(self, data, 'Loaded logger configuration')

View File

@ -2,8 +2,8 @@
Tests for common protocol functions Tests for common protocol functions
""" """
import sys
import unittest import unittest
import six
from pybitmessage import protocol, state from pybitmessage import protocol, state
from pybitmessage.helper_startup import fixSocket from pybitmessage.helper_startup import fixSocket
@ -79,7 +79,7 @@ class TestProtocol(TestSocketInet):
self.assertEqual(protocol.checkIPAddress(globalhost), '8.8.8.8') self.assertEqual(protocol.checkIPAddress(globalhost), '8.8.8.8')
@unittest.skipIf( @unittest.skipIf(
sys.hexversion >= 0x3000000, 'this is still not working with python3') six.PY3, 'this is still not working with python3')
def test_check_local_socks(self): def test_check_local_socks(self):
"""The SOCKS part of the local check""" """The SOCKS part of the local check"""
self.assertTrue( self.assertTrue(

View File

@ -3,6 +3,7 @@ Tests for RandomTrackingDict Class
""" """
import random import random
import unittest import unittest
import six
from time import time from time import time
@ -17,7 +18,7 @@ class TestRandomTrackingDict(unittest.TestCase):
"""helper function for tests, generates a random string""" """helper function for tests, generates a random string"""
retval = '' retval = ''
for _ in range(32): for _ in range(32):
retval += chr(random.randint(0, 255)) retval += six.int2byte(random.randint(0, 255))
return retval return retval
def test_check_randomtrackingdict(self): def test_check_randomtrackingdict(self):

View File

@ -3,7 +3,7 @@ Translating text
""" """
import os import os
from ver import ustr from unqstr import ustr
try: try:
import state import state

View File

@ -1,30 +1,21 @@
import sys import sys
import six
if not hasattr(sys, "hexversion"):
sys.exit("Python version: {0}\n"
"PyBitmessage requires Python 2.7.4 or greater"
.format(sys.version))
if sys.hexversion < 0x3000000:
VER = 2
else:
VER = 3
def ustr(v): def ustr(v):
if VER == 3: if six.PY3:
if isinstance(v, str): if isinstance(v, str):
return v return v
else: else:
return str(v) return str(v)
# assume VER == 2 # assume six.PY2
if isinstance(v, unicode): if isinstance(v, unicode):
return v.encode("utf-8", "replace") return v.encode("utf-8", "replace")
return str(v) return str(v)
def unic(v): def unic(v):
if VER == 3: if six.PY3:
return v return v
# assume VER == 2 # assume six.PY2
if isinstance(v, unicode): if isinstance(v, unicode):
return v return v
return unicode(v, "utf-8", "replace") return unicode(v, "utf-8", "replace")

View File

@ -4,13 +4,13 @@ Complete UPnP port forwarding implementation in separate thread.
Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port Reference: http://mattscodecave.com/posts/using-python-and-upnp-to-forward-a-port
""" """
import httplib from six.moves import http_client as httplib
import re import re
import socket import socket
import time import time
import urllib2 from six.moves.urllib.request import urlopen
from random import randint from random import randint
from urlparse import urlparse from six.moves.urllib.parse import urlparse
from xml.dom.minidom import Document # nosec B408 from xml.dom.minidom import Document # nosec B408
from defusedxml.minidom import parseString from defusedxml.minidom import parseString
@ -108,7 +108,7 @@ class Router: # pylint: disable=old-style-class
logger.error("UPnP: missing location header") logger.error("UPnP: missing location header")
# get the profile xml file and read it into a variable # get the profile xml file and read it into a variable
directory = urllib2.urlopen(header['location']).read() directory = urlopen(header['location']).read()
# create a DOM object that represents the `directory` document # create a DOM object that represents the `directory` document
dom = parseString(directory) dom = parseString(directory)

View File

@ -3,11 +3,12 @@
import random # noseq import random # noseq
import sys import sys
import unittest import unittest
import six
def unittest_discover(): def unittest_discover():
"""Explicit test suite creation""" """Explicit test suite creation"""
if sys.hexversion >= 0x3000000: if six.PY3:
from pybitmessage import pathmagic from pybitmessage import pathmagic
pathmagic.setup() pathmagic.setup()
loader = unittest.defaultTestLoader loader = unittest.defaultTestLoader