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

#11812 Mark TerminalRealm as implementing IRealm #11813

Conversation

DMRobertson
Copy link
Contributor

@DMRobertson DMRobertson commented Feb 25, 2023

Scope and purpose

Fixes #11812.
Related to matrix-org/synapse#15097.

Contributor Checklist:

This process applies to all pull requests - no matter how small.
Have a look at our developer documentation before submitting your Pull Request.

Below is a non-exhaustive list (as a reminder):

  • The title of the PR should describe the changes and starts with the associated issue number, like “#9782 Remove twisted.news. #1234 Brief description”.
  • A release notes news fragment file was create in src/twisted/newsfragments/ (see: Release notes fragments docs.)
  • The automated tests were updated.
  • Once all checks are green, request a review by leaving a comment that contains exactly the string please review.
    Our bot will trigger the review process, by applying the pending review label
    and requesting a review from the Twisted dev team.

@DMRobertson
Copy link
Contributor Author

DMRobertson commented Feb 25, 2023

AFAICS the test failure isn't related. A flake?

@DMRobertson
Copy link
Contributor Author

please review

@glyph glyph marked this pull request as ready for review February 25, 2023 11:04
@glyph
Copy link
Member

glyph commented Feb 25, 2023

Probably a flake. I've re-run the failed job.

Copy link
Member

@adiroiban adiroiban left a comment

Choose a reason for hiding this comment

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

Many thanks for the changes.

I think that we need a test for this change.

I have this helper in my tests to check for interface implementations.

    def assertProvides(self, interface, obj):
        self.assertTrue(
            interface.providedBy(obj),
            'Object %s does not provided interface %s.' % (obj, interface))
        from zope.interface.verify import verifyObject
        verifyObject(interface, obj)

I think that something like this can be used to check

sut = TerminalRealm()
self.assertProvides(IRealm, sut)

I see the tests for this files are declared as follows, but I don't see any existing test inside src/twisted/conch/test/test_manhole.py for this class.

# -*- test-case-name: twisted.conch.test.test_manhole -*-

but I think a simple instantiation should be enough.

Thanks again!

@exarkun
Copy link
Member

exarkun commented Mar 2, 2023

Many thanks for the changes.

I think that we need a test for this change.

I have this helper in my tests to check for interface implementations.

    def assertProvides(self, interface, obj):
        self.assertTrue(
            interface.providedBy(obj),
            'Object %s does not provided interface %s.' % (obj, interface))
        from zope.interface.verify import verifyObject
        verifyObject(interface, obj)

I think that something like this can be used to check

sut = TerminalRealm()
self.assertProvides(IRealm, sut)

If such a test is added, I suggest doing it with hamcrest instead of a new TestCase method, so that the assertion looks like:

assert_that(sut, provides(IRealm))

making it much easier to re-use this infrastructure across different tests.

@DMRobertson
Copy link
Contributor Author

I have added a test and a new hamcrest matcher.

If you'll allow me to grumble: while I appreciate that .providedBy and .verifyObject are runtime-visible behaviour, it seems like a lot of overhead for a one-line, drive-by type hint fix.

please review

@chevah-robot chevah-robot requested a review from a team March 9, 2023 15:36
@adiroiban
Copy link
Member

Thanks for the changes. Much appreciated.

If you'll allow me to grumble: while I appreciate that .providedBy and .verifyObject are runtime-visible behaviour, it seems like a lot of overhead for a one-line, drive-by type hint fix.

I understand your complaint.
My understanding is that the current quality assurance policy for the Twisted project is to make sure any change is covered by automated tests.
This includes changes for code that was not previously covered.

If you think that my understanding of the current policy is wrong, or you think that it should be changed, I think that we can discuss this over the mailing list or IRC/Gitter ...(but gitter migration is kind of a mess right now, so better email)

@DMRobertson
Copy link
Contributor Author

I don't know why the latest test run had a job that timed out, but the new test was skipped as intended, so I would assume it is not a regression.

Copy link
Member

@adiroiban adiroiban left a comment

Choose a reason for hiding this comment

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

Sorry for the late review.

The interface changes are ok.

I am not very happy with the tests :) and the missing test coverage

