Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2025-04-11 09:51:10 +0200
committerShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2025-04-24 12:17:05 +0200
commit70f11d5bd4263b0b29f06cbf7a6ff083c882c376 (patch)
tree96a6f1e6bc5acd37927546cfd56e96e1af9f3dae /sources/pyside-tools/project_lib
parent7980ebc7793aa8e1a8d39f3279ac9296b613d84e (diff)
Remove dependency on tomlkit
- Since we only needed parsing and since the pyproject.toml only contained two sections relevant for deployment/project tool, we can remove the dependency of tomlkit and replace it with simple function doing the parsing and writing of the pyproject.toml Pick-to: 6.8 6.9 Fixes: PYSIDE-3087 Change-Id: Idff951578f7bab311d8bc469c1d437b022ca475a Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/pyside-tools/project_lib')
-rw-r--r--sources/pyside-tools/project_lib/pyproject_toml.py142
1 files changed, 96 insertions, 46 deletions
diff --git a/sources/pyside-tools/project_lib/pyproject_toml.py b/sources/pyside-tools/project_lib/pyproject_toml.py
index e10351df9..fafe0d67d 100644
--- a/sources/pyside-tools/project_lib/pyproject_toml.py
+++ b/sources/pyside-tools/project_lib/pyproject_toml.py
@@ -3,50 +3,111 @@
from __future__ import annotations
import sys
+# TODO: Remove this import when Python 3.11 is the minimum supported version
+if sys.version_info >= (3, 11):
+ import tomllib
from pathlib import Path
-import tomlkit
-from tomlkit.toml_file import TOMLFile
from . import PYPROJECT_JSON_PATTERN
from .pyproject_parse_result import PyProjectParseResult
from .pyproject_json import parse_pyproject_json
+def _parse_toml_content(content: str) -> dict:
+ """
+ Parse TOML content for project name and files list only.
+ """
+ result = {"project": {}, "tool": {"pyside6-project": {}}}
+ current_section = None
+
+ for line in content.splitlines():
+ line = line.strip()
+ if not line or line.startswith('#'):
+ continue
+
+ if line == '[project]':
+ current_section = 'project'
+ elif line == '[tool.pyside6-project]':
+ current_section = 'tool.pyside6-project'
+ elif '=' in line and current_section:
+ key, value = [part.strip() for part in line.split('=', 1)]
+
+ # Handle string values - name of the project
+ if value.startswith('"') and value.endswith('"'):
+ value = value[1:-1]
+ # Handle array of strings - files names
+ elif value.startswith('[') and value.endswith(']'):
+ items = value[1:-1].split(',')
+ value = [item.strip().strip('"') for item in items if item.strip()]
+
+ if current_section == 'project':
+ result['project'][key] = value
+ else: # tool.pyside6-project
+ result['tool']['pyside6-project'][key] = value
+
+ return result
+
+
+def _write_toml_content(data: dict) -> str:
+ """
+ Write minimal TOML content with project and tool.pyside6-project sections.
+ """
+ lines = []
+
+ if 'project' in data and data['project']:
+ lines.append('[project]')
+ for key, value in sorted(data['project'].items()):
+ if isinstance(value, str):
+ lines.append(f'{key} = "{value}"')
+
+ if 'tool' in data and 'pyside6-project' in data['tool']:
+ lines.append('\n[tool.pyside6-project]')
+ for key, value in sorted(data['tool']['pyside6-project'].items()):
+ if isinstance(value, list):
+ items = [f'"{item}"' for item in sorted(value)]
+ lines.append(f'{key} = [{", ".join(items)}]')
+ else:
+ lines.append(f'{key} = "{value}"')
+
+ return '\n'.join(lines)
+
+
def parse_pyproject_toml(pyproject_toml_file: Path) -> PyProjectParseResult:
"""
Parse a pyproject.toml file and return a PyProjectParseResult object.
"""
result = PyProjectParseResult()
+
try:
- root_table = TOMLFile(pyproject_toml_file).read()
+ content = pyproject_toml_file.read_text(encoding='utf-8')
+ # TODO: Remove the manual parsing when Python 3.11 is the minimum supported version
+ if sys.version_info >= (3, 11):
+ root_table = tomllib.loads(content) # Use tomllib for Python >= 3.11
+ print("Using tomllib for parsing TOML content")
+ else:
+ root_table = _parse_toml_content(content) # Fallback to manual parsing
except Exception as e:
result.errors.append(str(e))
return result
- tool_table = root_table.get("tool")
- if not tool_table:
- result.errors.append("Missing [tool] table")
- return result
-
- pyside_table = tool_table.get("pyside6-project")
+ pyside_table = root_table.get("tool", {}).get("pyside6-project", {})
if not pyside_table:
result.errors.append("Missing [tool.pyside6-project] table")
return result
- files = pyside_table.get("files")
+ files = pyside_table.get("files", [])
if not isinstance(files, list):
result.errors.append("Missing or invalid files list")
return result
+ # Convert paths
for file in files:
if not isinstance(file, str):
result.errors.append(f"Invalid file: {file}")
return result
-
file_path = Path(file)
if not file_path.is_absolute():
file_path = (pyproject_toml_file.parent / file).resolve()
-
result.files.append(file_path)
return result
@@ -55,30 +116,19 @@ def parse_pyproject_toml(pyproject_toml_file: Path) -> PyProjectParseResult:
def write_pyproject_toml(pyproject_file: Path, project_name: str, project_files: list[str]):
"""
Create or update a pyproject.toml file with the specified content.
-
- Raises a ValueError if the project file is not a valid TOML file.
-
- :param pyproject_file: The pyproject.toml file path to create or update.
- :param project_name: The name of the project.
- :param project_files: The relative paths of the files to include in the project.
"""
- if pyproject_file.exists():
- try:
- doc = TOMLFile(pyproject_file).read()
- except Exception as e:
- raise f"Error parsing TOML: {str(e)}"
- else:
- doc = tomlkit.document()
-
- project_table = doc.setdefault("project", tomlkit.table())
- project_table["name"] = project_name
-
- tool_table = doc.setdefault("tool", tomlkit.table())
- pyside_table = tool_table.setdefault("pyside6-project", tomlkit.table())
-
- pyside_table["files"] = sorted(project_files)
+ data = {
+ "project": {"name": project_name},
+ "tool": {
+ "pyside6-project": {"files": sorted(project_files)}
+ }
+ }
- pyproject_file.write_text(tomlkit.dumps(doc), encoding="utf-8")
+ try:
+ content = _write_toml_content(data)
+ pyproject_file.write_text(content, encoding='utf-8')
+ except Exception as e:
+ raise ValueError(f"Error writing TOML file: {str(e)}")
def migrate_pyproject(pyproject_file: Path | str = None) -> int:
@@ -138,25 +188,25 @@ def migrate_pyproject(pyproject_file: Path | str = None) -> int:
if pyproject_toml_file.exists():
already_existing_file = True
try:
- doc = TOMLFile(pyproject_toml_file).read()
+ content = pyproject_toml_file.read_text(encoding='utf-8')
+ data = _parse_toml_content(content)
except Exception as e:
- raise f"Error parsing TOML: {str(e)}"
+ raise ValueError(f"Error parsing TOML: {str(e)}")
else:
already_existing_file = False
- doc = tomlkit.document()
-
- project_table = doc.setdefault("project", tomlkit.table())
- if "name" not in project_table:
- project_table["name"] = project_name
+ data = {"project": {}, "tool": {"pyside6-project": {}}}
- tool_table = doc.setdefault("tool", tomlkit.table())
- pyside_table = tool_table.setdefault("pyside6-project", tomlkit.table())
+ # Update project name if not present
+ if "name" not in data["project"]:
+ data["project"]["name"] = project_name
- pyside_table["files"] = sorted(
+ # Update files list
+ data["tool"]["pyside6-project"]["files"] = sorted(
p.relative_to(project_folder).as_posix() for p in output_files
)
- toml_content = tomlkit.dumps(doc).replace('\r\n', '\n').replace('\r', '\n')
+ # Generate TOML content
+ toml_content = _write_toml_content(data)
if already_existing_file:
print(f"WARNING: A pyproject.toml file already exists at \"{pyproject_toml_file}\"")
@@ -167,7 +217,7 @@ def migrate_pyproject(pyproject_file: Path | str = None) -> int:
return 0
try:
- Path(pyproject_toml_file).write_text(toml_content)
+ pyproject_toml_file.write_text(toml_content)
except Exception as e:
print(f"Error writing to \"{pyproject_toml_file}\": {str(e)}", file=sys.stderr)
return 1