smithy-test 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ {
2
+ "changes": [
3
+ {
4
+ "type": "feature",
5
+ "description": "Added the `smithy-test` package providing `deep_equal`, a NaN-aware structural equality check for generated protocol tests."
6
+ },
7
+ {
8
+ "type": "feature",
9
+ "description": "Added `xml_equal` for comparing XML documents in protocol tests."
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,36 @@
1
+ # Eclipse
2
+ .classpath
3
+ .project
4
+ .settings/
5
+
6
+ # Intellij
7
+ .idea/
8
+ *.iml
9
+ *.iws
10
+
11
+ # VS Code
12
+ .vscode/
13
+
14
+ # Mac
15
+ .DS_Store
16
+
17
+ # Maven
18
+ target/
19
+ **/dependency-reduced-pom.xml
20
+
21
+ # Gradle
22
+ **/.gradle
23
+ build/
24
+ */out/
25
+ **/*/out/
26
+
27
+ # Python
28
+ __pycache__
29
+ *.swp
30
+ .mypy_cache
31
+ .coverage
32
+ coverage.xml
33
+ htmlcov
34
+ *.egg-info
35
+ dist
36
+ .venv
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ ## v0.1.0
4
+
5
+ ### Features
6
+ * Added the `smithy-test` package providing `deep_equal`, a NaN-aware structural equality check for generated protocol tests.
7
+ * Added `xml_equal` for comparing XML documents in protocol tests.
@@ -0,0 +1 @@
1
+ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.5
2
+ Name: smithy-test
3
+ Version: 0.1.0
4
+ Summary: Test-support helpers for generated Smithy clients.
5
+ Project-URL: Changelog, https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-test/CHANGELOG.md
6
+ Project-URL: Code, https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-test/
7
+ Project-URL: Issue tracker, https://github.com/smithy-lang/smithy-python/issues
8
+ Author: Amazon Web Services
9
+ License: Apache License 2.0
10
+ License-File: NOTICE
11
+ Keywords: sdk,smithy,test
12
+ Classifier: Development Status :: 2 - Pre-Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Natural Language :: English
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
25
+ Classifier: Programming Language :: Python :: Implementation :: CPython
26
+ Classifier: Topic :: Software Development :: Libraries
27
+ Requires-Python: >=3.12
28
+ Description-Content-Type: text/markdown
29
+
30
+ # smithy-test
31
+
32
+ Test-support helpers shared by generated Smithy clients, kept out of the runtime
33
+ packages. Currently provides `deep_equal`, a structural equality check used by the
34
+ generated protocol tests that treats `NaN == NaN`.
@@ -0,0 +1,5 @@
1
+ # smithy-test
2
+
3
+ Test-support helpers shared by generated Smithy clients, kept out of the runtime
4
+ packages. Currently provides `deep_equal`, a structural equality check used by the
5
+ generated protocol tests that treats `NaN == NaN`.
@@ -0,0 +1,49 @@
1
+ [project]
2
+ name = "smithy-test"
3
+ dynamic = ["version"]
4
+ requires-python = ">=3.12"
5
+ authors = [
6
+ {name = "Amazon Web Services"},
7
+ ]
8
+ description = "Test-support helpers for generated Smithy clients."
9
+ readme = "README.md"
10
+ license = {text = "Apache License 2.0"}
11
+ keywords = ["smithy", "sdk", "test"]
12
+ classifiers = [
13
+ "Development Status :: 2 - Pre-Alpha",
14
+ "Intended Audience :: Developers",
15
+ "Intended Audience :: System Administrators",
16
+ "Natural Language :: English",
17
+ "License :: OSI Approved :: Apache Software License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Programming Language :: Python :: Implementation :: CPython",
26
+ "Programming Language :: Python :: Free Threading :: 2 - Beta",
27
+ "Topic :: Software Development :: Libraries"
28
+ ]
29
+ dependencies = []
30
+
31
+ [project.urls]
32
+ "Changelog" = "https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-test/CHANGELOG.md"
33
+ "Code" = "https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-test/"
34
+ "Issue tracker" = "https://github.com/smithy-lang/smithy-python/issues"
35
+
36
+ [build-system]
37
+ requires = ["hatchling"]
38
+ build-backend = "hatchling.build"
39
+
40
+ [tool.hatch.version]
41
+ path = "src/smithy_test/__init__.py"
42
+
43
+ [tool.hatch.build]
44
+ exclude = [
45
+ "tests",
46
+ ]
47
+
48
+ [tool.ruff]
49
+ src = ["src"]
@@ -0,0 +1,7 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ from ._private.equality import deep_equal as deep_equal
4
+ from ._private.equality import xml_equal as xml_equal
5
+
6
+ __version__ = "0.1.0"
7
+ __all__ = ("deep_equal", "xml_equal")
@@ -0,0 +1,2 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,67 @@
1
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ import dataclasses
4
+ import math
5
+ from collections.abc import Mapping, Sequence
6
+ from typing import cast
7
+ from xml.dom.minidom import Element, Node, parseString
8
+
9
+
10
+ def deep_equal(a: object, b: object) -> bool:
11
+ """Structural equality for deserialized shapes that treats ``NaN == NaN``."""
12
+ if isinstance(a, float) and isinstance(b, float):
13
+ return a == b or (math.isnan(a) and math.isnan(b))
14
+ if dataclasses.is_dataclass(a) and dataclasses.is_dataclass(b):
15
+ if type(a) is not type(b):
16
+ return False
17
+ return all(
18
+ deep_equal(getattr(a, f.name), getattr(b, f.name))
19
+ for f in dataclasses.fields(a)
20
+ if f.compare
21
+ )
22
+ if isinstance(a, (list, tuple)) and isinstance(b, (list, tuple)):
23
+ a_seq = cast(Sequence[object], a)
24
+ b_seq = cast(Sequence[object], b)
25
+ return len(a_seq) == len(b_seq) and all(
26
+ deep_equal(x, y) for x, y in zip(a_seq, b_seq)
27
+ )
28
+ if isinstance(a, dict) and isinstance(b, dict):
29
+ a_map = cast(Mapping[object, object], a)
30
+ b_map = cast(Mapping[object, object], b)
31
+ return a_map.keys() == b_map.keys() and all(
32
+ deep_equal(a_map[k], b_map[k]) for k in a_map
33
+ )
34
+ # bool subclasses int; the subclass check would admit 1 == True without this.
35
+ if isinstance(a, bool) != isinstance(b, bool):
36
+ return False
37
+ return (isinstance(a, type(b)) or isinstance(b, type(a))) and a == b # pyright: ignore[reportUnknownArgumentType]
38
+
39
+
40
+ def xml_equal(a: bytes, b: bytes) -> bool:
41
+ """Semantic equality for XML documents.
42
+
43
+ Only the order of same-named sibling elements (such as list items) is
44
+ significant; structure members, attributes, whitespace-only text, and
45
+ whitespace around text may differ. Namespace declarations are compared as
46
+ attributes.
47
+ """
48
+ return _canonical_xml(a) == _canonical_xml(b)
49
+
50
+
51
+ def _canonical_xml(document: bytes) -> object:
52
+ root = parseString(document).documentElement # noqa: S318
53
+ assert root is not None # noqa: S101
54
+ return _canonical_element(root)
55
+
56
+
57
+ def _canonical_element(element: Element) -> object:
58
+ text: str = ""
59
+ children: list[tuple[str, object]] = []
60
+ for node in element.childNodes:
61
+ if node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
62
+ text += cast(str, node.data) # type: ignore
63
+ elif node.nodeType == Node.ELEMENT_NODE:
64
+ children.append((node.tagName, _canonical_element(node)))
65
+ # A stable sort keeps same-named siblings in document order.
66
+ children.sort(key=lambda child: child[0])
67
+ return (element.tagName, dict(element.attributes.items()), text.strip(), children)
@@ -0,0 +1 @@
1
+ # PEP 561