From 460aff7cffc8fcf7ceca8bcb68c28fb0b6cd8232 Mon Sep 17 00:00:00 2001 From: Ondra Medek Date: Wed, 25 Apr 2018 09:15:40 +0200 Subject: [PATCH] FitFile.get_messages remove parsing names to int, remove Python 2 str shim Use utils.is_iterable and use set for quicker in test --- fitparse/base.py | 16 ++++------------ fitparse/utils.py | 11 +++++++++-- tests/test_utils.py | 12 +++++++++++- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/fitparse/base.py b/fitparse/base.py index 0e6abbe..125d620 100644 --- a/fitparse/base.py +++ b/fitparse/base.py @@ -5,7 +5,6 @@ # Python 2 compat try: num_types = (int, float, long) - str = basestring except NameError: num_types = (int, float) @@ -16,7 +15,7 @@ BASE_TYPES, BASE_TYPE_BYTE, add_dev_data_id, add_dev_field_description, get_dev_type ) -from fitparse.utils import fileish_open, FitParseError, FitEOFError, FitCRCError, FitHeaderError +from fitparse.utils import fileish_open, is_iterable, FitParseError, FitEOFError, FitCRCError, FitHeaderError class FitFile(object): @@ -407,17 +406,10 @@ def get_messages(self, name=None, with_definitions=False, as_dict=False): as_dict = False if name is not None: - if isinstance(name, (tuple, list)): - names = name + if is_iterable(name): + names = set(name) else: - names = [name] - - # Convert any string numbers in names to ints - # TODO: Revisit Python2/3 str/bytes typecheck issues - names = set([ - int(n) if (isinstance(n, str) and n.isdigit()) else n - for n in names - ]) + names = set((name,)) def should_yield(message): if with_definitions or message.type == 'data': diff --git a/fitparse/utils.py b/fitparse/utils.py index 9f4a367..d3e427a 100644 --- a/fitparse/utils.py +++ b/fitparse/utils.py @@ -1,6 +1,6 @@ -import re - import io +import re +from collections import Iterable class FitParseError(ValueError): @@ -56,3 +56,10 @@ def fileish_open(fileish, mode): else: # Python 3 - file contents return io.BytesIO(fileish) + + +def is_iterable(obj): + """Check, if the obj is iterable but not string or bytes. + :rtype bool""" + # Speed: do not use iter() although it's more robust, see also https://stackoverflow.com/questions/1952464/ + return isinstance(obj, Iterable) and not isinstance(obj, (str, bytes)) diff --git a/tests/test_utils.py b/tests/test_utils.py index e0b6547..966548c 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,7 +5,7 @@ import sys import tempfile -from fitparse.utils import fileish_open +from fitparse.utils import fileish_open, is_iterable if sys.version_info >= (2, 7): import unittest @@ -61,6 +61,16 @@ def test_fopen(fileish): except OSError: pass + def test_is_iterable(self): + self.assertFalse(is_iterable(None)) + self.assertFalse(is_iterable(1)) + self.assertFalse(is_iterable('1')) + self.assertFalse(is_iterable(b'1')) + + self.assertTrue(is_iterable((1, 2))) + self.assertTrue(is_iterable([1, 2])) + self.assertTrue(is_iterable(range(2))) + if __name__ == '__main__': unittest.main()