aws / jsii

jsii allows code in any language to naturally interact with JavaScript classes. It is the technology that enables the AWS Cloud Development Kit to deliver polyglot libraries from a single codebase!
https://aws.github.io/jsii
Apache License 2.0
2.62k stars 244 forks source link

python: Implementing an interface is non-obvious #576

Closed garnaat closed 1 year ago

garnaat commented 5 years ago

It is possible to interface a JSII interface in Python but its not immediately obvious. A reasonable approach might be to treat the interface as a class and create a subclass of it, e.g.:

from aws_cdk.core import IAspect, IConstruct

class MonitoringAspect(IAspect):
    def visit(self, node: IConstruct) -> None:
        print("visit %s" % node.node.path)

But this won't work. The correct approach is to use the @jsii.implements decorator, e.g.:

from aws_cdk.core import IAspect, IConstruct

@jsii.implements(IAspect)
class MonitoringAspect():
    def visit(self, node: IConstruct) -> None:
        print("visit %s" % node.node.path)

We should make sure this is documented and that we provide examples. In addition, it may be useful to insert comments into the generated Python code around Interfaces to give additional hints about how to correctly implement interfaces in Python.

rix0rrr commented 5 years ago

Better yet--we should refactor this so that it's no longer necessary! :)

Doug-AWS commented 5 years ago

+1

dstufft commented 5 years ago

I just happened to peak in on this, and just to provide some background, the reason it's a decorator instead of a class itself is because of the use of metaclasses within the JSII. If something wanted to implement an interface and an abstract class, it would need to be something like:

class MonitoringAspect(metaclass=jsii.InterfaceWithAbstract):
   ...

This is because abstract classes and concrete classes both use metaclasses, and Python doesn't support having the same class have two different metaclasses in it's inheritance tree, you have to manually resolve them into a new metaclass and pass that metaclass as your own metaclass.

github-actions[bot] commented 1 year ago

This issue has not received any attention in 2 years. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.