Skip to content

Commit 7c669be

Browse files
authored
BC: Helpes internal (#506)
fixes #503 removes the following symbols from public API: - `models.ComparableTuple` - `model.sha1sum` - `model.get_now_utc` - `model.dependency.DependencyDependencies` --------- Signed-off-by: Jan Kowalleck <[email protected]>
1 parent b9193a2 commit 7c669be

17 files changed

+334
-158
lines changed

cyclonedx/_internal/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL CLASSES IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""

cyclonedx/_internal/compare.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL CLASSES IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""
21+
22+
23+
from itertools import zip_longest
24+
from typing import Any, Optional, Tuple
25+
26+
27+
class ComparableTuple(Tuple[Optional[Any], ...]):
28+
"""
29+
Allows comparison of tuples, allowing for None values.
30+
"""
31+
32+
def __lt__(self, other: Any) -> bool:
33+
for s, o in zip_longest(self, other):
34+
if s == o:
35+
continue
36+
# the idea is to have any consistent order, not necessarily "natural" order.
37+
if s is None:
38+
return False
39+
if o is None:
40+
return True
41+
return True if s < o else False
42+
return False
43+
44+
def __gt__(self, other: Any) -> bool:
45+
for s, o in zip_longest(self, other):
46+
if s == o:
47+
continue
48+
# the idea is to have any consistent order, not necessarily "natural" order.
49+
if s is None:
50+
return True
51+
if o is None:
52+
return False
53+
return True if s > o else False
54+
return False

cyclonedx/_internal/hash.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL CLASSES IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""
21+
22+
23+
from hashlib import sha1
24+
25+
26+
def file_sha1sum(filename: str) -> str:
27+
"""
28+
Generate a SHA1 hash of the provided file.
29+
30+
Args:
31+
filename:
32+
Absolute path to file to hash as `str`
33+
34+
Returns:
35+
SHA-1 hash
36+
"""
37+
h = sha1() # nosec B303, B324
38+
with open(filename, 'rb') as f:
39+
for byte_block in iter(lambda: f.read(4096), b''):
40+
h.update(byte_block)
41+
return h.hexdigest()

cyclonedx/_internal/time.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL CLASSES IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""
21+
22+
23+
from datetime import datetime, timezone
24+
25+
26+
def get_now_utc() -> datetime:
27+
return datetime.now(tz=timezone.utc)

cyclonedx/model/__init__.py

Lines changed: 53 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,19 @@
2121
"""
2222

2323
import re
24-
from datetime import datetime, timezone
24+
from datetime import datetime
2525
from enum import Enum
2626
from functools import reduce
27-
from hashlib import sha1
28-
from itertools import zip_longest
2927
from json import loads as json_loads
30-
from typing import Any, Dict, FrozenSet, Generator, Iterable, List, Optional, Tuple, Type, TypeVar
28+
from typing import Any, Dict, FrozenSet, Generator, Iterable, List, Optional, Tuple, Type
3129
from warnings import warn
3230
from xml.etree.ElementTree import Element as XmlElement # nosec B405
3331

3432
import serializable
3533
from sortedcontainers import SortedSet
3634

3735
from .. import __version__ as __ThisToolVersion # noqa: N812
36+
from .._internal.compare import ComparableTuple as _ComparableTuple
3837
from ..exception.model import (
3938
InvalidLocaleTypeException,
4039
InvalidUriException,
@@ -52,61 +51,6 @@
5251
)
5352

5453

55-
def get_now_utc() -> datetime:
56-
return datetime.now(tz=timezone.utc)
57-
58-
59-
def sha1sum(filename: str) -> str:
60-
"""
61-
Generate a SHA1 hash of the provided file.
62-
63-
Args:
64-
filename:
65-
Absolute path to file to hash as `str`
66-
67-
Returns:
68-
SHA-1 hash
69-
"""
70-
h = sha1() # nosec B303, B324
71-
with open(filename, 'rb') as f:
72-
for byte_block in iter(lambda: f.read(4096), b''):
73-
h.update(byte_block)
74-
return h.hexdigest()
75-
76-
77-
_T = TypeVar('_T')
78-
79-
80-
class ComparableTuple(Tuple[Optional[_T], ...]):
81-
"""
82-
Allows comparison of tuples, allowing for None values.
83-
"""
84-
85-
def __lt__(self, other: Any) -> bool:
86-
for s, o in zip_longest(self, other):
87-
if s == o:
88-
continue
89-
# the idea is to have any consistent order, not necessarily "natural" order.
90-
if s is None:
91-
return False
92-
if o is None:
93-
return True
94-
return True if s < o else False
95-
return False
96-
97-
def __gt__(self, other: Any) -> bool:
98-
for s, o in zip_longest(self, other):
99-
if s == o:
100-
continue
101-
# the idea is to have any consistent order, not necessarily "natural" order.
102-
if s is None:
103-
return True
104-
if o is None:
105-
return False
106-
return True if s > o else False
107-
return False
108-
109-
11054
@serializable.serializable_enum
11155
class DataFlow(str, Enum):
11256
"""
@@ -184,8 +128,11 @@ def __eq__(self, other: object) -> bool:
184128

185129
def __lt__(self, other: object) -> bool:
186130
if isinstance(other, DataClassification):
187-
return ComparableTuple((self.flow, self.classification)) < \
188-
ComparableTuple((other.flow, other.classification))
131+
return _ComparableTuple((
132+
self.flow, self.classification
133+
)) < _ComparableTuple((
134+
other.flow, other.classification
135+
))
189136
return NotImplemented
190137

191138
def __hash__(self) -> int:
@@ -279,8 +226,11 @@ def __eq__(self, other: object) -> bool:
279226

280227
def __lt__(self, other: Any) -> bool:
281228
if isinstance(other, AttachedText):
282-
return ComparableTuple((self.content_type, self.content, self.encoding)) < \
283-
ComparableTuple((other.content_type, other.content, other.encoding))
229+
return _ComparableTuple((
230+
self.content_type, self.content, self.encoding
231+
)) < _ComparableTuple((
232+
other.content_type, other.content, other.encoding
233+
))
284234
return NotImplemented
285235

286236
def __hash__(self) -> int:
@@ -481,7 +431,11 @@ def __eq__(self, other: object) -> bool:
481431

482432
def __lt__(self, other: Any) -> bool:
483433
if isinstance(other, HashType):
484-
return ComparableTuple((self.alg, self.content)) < ComparableTuple((other.alg, other.content))
434+
return _ComparableTuple((
435+
self.alg, self.content
436+
)) < _ComparableTuple((
437+
other.alg, other.content
438+
))
485439
return NotImplemented
486440

487441
def __hash__(self) -> int:
@@ -806,8 +760,11 @@ def __eq__(self, other: object) -> bool:
806760

807761
def __lt__(self, other: Any) -> bool:
808762
if isinstance(other, ExternalReference):
809-
return ComparableTuple((self._type, self._url, self._comment)) < \
810-
ComparableTuple((other._type, other._url, other._comment))
763+
return _ComparableTuple((
764+
self._type, self._url, self._comment
765+
)) < _ComparableTuple((
766+
other._type, other._url, other._comment
767+
))
811768
return NotImplemented
812769

813770
def __hash__(self) -> int:
@@ -875,7 +832,11 @@ def __eq__(self, other: object) -> bool:
875832

876833
def __lt__(self, other: Any) -> bool:
877834
if isinstance(other, Property):
878-
return ComparableTuple((self.name, self.value)) < ComparableTuple((other.name, other.value))
835+
return _ComparableTuple((
836+
self.name, self.value
837+
)) < _ComparableTuple((
838+
other.name, other.value
839+
))
879840
return NotImplemented
880841

881842
def __hash__(self) -> int:
@@ -958,8 +919,11 @@ def __eq__(self, other: object) -> bool:
958919

959920
def __lt__(self, other: Any) -> bool:
960921
if isinstance(other, NoteText):
961-
return ComparableTuple((self.content, self.content_type, self.encoding)) < \
962-
ComparableTuple((other.content, other.content_type, other.encoding))
922+
return _ComparableTuple((
923+
self.content, self.content_type, self.encoding
924+
)) < _ComparableTuple((
925+
other.content, other.content_type, other.encoding
926+
))
963927
return NotImplemented
964928

965929
def __hash__(self) -> int:
@@ -1035,7 +999,11 @@ def __eq__(self, other: object) -> bool:
1035999

10361000
def __lt__(self, other: Any) -> bool:
10371001
if isinstance(other, Note):
1038-
return ComparableTuple((self.locale, self.text)) < ComparableTuple((other.locale, other.text))
1002+
return _ComparableTuple((
1003+
self.locale, self.text
1004+
)) < _ComparableTuple((
1005+
other.locale, other.text
1006+
))
10391007
return NotImplemented
10401008

10411009
def __hash__(self) -> int:
@@ -1116,8 +1084,11 @@ def __eq__(self, other: object) -> bool:
11161084

11171085
def __lt__(self, other: Any) -> bool:
11181086
if isinstance(other, OrganizationalContact):
1119-
return ComparableTuple((self.name, self.email, self.phone)) < \
1120-
ComparableTuple((other.name, other.email, other.phone))
1087+
return _ComparableTuple((
1088+
self.name, self.email, self.phone
1089+
)) < _ComparableTuple((
1090+
other.name, other.email, other.phone
1091+
))
11211092
return NotImplemented
11221093

11231094
def __hash__(self) -> int:
@@ -1323,8 +1294,11 @@ def __eq__(self, other: object) -> bool:
13231294

13241295
def __lt__(self, other: Any) -> bool:
13251296
if isinstance(other, Tool):
1326-
return ComparableTuple((self.vendor, self.name, self.version)) < \
1327-
ComparableTuple((other.vendor, other.name, other.version))
1297+
return _ComparableTuple((
1298+
self.vendor, self.name, self.version
1299+
)) < _ComparableTuple((
1300+
other.vendor, other.name, other.version
1301+
))
13281302
return NotImplemented
13291303

13301304
def __hash__(self) -> int:
@@ -1404,8 +1378,11 @@ def __eq__(self, other: object) -> bool:
14041378

14051379
def __lt__(self, other: Any) -> bool:
14061380
if isinstance(other, IdentifiableAction):
1407-
return ComparableTuple((self.timestamp, self.name, self.email)) < \
1408-
ComparableTuple((other.timestamp, other.name, other.email))
1381+
return _ComparableTuple((
1382+
self.timestamp, self.name, self.email
1383+
)) < _ComparableTuple((
1384+
other.timestamp, other.name, other.email
1385+
))
14091386
return NotImplemented
14101387

14111388
def __hash__(self) -> int:

0 commit comments

Comments
 (0)