Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[MESSAGES CONTROL]
disable=R0201,W0105
disable=R0201,R0205,W0105

[BASIC]

Expand Down
2 changes: 1 addition & 1 deletion maxminddb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def open_database(database, mode=MODE_AUTO):
"MODE_MMAP_EXT requires the maxminddb.extension module to be available"
)
return maxminddb.extension.Reader(database)
elif mode in (MODE_AUTO, MODE_MMAP, MODE_FILE, MODE_MEMORY, MODE_FD):
if mode in (MODE_AUTO, MODE_MMAP, MODE_FILE, MODE_MEMORY, MODE_FD):
return maxminddb.reader.Reader(database, mode)
raise ValueError('Unsupported open mode: {0}'.format(mode))

Expand Down
5 changes: 2 additions & 3 deletions maxminddb/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ def __init__(self, database):
def __getitem__(self, key):
if isinstance(key, slice):
return self._read(key.stop - key.start, key.start)
elif isinstance(key, int):
if isinstance(key, int):
return self._read(1, key)
else:
raise TypeError("Invalid argument type.")
raise TypeError("Invalid argument type.")

def rfind(self, needle, start):
"""Reverse find needle from start"""
Expand Down
10 changes: 6 additions & 4 deletions maxminddb/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ def __init__(self, database, mode=MODE_AUTO):
(metadata, _) = metadata_decoder.decode(metadata_start)
self._metadata = Metadata(**metadata) # pylint: disable=bad-option-value

self._decoder = Decoder(self._buffer, self._metadata.search_tree_size +
self._DATA_SECTION_SEPARATOR_SIZE)
self._decoder = Decoder(
self._buffer, self._metadata.search_tree_size +
self._DATA_SECTION_SEPARATOR_SIZE)
self.closed = False

def metadata(self):
Expand Down Expand Up @@ -131,7 +132,7 @@ def _find_address_in_tree(self, ip_address):
if node == self._metadata.node_count:
# Record is empty
return 0
elif node > self._metadata.node_count:
if node > self._metadata.node_count:
return node

raise InvalidDatabaseError('Invalid node in search tree')
Expand Down Expand Up @@ -168,7 +169,8 @@ def _read_node(self, node_number, index):
else:
middle = (0xF0 & middle) >> 4
offset = base_offset + index * 4
node_bytes = byte_from_int(middle) + self._buffer[offset:offset + 3]
node_bytes = byte_from_int(middle) + self._buffer[offset:offset +
3]
elif record_size == 32:
offset = base_offset + index * 4
node_bytes = self._buffer[offset:offset + 4]
Expand Down
16 changes: 8 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,14 @@ def run_setup(with_cext):
try:
run_setup(True)
except BuildFailed as exc:
status_msgs(exc.cause,
"WARNING: The C extension could not be compiled, " +
"speedups are not enabled.",
"Failure information, if any, is above.",
"Retrying the build without the C extension now.")
status_msgs(
exc.cause, "WARNING: The C extension could not be compiled, " +
"speedups are not enabled.",
"Failure information, if any, is above.",
"Retrying the build without the C extension now.")

run_setup(False)

status_msgs("WARNING: The C extension could not be compiled, " +
"speedups are not enabled.",
"Plain-Python build succeeded.")
status_msgs(
"WARNING: The C extension could not be compiled, " +
"speedups are not enabled.", "Plain-Python build succeeded.")
4 changes: 2 additions & 2 deletions tests/decoder_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ def test_string(self):

def test_byte(self):
# Python 2.6 doesn't support dictionary comprehension
b = dict((byte_from_int(0xc0 ^ int_from_byte(k[0])) + k[1:], v.encode(
'utf-8')) for k, v in self.strings.items())
b = dict((byte_from_int(0xc0 ^ int_from_byte(k[0])) + k[1:],
v.encode('utf-8')) for k, v in self.strings.items())
self.validate_type_decoding('byte', b)

def test_uint16(self):
Expand Down
89 changes: 42 additions & 47 deletions tests/reader_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ def test_no_ipv4_search_tree(self):
def test_ipv6_address_in_ipv4_database(self):
reader = open_database(
'tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb', self.mode)
with self.assertRaisesRegex(ValueError, 'Error looking up 2001::. '
'You attempted to look up an IPv6 address '
'in an IPv4-only database'):
with self.assertRaisesRegex(
ValueError, 'Error looking up 2001::. '
'You attempted to look up an IPv6 address '
'in an IPv4-only database'):
reader.get('2001::')
reader.close()

Expand All @@ -123,28 +124,28 @@ def test_no_extension_exception(self):
def test_ip_object_lookup(self):
reader = open_database('tests/data/test-data/GeoIP2-City-Test.mmdb',
self.mode)
with self.assertRaisesRegex(
TypeError, "must be str(?:ing)?, not IPv6Address"):
with self.assertRaisesRegex(TypeError,
"must be str(?:ing)?, not IPv6Address"):
reader.get(compat_ip_address('2001:220::'))
reader.close()

