def test_invalidArguments(self):
        """
        Passing an argument of the wrong type to any of the constructor
        arguments of L{URL} will raise a descriptive L{TypeError}.

        L{URL} typechecks very aggressively to ensure that its constitutent
        parts are all properly immutable and to prevent confusing errors when
        bad data crops up in a method call long after the code that called the
        constructor is off the stack.
        """
        class Unexpected(object):
            def __str__(self):
                return "wrong"

            def __repr__(self):
                return "<unexpected>"

        defaultExpectation = "unicode" if bytes is str else "str"

        def assertRaised(raised, expectation, name):
            self.assertEqual(str(raised.exception),
                             "expected {0} for {1}, got {2}".format(
                                 expectation,
                                 name, "<unexpected>"))

        def check(param, expectation=defaultExpectation):
            with self.assertRaises(TypeError) as raised:
                URL(**{param: Unexpected()})

            assertRaised(raised, expectation, param)

        check("scheme")
        check("host")
        check("fragment")
        check("rooted", "bool")
        check("userinfo")
        check("port", "int or NoneType")

        with self.assertRaises(TypeError) as raised:
            URL(path=[Unexpected()])

        assertRaised(raised, defaultExpectation, "path segment")

        with self.assertRaises(TypeError) as raised:
            URL(query=[(u"name", Unexpected())])

        assertRaised(raised, defaultExpectation + " or NoneType",
                     "query parameter value")

        with self.assertRaises(TypeError) as raised:
            URL(query=[(Unexpected(), u"value")])

        assertRaised(raised, defaultExpectation, "query parameter name")
        # No custom error message for this one, just want to make sure
        # non-2-tuples don't get through.

        with self.assertRaises(TypeError):
            URL(query=[Unexpected()])

        with self.assertRaises(ValueError):
            URL(query=[('k', 'v', 'vv')])

        with self.assertRaises(ValueError):
            URL(query=[('k',)])

        url = URL.from_text("https://valid.example.com/")
        with self.assertRaises(TypeError) as raised:
            url.child(Unexpected())
        assertRaised(raised, defaultExpectation, "path segment")
        with self.assertRaises(TypeError) as raised:
            url.sibling(Unexpected())
        assertRaised(raised, defaultExpectation, "path segment")
        with self.assertRaises(TypeError) as raised:
            url.click(Unexpected())
        assertRaised(raised, defaultExpectation, "relative URL")

        Passing an argument of the wrong type to any of the constructor
        arguments of L{URL} will raise a descriptive L{TypeError}.

        L{URL} typechecks very aggressively to ensure that its constitutent
        parts are all properly immutable and to prevent confusing errors when
        bad data crops up in a method call long after the code that called the
        constructor is off the stack.
        
stackoverflow/venv/lib/python3.6/site-packages/hyperlink/test/test_url.py