diff --git a/.github/workflows/python-testing.yml b/.github/workflows/python-testing.yml index f1dd709..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 setup.py 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/.gitignore b/.gitignore index 0e93bb2..16dc710 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,172 @@ env build/ dist/ -pyvnt.egg-info \ No newline at end of file +pyvnt.egg-info +manual_tests/* +**/__pycache__/* +.vscode + + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*.pyc +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ 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/__pycache__/test_pyvnt.cpython-312-pytest-8.2.0.pyc b/manual_tests/__pycache__/test_pyvnt.cpython-312-pytest-8.2.0.pyc deleted file mode 100644 index 3463b13..0000000 Binary files a/manual_tests/__pycache__/test_pyvnt.cpython-312-pytest-8.2.0.pyc and /dev/null differ 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/__pycache__/__init__.cpython-311.pyc b/pyvnt/DictionaryElement/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index e55751d..0000000 Binary files a/pyvnt/DictionaryElement/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/pyvnt/DictionaryElement/__pycache__/foamDS.cpython-311.pyc b/pyvnt/DictionaryElement/__pycache__/foamDS.cpython-311.pyc deleted file mode 100644 index 215e032..0000000 Binary files a/pyvnt/DictionaryElement/__pycache__/foamDS.cpython-311.pyc and /dev/null differ diff --git a/pyvnt/DictionaryElement/__pycache__/keyData.cpython-311.pyc b/pyvnt/DictionaryElement/__pycache__/keyData.cpython-311.pyc deleted file mode 100644 index d957d3d..0000000 Binary files a/pyvnt/DictionaryElement/__pycache__/keyData.cpython-311.pyc and /dev/null differ diff --git a/pyvnt/DictionaryElement/__pycache__/showTree.cpython-311.pyc b/pyvnt/DictionaryElement/__pycache__/showTree.cpython-311.pyc deleted file mode 100644 index 4971a29..0000000 Binary files a/pyvnt/DictionaryElement/__pycache__/showTree.cpython-311.pyc and /dev/null differ 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/__pycache__/__init__.cpython-311.pyc b/pyvnt/Reference/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 64d59a9..0000000 Binary files a/pyvnt/Reference/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/pyvnt/Reference/__pycache__/basic.cpython-311.pyc b/pyvnt/Reference/__pycache__/basic.cpython-311.pyc deleted file mode 100644 index c468e65..0000000 Binary files a/pyvnt/Reference/__pycache__/basic.cpython-311.pyc and /dev/null differ diff --git a/pyvnt/Reference/__pycache__/errorClasses.cpython-311.pyc b/pyvnt/Reference/__pycache__/errorClasses.cpython-311.pyc deleted file mode 100644 index dc4319a..0000000 Binary files a/pyvnt/Reference/__pycache__/errorClasses.cpython-311.pyc and /dev/null differ diff --git a/pyvnt/Reference/basic.py b/pyvnt/Reference/basic.py index b6279de..4b34408 100755 --- a/pyvnt/Reference/basic.py +++ b/pyvnt/Reference/basic.py @@ -73,6 +73,12 @@ def giveVal(self): def __repr__(self): return f"PropertyInt(name = {self._ValueProperty__name}, default = {self.__default}, minimum = {self.__minimum}, maximum = {self.__maximum})" + + def writeOut(self, file): + ''' + Function to write the object to a file + ''' + file.write(f"{self.__default}") class PropertyFloat(ValueProperty): @@ -127,6 +133,12 @@ def giveVal(self): def __repr__(self): return f"PropertyFloat(name = {self._ValueProperty__name}, default = {self.__default}, minimum = {self.__minimum}, maximum = {self.__maximum})" + + 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 @@ -266,4 +278,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/__pycache__/__init__.cpython-311.pyc b/pyvnt/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index d2350e4..0000000 Binary files a/pyvnt/__pycache__/__init__.cpython-311.pyc and /dev/null differ 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/__pycache__/test_basic.cpython-312-pytest-8.2.0.pyc b/tests/__pycache__/test_basic.cpython-312-pytest-8.2.0.pyc deleted file mode 100644 index 6e4e529..0000000 Binary files a/tests/__pycache__/test_basic.cpython-312-pytest-8.2.0.pyc and /dev/null differ diff --git a/tests/__pycache__/test_keyData.cpython-312-pytest-8.2.0.pyc b/tests/__pycache__/test_keyData.cpython-312-pytest-8.2.0.pyc deleted file mode 100644 index 6ad8185..0000000 Binary files a/tests/__pycache__/test_keyData.cpython-312-pytest-8.2.0.pyc and /dev/null differ diff --git a/tests/__pycache__/test_node.cpython-312-pytest-8.2.0.pyc b/tests/__pycache__/test_node.cpython-312-pytest-8.2.0.pyc deleted file mode 100644 index 7de7234..0000000 Binary files a/tests/__pycache__/test_node.cpython-312-pytest-8.2.0.pyc and /dev/null differ diff --git a/tests/__pycache__/test_pyvnt.cpython-312-pytest-8.2.0.pyc b/tests/__pycache__/test_pyvnt.cpython-312-pytest-8.2.0.pyc deleted file mode 100644 index b68eaf3..0000000 Binary files a/tests/__pycache__/test_pyvnt.cpython-312-pytest-8.2.0.pyc and /dev/null differ 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