def test_broken_database(self):
reader = open_database('tests/data/test-data/'
'GeoIP2-City-Test-Broken-Double-Format.mmdb',
self.mode)
with self.assertRaisesRegex(InvalidDatabaseError,
"The MaxMind DB file's data "
"section contains bad data \(unknown data "
"type or corrupt data\)"):
reader = open_database(
'tests/data/test-data/'
'GeoIP2-City-Test-Broken-Double-Format.mmdb', self.mode)
with self.assertRaisesRegex(
InvalidDatabaseError, r"The MaxMind DB file's data "
r"section contains bad data \(unknown data "
r"type or corrupt data\)"):
reader.get('2001:220::')
reader.close()

def test_ip_validation(self):
reader = open_database(
'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode)
self.assertRaisesRegex(ValueError,
"'not_ip' does not appear to be an IPv4 or "
"IPv6 address", reader.get, ('not_ip'))
self.assertRaisesRegex(
ValueError, "'not_ip' does not appear to be an IPv4 or "
"IPv6 address", reader.get, ('not_ip'))
reader.close()

def test_missing_database(self):
Expand All @@ -153,10 +154,11 @@ def test_missing_database(self):
self.mode)

def test_nondatabase(self):
self.assertRaisesRegex(InvalidDatabaseError,
'Error opening database file \(README.rst\). '
'Is this a valid MaxMind DB file\?',
open_database, 'README.rst', self.mode)
self.assertRaisesRegex(
InvalidDatabaseError,
r'Error opening database file \(README.rst\). '
r'Is this a valid MaxMind DB file\?', open_database, 'README.rst',
self.mode)

def test_too_many_constructor_args(self):
cls = self.readerClass[0]
Expand All @@ -166,20 +168,18 @@ def test_bad_constructor_mode(self):
cls = self.readerClass[0]
self.assertRaisesRegex(
ValueError,
'Unsupported open mode \(100\)',
r'Unsupported open mode \(100\)',
cls,
'README.md',
mode=100)

def test_no_constructor_args(self):
cls = self.readerClass[0]
self.assertRaisesRegex(
TypeError,
' 1 required positional argument|'
'\(pos 1\) not found|'
'takes at least 2 arguments|'
'function missing required argument \'database\' \(pos 1\)',
cls)
TypeError, r' 1 required positional argument|'
r'\(pos 1\) not found|'
r'takes at least 2 arguments|'
r'function missing required argument \'database\' \(pos 1\)', cls)

def test_too_many_get_args(self):
reader = open_database(
Expand All @@ -203,8 +203,9 @@ def test_metadata_unknown_attribute(self):
reader = open_database(
'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode)
metadata = reader.metadata()
with self.assertRaisesRegex(AttributeError, "'Metadata' object has no "
"attribute 'blah'"):
with self.assertRaisesRegex(
AttributeError, "'Metadata' object has no "
"attribute 'blah'"):
metadata.blah
reader.close()

Expand All @@ -226,9 +227,9 @@ def test_closed_get(self):
reader = open_database(
'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode)
reader.close()
self.assertRaisesRegex(ValueError,
'Attempt to read from a closed MaxMind DB.'
'|closed', reader.get, ('1.1.1.1'))
self.assertRaisesRegex(
ValueError, 'Attempt to read from a closed MaxMind DB.'
'|closed', reader.get, ('1.1.1.1'))

def test_with_statement(self):
filename = 'tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb'
Expand Down Expand Up @@ -342,10 +343,8 @@ def _check_ip_v4(self, reader, file_name):
address = '1.1.1.' + str(pow(2, i))
self.assertEqual({
'ip': address
},
reader.get(address),
'found expected data record for ' + address +
' in ' + file_name)
}, reader.get(address), 'found expected data record for ' + address
+ ' in ' + file_name)

pairs = {
'1.1.1.3': '1.1.1.2',
Expand All @@ -359,10 +358,10 @@ def _check_ip_v4(self, reader, file_name):
for key_address, value_address in pairs.items():
data = {'ip': value_address}

self.assertEqual(data,
reader.get(key_address),
'found expected data record for ' + key_address +
' in ' + file_name)
self.assertEqual(
data, reader.get(key_address),
'found expected data record for ' + key_address + ' in ' +
file_name)

for ip in ['1.1.1.33', '255.254.253.123']:
self.assertIsNone(reader.get(ip))
Expand All @@ -375,10 +374,8 @@ def _check_ip_v6(self, reader, file_name):
for address in subnets:
self.assertEqual({
'ip': address
},
reader.get(address),
'found expected data record for ' + address +
' in ' + file_name)
}, reader.get(address), 'found expected data record for ' + address
+ ' in ' + file_name)

pairs = {
'::2:0:1': '::2:0:0',
Expand All @@ -394,10 +391,8 @@ def _check_ip_v6(self, reader, file_name):
for key_address, value_address in pairs.items():
self.assertEqual({
'ip': value_address
},
reader.get(key_address),
'found expected data record for ' + key_address +
' in ' + file_name)
}, reader.get(key_address), 'found expected data record for ' +
key_address + ' in ' + file_name)

for ip in ['1.1.1.33', '255.254.253.123', '89fa::']:
self.assertIsNone(reader.get(ip))
Expand Down