Archived Tasking Documentation - DevOps-MBSE/AaC GitHub Wiki
Below will be a collection of evaluations and documentation around previously worked items so that the thoughts and design decisions are captured for future efforts with current development effort being put on hold.
Project configuration with setup.py, which is an executable file that contains a build script, was standard python practice for many years. Recently, however, the usage of a non-executable pyproject.toml file, which contains project configurations in a much more secure way, is preferred practice.
Making Sense of pyproject.toml, setup.cfg, and setup.py - DEV Community
Below are several changes that will need to be implemented for a future AaC build system migration:
The primary difference between setup.py and pyproject.toml is that setup.py files have the project configurations listed in the setup method call, while pyproject.toml files are configuration files with several tables where the settings are listed.
A MANIFEST.in file is required for TOML build chains. It will need to be created if it does not already exist.
graft src
graft tests
include tox.ini
include src/aac/aac.aac
For toml builds, a .python-version file is required, which is just a text file that contains the desired version. For setup.py builds, the system version is used, so a .python-version file will need to be created during a transition.
setup.py files have the project configurations listed in the setup call pyproject.toml files are configuration files with several headers where the settings are listed.
The only change required is in the Build distribution package step. In setup.py chains, this build step calls setup.py to create a wheel file. run: python setup.py bdist_wheel
In toml chains, you build python directly. run: python -m build
No large changes would be required for the tox.ini file. The only necessary adjustment is using python -m unittest instead of the nose command for testing, and potentially adjusting python versioning, since it will no longer just use the system python version.
Resources that could be useful for writing pyproject.toml files: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#dependencies-and-requirements
The pyproject.toml file for a future build chain migration of AaC will look like the following: [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta"
[project] name = "aac" version = "0.4.18" authors = [ { name="bunchw", email="asdfasdaf@email.com" }, { name="lizzcondrey", email="asdfasdfd@mail.com" }, ] description = "A distinctly different take on Model-Based System Engineering (MBSE) that allows a system modeller to define a system in simple yaml. " requires-python = ">= 3.11" readme = "README.md" license = {text = "MIT License"} keywords = ["SysML", "Architecture-as-Code", "System Engineering", "MBSE"] classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Topic :: Scientific/Engineering" ]
[project.optional-dependencies] runtime = [ "attrs ~= 22.2.0", "pyrsistent ~= 0.19.3", "PyYAML ~= 6.0.0", "types-PyYAML ~= 6.0.12.2", "six ~= 1.16.0", "click ~= 8.1.3", "pathspec ~= 0.10.3", "regex ~= 2022.10.31", "typing-extensions ~= 4.8.0", "pluggy ~= 1.0.0", "Jinja2 ~= 3.1.2", "black >= 23.9.1", "MarkupSafe ~= 2.1.1", "pygls ~= 0.13.1", "fastapi ~= 0.109.1", "starlette >= 0.22.0", "anyio < 5, ~= 3.6.2", "sniffio ~= 1.3.0", "uvicorn ~= 0.20.0", "requests >= 2.28.1", ]
dev = [ "wheel ~= 0.42.0", "pip-tools >= 6.9.0", "tomli >= 2.0.1; python_version < '3.11'", "platformdirs >= 2.4", "coverage >= 6.0", "mccabe >= 0.6.1", "mypy ~= 1.1.0", "mypy-extensions ~= 1.0.0", "pycodestyle >= 2.8.0", "pyflakes >= 2.4", "build >= 1.0.0", "twine == 3.4.2", "pipdeptree >= 2.2.0", "Pygments >= 2.5.1", "types-PyYAML >= 6.0.9", "requests >= 2.27.0", ]
doc = [ "sphinx >= 7.3.7", "sphinxcontrib-applehelp ~= 1.0.2", "sphinxcontrib-devhelp ~= 1.0.2", "sphinxcontrib-htmlhelp ~= 2.0.0", "sphinxcontrib-jsmath ~= 1.0.1", "sphinxcontrib-qthelp ~= 1.0.3", "sphinxcontrib-serializinghtml ~= 1.1.9", "sphinx-copybutton ~= 0.5.2", "sphinx_contributors ~= 0.2.7", "sphinx-autobuild ~= 2021.3.14", "sphinx-simplepdf ~= 1.6.0", "furo ~= 2024.5.6", "docutils ~= 0.19", "myst-parser ~= 2.0.0", "pytz ~= 2023.3" ]
test = [ "build>=1.0.0", "tox >= 3.24", "nose2 >= 0.10.0", "behave >= 1.2.6", "coverage >= 6.0", "flake8 >= 4.0", "flake8-docstrings >= 1.6.0", "flake8-fixme >= 1.1.1", "flake8-eradicate >= 1.5.0", "flake8-assertive >= 1.3.0", "eradicate<3.0,>=2.0", "httpx >= 0.23.0", ]
all = [ "aac[runtime]", "aac[dev]", "aac[doc]", "aac[test]" ]
[project.entry-points."console_scripts"] aac = "aac.execute.command_line:cli"
[project.urls] Homepage = "https://github.com/DevOps-MBSE/AaC" Issues = "https://github.com/DevOps-MBSE/AaC/issues"
[tool.setuptools] include-package-data = true package-dir = {"" = "src"} [tool.setuptools.packages.find] where = ["src"] exclude = ["tests"] [tool.setuptools.package-data] mypkg = ["/*.aac", "/.jinja2", ".yaml"]
The changes needed for the AaC Lexeme system are:
Remove None as a location whenever LanguageError is raised In primitive_field_value_check(), the first language error within the if statement takes a None as location. This can be changed to giving the defining_definition name location.
Old code: if not field_value: if is_required: raise LanguageError(message=f"Missing required field {field_name}.", location=None)
New code: if not field_value: if is_required: raise LanguageError(message=f"Missing required field {field_name}.", location=get_location_str(defining_definition.structure["name"], lexemes))
field_instance_check() get_defining_schema_for_root() get_python_type_from_primitive() get_definitions_of_type() check_schema_constraint() Change the get_location_str method to return a source_location instead of a string. lexeme[index].location() returns a source location object which can be returned through get_location_str(). This would also include a change to the methods name, as it would no longer be getting a location string.
Adjust the Language Error class so that it can accept multiple source location, in the case that get_location_str finds multiple locations that are linked to more than one root definition.
Story set for iteration 24.4.
In primitive_field_value_check(), the first language error within the if statement takes a None as location. This can be changed to giving the defining_definition name location.
Old code: if not field_value: if is_required: raise LanguageError(message=f"Missing required field {field_name}.", location=None)
New code: if not field_value: if is_required: raise LanguageError(message=f"Missing required field {field_name}.", location=get_location_str(defining_definition.structure["name"], lexemes))
To have get_location_str return a source_location instead of string is possible, as the method takes the lexemes list and lexeme value as arguments. lexeme[index].location returns a SourceLocation.
In the get_location_str, there is an if statement with three possible outcomes:
The first is for when there is only one match for the field found, it returns the location as a string.
In the second case, it finds multiple matches that all link back to the same location, so the method returns that locatin as a string.
In the third case, it finds multiple matches that link back to more than one root definition, so it returns all the locations listed in a string.
The biggest difficulty with returning a source location instead of a string would be that third case, as a source location object cannot contain multiple locations.
The logic of the method will have to be somehow changed to only ever return one location, or every place that calls the method will have to be changed to account for recieving a list of source locations.
The logic within the third case could be changed to only return one source location, but this could potentially cause the wrong location to be flagged in certain circumstances.
The places where the method is called could be adjusted to account for possible lists, but it would then need to determine which item in the list would need to be passed to the Language Error. This could potentially cause the same problem as the first.
Another option would be to allow for Language Error to accept a list of locations instead of a single one.
And Another option would be to allow for SourceLocation objects to optionally contain multiple locations.
My prefered option would be to adjust the LanguageError class so that it can accept multiple source locations.
If this method is changed to return a Source Location, the name of the method should also be changed.