If you think that hamcrest is better, we can have this merged.

for me self.assertProvides(NonemptyInterface, MissingDecorator()) and self.assertNotProvides() is easier to read and write than

 assert_that(
            provides(NonemptyInterface).matches(MissingDecorator()), equal_to(False)
        )

Comment on lines +19 to +21
def test_TerminalRealm_implements_IRealm(self) -> None:
"""Regression test for #11812."""
assert_that(TerminalRealm(), provides(IRealm))
Copy link
Member

Choose a reason for hiding this comment

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

I don't have a much better suggestion,

but instead of pointing to a bug ID is best to describe the scope and purpose of the test.

Suggested change
def test_TerminalRealm_implements_IRealm(self) -> None:
"""Regression test for #11812."""
assert_that(TerminalRealm(), provides(IRealm))
def test_interfaces(self) -> None:
"""
Generic check that the interfaces are implemented.
"""
assert_that(TerminalRealm(), provides(IRealm))

Comment on lines +9 to +17
except ImportError:
ssh = False
else:
ssh = True


class TerminalRealmTests(unittest.TestCase):
if not ssh:
skip = "cannot import t.conch.manhole_ssh (cryptography requirements missing?)"
Copy link
Member

Choose a reason for hiding this comment

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

minor comment.

mabye we can remove the last if :)

Suggested change
except ImportError:
ssh = False
else:
ssh = True
class TerminalRealmTests(unittest.TestCase):
if not ssh:
skip = "cannot import t.conch.manhole_ssh (cryptography requirements missing?)"
except ImportError:
skipNoConch = 'No t.conch.manhole_ssh available.
else:
skipNoConch = None
class TerminalRealmTests(unittest.TestCase):
skip = skipNoConch

return True

def describe_mismatch(self, item: object, description: Description) -> None:
if self._verify_exception is None:
Copy link
Member

Choose a reason for hiding this comment

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

I think that we are missing some tests for invalid interface implementations.

class EmptyClass:
...

assert_that(provides(EmptyInterface).matches(EmptyClass()), equal_to(True))
Copy link
Member

Choose a reason for hiding this comment

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

I am not familiar with matchers.
But I fell the final equals_to(True) or equals_to(False is verbose

I was expecting something like

- assert_that(provides(EmptyInterface).matches(EmptyClass()), equal_to(True))
+ assert_that(providers(EmptyInterface).matches(EmptyClass()))
+ assert_that(not().providers(EmptyInterface).matches(EmptyClass()))

@@ -93,3 +97,46 @@ def getContent(p: IFilePath) -> str:
return f.read().decode(encoding)

return after(getContent, m)


class _MatchInterfaceProvider(BaseMatcher[object]):
Copy link
Member

Choose a reason for hiding this comment

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

I don't know what to say about these matchers :)

The assertion helper is needed.

I have something similar using old-school xunit assertion style :)

    def assertProvides(self, interface, obj):
        self.assertTrue(
            interface.providedBy(obj),
            'Object %s does not provided interface %s.' % (obj, interface))
        verifyObject(interface, obj)

    def assertNotProvides(self, interface, obj):
        self.assertFalse(
            interface.providedBy(obj),
            'Object %s does not provided interface %s.' % (obj, interface))

https://github.com/chevah/compat/blob/master/src/chevah_compat/testing/assertion.py#L219-L228

Maybe, I am just getting old, but I find these hamcrest part too complicated :)

I know that old-style xunit is based on inheritance , but we are already writing tests in xunit style

@DMRobertson
Copy link
Contributor Author

Thanks for your response. I don't think I have the time to see this through at the moment, so I will close this PR. With that said, I'd be more than happy for anyone else to take this over.

@DMRobertson DMRobertson closed this Nov 3, 2023
@glyph
Copy link
Member

glyph commented Nov 3, 2023

Thanks for your response. I don't think I have the time to see this through at the moment, so I will close this PR. With that said, I'd be more than happy for anyone else to take this over.

Thanks for taking the time to contribute, and thanks for letting us know - always better to have a clear response than a PR left in limbo forever!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TerminalRealm does not mark itself as implementing IRealm
5 participants