diff --git a/.gitignore b/.gitignore index 0cf09db..49fdb19 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .vscode *.pickle +test.py # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/README.md b/README.md index ae2e97a..3f887c3 100644 --- a/README.md +++ b/README.md @@ -100,29 +100,27 @@ my_class_instance.set_title("Test") my_class_instance.save() ``` -### Instance initialization +### Override the \_\_init\_\_ method -#### Override the \_\_init\_\_ method - -The `__init__` method can be overrided to provide default configurations, like for example -the saving path in below example. +The `__init__` method can be overrided to add attributes and provide default configurations, +like for example the saving path in below example. Remember that the `super()` call should +be always done at the end. ```python class MyClass(Pyrmanent): def __init__(self, name, autosave=True): + self.first_value = 1 + self.second_value = 2 super().__init__(name=name, folder="data", autosave=autosave) ``` -#### The init method +### Reset instance data -On the other hand, you can define the `init` method (without the underscores) to initialize -attribute values. This method is called before saving the instance data for the first time. +To reset instance data, call the `reset` method and then initialize the instance again. ```python -class MyClass(Pyrmanent): - def init(self): - self.first_value = 1 - self.second_value = 2 +my_class_instance.reset() +my_class_instance = MyClass() ``` ### Use dill instead of pickle diff --git a/pyrmanent/pyrmanent_class.py b/pyrmanent/pyrmanent_class.py index f4a858d..fb6a80b 100644 --- a/pyrmanent/pyrmanent_class.py +++ b/pyrmanent/pyrmanent_class.py @@ -1,3 +1,4 @@ +import inspect import os from pickle import UnpicklingError @@ -34,7 +35,6 @@ def __init__(self, name="", folder="", autosave=True): self._create_folder(folder) if not self.load(): - self.init() self.save() def load(self): @@ -69,9 +69,12 @@ def autosave(self): if self._autosave: self.save() - def init(self): - """This method is called before saving the instance data for the first time. - You can initialize attribute values by replacing this with your own method.""" + def reset(self): + try: + os.remove(self._path) + except OSError as exc: + exc_msg = "File %s not deleted: %s" % (self._filename, exc) + raise PyrmanentError(exc_msg) from exc def _create_folder(self, folder): self._prepare_path(folder) @@ -80,8 +83,8 @@ def _create_folder(self, folder): try: os.makedirs(self._folder) except OSError as exc: - exc_msg = "Folder creation error for %s: %s" - raise PyrmanentError(exc_msg, self._filename, exc) from exc + exc_msg = "Folder creation error for %s: %s" % (self._filename, exc) + raise PyrmanentError(exc_msg) from exc def _prepare_path(self, folder): if folder: diff --git a/setup.py b/setup.py index 175fcd0..22ad6b9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pyrmanent", - version="1.0.1", + version="1.1.0", author="Sergio Abad", author_email="sergio.abad@bytelix.com", description="Make all your classes permanent in a flash", diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_attributes.py b/tests/test_attributes.py new file mode 100644 index 0000000..cf6ac1a --- /dev/null +++ b/tests/test_attributes.py @@ -0,0 +1,35 @@ +import os +import unittest + +from pyrmanent import Pyrmanent + + +class Example(Pyrmanent): + def __init__(self): + self.menu = "pizza" + if hasattr(self, "updated"): + self.drink = "cola" + super().__init__() + + +class TestAttributes(unittest.TestCase): + def test_attributes(self): + self._clean() + example = Example() + self.assertTrue(hasattr(example, "menu")) + self.assertFalse(hasattr(example, "drink")) + + def test_attributes_updated(self): + example = Example() + example.updated = True + example.__init__() + + self.assertEqual("cola", example.drink) + self._clean() + + @staticmethod + def _clean(): + try: + os.remove("Example.pickle") + except OSError: + pass diff --git a/tests/test_files.py b/tests/test_files.py index 4630867..b63c6a7 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -13,14 +13,28 @@ class TestFiles(unittest.TestCase): def test_pickle_file(self): Example() self.assertTrue(os.path.isfile("Example.pickle")) - os.remove("Example.pickle") def test_custom_folder(self): Example(folder="saves") self.assertTrue(os.path.isfile("saves/Example.pickle")) - shutil.rmtree("saves") def test_custom_nested_folder(self): Example(folder="saves/data") self.assertTrue(os.path.isfile("saves/data/Example.pickle")) - shutil.rmtree("saves") + + def setUp(self): + self._clean() + + def tearDown(self): + self._clean() + + @staticmethod + def _clean(): + try: + os.remove("Example.pickle") + except OSError: + pass + try: + shutil.rmtree("saves") + except OSError: + pass diff --git a/tests/test_name.py b/tests/test_name.py index de5c988..b65f35f 100644 --- a/tests/test_name.py +++ b/tests/test_name.py @@ -18,3 +18,17 @@ def test_no_custom_name(self): Example() self.assertTrue(os.path.isfile("Example.pickle")) os.remove("Example.pickle") + + def setUp(self): + self._clean() + + def tearDown(self): + self._clean() + + @staticmethod + def _clean(): + for file in ["Example", "Example_foo"]: + try: + os.remove(file + ".pickle") + except OSError: + pass diff --git a/tests/test_persistency.py b/tests/test_persistency.py index 40cc9f3..0922ff2 100644 --- a/tests/test_persistency.py +++ b/tests/test_persistency.py @@ -5,8 +5,9 @@ class Example(Pyrmanent): - def init(self): + def __init__(self, name=""): self.menu = "pizza" + super().__init__(name=name) class TestPersistency(unittest.TestCase): @@ -14,7 +15,6 @@ def test_init_values(self): example = Example() self.assertTrue(hasattr(example, "menu")) self.assertEqual(example.menu, "pizza") - os.remove("Example.pickle") def test_not_saved_values(self): example = Example() @@ -22,7 +22,6 @@ def test_not_saved_values(self): example = Example() self.assertTrue(hasattr(example, "menu")) self.assertEqual(example.menu, "pizza") - os.remove("Example.pickle") def test_saved_values(self): example = Example() @@ -31,7 +30,6 @@ def test_saved_values(self): example = Example() self.assertTrue(hasattr(example, "menu")) self.assertEqual(example.menu, "rice") - os.remove("Example.pickle") def test_values_for_different_names(self): first = Example(name="first") @@ -46,5 +44,17 @@ def test_values_for_different_names(self): self.assertTrue(hasattr(second, "menu")) self.assertEqual(first.menu, "rice") self.assertEqual(second.menu, "soup") - os.remove("Example_first.pickle") - os.remove("Example_second.pickle") + + def setUp(self): + self._clean() + + def tearDown(self): + self._clean() + + @staticmethod + def _clean(): + for file in ["Example", "Example_first", "Example_second"]: + try: + os.remove(file + ".pickle") + except OSError: + pass diff --git a/tests/test_reset.py b/tests/test_reset.py new file mode 100644 index 0000000..62f9337 --- /dev/null +++ b/tests/test_reset.py @@ -0,0 +1,38 @@ +import os +import unittest + +from pyrmanent import Pyrmanent + + +class Example(Pyrmanent): + def __init__(self): + self.menu = "pizza" + super().__init__() + + +class TestReset(unittest.TestCase): + def test_reset(self): + example = Example() + example.menu = "rice" + example.drink = "cola" + example.save() + self.assertEqual(example.menu, "rice") + self.assertTrue(hasattr(example, "drink")) + + example.reset() + example = Example() + self.assertEqual(example.menu, "pizza") + self.assertFalse(hasattr(example, "drink")) + + def setUp(self): + self._clean() + + def tearDown(self): + self._clean() + + @staticmethod + def _clean(): + try: + os.remove("Example.pickle") + except OSError: + pass