Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/changes/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## ✨ Features

* #426: Allowed configuring the python version used for coverage

## Bugfixes

* #463: Fixed dependency:licenses to correctly parse exceptional names
32 changes: 23 additions & 9 deletions exasol/toolbox/util/dependencies/poetry_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import re
import subprocess
import sys
from pathlib import Path
from typing import Optional

import tomlkit
from pydantic import (
BaseModel,
model_validator,
)
from tomlkit import TOMLDocument

Expand Down Expand Up @@ -84,19 +84,33 @@ class PoetryDependencies(BaseModel):
working_directory: Path

@staticmethod
def _extract_from_line(line: str) -> Package:
pattern = r"\s+(\d+(?:\.\d+)*)\s+"
match = re.split(pattern, line)
return Package(name=match[0], version=match[1]) #
def _extract_from_line(line: str) -> Optional[Package]:
# remove (!) from line as indicates not installed in environment,
# which could occur for optional dependencies
split_line = line.replace("(!)", "").strip().split(maxsplit=2)
if len(split_line) < 2:
print(f"Unable to parse dependency={line}")
return None
return Package(name=split_line[0], version=split_line[1])

def _extract_from_poetry_show(self, output_text: str) -> list[Package]:
return [self._extract_from_line(line) for line in output_text.splitlines()]
return [
package
for line in output_text.splitlines()
if (package := self._extract_from_line(line))
]

@property
def direct_dependencies(self) -> dict[str, list[Package]]:
dependencies = {}
for group in self.groups:
command = ("poetry", "show", "--top-level", f"--only={group.name}")
command = (
"poetry",
"show",
"--top-level",
f"--only={group.name}",
"--no-truncate",
)
output = subprocess.run(
command,
capture_output=True,
Expand All @@ -110,7 +124,7 @@ def direct_dependencies(self) -> dict[str, list[Package]]:

@property
def all_dependencies(self) -> dict[str, list[Package]]:
command = ("poetry", "show")
command = ("poetry", "show", "--no-truncate")
output = subprocess.run(
command,
capture_output=True,
Expand All @@ -128,7 +142,7 @@ def all_dependencies(self) -> dict[str, list[Package]]:
}
for line in output.stdout.splitlines():
dep = self._extract_from_line(line=line)
if dep.name not in names_direct_dependencies:
if dep and dep.name not in names_direct_dependencies:
transitive_dependencies.append(dep)

return direct_dependencies | {TRANSITIVE_GROUP.name: transitive_dependencies}
8 changes: 8 additions & 0 deletions test/unit/util/dependencies/poetry_dependencies_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ class TestPoetryDependencies:
"import-linter 2.3 Enforces rules for the imports within and between Python packages.",
Package(name="import-linter", version="2.3"),
),
(
"python-dateutil 2.9.0.post0 Extensions to the standard Python datetime module",
Package(name="python-dateutil", version="2.9.0.post0"),
),
(
"types-requests 2.32.0.20250602",
Package(name="types-requests", version="2.32.0.20250602"),
),
],
)
def test_extract_from_line(line, expected):
Expand Down