diff --git a/distro.py b/distro.py index 3ce45af..0287eb8 100755 --- a/distro.py +++ b/distro.py @@ -757,7 +757,7 @@ def version(self, pretty=False, best=False): version = v break if pretty and version and self.codename(): - version = u'{0} ({1})'.format(version, self.codename()) + version = '{0} ({1})'.format(version, self.codename()) return version def version_parts(self, best=False): @@ -967,8 +967,6 @@ def _parse_os_release_content(lines): # * commands or their arguments (not allowed in os-release) if '=' in token: k, v = token.split('=', 1) - if isinstance(v, bytes): - v = v.decode('utf-8') props[k.lower()] = v else: # Ignore any tokens that are not variable assignments @@ -1012,7 +1010,7 @@ def _lsb_release_info(self): stdout = subprocess.check_output(cmd, stderr=devnull) except OSError: # Command not found return {} - content = stdout.decode(sys.getfilesystemencoding()).splitlines() + content = self._to_str(stdout).splitlines() return self._parse_lsb_release_content(content) @staticmethod @@ -1047,7 +1045,7 @@ def _uname_info(self): stdout = subprocess.check_output(cmd, stderr=devnull) except OSError: return {} - content = stdout.decode(sys.getfilesystemencoding()).splitlines() + content = self._to_str(stdout).splitlines() return self._parse_uname_content(content) @staticmethod @@ -1067,6 +1065,20 @@ def _parse_uname_content(lines): props['release'] = version return props + @staticmethod + def _to_str(text): + encoding = sys.getfilesystemencoding() + encoding = 'utf-8' if encoding == 'ascii' else encoding + + if sys.version_info[0] >= 3: + if isinstance(text, bytes): + return text.decode(encoding) + else: + if isinstance(text, unicode): # noqa + return text.encode(encoding) + + return text + @cached_property def _distro_release_info(self): """ @@ -1169,8 +1181,6 @@ def _parse_distro_release_content(line): Returns: A dictionary containing all information items. """ - if isinstance(line, bytes): - line = line.decode('utf-8') matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( line.strip()[::-1]) distro_info = {} diff --git a/tests/test_distro.py b/tests/test_distro.py index 5521068..b84e074 100644 --- a/tests/test_distro.py +++ b/tests/test_distro.py @@ -1,3 +1,4 @@ +# coding=utf-8 # Copyright 2015,2016 Nir Cohen # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -191,11 +192,11 @@ def test_fedora19_os_release(self): desired_outcome = { 'id': 'fedora', 'name': 'Fedora', - 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', + 'pretty_name': 'Fedora 19 (Schrödinger’s Cat)', 'version': '19', - 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', + 'pretty_version': '19 (Schrödinger’s Cat)', 'best_version': '19', - 'codename': u'Schr\u00F6dinger\u2019s Cat' + 'codename': 'Schrödinger’s Cat' } self._test_outcome(desired_outcome) @@ -703,11 +704,11 @@ def test_fedora19_dist_release(self): desired_outcome = { 'id': 'fedora', 'name': 'Fedora', - 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', + 'pretty_name': 'Fedora 19 (Schrödinger’s Cat)', 'version': '19', - 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', + 'pretty_version': '19 (Schrödinger’s Cat)', 'best_version': '19', - 'codename': u'Schr\u00F6dinger\u2019s Cat', + 'codename': 'Schrödinger’s Cat', 'major_version': '19' } self._test_outcome(desired_outcome, 'fedora', '19') @@ -1078,11 +1079,11 @@ def test_fedora19_release(self): desired_outcome = { 'id': 'fedora', 'name': 'Fedora', - 'pretty_name': u'Fedora 19 (Schr\u00F6dinger\u2019s Cat)', + 'pretty_name': 'Fedora 19 (Schrödinger’s Cat)', 'version': '19', - 'pretty_version': u'19 (Schr\u00F6dinger\u2019s Cat)', + 'pretty_version': '19 (Schrödinger’s Cat)', 'best_version': '19', - 'codename': u'Schr\u00F6dinger\u2019s Cat', + 'codename': 'Schrödinger’s Cat', 'major_version': '19' } self._test_outcome(desired_outcome) @@ -1091,7 +1092,7 @@ def test_fedora19_release(self): 'id': 'fedora', 'name': 'Fedora', 'version_id': '19', - 'codename': u'Schr\u00F6dinger\u2019s Cat' + 'codename': 'Schrödinger’s Cat' } self._test_release_file_info('fedora-release', desired_info) @@ -1618,7 +1619,7 @@ def _bad_os_listdir(path='.'): raise OSError() -@pytest.mark.skipIf(not IS_LINUX, reason='Irrelevant on non-linx') +@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linx') class TestOverallWithEtcNotReadable(TestOverall): def setup_method(self, test_method): self._old_listdir = os.listdir @@ -2060,3 +2061,20 @@ def test_repr(self): assert "LinuxDistribution" in repr_str for attr in MODULE_DISTRO.__dict__.keys(): assert attr + '=' in repr_str + + +@pytest.mark.skipif(not IS_LINUX, reason='Irrelevant on non-linux') +class TestToStr: + """Test the _to_str() method. + """ + + def test_to_str(self): + ret = distro.LinuxDistribution._to_str(b'bytes') + assert isinstance(ret, str) + assert ret == 'bytes' + + ret = distro.LinuxDistribution._to_str(u'bytes') + assert isinstance(ret, str) + + ret = distro.LinuxDistribution._to_str('bytes') + assert isinstance(ret, str)