diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index c9c7ebc..bea6be8 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ] + python-version: [ "3.11", "3.12", "3.13", "3.14" ] steps: - name: Checkout uses: actions/checkout@v7 @@ -34,7 +34,7 @@ jobs: contents: write strategy: matrix: - python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ] + python-version: [ "3.11", "3.12", "3.13", "3.14" ] steps: - name: Checkout uses: actions/checkout@v7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53eb794..08f38a3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Poetry project uses: ./.github/actions/setup-poetry-project with: - python-version: '3.10' + python-version: '3.11' install-args: --sync --no-interaction - name: Package project run: | diff --git a/AGENTS.md b/AGENTS.md index 658d705..23b21d2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,7 @@ read/write Siemens [Standard BOM](https://sbom.siemens.io/latest/format.html) ## Commands (run from repo root) -- Full check (lint + type + tests, Python 3.10-3.14): `poetry run tox run` +- Full check (lint + type + tests, Python 3.11-3.14): `poetry run tox run` - Lint + types only: `poetry run tox run -e lint,type` - Tests on one interpreter: `poetry run tox run -e 3.12` - Single test: `poetry run python -m unittest tests.test_v3_parser.SbomV3ParserTestCase.test_read_sunny_day` @@ -46,7 +46,7 @@ Config: - [mypy](https://mypy.readthedocs.io/en/stable/) `strict = True`, `implicit_reexport = False`; - [flake8](https://flake8.pycqa.org/) max line length 140, max complexity 8, doctests checked. -- Requires Python >=3.10,<4.0 and [Poetry](https://python-poetry.org/) >= 2.0. +- Requires Python >=3.11,<4.0 and [Poetry](https://python-poetry.org/) >= 2.0. - Release: bump `version` in [`pyproject.toml`](pyproject.toml); pushing a `vX.Y.Z` tag publishes to [PyPI](https://pypi.org/p/siemens-standard-bom) (see [`release.yml`](.github/workflows/release.yml)). - The self tool-entry version reads from installed package metadata, so `poetry install` diff --git a/README.md b/README.md index 8103087..823ac8b 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ component.licenses = licenses In order to build this library on your local PC, and/or contribute to this library, mind the following prerequisites: -- [Python](https://www.python.org/doc/versions/) >=3.10, <4.0 +- [Python](https://www.python.org/doc/versions/) >=3.11, <4.0 - [Poetry](https://python-poetry.org/) >= v2.0 --- diff --git a/poetry.lock b/poetry.lock index e9c3f41..7396248 100644 --- a/poetry.lock +++ b/poetry.lock @@ -712,7 +712,6 @@ ast-serialize = ">=0.6.0,<1.0.0" librt = {version = ">=0.13.0", markers = "platform_python_implementation != \"PyPy\""} mypy_extensions = ">=1.0.0" pathspec = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing_extensions = [ {version = ">=4.6.0", markers = "python_version < \"3.15\""}, {version = ">=4.14.0", markers = "python_version >= \"3.15\""}, @@ -884,22 +883,6 @@ files = [ [package.dependencies] packaging = ">=25" -tomli = {version = ">=2.3", markers = "python_version < \"3.11\""} - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" [[package]] name = "python-discovery" @@ -916,18 +899,6 @@ files = [ [package.dependencies] filelock = ">=3.15.4" -[[package]] -name = "six" -version = "1.17.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, - {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, -] - [[package]] name = "sortedcontainers" version = "2.4.0" @@ -956,64 +927,6 @@ files = [ sortedcontainers = ">=2,<3" typing-extensions = ">=4.1.0,<5.0.0" -[[package]] -name = "tomli" -version = "2.4.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version == \"3.10\"" -files = [ - {file = "tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30"}, - {file = "tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a"}, - {file = "tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076"}, - {file = "tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9"}, - {file = "tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c"}, - {file = "tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc"}, - {file = "tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049"}, - {file = "tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e"}, - {file = "tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece"}, - {file = "tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a"}, - {file = "tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085"}, - {file = "tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9"}, - {file = "tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5"}, - {file = "tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585"}, - {file = "tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1"}, - {file = "tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917"}, - {file = "tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9"}, - {file = "tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257"}, - {file = "tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54"}, - {file = "tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a"}, - {file = "tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897"}, - {file = "tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f"}, - {file = "tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d"}, - {file = "tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5"}, - {file = "tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd"}, - {file = "tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36"}, - {file = "tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd"}, - {file = "tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf"}, - {file = "tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac"}, - {file = "tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662"}, - {file = "tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853"}, - {file = "tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15"}, - {file = "tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba"}, - {file = "tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6"}, - {file = "tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7"}, - {file = "tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232"}, - {file = "tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4"}, - {file = "tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c"}, - {file = "tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d"}, - {file = "tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41"}, - {file = "tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c"}, - {file = "tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f"}, - {file = "tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8"}, - {file = "tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26"}, - {file = "tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396"}, - {file = "tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe"}, - {file = "tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f"}, -] - [[package]] name = "tomli-w" version = "1.2.0" @@ -1047,7 +960,6 @@ platformdirs = ">=4.9.4" pluggy = ">=1.6" pyproject-api = ">=1.10" python-discovery = ">=1.4.4" -tomli = {version = ">=2.4", markers = "python_version < \"3.11\""} tomli-w = ">=1.2" typing-extensions = {version = ">=4.15", markers = "python_version < \"3.13\""} virtualenv = ">=21.1" @@ -1056,18 +968,6 @@ virtualenv = ">=21.1" completion = ["argcomplete (>=3.6.3)"] testing = ["devpi-process (>=1.1.1)", "pytest (>=9.0.2)", "pytest-mock (>=3.15.1)"] -[[package]] -name = "types-python-dateutil" -version = "2.9.0.20260807" -description = "Typing stubs for python-dateutil" -optional = false -python-versions = ">=3.10" -groups = ["dev"] -files = [ - {file = "types_python_dateutil-2.9.0.20260807-py3-none-any.whl", hash = "sha256:54aa3707350ed7a9cc0776fd2f6739679d6967d11b40150985e81edcb86df4db"}, - {file = "types_python_dateutil-2.9.0.20260807.tar.gz", hash = "sha256:e0b8a90d464c8684c66b7b8e4556d9074afdddcc56ca45323f0987134f9e7034"}, -] - [[package]] name = "typing-extensions" version = "4.16.0" @@ -1098,9 +998,8 @@ distlib = ">=0.3.7,<1" filelock = {version = ">=3.24.2,<4", markers = "python_version >= \"3.10\""} platformdirs = ">=3.9.1,<5" python-discovery = ">=1.4.2" -typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} [metadata] lock-version = "2.1" -python-versions = ">=3.10,<4.0" -content-hash = "6cbcfcc8b511bfc8d0864cc68a4c82e52a95b3e0c494c06f512df6721e88c018" +python-versions = ">=3.11,<4.0" +content-hash = "5f7c88eab48ac4f780f4b2f3b1f4822678e1856be9fe446378fbae0206966a5b" diff --git a/pyproject.toml b/pyproject.toml index 03ce49b..5c1b725 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "siemens-standard-bom" -version = "4.3.0" +version = "5.0.0" description = "Standard BOM Format Library" keywords = ["sbom", "software-bill-of-materials", "cyclonedx", "cdx"] authors = [ @@ -17,7 +17,6 @@ classifiers = [ "Operating System :: OS Independent", "Topic :: Software Development", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", @@ -25,9 +24,8 @@ classifiers = [ ] urls = { homepage = "https://sbom.siemens.io/", repository = "https://github.com/siemens/standard-bom-python", "Bug Tracker" = "https://github.com/siemens/standard-bom-python/issues", documentation = "https://github.com/siemens/standard-bom-python/blob/main/README.md" } -requires-python = ">=3.10,<4.0" +requires-python = ">=3.11,<4.0" dependencies = [ - "python-dateutil (>=2.9.0.post0,<3.0.0)", "cyclonedx-python-lib(>=11.12.0,<12.0.0)", ] [build-system] @@ -46,6 +44,5 @@ coverage = "7.15.4" flake8 = "7.3.0" deepdiff = "9.1.0" mypy = "2.3.1" -types-python-dateutil = "2.9.0.20260807" tox = "4.60.0" sortedcontainers-stubs = "2.4.3" diff --git a/tests/abstract_sbom_compare.py b/tests/abstract_sbom_compare.py index 563ebd0..d106ee3 100644 --- a/tests/abstract_sbom_compare.py +++ b/tests/abstract_sbom_compare.py @@ -5,12 +5,10 @@ import unittest from abc import ABC -from datetime import datetime from pathlib import Path -from typing import Optional, Tuple +from typing import Tuple from cyclonedx.model.bom_ref import BomRef -from dateutil import parser as dateparser from deepdiff import DeepDiff from siemens_standard_bom.model import StandardBom @@ -49,13 +47,3 @@ def write_read_compare(self, input_filename: str, output_filename: str) -> Tuple self.assertEqual({}, DeepDiff(expected_bom.bom, actual_bom.bom, exclude_regex_paths=exclude_regex_paths)) self.assertEqual({}, DeepDiff(expected_bom, actual_bom, exclude_regex_paths=exclude_regex_paths)) return actual_bom, expected_bom - - -def read_timestamp(param: str | None) -> Optional[datetime]: - if param is None: - return None - try: - timestamp = dateparser.isoparse(param) - return timestamp - except ValueError: - return None diff --git a/tests/test_v2_parser.py b/tests/test_v2_parser.py index f5bcb7a..4bca8b5 100644 --- a/tests/test_v2_parser.py +++ b/tests/test_v2_parser.py @@ -3,13 +3,13 @@ # SPDX-License-Identifier: MIT # -from datetime import datetime, timedelta, timezone +from datetime import datetime from packageurl import PackageURL from siemens_standard_bom.model import SbomNature from siemens_standard_bom.parser import StandardBomParser -from tests.abstract_sbom_compare import AbstractSbomComparingTestCase, read_timestamp +from tests.abstract_sbom_compare import AbstractSbomComparingTestCase class SbomV2ParserTestCase(AbstractSbomComparingTestCase): @@ -91,22 +91,6 @@ def test_serial_number(self) -> None: actual_bom, expected_bom = self.write_read_compare(input_filename, output_filename) self.assertEqual(actual_bom.serial_number, expected_bom.serial_number) - def test_timestamps(self) -> None: - self.assertEqual(datetime(2009, 8, 7, 6, 5, 0, 0, timezone.utc), read_timestamp("2009-08-07T06:05Z")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone.utc), read_timestamp("2009-08-07T06:05:04Z")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=1))), - read_timestamp("2009-08-07T06:05:04+01:00")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=0))), - read_timestamp("2009-08-07T06:05:04+00:00")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=0))), - read_timestamp("2009-08-07T06:05:04+00")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=1))), - read_timestamp("2009-08-07T06:05:04+01")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=4, minutes=30))), - read_timestamp("2009-08-07T06:05:04+04:30")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 0, 0, timezone(timedelta(hours=4))), - read_timestamp("2009-08-07T06:05+04:00")) - def test_multiple_dependencies(self) -> None: input_filename = "tests/v2/multiple-dependencies.cdx.json" output_filename = "output/v2/multiple-dependencies.cdx.json" diff --git a/tests/test_v3_parser.py b/tests/test_v3_parser.py index 9291359..cc569a6 100644 --- a/tests/test_v3_parser.py +++ b/tests/test_v3_parser.py @@ -3,14 +3,14 @@ # SPDX-License-Identifier: MIT # -from datetime import datetime, timedelta, timezone +from datetime import datetime from cyclonedx.model.contact import OrganizationalContact from packageurl import PackageURL from siemens_standard_bom.model import SbomNature from siemens_standard_bom.parser import StandardBomParser -from tests.abstract_sbom_compare import AbstractSbomComparingTestCase, read_timestamp +from tests.abstract_sbom_compare import AbstractSbomComparingTestCase class SbomV3ParserTestCase(AbstractSbomComparingTestCase): @@ -76,6 +76,11 @@ def test_read_sunny_day(self) -> None: self.assertEqual("binaries/49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d/commons-codec-1.15.jar", commons_codec.relative_path) + def test_read_timestamp_with_offset(self) -> None: + bom = StandardBomParser.parse("tests/v3/timestamp-offset.cdx.json") + + self.assertEqual(datetime.fromisoformat("2022-07-08T15:00:00+04:30"), bom.timestamp) + def test_serial_number(self) -> None: input_filename = "tests/v3/serial-number.cdx.json" output_filename = "output/v3/serial-number.cdx.json" @@ -83,22 +88,6 @@ def test_serial_number(self) -> None: actual_bom, expected_bom = self.write_read_compare(input_filename, output_filename) self.assertEqual(actual_bom.serial_number, expected_bom.serial_number) - def test_timestamps(self) -> None: - self.assertEqual(datetime(2009, 8, 7, 6, 5, 0, 0, timezone.utc), read_timestamp("2009-08-07T06:05Z")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone.utc), read_timestamp("2009-08-07T06:05:04Z")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=1))), - read_timestamp("2009-08-07T06:05:04+01:00")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=0))), - read_timestamp("2009-08-07T06:05:04+00:00")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=0))), - read_timestamp("2009-08-07T06:05:04+00")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=1))), - read_timestamp("2009-08-07T06:05:04+01")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 4, 0, timezone(timedelta(hours=4, minutes=30))), - read_timestamp("2009-08-07T06:05:04+04:30")) - self.assertEqual(datetime(2009, 8, 7, 6, 5, 0, 0, timezone(timedelta(hours=4))), - read_timestamp("2009-08-07T06:05+04:00")) - def test_multiple_dependencies(self) -> None: input_filename = "tests/v3/multiple-dependencies.cdx.json" output_filename = "output/v3/multiple-dependencies.cdx.json" diff --git a/tests/v3/timestamp-offset.cdx.json b/tests/v3/timestamp-offset.cdx.json new file mode 100644 index 0000000..1853bbd --- /dev/null +++ b/tests/v3/timestamp-offset.cdx.json @@ -0,0 +1,8 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "version": 1, + "metadata": { + "timestamp": "2022-07-08T15:00:00+04:30" + } +} diff --git a/tox.toml b/tox.toml index 1a2de04..24a7207 100644 --- a/tox.toml +++ b/tox.toml @@ -1,5 +1,5 @@ requires = ["tox>=4"] -env_list = ["lint", "type", "3.10", "3.11", "3.12", "3.13", "3.14"] +env_list = ["lint", "type", "3.11", "3.12", "3.13", "3.14"] [env_run_base] description = "Run unit tests" @@ -26,7 +26,6 @@ commands = [ description = "Run type checker" deps = [ "mypy>=1.8", - "types-python-dateutil>=2.8", "sortedcontainers-stubs>=2.4", "deepdiff>=8", ]