Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pacmak): allow typeguard==3.x and typeguard==4.x #4611

Merged
merged 20 commits into from
Aug 27, 2024
Merged
6 changes: 4 additions & 2 deletions packages/@jsii/python-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
"build": "cp ../../../README.md . && rm -f jsii-*.whl && npm run generate && npm run deps && npm run lint",
"lint": "ts-node build-tools/venv.ts black .",
"package": "package-python && package-private",
"test": "npm run test:gen && npm run test:run && npm run test:types",
"test": "npm run test:gen && npm run test:run:typeguard-2 && npm run test:run:typeguard-3 && npm run test:run:typeguard-4 && npm run test:types",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will now run three test suites, for each typeguard major version we support. These tests are pretty quick so compared to the current latency of PR validation, they don't add much.

"test:gen": "npm run deps && ts-node build-tools/gen-calc.ts",
"test:run": "ts-node build-tools/venv.ts py.test -v --mypy",
"test:run:typeguard-2": "ts-node build-tools/venv.ts python -m pip install typeguard==2.13.3 && ts-node build-tools/venv.ts py.test -v --mypy",
"test:run:typeguard-3": "ts-node build-tools/venv.ts python -m pip install typeguard==3.0.2 && ts-node build-tools/venv.ts py.test -v --mypy",
"test:run:typeguard-4": "ts-node build-tools/venv.ts python -m pip install typeguard==4.3.0 && ts-node build-tools/venv.ts py.test -v --mypy",
"test:types": "pyright -p .",
"test:update": "UPDATE_DIFF=1 npm run test"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/@jsii/python-runtime/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"cattrs>=1.8,<23.3",
"importlib_resources>=5.2.0",
"publication>=0.0.3", # This is used by all generated code.
"typeguard~=2.13.3", # This is used by all generated code.
"typeguard>=2.13.3,<5.0.0", # This is used by all generated code.
"python-dateutil",
"typing_extensions>=3.8,<5.0",
],
Expand Down
4 changes: 4 additions & 0 deletions packages/@jsii/python-runtime/src/jsii/_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ def implements(*interfaces: Type[Any]) -> Callable[[T], T]:
def deco(cls):
cls.__jsii_type__ = getattr(cls, "__jsii_type__", None)
cls.__jsii_ifaces__ = getattr(cls, "__jsii_ifaces__", []) + list(interfaces)
cls.__jsii_proxy_class__ = lambda: getattr(cls, "__jsii_proxy_class__", None)
Copy link
Contributor Author

@iliapolo iliapolo Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required because __jsii_proxy_class__ is added to protocols, and therefore should be implemented in classes.

code.line(
'# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface',
);

For pacmak generated classes, __jsii_proxy_class__ is autoamtically added:

code.line(
'# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class',
);

But in order to support user defined protocol implementations, this needs to be added via the @jsii.implements decorator as well.

Note that prior to 4.x, typeguard didn't actually type check our protocols so this wasn't needed.


# https://github.com/agronholm/typeguard/issues/479
cls.__protocol_attrs__ = getattr(cls, "__protocol_attrs__", [])
return cls

return deco
Expand Down
11 changes: 0 additions & 11 deletions packages/@jsii/python-runtime/tests/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ def test_inheritance_maintained(self):

assert base_names == ["DerivedStruct", "MyFirstStruct"]

def test_descriptive_error_when_passing_function(self):
Copy link
Contributor Author

@iliapolo iliapolo Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to test_runtime_checking.py, where all other type checking is asserted on.

obj = jsii_calc.Calculator()

with pytest.raises(
TypeError,
match=re.escape(
"type of argument value must be one of (int, float); got method instead"
),
):
obj.add(cast(Any, self.test_descriptive_error_when_passing_function))

def test_implements_interface(self) -> None:
"""Checks that jsii-generated classes correctly implement the relevant jsii-generated interfaces."""

Expand Down
Loading
Loading