Enforce pycodestyle in lib/

This commit is contained in:
Neil Booth 2018-06-10 19:04:07 +09:00
parent 46adf543fc
commit 23e484b1d9
5 changed files with 79 additions and 45 deletions

View File

@ -28,7 +28,7 @@ install:
# command to run tests # command to run tests
script: script:
- pytest --cov=server --cov=lib --cov=wallet - pytest --cov=server --cov=lib --cov=wallet
- pycodestyle server/*.py - pycodestyle server/*.py lib/*.py
# Dont report coverage from nightly # Dont report coverage from nightly
after_success: after_success:
- if [[ $(python3 -V 2>&1) == *"Python 3.6"* ]]; then - if [[ $(python3 -V 2>&1) == *"Python 3.6"* ]]; then

View File

@ -60,7 +60,7 @@ class Coin(object):
REORG_LIMIT = 200 REORG_LIMIT = 200
# Not sure if these are coin-specific # Not sure if these are coin-specific
RPC_URL_REGEX = re.compile('.+@(\[[0-9a-fA-F:]+\]|[^:]+)(:[0-9]+)?') RPC_URL_REGEX = re.compile('.+@(\\[[0-9a-fA-F:]+\\]|[^:]+)(:[0-9]+)?')
VALUE_PER_COIN = 100000000 VALUE_PER_COIN = 100000000
CHUNK_SIZE = 2016 CHUNK_SIZE = 2016
BASIC_HEADER_SIZE = 80 BASIC_HEADER_SIZE = 80
@ -260,8 +260,8 @@ class Coin(object):
@classmethod @classmethod
def static_header_len(cls, height): def static_header_len(cls, height):
'''Given a header height return its length.''' '''Given a header height return its length.'''
return cls.static_header_offset(height + 1) \ return (cls.static_header_offset(height + 1)
- cls.static_header_offset(height) - cls.static_header_offset(height))
@classmethod @classmethod
def block_header(cls, block, height): def block_header(cls, block, height):
@ -318,7 +318,7 @@ class AuxPowMixin(object):
class EquihashMixin(object): class EquihashMixin(object):
STATIC_BLOCK_HEADERS = False STATIC_BLOCK_HEADERS = False
BASIC_HEADER_SIZE = 140 # Excluding Equihash solution BASIC_HEADER_SIZE = 140 # Excluding Equihash solution
DESERIALIZER = lib_tx.DeserializerEquihash DESERIALIZER = lib_tx.DeserializerEquihash
@classmethod @classmethod
@ -383,6 +383,7 @@ class BitcoinMixin(object):
'4ff763ae46a2a6c172b3f1b60a8ce26f') '4ff763ae46a2a6c172b3f1b60a8ce26f')
RPC_PORT = 8332 RPC_PORT = 8332
class HOdlcoin(Coin): class HOdlcoin(Coin):
NAME = "HOdlcoin" NAME = "HOdlcoin"
SHORTNAME = "HODLC" SHORTNAME = "HODLC"
@ -573,7 +574,8 @@ class BitcoinCashTestnet(BitcoinTestnetMixin, Coin):
PEERS = [ PEERS = [
'electrum-testnet-abc.criptolayer.net s50112', 'electrum-testnet-abc.criptolayer.net s50112',
'bchtestnet.arihanc.com t53001 s53002', 'bchtestnet.arihanc.com t53001 s53002',
'ciiattqkgzebpp6jofjbrkhvhwmgnsfoayljdcrve2p3qmkbv3duaoyd.onion t53001 s53002', 'ciiattqkgzebpp6jofjbrkhvhwmgnsfoayljdcrve2p3qmkbv3duaoyd.onion '
't53001 s53002',
] ]
@ -596,7 +598,7 @@ class BitcoinSegwitRegtest(BitcoinSegwitTestnet):
NET = "regtest" NET = "regtest"
GENESIS_HASH = ('0f9188f13cb7b2c71f2a335e3a4fc328' GENESIS_HASH = ('0f9188f13cb7b2c71f2a335e3a4fc328'
'bf5beb436012afca590b1a11466e2206') 'bf5beb436012afca590b1a11466e2206')
PEERS= [] PEERS = []
TX_COUNT = 1 TX_COUNT = 1
TX_COUNT_HEIGHT = 1 TX_COUNT_HEIGHT = 1
@ -666,7 +668,7 @@ class LitecoinTestnet(Litecoin):
class Viacoin(AuxPowMixin, Coin): class Viacoin(AuxPowMixin, Coin):
NAME="Viacoin" NAME = "Viacoin"
SHORTNAME = "VIA" SHORTNAME = "VIA"
NET = "mainnet" NET = "mainnet"
P2PKH_VERBYTE = bytes.fromhex("47") P2PKH_VERBYTE = bytes.fromhex("47")
@ -932,6 +934,7 @@ class Zcash(EquihashMixin, Coin):
RPC_PORT = 8232 RPC_PORT = 8232
REORG_LIMIT = 800 REORG_LIMIT = 800
class ZcashTestnet(Zcash): class ZcashTestnet(Zcash):
SHORTNAME = "TAZ" SHORTNAME = "TAZ"
NET = "testnet" NET = "testnet"
@ -945,6 +948,7 @@ class ZcashTestnet(Zcash):
TX_PER_BLOCK = 2 TX_PER_BLOCK = 2
RPC_PORT = 18232 RPC_PORT = 18232
class SnowGem(EquihashMixin, Coin): class SnowGem(EquihashMixin, Coin):
NAME = "SnowGem" NAME = "SnowGem"
SHORTNAME = "SNG" SHORTNAME = "SNG"
@ -976,9 +980,11 @@ class SnowGem(EquihashMixin, Coin):
'timestamp': timestamp, 'timestamp': timestamp,
'bits': bits, 'bits': bits,
'nonce': hash_to_str(header[108:140]), 'nonce': hash_to_str(header[108:140]),
'n_solution': base64.b64encode(lib_tx.Deserializer(header, start=140)._read_varbytes()).decode('utf8') 'n_solution': base64.b64encode(lib_tx.Deserializer(
header, start=140)._read_varbytes()).decode('utf8')
} }
class BitcoinZ(EquihashMixin, Coin): class BitcoinZ(EquihashMixin, Coin):
NAME = "BitcoinZ" NAME = "BitcoinZ"
SHORTNAME = "BTCZ" SHORTNAME = "BTCZ"
@ -995,6 +1001,7 @@ class BitcoinZ(EquihashMixin, Coin):
RPC_PORT = 1979 RPC_PORT = 1979
REORG_LIMIT = 800 REORG_LIMIT = 800
class Hush(EquihashMixin, Coin): class Hush(EquihashMixin, Coin):
NAME = "Hush" NAME = "Hush"
SHORTNAME = "HUSH" SHORTNAME = "HUSH"
@ -1002,8 +1009,8 @@ class Hush(EquihashMixin, Coin):
P2PKH_VERBYTE = bytes.fromhex("1CB8") P2PKH_VERBYTE = bytes.fromhex("1CB8")
P2SH_VERBYTES = [bytes.fromhex("1CBD")] P2SH_VERBYTES = [bytes.fromhex("1CBD")]
WIF_BYTE = bytes.fromhex("80") WIF_BYTE = bytes.fromhex("80")
GENESIS_HASH = ( '0003a67bc26fe564b75daf11186d3606' GENESIS_HASH = ('0003a67bc26fe564b75daf11186d3606'
'52eb435a35ba3d9d3e7e5d5f8e62dc17') '52eb435a35ba3d9d3e7e5d5f8e62dc17')
DESERIALIZER = lib_tx.DeserializerZcash DESERIALIZER = lib_tx.DeserializerZcash
TX_COUNT = 329196 TX_COUNT = 329196
TX_COUNT_HEIGHT = 68379 TX_COUNT_HEIGHT = 68379
@ -1011,6 +1018,7 @@ class Hush(EquihashMixin, Coin):
RPC_PORT = 8822 RPC_PORT = 8822
REORG_LIMIT = 800 REORG_LIMIT = 800
class Zclassic(EquihashMixin, Coin): class Zclassic(EquihashMixin, Coin):
NAME = "Zclassic" NAME = "Zclassic"
SHORTNAME = "ZCL" SHORTNAME = "ZCL"
@ -1018,8 +1026,8 @@ class Zclassic(EquihashMixin, Coin):
P2PKH_VERBYTE = bytes.fromhex("1CB8") P2PKH_VERBYTE = bytes.fromhex("1CB8")
P2SH_VERBYTES = [bytes.fromhex("1CBD")] P2SH_VERBYTES = [bytes.fromhex("1CBD")]
WIF_BYTE = bytes.fromhex("80") WIF_BYTE = bytes.fromhex("80")
GENESIS_HASH = ( '0007104ccda289427919efc39dc9e4d4' GENESIS_HASH = ('0007104ccda289427919efc39dc9e4d4'
'99804b7bebc22df55f8b834301260602') '99804b7bebc22df55f8b834301260602')
DESERIALIZER = lib_tx.DeserializerZcash DESERIALIZER = lib_tx.DeserializerZcash
TX_COUNT = 329196 TX_COUNT = 329196
TX_COUNT_HEIGHT = 68379 TX_COUNT_HEIGHT = 68379
@ -1027,6 +1035,7 @@ class Zclassic(EquihashMixin, Coin):
RPC_PORT = 8023 RPC_PORT = 8023
REORG_LIMIT = 800 REORG_LIMIT = 800
class Koto(Coin): class Koto(Coin):
NAME = "Koto" NAME = "Koto"
SHORTNAME = "KOTO" SHORTNAME = "KOTO"
@ -1047,6 +1056,7 @@ class Koto(Coin):
'electrum.kotocoin.info s t', 'electrum.kotocoin.info s t',
] ]
class KotoTestnet(Koto): class KotoTestnet(Koto):
SHORTNAME = "TOKO" SHORTNAME = "TOKO"
NET = "testnet" NET = "testnet"
@ -1064,6 +1074,7 @@ class KotoTestnet(Koto):
'testnet.kotocoin.info s t', 'testnet.kotocoin.info s t',
] ]
class Komodo(KomodoMixin, EquihashMixin, Coin): class Komodo(KomodoMixin, EquihashMixin, Coin):
NAME = "Komodo" NAME = "Komodo"
SHORTNAME = "KMD" SHORTNAME = "KMD"
@ -1075,6 +1086,7 @@ class Komodo(KomodoMixin, EquihashMixin, Coin):
REORG_LIMIT = 800 REORG_LIMIT = 800
PEERS = [] PEERS = []
class Monaize(KomodoMixin, EquihashMixin, Coin): class Monaize(KomodoMixin, EquihashMixin, Coin):
NAME = "Monaize" NAME = "Monaize"
SHORTNAME = "MNZ" SHORTNAME = "MNZ"
@ -1220,6 +1232,7 @@ class Monacoin(Coin):
'electrum-mona.bitbank.cc s t', 'electrum-mona.bitbank.cc s t',
] ]
class MonacoinTestnet(Monacoin): class MonacoinTestnet(Monacoin):
SHORTNAME = "XMN" SHORTNAME = "XMN"
NET = "testnet" NET = "testnet"
@ -1354,15 +1367,16 @@ class CanadaeCoin(AuxPowMixin, Coin):
RPC_PORT = 34330 RPC_PORT = 34330
REORG_LIMIT = 1000 REORG_LIMIT = 1000
class Denarius(Coin): class Denarius(Coin):
NAME = "Denarius" NAME = "Denarius"
SHORTNAME = "DNR" SHORTNAME = "DNR"
NET = "mainnet" NET = "mainnet"
XPUB_VERBYTES = bytes.fromhex("0488b21e") XPUB_VERBYTES = bytes.fromhex("0488b21e")
XPRV_VERBYTES = bytes.fromhex("0488ade4") XPRV_VERBYTES = bytes.fromhex("0488ade4")
P2PKH_VERBYTE = bytes.fromhex("1E") #Address starts with a D P2PKH_VERBYTE = bytes.fromhex("1E") # Address starts with a D
P2SH_VERBYTES = [bytes.fromhex("5A")] P2SH_VERBYTES = [bytes.fromhex("5A")]
WIF_BYTE = bytes.fromhex("9E") #WIF starts with a 6 WIF_BYTE = bytes.fromhex("9E") # WIF starts with a 6
GENESIS_HASH = ('00000d5dbbda01621cfc16bbc1f9bf32' GENESIS_HASH = ('00000d5dbbda01621cfc16bbc1f9bf32'
'64d641a5dbf0de89fd0182c2c4828fcd') '64d641a5dbf0de89fd0182c2c4828fcd')
DESERIALIZER = lib_tx.DeserializerTxTime DESERIALIZER = lib_tx.DeserializerTxTime
@ -1462,6 +1476,7 @@ class Feathercoin(Coin):
'electrumx-ch-1.feathercoin.ch s t', 'electrumx-ch-1.feathercoin.ch s t',
] ]
class UFO(Coin): class UFO(Coin):
NAME = "UniformFiscalObject" NAME = "UniformFiscalObject"
SHORTNAME = "UFO" SHORTNAME = "UFO"
@ -1483,6 +1498,7 @@ class UFO(Coin):
'electrumx1.ufobject.com s t', 'electrumx1.ufobject.com s t',
] ]
class Newyorkcoin(AuxPowMixin, Coin): class Newyorkcoin(AuxPowMixin, Coin):
NAME = "Newyorkcoin" NAME = "Newyorkcoin"
SHORTNAME = "NYC" SHORTNAME = "NYC"
@ -1498,6 +1514,7 @@ class Newyorkcoin(AuxPowMixin, Coin):
TX_PER_BLOCK = 2 TX_PER_BLOCK = 2
REORG_LIMIT = 2000 REORG_LIMIT = 2000
class NewyorkcoinTestnet(Newyorkcoin): class NewyorkcoinTestnet(Newyorkcoin):
SHORTNAME = "tNYC" SHORTNAME = "tNYC"
NET = "testnet" NET = "testnet"
@ -1512,6 +1529,7 @@ class NewyorkcoinTestnet(Newyorkcoin):
TX_PER_BLOCK = 2 TX_PER_BLOCK = 2
REORG_LIMIT = 2000 REORG_LIMIT = 2000
class Bitcore(BitcoinMixin, Coin): class Bitcore(BitcoinMixin, Coin):
NAME = "Bitcore" NAME = "Bitcore"
SHORTNAME = "BTX" SHORTNAME = "BTX"
@ -1540,6 +1558,7 @@ class GameCredits(Coin):
RPC_PORT = 40001 RPC_PORT = 40001
REORG_LIMIT = 1000 REORG_LIMIT = 1000
class Machinecoin(Coin): class Machinecoin(Coin):
NAME = "Machinecoin" NAME = "Machinecoin"
SHORTNAME = "MAC" SHORTNAME = "MAC"
@ -1558,6 +1577,7 @@ class Machinecoin(Coin):
RPC_PORT = 40332 RPC_PORT = 40332
REORG_LIMIT = 800 REORG_LIMIT = 800
class BitcoinAtom(Coin): class BitcoinAtom(Coin):
NAME = "BitcoinAtom" NAME = "BitcoinAtom"
SHORTNAME = "BCA" SHORTNAME = "BCA"
@ -1607,10 +1627,13 @@ class Decred(Coin):
P2PKH_VERBYTE = bytes('Ds', 'utf-8') P2PKH_VERBYTE = bytes('Ds', 'utf-8')
P2SH_VERBYTES = [bytes('Dc', 'utf-8')] P2SH_VERBYTES = [bytes('Dc', 'utf-8')]
WIF_BYTE = bytes('Pm', 'utf-8') WIF_BYTE = bytes('Pm', 'utf-8')
GENESIS_HASH = ('298e5cc3d985bfe7f81dc135f360abe089edd4396b86d2de66b0cef42b21d980') GENESIS_HASH = ('298e5cc3d985bfe7f81dc135f360abe089ed'
'd4396b86d2de66b0cef42b21d980')
DESERIALIZER = lib_tx.DeserializerDecred DESERIALIZER = lib_tx.DeserializerDecred
ENCODE_CHECK = partial(Base58.encode_check, hash_fn=lib_tx.DeserializerDecred.blake256) ENCODE_CHECK = partial(Base58.encode_check,
DECODE_CHECK = partial(Base58.decode_check, hash_fn=lib_tx.DeserializerDecred.blake256) hash_fn=lib_tx.DeserializerDecred.blake256)
DECODE_CHECK = partial(Base58.decode_check,
hash_fn=lib_tx.DeserializerDecred.blake256)
HEADER_HASH = lib_tx.DeserializerDecred.blake256 HEADER_HASH = lib_tx.DeserializerDecred.blake256
BASIC_HEADER_SIZE = 180 BASIC_HEADER_SIZE = 180
ALLOW_ADVANCING_ERRORS = True ALLOW_ADVANCING_ERRORS = True
@ -1641,7 +1664,8 @@ class DecredTestnet(Decred):
P2PKH_VERBYTE = bytes('Ts', 'utf-8') P2PKH_VERBYTE = bytes('Ts', 'utf-8')
P2SH_VERBYTES = [bytes('Tc', 'utf-8')] P2SH_VERBYTES = [bytes('Tc', 'utf-8')]
WIF_BYTE = bytes('Pt', 'utf-8') WIF_BYTE = bytes('Pt', 'utf-8')
GENESIS_HASH = ('4261602a9d07d80ad47621a64ba6a07754902e496777edc4ff581946bd7bc29c') GENESIS_HASH = ('4261602a9d07d80ad47621a64ba6a0'
'7754902e496777edc4ff581946bd7bc29c')
TX_COUNT = 3176305 TX_COUNT = 3176305
TX_COUNT_HEIGHT = 254198 TX_COUNT_HEIGHT = 254198
TX_PER_BLOCK = 1000 TX_PER_BLOCK = 1000
@ -1677,6 +1701,7 @@ class Axe(Dash):
import x11_hash import x11_hash
return x11_hash.getPoWHash(header) return x11_hash.getPoWHash(header)
class Xuez(Coin): class Xuez(Coin):
NAME = "Xuez" NAME = "Xuez"
SHORTNAME = "XUEZ" SHORTNAME = "XUEZ"
@ -1688,8 +1713,6 @@ class Xuez(Coin):
WIF_BYTE = bytes.fromhex("d4") WIF_BYTE = bytes.fromhex("d4")
GENESIS_HASH = ('000000e1febc39965b055e8e0117179a' GENESIS_HASH = ('000000e1febc39965b055e8e0117179a'
'4d18e24e7aaa0c69864c4054b4f29445') '4d18e24e7aaa0c69864c4054b4f29445')
TX_COUNT = 30000 TX_COUNT = 30000
TX_COUNT_HEIGHT = 15000 TX_COUNT_HEIGHT = 15000
TX_PER_BLOCK = 1 TX_PER_BLOCK = 1
@ -1709,7 +1732,7 @@ class Xuez(Coin):
import xevan_hash import xevan_hash
if version == 1 : if version == 1:
return xevan_hash.getPoWHash(header[:80]) return xevan_hash.getPoWHash(header[:80])
else: else:
return xevan_hash.getPoWHash(header) return xevan_hash.getPoWHash(header)
@ -1718,7 +1741,7 @@ class Xuez(Coin):
def electrum_header(cls, header, height): def electrum_header(cls, header, height):
version, = struct.unpack('<I', header[:4]) version, = struct.unpack('<I', header[:4])
timestamp, bits, nonce = struct.unpack('<III', header[68:80]) timestamp, bits, nonce = struct.unpack('<III', header[68:80])
if version == 1 : if version == 1:
return { return {
'block_height': height, 'block_height': height,
'version': version, 'version': version,
@ -1740,6 +1763,7 @@ class Xuez(Coin):
'nAccumulatorCheckpoint': hash_to_str(header[80:112]), 'nAccumulatorCheckpoint': hash_to_str(header[80:112]),
} }
class Pac(Coin): class Pac(Coin):
NAME = "PAC" NAME = "PAC"
SHORTNAME = "PAC" SHORTNAME = "PAC"
@ -1770,6 +1794,7 @@ class Pac(Coin):
import x11_hash import x11_hash
return x11_hash.getPoWHash(header) return x11_hash.getPoWHash(header)
class PacTestnet(Pac): class PacTestnet(Pac):
SHORTNAME = "tPAC" SHORTNAME = "tPAC"
NET = "testnet" NET = "testnet"

View File

@ -74,8 +74,9 @@ def hash_to_hex_str(x):
''' '''
return bytes(reversed(x)).hex() return bytes(reversed(x)).hex()
# Temporary
hash_to_str = hash_to_hex_str hash_to_str = hash_to_hex_str # Temporary
def hex_str_to_hash(x): def hex_str_to_hash(x):
'''Convert a displayed hex string to a binary hash.''' '''Convert a displayed hex string to a binary hash.'''

View File

@ -260,16 +260,16 @@ class DeserializerAuxPow(Deserializer):
if version & self.VERSION_AUXPOW: if version & self.VERSION_AUXPOW:
# We are going to calculate the block size then read it as bytes # We are going to calculate the block size then read it as bytes
self.cursor = start self.cursor = start
self.cursor += static_header_size # Block normal header self.cursor += static_header_size # Block normal header
self.read_tx() # AuxPow transaction self.read_tx() # AuxPow transaction
self.cursor += 32 # Parent block hash self.cursor += 32 # Parent block hash
merkle_size = self._read_varint() merkle_size = self._read_varint()
self.cursor += 32 * merkle_size # Merkle branch self.cursor += 32 * merkle_size # Merkle branch
self.cursor += 4 # Index self.cursor += 4 # Index
merkle_size = self._read_varint() merkle_size = self._read_varint()
self.cursor += 32 * merkle_size # Chain merkle branch self.cursor += 32 * merkle_size # Chain merkle branch
self.cursor += 4 # Chain index self.cursor += 4 # Chain index
self.cursor += 80 # Parent block header self.cursor += 80 # Parent block header
header_end = self.cursor header_end = self.cursor
else: else:
header_end = static_header_size header_end = static_header_size
@ -315,7 +315,7 @@ class DeserializerZcash(DeserializerEquihash):
self._read_le_uint32() # versionGroupId self._read_le_uint32() # versionGroupId
else: else:
version = header version = header
base_tx = TxJoinSplit( base_tx = TxJoinSplit(
version, version,
self._read_inputs(), # inputs self._read_inputs(), # inputs
self._read_outputs(), # outputs self._read_outputs(), # outputs
@ -326,9 +326,9 @@ class DeserializerZcash(DeserializerEquihash):
if base_tx.version >= 2: if base_tx.version >= 2:
joinsplit_size = self._read_varint() joinsplit_size = self._read_varint()
if joinsplit_size > 0: if joinsplit_size > 0:
self.cursor += joinsplit_size * 1802 # JSDescription self.cursor += joinsplit_size * 1802 # JSDescription
self.cursor += 32 # joinSplitPubKey self.cursor += 32 # joinSplitPubKey
self.cursor += 64 # joinSplitSig self.cursor += 64 # joinSplitSig
return base_tx return base_tx
@ -343,11 +343,11 @@ class TxTime(namedtuple("Tx", "version time inputs outputs locktime")):
class DeserializerTxTime(Deserializer): class DeserializerTxTime(Deserializer):
def read_tx(self): def read_tx(self):
return TxTime( return TxTime(
self._read_le_int32(), # version self._read_le_int32(), # version
self._read_le_uint32(), # time self._read_le_uint32(), # time
self._read_inputs(), # inputs self._read_inputs(), # inputs
self._read_outputs(), # outputs self._read_outputs(), # outputs
self._read_le_uint32(), # locktime self._read_le_uint32(), # locktime
) )
@ -408,7 +408,7 @@ class DeserializerBitcoinAtom(DeserializerSegWit):
'''Return the block header bytes''' '''Return the block header bytes'''
header_len = static_header_size header_len = static_header_size
if height >= self.FORK_BLOCK_HEIGHT: if height >= self.FORK_BLOCK_HEIGHT:
header_len += 4 # flags header_len += 4 # flags
return self._read_nbytes(header_len) return self._read_nbytes(header_len)
@ -511,4 +511,4 @@ class DeserializerDecred(Deserializer):
locktime, locktime,
expiry, expiry,
witness witness
), DeserializerDecred.blake256(no_witness_tx) ), DeserializerDecred.blake256(no_witness_tx)

View File

@ -249,7 +249,11 @@ def address_string(address):
# See http://stackoverflow.com/questions/2532053/validate-a-hostname-string # See http://stackoverflow.com/questions/2532053/validate-a-hostname-string
# Note underscores are valid in domain names, but strictly invalid in host # Note underscores are valid in domain names, but strictly invalid in host
# names. We ignore that distinction. # names. We ignore that distinction.
SEGMENT_REGEX = re.compile("(?!-)[A-Z_\d-]{1,63}(?<!-)$", re.IGNORECASE)
SEGMENT_REGEX = re.compile("(?!-)[A-Z_\\d-]{1,63}(?<!-)$", re.IGNORECASE)
def is_valid_hostname(hostname): def is_valid_hostname(hostname):
if len(hostname) > 255: if len(hostname) > 255:
return False return False
@ -258,6 +262,7 @@ def is_valid_hostname(hostname):
hostname = hostname[:-1] hostname = hostname[:-1]
return all(SEGMENT_REGEX.match(x) for x in hostname.split(".")) return all(SEGMENT_REGEX.match(x) for x in hostname.split("."))
def protocol_tuple(s): def protocol_tuple(s):
'''Converts a protocol version number, such as "1.0" to a tuple (1, 0). '''Converts a protocol version number, such as "1.0" to a tuple (1, 0).
@ -267,6 +272,7 @@ def protocol_tuple(s):
except Exception: except Exception:
return (0, ) return (0, )
def version_string(ptuple): def version_string(ptuple):
'''Convert a version tuple such as (1, 2) to "1.2". '''Convert a version tuple such as (1, 2) to "1.2".
There is always at least one dot, so (1, ) becomes "1.0".''' There is always at least one dot, so (1, ) becomes "1.0".'''
@ -274,6 +280,7 @@ def version_string(ptuple):
ptuple += (0, ) ptuple += (0, )
return '.'.join(str(p) for p in ptuple) return '.'.join(str(p) for p in ptuple)
def protocol_version(client_req, server_min, server_max): def protocol_version(client_req, server_min, server_max):
'''Given a client protocol request, return the protocol version '''Given a client protocol request, return the protocol version
to use as a tuple. to use as a tuple.
@ -298,6 +305,7 @@ def protocol_version(client_req, server_min, server_max):
return result return result
unpack_int32_from = Struct('<i').unpack_from unpack_int32_from = Struct('<i').unpack_from
unpack_int64_from = Struct('<q').unpack_from unpack_int64_from = Struct('<q').unpack_from
unpack_uint16_from = Struct('<H').unpack_from unpack_uint16_from = Struct('<H').unpack_from