python-introspect 0.1.9__tar.gz → 0.1.10__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.
Files changed (29) hide show
  1. {python_introspect-0.1.9/src/python_introspect.egg-info → python_introspect-0.1.10}/PKG-INFO +1 -1
  2. {python_introspect-0.1.9 → python_introspect-0.1.10}/pyproject.toml +1 -1
  3. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/__init__.py +4 -1
  4. python_introspect-0.1.10/src/python_introspect/callable_declaration.py +37 -0
  5. {python_introspect-0.1.9 → python_introspect-0.1.10/src/python_introspect.egg-info}/PKG-INFO +1 -1
  6. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect.egg-info/SOURCES.txt +2 -0
  7. python_introspect-0.1.10/tests/test_callable_declaration.py +40 -0
  8. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_init.py +1 -1
  9. {python_introspect-0.1.9 → python_introspect-0.1.10}/LICENSE +0 -0
  10. {python_introspect-0.1.9 → python_introspect-0.1.10}/README.md +0 -0
  11. {python_introspect-0.1.9 → python_introspect-0.1.10}/setup.cfg +0 -0
  12. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/annotation_types.py +0 -0
  13. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/dataclass_projection.py +0 -0
  14. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/enableable.py +0 -0
  15. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/environment_projection.py +0 -0
  16. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/exceptions.py +0 -0
  17. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/signature_analyzer.py +0 -0
  18. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/unified_parameter_analyzer.py +0 -0
  19. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect/validation.py +0 -0
  20. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect.egg-info/dependency_links.txt +0 -0
  21. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect.egg-info/requires.txt +0 -0
  22. {python_introspect-0.1.9 → python_introspect-0.1.10}/src/python_introspect.egg-info/top_level.txt +0 -0
  23. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_annotation_types.py +0 -0
  24. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_dataclass_projection.py +0 -0
  25. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_environment_projection.py +0 -0
  26. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_exceptions.py +0 -0
  27. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_signature_analyzer.py +0 -0
  28. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_unified_parameter_analyzer.py +0 -0
  29. {python_introspect-0.1.9 → python_introspect-0.1.10}/tests/test_validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-introspect
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: Pure Python introspection toolkit for function signatures, dataclasses, and type hints
5
5
  Author-email: Tristan Simas <tristan.simas@mail.mcgill.ca>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-introspect"
7
- version = "0.1.9"
7
+ version = "0.1.10"
8
8
  description = "Pure Python introspection toolkit for function signatures, dataclasses, and type hints"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -9,7 +9,7 @@ Extensibility:
9
9
  type resolution for framework-specific types (lazy configs, proxies, etc.)
10
10
  """
11
11
 
12
- __version__ = "0.1.9"
12
+ __version__ = "0.1.10"
13
13
 
14
14
  from .signature_analyzer import (
15
15
  SignatureAnalyzer,
@@ -71,6 +71,7 @@ from .annotation_types import (
71
71
  resolve_annotated,
72
72
  resolve_optional,
73
73
  )
74
+ from .callable_declaration import callable_declaration_kwargs
74
75
 
75
76
  __all__ = [
76
77
  # Version
@@ -127,4 +128,6 @@ __all__ = [
127
128
  "optional_member_type",
128
129
  "resolve_annotated",
129
130
  "resolve_optional",
131
+ # Callable declarations
132
+ "callable_declaration_kwargs",
130
133
  ]
@@ -0,0 +1,37 @@
1
+ """Declaration projections derived from callable signatures."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import inspect
6
+ from collections.abc import Callable, Mapping
7
+ from typing import TypeVar
8
+
9
+
10
+ ParameterValue = TypeVar("ParameterValue")
11
+
12
+
13
+ def callable_declaration_kwargs(
14
+ func: Callable,
15
+ kwargs: Mapping[str, ParameterValue],
16
+ *,
17
+ values_equal: Callable[[object, object], bool],
18
+ ) -> dict[str, ParameterValue]:
19
+ """Return declared kwargs whose values differ from signature defaults.
20
+
21
+ Equality remains caller-owned so frameworks can supply semantics for
22
+ arrays, lazy values, and other values whose ``==`` result is not boolean.
23
+ """
24
+
25
+ try:
26
+ defaults = {
27
+ name: parameter.default
28
+ for name, parameter in inspect.signature(func).parameters.items()
29
+ if parameter.default is not inspect.Parameter.empty
30
+ }
31
+ except (TypeError, ValueError):
32
+ defaults = {}
33
+ return {
34
+ name: value
35
+ for name, value in kwargs.items()
36
+ if name not in defaults or not values_equal(value, defaults[name])
37
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-introspect
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: Pure Python introspection toolkit for function signatures, dataclasses, and type hints
5
5
  Author-email: Tristan Simas <tristan.simas@mail.mcgill.ca>
6
6
  License: MIT
@@ -3,6 +3,7 @@ README.md
3
3
  pyproject.toml
4
4
  src/python_introspect/__init__.py
5
5
  src/python_introspect/annotation_types.py
6
+ src/python_introspect/callable_declaration.py
6
7
  src/python_introspect/dataclass_projection.py
7
8
  src/python_introspect/enableable.py
8
9
  src/python_introspect/environment_projection.py
@@ -16,6 +17,7 @@ src/python_introspect.egg-info/dependency_links.txt
16
17
  src/python_introspect.egg-info/requires.txt
17
18
  src/python_introspect.egg-info/top_level.txt
18
19
  tests/test_annotation_types.py
20
+ tests/test_callable_declaration.py
19
21
  tests/test_dataclass_projection.py
20
22
  tests/test_environment_projection.py
21
23
  tests/test_exceptions.py
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from operator import attrgetter
4
+
5
+ from python_introspect import callable_declaration_kwargs
6
+
7
+
8
+ def sample_function(value, threshold: float = 1.0, enabled: bool = True):
9
+ return value
10
+
11
+
12
+ def test_callable_declaration_kwargs_projects_signature_defaults() -> None:
13
+ kwargs = {
14
+ "threshold": 1,
15
+ "enabled": False,
16
+ "extension_parameter": "preserved",
17
+ }
18
+
19
+ declaration = callable_declaration_kwargs(
20
+ sample_function,
21
+ kwargs,
22
+ values_equal=lambda left, right: left == right,
23
+ )
24
+
25
+ assert declaration == {
26
+ "enabled": False,
27
+ "extension_parameter": "preserved",
28
+ }
29
+
30
+
31
+ def test_callable_declaration_kwargs_preserves_values_for_opaque_callable() -> None:
32
+ kwargs = {"extension_parameter": "preserved"}
33
+
34
+ declaration = callable_declaration_kwargs(
35
+ attrgetter("value"),
36
+ kwargs,
37
+ values_equal=lambda left, right: left == right,
38
+ )
39
+
40
+ assert declaration == kwargs
@@ -11,7 +11,7 @@ class TestPackageImports:
11
11
  """Test that __version__ is available."""
12
12
  assert hasattr(python_introspect, "__version__")
13
13
  assert isinstance(python_introspect.__version__, str)
14
- assert python_introspect.__version__ == "0.1.9"
14
+ assert python_introspect.__version__ == "0.1.10"
15
15
 
16
16
  def test_signature_analyzer_import(self):
17
17
  """Test SignatureAnalyzer is importable."""