141 lines
4.1 KiB
Python
Executable File
141 lines
4.1 KiB
Python
Executable File
# Copyright 2010 by Eric Talevich. All rights reserved.
|
|
# Copyright 2012 by Wibowo Arindrarto. All rights reserved.
|
|
#
|
|
# This file is part of the Biopython distribution and governed by your
|
|
# choice of the "Biopython License Agreement" or the "BSD 3-Clause License".
|
|
# Please see the LICENSE file that should have been included as part of this
|
|
# package.
|
|
"""Common utility functions for various Bio submodules."""
|
|
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
|
|
|
|
def iterlen(items):
|
|
"""Count the number of items in an iterable.
|
|
|
|
If the argument supports len(items), and some iterators do, then
|
|
this returns len(items). Otherwise it will scan over the entries
|
|
in order to count them.
|
|
|
|
Exhausts a generator, but doesn't require creating a full list.
|
|
|
|
>>> iterlen("abcde")
|
|
5
|
|
>>> iterlen(iter("abcde"))
|
|
5
|
|
|
|
"""
|
|
try:
|
|
# e.g. Under Python 2, the xrange iterator defines __len__
|
|
return len(items)
|
|
except TypeError:
|
|
for i, x in enumerate(items):
|
|
count = i
|
|
return count + 1
|
|
|
|
|
|
def read_forward(handle):
|
|
"""Read through whitespaces, return the first non-whitespace line."""
|
|
while True:
|
|
line = handle.readline()
|
|
# if line is empty or line has characters and stripping does not remove
|
|
# them, return the line
|
|
if (not line) or (line and line.strip()):
|
|
return line
|
|
|
|
|
|
def _read_header(handle, length):
|
|
"""Read the specified number of characters from the given handle.
|
|
|
|
Raise a ValueError("Empty file.") if the length of data read is zero. The
|
|
reason for having a separate function for the header is it enables raising
|
|
an empty file error if the length of the data read is zero. This might
|
|
not always be the case later in the file.
|
|
"""
|
|
data = handle.read(length)
|
|
if not data:
|
|
raise ValueError("Empty file.")
|
|
if len(data) < length:
|
|
raise ValueError("Improper header, cannot read %d bytes from handle" % length)
|
|
return data
|
|
|
|
|
|
def trim_str(string, max_len, concat_char):
|
|
"""Truncate the given string for display."""
|
|
if len(string) > max_len:
|
|
return string[:max_len - len(concat_char)] + concat_char
|
|
return string
|
|
|
|
|
|
def getattr_str(obj, attr, fmt=None, fallback="?"):
|
|
"""Return string of the given object's attribute.
|
|
|
|
Defaults to the given fallback value if attribute is not present.
|
|
"""
|
|
if hasattr(obj, attr):
|
|
if fmt is not None:
|
|
return fmt % getattr(obj, attr)
|
|
return str(getattr(obj, attr))
|
|
return fallback
|
|
|
|
|
|
def find_test_dir(start_dir=None):
|
|
"""Find the absolute path of Biopython's Tests directory.
|
|
|
|
Arguments:
|
|
start_dir -- Initial directory to begin lookup (default to current dir)
|
|
|
|
If the directory is not found up the filesystem's root directory, an
|
|
exception will be raised.
|
|
|
|
"""
|
|
if not start_dir:
|
|
# no callbacks in function signatures!
|
|
# defaults to the current directory
|
|
# (using __file__ would give the installed Biopython)
|
|
start_dir = "."
|
|
|
|
target = os.path.abspath(start_dir)
|
|
while True:
|
|
if os.path.isdir(os.path.join(target, "Bio")) and \
|
|
os.path.isdir(os.path.join(target, "Tests")):
|
|
# Good, we're in the Biopython root now
|
|
return os.path.abspath(os.path.join(target, "Tests"))
|
|
# Recurse up the tree
|
|
# TODO - Test this on Windows
|
|
new, tmp = os.path.split(target)
|
|
if target == new:
|
|
# Reached root
|
|
break
|
|
target = new
|
|
raise ValueError("Not within Biopython source tree: %r" %
|
|
os.path.abspath(start_dir))
|
|
|
|
|
|
def run_doctest(target_dir=None, *args, **kwargs):
|
|
"""Run doctest for the importing module."""
|
|
import doctest
|
|
|
|
# default doctest options
|
|
default_kwargs = {
|
|
"optionflags": doctest.ELLIPSIS,
|
|
}
|
|
kwargs.update(default_kwargs)
|
|
|
|
cur_dir = os.path.abspath(os.curdir)
|
|
|
|
print("Running doctests...")
|
|
try:
|
|
os.chdir(find_test_dir(target_dir))
|
|
doctest.testmod(*args, **kwargs)
|
|
finally:
|
|
# and revert back to initial directory
|
|
os.chdir(cur_dir)
|
|
print("Done")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run_doctest()
|