diff --git a/.github/workflows/python-testing.yml b/.github/workflows/python-testing.yml index 787399a..1e7670a 100644 --- a/.github/workflows/python-testing.yml +++ b/.github/workflows/python-testing.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 @@ -24,12 +24,12 @@ jobs: uses: actions/setup-python@v3 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Install dependencies and build package run: | python -m pip install --upgrade pip - python -m pip install pytest anytree setuptools wheel - python setup.py sdist bdist_wheel - python -m pip install . + python -m pip install pytest anytree setuptools wheel build + python -m build + pip install dist/*.whl - name: Test with pytest run: | - pytest -v \ No newline at end of file + pytest -v tests/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bcea480 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "files.associations": { + "dictionaryFile.C": "cpp" + }, + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} \ No newline at end of file diff --git a/manual_tests/test_pyvnt.py b/manual_tests/test_pyvnt.py index 477429e..f54e1d7 100755 --- a/manual_tests/test_pyvnt.py +++ b/manual_tests/test_pyvnt.py @@ -9,7 +9,7 @@ # set up automated tests for CI/CD in github # test for KeyData and Foam classes -''' + key1 = KeyData('solver', prop1, prop2) print(key1.giveVal()) head = Foam("test_head",None, None) @@ -19,19 +19,21 @@ child1 = Foam('test_child', head, None) child2 = Foam('test_child2', child1, None, key1) child3 = Foam('test_child3', child1, None, key1) -''' + # Display tests -''' -print(head) + +# print(head) showTree(head) -print(RenderTree(child1).by_attr()) -''' +# print(RenderTree(child1).by_attr()) + # Test for Keydata class singularily -key1 = KeyData('solver', prop1) -print(key1) +# key1 = KeyData('solver', prop1) +# print(key1) + +writeTo(head, 'testFile.txt') diff --git a/manual_tests/treeTest.py b/manual_tests/treeTest.py index 656dd7d..dde0a62 100755 --- a/manual_tests/treeTest.py +++ b/manual_tests/treeTest.py @@ -1,11 +1,11 @@ -from .pyvnt.DictionaryElement.foamDS import * -from .pyvnt.DictionaryElement.keyData import * -from .pyvnt.Reference.basic import * +from pyvnt import * prop1 = EnumProp('val1', items={'PCG', 'PBiCG', 'PBiCGStab'}, default='PCG') key1 = KeyData('solver', prop1) -head = Foam(name="test_head", children = [key1]) +head = Foam("test_head", None, None, key1) -head.dispTree() \ No newline at end of file +# head.dispTree() + +showTree(head) \ No newline at end of file diff --git a/pyvnt/Converter/Writer/__init__.py b/pyvnt/Converter/Writer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyvnt/Converter/Writer/writer.py b/pyvnt/Converter/Writer/writer.py new file mode 100644 index 0000000..6e89ae7 --- /dev/null +++ b/pyvnt/Converter/Writer/writer.py @@ -0,0 +1,13 @@ +from pyvnt.DictionaryElement import * + +def writeTo(root, path): + ''' + Function to write the dictionary object to the file + + Parameters: + Foam: Dictionary object to be written + path: Path to the file where the dictionary object is to be written + + ''' + with open(path, "w") as file: + root.writeOut(file) \ No newline at end of file diff --git a/pyvnt/Converter/__init__.py b/pyvnt/Converter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyvnt/DictionaryElement/foamDS.py b/pyvnt/DictionaryElement/foamDS.py index 542cece..fadc543 100755 --- a/pyvnt/DictionaryElement/foamDS.py +++ b/pyvnt/DictionaryElement/foamDS.py @@ -3,6 +3,7 @@ from typing import Any, Type from pyvnt.DictionaryElement.keyData import KeyData from pyvnt.Reference.errorClasses import * +from pyvnt.utils.makeIndent import makeIndent ''' Criteria for classes: @@ -134,5 +135,41 @@ def reorderData(self, data: KeyData, pos: int): self.data.insert(data, pos) except: raise AttributeError(f"{data.name} does not exist in this node") + + def writeOut(self, file, indent = 0): + ''' + Function to write the current node to the file + ''' + + ''' + if self.parent == None: + # TODO: Add the header to the file + pass + else: + file.write(f"{self.name}\n") + file.write("{\n") + for d in self.data: + file.write("\t") + d.writeOut(file) + file.write("}\n") + ''' + + makeIndent(file, indent) + file.write(f"{self.name}\n") + + makeIndent(file, indent) + file.write("{\n") + + for d in self.data: + d.writeOut(file, indent+1) + + # makeIndent(file, indent) + + for child in self.children: + child.writeOut(file, indent+1) + file.write("\n") + + makeIndent(file, indent) + file.write("}\n") diff --git a/pyvnt/DictionaryElement/keyData.py b/pyvnt/DictionaryElement/keyData.py index 894615d..9469b33 100755 --- a/pyvnt/DictionaryElement/keyData.py +++ b/pyvnt/DictionaryElement/keyData.py @@ -2,6 +2,7 @@ from collections import OrderedDict from anytree import NodeMixin from pyvnt.Reference.basic import * +from pyvnt.utils.makeIndent import makeIndent ''' @@ -71,7 +72,7 @@ def __setattr__(self, key, value): def appendVal(self, key: "str", val: ValueProperty): self._privateDict[key] = val - """ + ''' # TODO: Take input of the object to be replaced or the obejct name instead of the variable name as the string. -- done in replaceVal2 This piece of code is here to remind devs about what not to do @@ -107,7 +108,7 @@ def replaceVal2(self, old: ValueProperty | str, new: ValueProperty): for k, v in list(self.__dict__.items()): self.__dict__[replacement.get(k, k)] = self.__dict__.pop(k) self.__dict__[newKey] = new - """ + ''' def replaceVal(self, old: ValueProperty or str, new: ValueProperty): # uses orderedDict instead of regular Dictionary ''' @@ -147,9 +148,12 @@ def delVal(self, key: str): del self._privateDict[key] def __repr__(self): + last_elem = list(self._privateDict.keys())[-1] res_str = f"KeyData(" for key, val in self._privateDict.items(): - res_str = res_str + f"{key} : {val}, " + res_str = res_str + f"{key} : {val}" + if key != last_elem: + res_str = res_str + ", " res_str = res_str + ")" return res_str @@ -158,11 +162,30 @@ def giveVal(self): ''' Function to get all the keys and values stored in the object in a text format ''' + last_elem = list(self._privateDict.keys())[-1] + res = f"{self.name} : " for key, val in self._privateDict.items(): if key == 'name': continue else: - res = res + f"{val.giveVal()}, " + res = res + f"{val.giveVal()}" + if key != last_elem: + res = res + ", " - return res \ No newline at end of file + return res + + def writeOut(self, file, indent = 0): + ''' + Function to write the object to a file + ''' + col_width = 16 + last_elem = list(self._privateDict.keys())[-1] + + makeIndent(file, indent) + file.write(f"{self.name.ljust(col_width)}") + for key, val in self._privateDict.items(): + val.writeOut(file) + if key != last_elem: + file.write(" ") + file.write(";\n") \ No newline at end of file diff --git a/pyvnt/Reference/basic.py b/pyvnt/Reference/basic.py index 8be129c..9525d2d 100755 --- a/pyvnt/Reference/basic.py +++ b/pyvnt/Reference/basic.py @@ -104,6 +104,13 @@ def __eq__(self, other): def __ne__(self, other): return self.__default != other._PropertyFloat__default + def writeOut(self, file): + ''' + Function to write the object to a file + ''' + file.write(f"{self.__default}") + + class PropertyFloat(ValueProperty): ''' @@ -187,6 +194,13 @@ def __eq__(self, other): def __ne__(self, other): return self.__default != other._PropertyFloat__default + + def writeOut(self, file): + ''' + Function to write the object to a file + ''' + file.write(f"{self.__default}") + class PropertyString(ValueProperty): # for testing purposes only, to be scrapped @@ -326,4 +340,10 @@ def giveVal(self): Funciton to return the current value of the property ''' res = self.__default - return res \ No newline at end of file + return res + + def writeOut(self, file): + ''' + Function to write the object to a file + ''' + file.write(f"{self.__default}") \ No newline at end of file diff --git a/pyvnt/__init__.py b/pyvnt/__init__.py index f3073cd..e147810 100755 --- a/pyvnt/__init__.py +++ b/pyvnt/__init__.py @@ -1,4 +1,6 @@ from pyvnt.Reference.basic import * from pyvnt.DictionaryElement.foamDS import * -from pyvnt.DictionaryElement.showTree import * from pyvnt.DictionaryElement.keyData import * +from pyvnt.Converter.Writer.writer import * +from pyvnt.utils import * +from pyvnt.utils.showTree import * diff --git a/pyvnt/utils/__init__.py b/pyvnt/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyvnt/utils/makeIndent.py b/pyvnt/utils/makeIndent.py new file mode 100644 index 0000000..041f5ef --- /dev/null +++ b/pyvnt/utils/makeIndent.py @@ -0,0 +1,5 @@ + + +def makeIndent(file, indent: int): + for i in range(indent): + file.write("\t") \ No newline at end of file diff --git a/pyvnt/DictionaryElement/showTree.py b/pyvnt/utils/showTree.py similarity index 100% rename from pyvnt/DictionaryElement/showTree.py rename to pyvnt/utils/showTree.py diff --git a/setup.py b/setup.py index 09b370d..3d39964 100755 --- a/setup.py +++ b/setup.py @@ -12,8 +12,15 @@ author="", author_email="", description=DESCRIPTION, - packages_dir={"": "pyvnt"}, - packages=find_packages(exclude=['test']), + # packages_dir={"": "pyvnt"}, + # data_files=[('Shared_Objects', [ + # './pyvnt/Converter/cpp_src/dictionaryFile/lib/dictionaryFile.so', + # './pyvnt/Converter/cpp_src/dictionaryFileIterator/lib/dictionaryFileIterator.so' + # ])], + packages=find_packages(include=['pyvnt', 'pyvnt.*']), + # py_modules=['pyvnt'], + # include_package_data=True, + # package_data={'': ['./pyvnt/Converter/cpp_src/dictionaryFile/lib/dictionaryFile.so', './pyvnt/Converter/cpp_src/dictionaryFileIterator/lib/dictionaryFileIterator.so']}, install_requires=['anytree', 'dataclasses'], keywords=['python'], classifiers=[ diff --git a/testFile.txt b/testFile.txt new file mode 100644 index 0000000..5b57149 --- /dev/null +++ b/testFile.txt @@ -0,0 +1,17 @@ +test_head +{ + test_child + { + test_child2 + { + solver PCG PBiCG; + } + + test_child3 + { + solver PCG PBiCG; + } + + } + +} diff --git a/tests/test_keyData.py b/tests/test_keyData.py index ed8a687..ac715fd 100644 --- a/tests/test_keyData.py +++ b/tests/test_keyData.py @@ -17,25 +17,25 @@ def teardown_method(self, method): del self.items def test_keyData_print(self): - assert str(self.key1) == f"KeyData(val1 : {str(self.prop1)}, val2 : {str(self.prop2)}, )" + assert str(self.key1) == f"KeyData(val1 : {str(self.prop1)}, val2 : {str(self.prop2)})" def test_keyData_val(self): - assert self.key1.giveVal() == f"solver : {self.prop1.giveVal()}, {self.prop2.giveVal()}, " + assert self.key1.giveVal() == f"solver : {self.prop1.giveVal()}, {self.prop2.giveVal()}" def test_keyData_edit(self): tmp_prop1 = PropertyInt('tmpval1', 2, 1, 10) tmp_prop2 = PropertyInt('tmpval2', 3, 1, 10) self.key1.replaceVal('val1', tmp_prop1) - assert self.key1.giveVal() == f"solver : {tmp_prop1.giveVal()}, {self.prop2.giveVal()}, " + assert self.key1.giveVal() == f"solver : {tmp_prop1.giveVal()}, {self.prop2.giveVal()}" self.key1.replaceVal(self.prop2, tmp_prop2) - assert self.key1.giveVal() == f"solver : {tmp_prop1.giveVal()}, {tmp_prop2.giveVal()}, " + assert self.key1.giveVal() == f"solver : {tmp_prop1.giveVal()}, {tmp_prop2.giveVal()}" tmp_prop3 = PropertyInt('tmpval2', 4, 1, 10) self.key1.replaceVal(tmp_prop2, tmp_prop3) - assert self.key1.giveVal() == f"solver : {tmp_prop1.giveVal()}, {tmp_prop3.giveVal()}, " + assert self.key1.giveVal() == f"solver : {tmp_prop1.giveVal()}, {tmp_prop3.giveVal()}" def test_keyData_edit_fail(self): tmp_prop1 = PropertyInt('tmpval1', 2, 1, 10) @@ -52,6 +52,6 @@ def test_keyData_edit_fail(self): def test_keyData_del(self): self.key1.delVal('val1') - assert self.key1.giveVal() == f"solver : {self.prop2.giveVal()}, " + assert self.key1.giveVal() == f"solver : {self.prop2.giveVal()}" \ No newline at end of file