Skip to content

Commit

Permalink
Merge branch 'master' of ssh://github.com/KarrLab/wc_utils
Browse files Browse the repository at this point in the history
  • Loading branch information
jonrkarr committed Mar 8, 2019
2 parents 3e296de + b423930 commit 70b3f21
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
37 changes: 37 additions & 0 deletions tests/util/test_files.py
@@ -1,6 +1,7 @@
""" Tests of the file utilities
:Author: Jonathan Karr <jonrkarr@gmail.com>
:Author: Arthur Goldberg <Arthur.Goldberg@mssm.edu>
:Date: 2018-05-11
:Copyright: 2018, Karr Lab
:License: MIT
Expand All @@ -11,9 +12,12 @@
import shutil
import tempfile
import unittest
import getpass
from pathlib import Path


class FileUtilsTestCase(unittest.TestCase):

def setUp(self):
self.dirname = tempfile.mkdtemp()

Expand Down Expand Up @@ -60,3 +64,36 @@ def test_copytree_to_existing_destination(self):
files.copytree_to_existing_destination(os.path.join(base, 'a', 'b', 'c'), os.path.join(base, 'D'))
with open(os.path.join(base, 'D'), 'r') as file:
self.assertEqual(file.read(), '3')

def test_normalize_filename(self):
normalize_filename = files.normalize_filename

self.assertEqual(normalize_filename('~'), normalize_filename('~' + getpass.getuser()))
self.assertEqual(normalize_filename('~'), normalize_filename('$HOME'))
cur_dir = os.path.dirname(__file__)
self.assertEqual(cur_dir,
normalize_filename(os.path.join(cur_dir, '..', os.path.basename(cur_dir))))
test_filename = os.path.join(cur_dir, 'test_filename')
self.assertEqual(test_filename, normalize_filename('test_filename', dir=os.path.dirname(test_filename)))
self.assertEqual(os.path.join(os.getcwd(), 'test_filename'), normalize_filename('test_filename'))
with self.assertRaisesRegex(ValueError, r"directory '.+' isn't absolute"):
normalize_filename('test_filename', dir='~')

def test_normalize_filenames(self):
tmp_path = os.path.join(self.dirname, 'foo')
self.assertEqual(files.normalize_filenames([tmp_path]), [tmp_path])
file_in_dir = os.path.join('dir_name', 'bar')
expected_abs_file_in_dir = os.path.join(self.dirname, file_in_dir)
self.assertEqual(files.normalize_filenames([tmp_path, file_in_dir], absolute_file=tmp_path),
[tmp_path, expected_abs_file_in_dir])

def test_remove_silently(self):
test_file = os.path.join(self.dirname, 'test_file')
Path(test_file).touch()
self.assertEqual(files.remove_silently(test_file), None)

no_such_file = os.path.join(self.dirname, 'no_such_file')
self.assertEqual(files.remove_silently(no_such_file), None)

with self.assertRaises(TypeError):
files.remove_silently(12)
66 changes: 66 additions & 0 deletions wc_utils/util/files.py
@@ -1,13 +1,15 @@
""" File utils
:Author: Jonathan Karr <karr@mssm.edu>
:Author: Arthur Goldberg <Arthur.Goldberg@mssm.edu>
:Date: 2018-05-11
:Copyright: 2018, Karr Lab
:License: MIT
"""

import os
import shutil
import errno


def copytree_to_existing_destination(src, dst):
Expand Down Expand Up @@ -35,3 +37,67 @@ def copytree_to_existing_destination(src, dst):
shutil.copy2(s, d)
else:
shutil.copy2(src, dst)


def normalize_filename(filename, dir=None):
""" Normalize a filename to its fully expanded, real, absolute path
Expand `filename` by interpreting a user’s home directory, environment variables, and
normalizing its path. If `filename` is not an absolute path and `dir` is provided then
return a full path of `filename` in `dir`.
Args:
filename (:obj:`str`): a filename
dir (:obj:`str`, optional): a directory that contains `filename`
Returns:
:obj:`str`: `filename`'s fully expanded, absolute path
Raises:
:obj:`ValueError`: if neither `filename` after expansion nor `dir` are absolute
"""
filename = os.path.expanduser(filename)
filename = os.path.expandvars(filename)
if os.path.isabs(filename):
return os.path.normpath(filename)
elif dir:
# raise exception if dir isn't absolute
if not os.path.isabs(dir):
raise ValueError("directory '{}' isn't absolute".format(dir))
return os.path.normpath(os.path.join(dir, filename))
else:
return os.path.abspath(filename)


def normalize_filenames(filenames, absolute_file=None):
""" Normalize filenames relative to directory containing existing file
Args:
filenames (:obj:`list` of :obj:`str`): list of filenames
absolute_file (:obj:`str`, optional): file whose directory contains files in `filenames`
Returns:
:obj:`list` of :obj:`str`: absolute paths for files in `filenames`
"""
dir = None
if absolute_file:
dir = os.path.dirname(absolute_file)
return [normalize_filename(filename, dir=dir) for filename in filenames]


def remove_silently(filename):
""" Delete file `filename` if it exist, but report no error if it doesn't
Args:
filename (:obj:`str`): a filename
Raises:
:obj:`Exception`: if an error occurs that is not 'no such file or directory'
"""
try:
os.remove(filename)
except OSError as e:
# errno.ENOENT: no such file or directory
if e.errno != errno.ENOENT:
# re-raise exception if a different error occurred
raise # pragma: no cover; unclear how to execute this line

0 comments on commit 70b3f21

Please sign in to comment.