Update unit tests, doctests and makefiles
This commit is contained in:
parent
e020448e14
commit
58d1da9f71
2
makefile
2
makefile
|
@ -50,7 +50,7 @@ GETTEXT_SOURCE += $(DESKTOP_FILES_IN_H)
|
||||||
DESTDIR ?= /
|
DESTDIR ?= /
|
||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
|
|
||||||
PYTHON ?= python
|
PYTHON ?= python3
|
||||||
HELP2MAN ?= help2man
|
HELP2MAN ?= help2man
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
|
@ -90,7 +90,7 @@ class JsonConfig(object):
|
||||||
For newly-set keys, on_key_changed is also called. In this case,
|
For newly-set keys, on_key_changed is also called. In this case,
|
||||||
None will be the old_value:
|
None will be the old_value:
|
||||||
|
|
||||||
>>> def callback(*args): print 'callback:', args
|
>>> def callback(*args): print('callback:', args)
|
||||||
>>> c = JsonConfig(on_key_changed=callback)
|
>>> c = JsonConfig(on_key_changed=callback)
|
||||||
>>> c.a.b = 10
|
>>> c.a.b = 10
|
||||||
callback: ('a.b', None, 10)
|
callback: ('a.b', None, 10)
|
||||||
|
@ -103,7 +103,7 @@ class JsonConfig(object):
|
||||||
|
|
||||||
Please note that dict-style access will not call on_key_changed:
|
Please note that dict-style access will not call on_key_changed:
|
||||||
|
|
||||||
>>> def callback(*args): print 'callback:', args
|
>>> def callback(*args): print('callback:', args)
|
||||||
>>> c = JsonConfig(on_key_changed=callback)
|
>>> c = JsonConfig(on_key_changed=callback)
|
||||||
>>> c.a.b = 1 # This works as expected
|
>>> c.a.b = 1 # This works as expected
|
||||||
callback: ('a.b', None, 1)
|
callback: ('a.b', None, 1)
|
||||||
|
@ -130,14 +130,14 @@ class JsonConfig(object):
|
||||||
>>> c = JsonConfig()
|
>>> c = JsonConfig()
|
||||||
>>> c.a.b = 10
|
>>> c.a.b = 10
|
||||||
>>> backup = repr(c)
|
>>> backup = repr(c)
|
||||||
>>> print c.a.b
|
>>> print(c.a.b)
|
||||||
10
|
10
|
||||||
>>> c.a.b = 11
|
>>> c.a.b = 11
|
||||||
>>> print c.a.b
|
>>> print(c.a.b)
|
||||||
11
|
11
|
||||||
>>> c._restore(backup)
|
>>> c._restore(backup)
|
||||||
False
|
False
|
||||||
>>> print c.a.b
|
>>> print(c.a.b)
|
||||||
10
|
10
|
||||||
"""
|
"""
|
||||||
self._data = json.loads(backup)
|
self._data = json.loads(backup)
|
||||||
|
@ -176,7 +176,7 @@ class JsonConfig(object):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""
|
"""
|
||||||
>>> c = JsonConfig('{"a": 1}')
|
>>> c = JsonConfig('{"a": 1}')
|
||||||
>>> print c
|
>>> print(c)
|
||||||
{
|
{
|
||||||
"a": 1
|
"a": 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,11 +287,11 @@ def username_password_from_url(url):
|
||||||
>>> username_password_from_url(1)
|
>>> username_password_from_url(1)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: URL has to be a string or unicode object.
|
ValueError: URL has to be a string.
|
||||||
>>> username_password_from_url(None)
|
>>> username_password_from_url(None)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: URL has to be a string or unicode object.
|
ValueError: URL has to be a string.
|
||||||
>>> username_password_from_url('http://a@b:c@host.com/')
|
>>> username_password_from_url('http://a@b:c@host.com/')
|
||||||
('a@b', 'c')
|
('a@b', 'c')
|
||||||
>>> username_password_from_url('ftp://a:b:c@host.com/')
|
>>> username_password_from_url('ftp://a:b:c@host.com/')
|
||||||
|
@ -299,14 +299,14 @@ def username_password_from_url(url):
|
||||||
>>> username_password_from_url('http://i%2Fo:P%40ss%3A@host.com/')
|
>>> username_password_from_url('http://i%2Fo:P%40ss%3A@host.com/')
|
||||||
('i/o', 'P@ss:')
|
('i/o', 'P@ss:')
|
||||||
>>> username_password_from_url('ftp://%C3%B6sterreich@host.com/')
|
>>> username_password_from_url('ftp://%C3%B6sterreich@host.com/')
|
||||||
('\xc3\xb6sterreich', None)
|
('österreich', None)
|
||||||
>>> username_password_from_url('http://w%20x:y%20z@example.org/')
|
>>> username_password_from_url('http://w%20x:y%20z@example.org/')
|
||||||
('w x', 'y z')
|
('w x', 'y z')
|
||||||
>>> username_password_from_url('http://example.com/x@y:z@test.com/')
|
>>> username_password_from_url('http://example.com/x@y:z@test.com/')
|
||||||
(None, None)
|
(None, None)
|
||||||
"""
|
"""
|
||||||
if type(url) not in (str, str):
|
if not isinstance(url, str):
|
||||||
raise ValueError('URL has to be a string or unicode object.')
|
raise ValueError('URL has to be a string.')
|
||||||
|
|
||||||
(username, password) = (None, None)
|
(username, password) = (None, None)
|
||||||
|
|
||||||
|
@ -433,9 +433,9 @@ def file_age_to_string(days):
|
||||||
>>> file_age_to_string(0)
|
>>> file_age_to_string(0)
|
||||||
''
|
''
|
||||||
>>> file_age_to_string(1)
|
>>> file_age_to_string(1)
|
||||||
u'1 day ago'
|
'1 day ago'
|
||||||
>>> file_age_to_string(2)
|
>>> file_age_to_string(2)
|
||||||
u'2 days ago'
|
'2 days ago'
|
||||||
"""
|
"""
|
||||||
if days < 1:
|
if days < 1:
|
||||||
return ''
|
return ''
|
||||||
|
@ -1345,11 +1345,11 @@ def format_seconds_to_hour_min_sec(seconds):
|
||||||
human-readable string (duration).
|
human-readable string (duration).
|
||||||
|
|
||||||
>>> format_seconds_to_hour_min_sec(3834)
|
>>> format_seconds_to_hour_min_sec(3834)
|
||||||
u'1 hour, 3 minutes and 54 seconds'
|
'1 hour, 3 minutes and 54 seconds'
|
||||||
>>> format_seconds_to_hour_min_sec(3600)
|
>>> format_seconds_to_hour_min_sec(3600)
|
||||||
u'1 hour'
|
'1 hour'
|
||||||
>>> format_seconds_to_hour_min_sec(62)
|
>>> format_seconds_to_hour_min_sec(62)
|
||||||
u'1 minute and 2 seconds'
|
'1 minute and 2 seconds'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if seconds < 1:
|
if seconds < 1:
|
||||||
|
@ -1359,11 +1359,11 @@ def format_seconds_to_hour_min_sec(seconds):
|
||||||
|
|
||||||
seconds = int(seconds)
|
seconds = int(seconds)
|
||||||
|
|
||||||
hours = seconds/3600
|
hours = int(seconds/3600)
|
||||||
seconds = seconds%3600
|
seconds = int(seconds%3600)
|
||||||
|
|
||||||
minutes = seconds/60
|
minutes = int(seconds/60)
|
||||||
seconds = seconds%60
|
seconds = int(seconds%60)
|
||||||
|
|
||||||
if hours:
|
if hours:
|
||||||
result.append(N_('%(count)d hour', '%(count)d hours', hours) % {'count':hours})
|
result.append(N_('%(count)d hour', '%(count)d hours', hours) % {'count':hours})
|
||||||
|
@ -1424,24 +1424,20 @@ def convert_bytes(d):
|
||||||
strings. Any other data types will be left alone.
|
strings. Any other data types will be left alone.
|
||||||
|
|
||||||
>>> convert_bytes(None)
|
>>> convert_bytes(None)
|
||||||
>>> convert_bytes(1)
|
>>> convert_bytes(4711)
|
||||||
1
|
4711
|
||||||
>>> convert_bytes(4711L)
|
|
||||||
4711L
|
|
||||||
>>> convert_bytes(True)
|
>>> convert_bytes(True)
|
||||||
True
|
True
|
||||||
>>> convert_bytes(3.1415)
|
>>> convert_bytes(3.1415)
|
||||||
3.1415
|
3.1415
|
||||||
>>> convert_bytes('Hello')
|
>>> convert_bytes('Hello')
|
||||||
u'Hello'
|
'Hello'
|
||||||
>>> convert_bytes(u'Hey')
|
>>> type(convert_bytes(b'hoho'))
|
||||||
u'Hey'
|
<class 'bytes'>
|
||||||
>>> type(convert_bytes(bytes('hoho')))
|
|
||||||
<type 'bytes'>
|
|
||||||
"""
|
"""
|
||||||
if d is None:
|
if d is None:
|
||||||
return d
|
return d
|
||||||
if isinstance(d, bytes):
|
elif isinstance(d, bytes):
|
||||||
return d
|
return d
|
||||||
elif any(isinstance(d, t) for t in (int, int, bool, float)):
|
elif any(isinstance(d, t) for t in (int, int, bool, float)):
|
||||||
return d
|
return d
|
||||||
|
@ -1451,24 +1447,10 @@ def convert_bytes(d):
|
||||||
|
|
||||||
def sanitize_encoding(filename):
|
def sanitize_encoding(filename):
|
||||||
r"""
|
r"""
|
||||||
Generate a sanitized version of a string (i.e.
|
This is a no-op in Python 3 and will be removed in the future.
|
||||||
remove invalid characters and encode in the
|
|
||||||
detected native language encoding).
|
|
||||||
|
|
||||||
>>> sanitize_encoding('\x80')
|
|
||||||
''
|
|
||||||
>>> sanitize_encoding(u'unicode')
|
|
||||||
'unicode'
|
|
||||||
"""
|
"""
|
||||||
# The encoding problem goes away in Python 3.. hopefully!
|
|
||||||
if sys.version_info >= (3, 0):
|
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
global encoding
|
|
||||||
if not isinstance(filename, str):
|
|
||||||
filename = filename.decode(encoding, 'ignore')
|
|
||||||
return filename.encode(encoding, 'ignore')
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_filename(filename, max_length=0, use_ascii=False):
|
def sanitize_filename(filename, max_length=0, use_ascii=False):
|
||||||
"""
|
"""
|
||||||
|
@ -1497,10 +1479,10 @@ def find_mount_point(directory):
|
||||||
>>> find_mount_point('/')
|
>>> find_mount_point('/')
|
||||||
'/'
|
'/'
|
||||||
|
|
||||||
>>> find_mount_point(u'/something')
|
>>> find_mount_point(b'/something')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: Convert unicode objects to str first.
|
ValueError: Convert bytes objects to str first.
|
||||||
|
|
||||||
>>> find_mount_point(None)
|
>>> find_mount_point(None)
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
|
@ -1551,15 +1533,14 @@ def find_mount_point(directory):
|
||||||
'/media/usbdisk'
|
'/media/usbdisk'
|
||||||
>>> restore()
|
>>> restore()
|
||||||
"""
|
"""
|
||||||
if isinstance(directory, str):
|
if isinstance(directory, bytes):
|
||||||
# XXX: This is only valid for Python 2 - misleading error in Python 3?
|
# We do not accept byte strings, because they could fail when
|
||||||
# We do not accept unicode strings, because they could fail when
|
|
||||||
# trying to be converted to some native encoding, so fail loudly
|
# trying to be converted to some native encoding, so fail loudly
|
||||||
# and leave it up to the callee to encode into the proper encoding.
|
# and leave it up to the callee to decode from the proper encoding.
|
||||||
raise ValueError('Convert unicode objects to str first.')
|
raise ValueError('Convert bytes objects to str first.')
|
||||||
|
|
||||||
if not isinstance(directory, str):
|
if not isinstance(directory, str):
|
||||||
# In Python 2, we assume it's a byte str; in Python 3, we assume
|
# In Python 2, we assumed it's a byte str; in Python 3, we assume
|
||||||
# that it's a unicode str. The abspath/ismount/split functions of
|
# that it's a unicode str. The abspath/ismount/split functions of
|
||||||
# os.path work with unicode str in Python 3, but not in Python 2.
|
# os.path work with unicode str in Python 3, but not in Python 2.
|
||||||
raise ValueError('Directory names should be of type str.')
|
raise ValueError('Directory names should be of type str.')
|
||||||
|
|
|
@ -4,4 +4,4 @@ import re
|
||||||
here = os.path.dirname(__file__) or '.'
|
here = os.path.dirname(__file__) or '.'
|
||||||
main_module = open(os.path.join(here, '../src/gpodder/__init__.py')).read()
|
main_module = open(os.path.join(here, '../src/gpodder/__init__.py')).read()
|
||||||
metadata = dict(re.findall("__([a-z_]+)__\s*=\s*'([^']+)'", main_module))
|
metadata = dict(re.findall("__([a-z_]+)__\s*=\s*'([^']+)'", main_module))
|
||||||
print metadata['version']
|
print(metadata['version'])
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# gPodder Win32 Portable Cross-Build script
|
# gPodder Win32 Portable Cross-Build script
|
||||||
# 2014-10-21 Thomas Perl <m@thp.io>
|
# 2014-10-21 Thomas Perl <m@thp.io>
|
||||||
|
|
||||||
PYTHON ?= python
|
PYTHON ?= python3
|
||||||
|
|
||||||
VERSION := $(shell $(PYTHON) ../getversion.py)
|
VERSION := $(shell $(PYTHON) ../getversion.py)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# gPodder Win32 Setup Cross-Build script
|
# gPodder Win32 Setup Cross-Build script
|
||||||
# 2014-10-21 Thomas Perl <m@thp.io>
|
# 2014-10-21 Thomas Perl <m@thp.io>
|
||||||
|
|
||||||
PYTHON ?= python
|
PYTHON ?= python3
|
||||||
|
|
||||||
VERSION := $(shell $(PYTHON) ../getversion.py)
|
VERSION := $(shell $(PYTHON) ../getversion.py)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue