From fececdaceaf189c4fb6996ca4d3a9816c43c20e8 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Thu, 1 Nov 2018 17:24:15 +0530 Subject: [PATCH 1/3] Added support from Folder Dict, Now you can create a Dict for a folder and access their files like a dictionary --- boltons/folderdict.py | 94 ++++++++++++++++++++++++++++++++++++++++ tests/test_folderdict.py | 46 ++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 boltons/folderdict.py create mode 100644 tests/test_folderdict.py diff --git a/boltons/folderdict.py b/boltons/folderdict.py new file mode 100644 index 00000000..5a28598c --- /dev/null +++ b/boltons/folderdict.py @@ -0,0 +1,94 @@ +""" +A representation of a folder in the form of dictionary +So, you can access any directory in the form of a dict. +Keys - Files in the folder +Values - Their content + +CONSTRAINT:- +1) It supports files opened in r and w mode. Not in rb or wb mode. +2) No support for appending to a file +3) No support for setdefault + + +For example +folder_dict = FolderDict(FOLDER_PATH) + + +""" +import os + + +class FolderDict(dict): + + def get_absolute_path(self, file_name): + return os.path.join(self.folder_path, file_name) + + def get_only_files(self): + yield from [self.get_absolute_path(file_name) for file_name in os.listdir(self.folder_path) + if os.path.isfile(self.get_absolute_path(file_name))] + + def __init__(self, folder_path, create_new=False): + super().__init__() + self.folder_path = folder_path + self._dict = {} + if os.path.exists(self.folder_path) and os.path.isdir(self.folder_path): + for absolute_file_path in self.get_only_files(): + file_name = os.path.split(absolute_file_path)[1] + with open(absolute_file_path, "r") as reader: + self._dict[file_name] = reader.read() + else: + if create_new: + os.makedirs(folder_path, exist_ok=True) + else: + raise FileNotFoundError("[Errno 2] No such file or directory: '{}'".format(self.folder_path)) + + def __getitem__(self, item): + """ + https://stackoverflow.com/questions/20677923/python-print-last-traceback-only + We'll swallow the KeyError and we'll just raise FNF, as that's what the KeyError specifies + """ + try: + return self._dict[item] + except KeyError: + raise FileNotFoundError("[Errno 2] No such file or directory: '{}'". + format(os.path.join(self.folder_path, item))) from None + + def __setitem__(self, key, value): + """ + Be careful,it will overwrite the existing file. + We support w mode not a mode now + """ + with open(self.get_absolute_path(key), "w") as writer: + self._dict[key] = value + writer.write(value) + + def keys(self): + return self._dict.keys() + + def __iter__(self): + yield from self.keys() + + def values(self): + yield from [self._dict[key] for key in self.keys()] + + def items(self): + yield from [(k,self[k]) for k in self.keys()] + + def __contains__(self, item): + return item in self.keys() + + def __delitem__(self, key): + del self._dict[key] + os.remove(self.get_absolute_path(key)) + + def get(self, k, default=None): + return self[k] if k in self.keys() else default + + def pop(self, k): + content = self[k] + self.__delitem__(k) + return content + + def __repr__(self): + return "FolderDict({!r})".format(self.folder_path) + diff --git a/tests/test_folderdict.py b/tests/test_folderdict.py new file mode 100644 index 00000000..df7dce4a --- /dev/null +++ b/tests/test_folderdict.py @@ -0,0 +1,46 @@ +""" +Use named temporary folder to fecilitate test cases, +Write test cases for +1) get,set,delete +2) file not found error +3) keys +4) contains +""" +import tempfile +import os + +from boltons.folderdict import FolderDict + +with tempfile.TemporaryDirectory() as directory_name: + folder_dict = FolderDict(directory_name) + folder_dict["File1"] = "Sample file1" + + assert os.listdir(directory_name) == ["File1"] + assert open(os.path.join(directory_name, "File1")).read() == "Sample file1" + + val = folder_dict.pop("File1") + assert val == "Sample file1" + + try: + new_value = folder_dict["Another File"] + except FileNotFoundError: + val = "Correct exception raised" + + assert val == "Correct exception raised" + + folder_dict["File2"] = "Sample file2" + folder_dict["File3"] = "Sample file3" + folder_dict["File4"] = "Sample file4" + + assert sorted(os.listdir(directory_name)) == sorted(folder_dict.keys()) + + assert os.path.isfile(os.path.join(directory_name, "File2")) + assert os.path.isfile(os.path.join(directory_name, "File3")) + + + + + + + + From 34167461597d1c94f06c3f8162f4643167cadf13 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 2 Nov 2018 09:49:14 +0530 Subject: [PATCH 2/3] Added support for python 2.x --- boltons/folderdict.py | 24 +++++++++++++----------- tests/test_folderdict.py | 32 ++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/boltons/folderdict.py b/boltons/folderdict.py index 5a28598c..ae2b8fa6 100644 --- a/boltons/folderdict.py +++ b/boltons/folderdict.py @@ -12,8 +12,6 @@ For example folder_dict = FolderDict(FOLDER_PATH) - - """ import os @@ -24,11 +22,12 @@ def get_absolute_path(self, file_name): return os.path.join(self.folder_path, file_name) def get_only_files(self): - yield from [self.get_absolute_path(file_name) for file_name in os.listdir(self.folder_path) - if os.path.isfile(self.get_absolute_path(file_name))] + for file_name in os.listdir(self.folder_path): + absolute_file_path = self.get_absolute_path(file_name) + if os.path.isfile(absolute_file_path): + yield absolute_file_path def __init__(self, folder_path, create_new=False): - super().__init__() self.folder_path = folder_path self._dict = {} if os.path.exists(self.folder_path) and os.path.isdir(self.folder_path): @@ -40,7 +39,7 @@ def __init__(self, folder_path, create_new=False): if create_new: os.makedirs(folder_path, exist_ok=True) else: - raise FileNotFoundError("[Errno 2] No such file or directory: '{}'".format(self.folder_path)) + raise IOError("[Errno 2] No such file or directory: '{}'".format(self.folder_path)) def __getitem__(self, item): """ @@ -50,8 +49,8 @@ def __getitem__(self, item): try: return self._dict[item] except KeyError: - raise FileNotFoundError("[Errno 2] No such file or directory: '{}'". - format(os.path.join(self.folder_path, item))) from None + raise IOError("[Errno 2] No such file or directory: '{}'". + format(os.path.join(self.folder_path, item))) def __setitem__(self, key, value): """ @@ -66,13 +65,16 @@ def keys(self): return self._dict.keys() def __iter__(self): - yield from self.keys() + for key in self.keys(): + yield key def values(self): - yield from [self._dict[key] for key in self.keys()] + for key in self.keys(): + yield self._dict[key] def items(self): - yield from [(k,self[k]) for k in self.keys()] + for key in self.keys(): + yield key, self[key] def __contains__(self, item): return item in self.keys() diff --git a/tests/test_folderdict.py b/tests/test_folderdict.py index df7dce4a..1b9c881f 100644 --- a/tests/test_folderdict.py +++ b/tests/test_folderdict.py @@ -1,17 +1,25 @@ -""" -Use named temporary folder to fecilitate test cases, -Write test cases for -1) get,set,delete -2) file not found error -3) keys -4) contains -""" -import tempfile import os - +from contextlib import contextmanager +from tempfile import mkdtemp +import shutil from boltons.folderdict import FolderDict -with tempfile.TemporaryDirectory() as directory_name: + +@contextmanager +def temporary_directory(): + name = mkdtemp() + try: + yield name + finally: + shutil.rmtree(name) + +# Dirty hack to support python 2.x +try: + from tempfile import TemporaryDirectory +except ImportError: + TemporaryDirectory = temporary_directory + +with TemporaryDirectory() as directory_name: folder_dict = FolderDict(directory_name) folder_dict["File1"] = "Sample file1" @@ -23,7 +31,7 @@ try: new_value = folder_dict["Another File"] - except FileNotFoundError: + except IOError: val = "Correct exception raised" assert val == "Correct exception raised" From adca3582c943b49415ead081328868deeabaeaad Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 2 Nov 2018 09:58:55 +0530 Subject: [PATCH 3/3] Added indices in format specs to support OLD version 2.6 --- boltons/folderdict.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boltons/folderdict.py b/boltons/folderdict.py index ae2b8fa6..2574d99d 100644 --- a/boltons/folderdict.py +++ b/boltons/folderdict.py @@ -39,7 +39,7 @@ def __init__(self, folder_path, create_new=False): if create_new: os.makedirs(folder_path, exist_ok=True) else: - raise IOError("[Errno 2] No such file or directory: '{}'".format(self.folder_path)) + raise IOError("[Errno 2] No such file or directory: '{0}'".format(self.folder_path)) def __getitem__(self, item): """ @@ -49,7 +49,7 @@ def __getitem__(self, item): try: return self._dict[item] except KeyError: - raise IOError("[Errno 2] No such file or directory: '{}'". + raise IOError("[Errno 2] No such file or directory: '{0}'". format(os.path.join(self.folder_path, item))) def __setitem__(self, key, value):