From be717ad159ca6e73494ff1b35a9aef15c624f475 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Oct 2020 12:27:59 -0400 Subject: [PATCH 1/7] Remove __method__ as it does not appear to serve any purpose and it was assigned to __doc__ anyway. Fixes #71. --- src/foolscap/remoteinterface.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/foolscap/remoteinterface.py b/src/foolscap/remoteinterface.py index aec17cf6..cdb048b2 100644 --- a/src/foolscap/remoteinterface.py +++ b/src/foolscap/remoteinterface.py @@ -28,10 +28,9 @@ class RemoteInterfaceClass(interface.InterfaceClass): """ - def __init__(self, iname, bases=(), attrs=None, __module__=None): + def __init__(self, iname, bases=(), attrs=None): if attrs is None: - interface.InterfaceClass.__init__(self, iname, bases, attrs, - __module__) + interface.InterfaceClass.__init__(self, iname, bases, attrs) return # parse (and remove) the attributes that make this a RemoteInterface @@ -41,8 +40,7 @@ def __init__(self, iname, bases=(), attrs=None, __module__=None): raise # now let the normal InterfaceClass do its thing - interface.InterfaceClass.__init__(self, iname, bases, attrs, - __module__) + interface.InterfaceClass.__init__(self, iname, bases, attrs) # now add all the remote methods that InterfaceClass would have # complained about. This is really gross, and it really makes me @@ -92,8 +90,7 @@ def _parseRemoteInterface(self, iname, attrs): return remote_name, remote_attrs -RemoteInterface = RemoteInterfaceClass("RemoteInterface", - __module__="pb.flavors") +RemoteInterface = RemoteInterfaceClass("RemoteInterface") From 44ce706869e2b5e633d07530ecac82514874d617 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Oct 2020 15:03:02 -0400 Subject: [PATCH 2/7] Construct RemoteInterface as instance of RemoteInterfaceClass. Fixes #75. --- src/foolscap/remoteinterface.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/foolscap/remoteinterface.py b/src/foolscap/remoteinterface.py index cdb048b2..b36dd550 100644 --- a/src/foolscap/remoteinterface.py +++ b/src/foolscap/remoteinterface.py @@ -1,4 +1,5 @@ +import six import types import inspect from zope.interface import interface, providedBy, implementer @@ -90,9 +91,6 @@ def _parseRemoteInterface(self, iname, attrs): return remote_name, remote_attrs -RemoteInterface = RemoteInterfaceClass("RemoteInterface") - - def getRemoteInterface(obj): """Get the (one) RemoteInterface supported by the object, or None.""" @@ -409,3 +407,10 @@ def _makeConstraint(t): return LocalInterfaceConstraint(t) addToConstraintTypeMap(interface.InterfaceClass, _makeConstraint) + + +six.exec_("""class RemoteInterface(object): + __metaclass__ = RemoteInterfaceClass +""" if six.PY2 else """class RemoteInterface(metaclass=RemoteInterfaceClass): + pass +""") From 4100bdf0b10b27743abb98ba8c23fcd439c2dc0a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Oct 2020 15:36:56 -0400 Subject: [PATCH 3/7] Address issues with RemoteInterface construction on Python 2. --- src/foolscap/remoteinterface.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/foolscap/remoteinterface.py b/src/foolscap/remoteinterface.py index b36dd550..3c7edff4 100644 --- a/src/foolscap/remoteinterface.py +++ b/src/foolscap/remoteinterface.py @@ -34,6 +34,8 @@ def __init__(self, iname, bases=(), attrs=None): interface.InterfaceClass.__init__(self, iname, bases, attrs) return + attrs.pop('__metaclass__', None) + # parse (and remove) the attributes that make this a RemoteInterface try: rname, remote_attrs = self._parseRemoteInterface(iname, attrs) @@ -409,7 +411,7 @@ def _makeConstraint(t): addToConstraintTypeMap(interface.InterfaceClass, _makeConstraint) -six.exec_("""class RemoteInterface(object): +six.exec_("""class RemoteInterface(interface.Interface): __metaclass__ = RemoteInterfaceClass """ if six.PY2 else """class RemoteInterface(metaclass=RemoteInterfaceClass): pass From ff3b9e8c1e4fa13701273a2143ba80b1e58f47cf Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Oct 2020 19:19:18 -0400 Subject: [PATCH 4/7] Rely on six.with_metaclass for compatibility construction. --- src/foolscap/remoteinterface.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/foolscap/remoteinterface.py b/src/foolscap/remoteinterface.py index 3c7edff4..10442452 100644 --- a/src/foolscap/remoteinterface.py +++ b/src/foolscap/remoteinterface.py @@ -411,8 +411,5 @@ def _makeConstraint(t): addToConstraintTypeMap(interface.InterfaceClass, _makeConstraint) -six.exec_("""class RemoteInterface(interface.Interface): - __metaclass__ = RemoteInterfaceClass -""" if six.PY2 else """class RemoteInterface(metaclass=RemoteInterfaceClass): +class RemoteInterface(six.with_metaclass(RemoteInterfaceClass, interface.Interface)): pass -""") From d70d8ecee926d3693b9fac55aebe13573d4f71c9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 31 Oct 2020 15:15:57 -0400 Subject: [PATCH 5/7] Declare foolscap as type-checked. Even though it's not fully type-annotated, many of the types derive from zope.interface and are typed, so declare the status to allow mypy to perform checks where possible. Without this change, Tahoe-LAFS continues to report failures on RemoteInterface, and with it, those errors are satisfied. --- MANIFEST.in | 1 + setup.py | 4 ++++ src/foolscap/py.typed | 0 3 files changed, 5 insertions(+) create mode 100644 src/foolscap/py.typed diff --git a/MANIFEST.in b/MANIFEST.in index 53b12761..3a8a9b72 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,3 +7,4 @@ include tox.ini .coveragerc include misc/classify_foolscap.py include versioneer.py include src/foolscap/_version.py +include src/foolscap/py.typed diff --git a/setup.py b/setup.py index 747700f7..6a84a877 100755 --- a/setup.py +++ b/setup.py @@ -76,6 +76,10 @@ def run(self): }, } +setup_args.update( + include_package_data=True, +) + if __name__ == "__main__": setup(**setup_args) diff --git a/src/foolscap/py.typed b/src/foolscap/py.typed new file mode 100644 index 00000000..e69de29b From a57be96e8245b41975982100a4661e231e8a8834 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Dec 2020 14:18:09 -0500 Subject: [PATCH 6/7] Remove workaround for __metaclass__, no longer needed after ff3b9e8. --- src/foolscap/remoteinterface.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/foolscap/remoteinterface.py b/src/foolscap/remoteinterface.py index 10442452..04ffd06c 100644 --- a/src/foolscap/remoteinterface.py +++ b/src/foolscap/remoteinterface.py @@ -34,8 +34,6 @@ def __init__(self, iname, bases=(), attrs=None): interface.InterfaceClass.__init__(self, iname, bases, attrs) return - attrs.pop('__metaclass__', None) - # parse (and remove) the attributes that make this a RemoteInterface try: rname, remote_attrs = self._parseRemoteInterface(iname, attrs) From 682def413b807552585a1828f80e607e0f4b0a66 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 28 Dec 2020 14:41:49 -0500 Subject: [PATCH 7/7] Added comment pointing to the discussion about this particular implementation. --- src/foolscap/remoteinterface.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/foolscap/remoteinterface.py b/src/foolscap/remoteinterface.py index 04ffd06c..bd489f96 100644 --- a/src/foolscap/remoteinterface.py +++ b/src/foolscap/remoteinterface.py @@ -409,5 +409,8 @@ def _makeConstraint(t): addToConstraintTypeMap(interface.InterfaceClass, _makeConstraint) +# See +# https://github.com/warner/foolscap/pull/76/commits/ff3b9e8c1e4fa13701273a2143ba80b1e58f47cf#r549428977 +# for more background on the use of add_metaclass here. class RemoteInterface(six.with_metaclass(RemoteInterfaceClass, interface.Interface)): pass