initial import from Twisted, with gitignore, license, code, tests, and setup.py
This commit is contained in:
parent
dc187bd19e
commit
f0176169ee
|
@ -0,0 +1,50 @@
|
|||
docs/_build
|
||||
tmp.py
|
||||
htmlcov/
|
||||
|
||||
*.py[cod]
|
||||
|
||||
# emacs
|
||||
*~
|
||||
._*
|
||||
.\#*
|
||||
\#*\#
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
lib
|
||||
lib64
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Vim
|
||||
*.sw[op]
|
||||
|
||||
.cache/
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
from ._url import URL
|
||||
|
||||
__all__ = [
|
||||
"URL",
|
||||
]
|
|
@ -528,10 +528,9 @@ class URL(object):
|
|||
|
||||
For example::
|
||||
|
||||
>>> u = URL.fromText(u"http://localhost/a/b?x=y")
|
||||
>>> v = u.child(u"c", u"d")
|
||||
>>> print(v.asText())
|
||||
http://localhost/a/b/c/d?x=y
|
||||
>>> (URL.fromText(u"http://localhost/a/b?x=y")
|
||||
.child(u"c", u"d").asText())
|
||||
u'http://localhost/a/b/c?x=y'
|
||||
|
||||
@param segments: A path segment.
|
||||
@type segments: L{tuple} of L{unicode}
|
|
@ -92,11 +92,11 @@ class TestURL(TestCase):
|
|||
self.assertTrue(isinstance(u.host, unicode)
|
||||
or u.host is None, repr(u))
|
||||
for seg in u.path:
|
||||
self.assertTrue(isinstance(seg, unicode), repr(u))
|
||||
self.assertIsInstance(seg, unicode, repr(u))
|
||||
for (k, v) in u.query:
|
||||
self.assertTrue(isinstance(k, unicode), repr(u))
|
||||
self.assertIsInstance(k, unicode, repr(u))
|
||||
self.assertTrue(v is None or isinstance(v, unicode), repr(u))
|
||||
self.assertTrue(isinstance(u.fragment, unicode), repr(u))
|
||||
self.assertIsInstance(u.fragment, unicode, repr(u))
|
||||
|
||||
|
||||
def assertURL(self, u, scheme, host, path, query,
|
||||
|
@ -170,11 +170,11 @@ class TestURL(TestCase):
|
|||
|
||||
def test_repr(self):
|
||||
"""
|
||||
L{URL.__repr__} will display the canoncial form of the URL, wrapped in
|
||||
L{URL.__repr__} will display the canonical form of the URL, wrapped in
|
||||
a L{URL.fromText} invocation, so that it is C{eval}-able but still easy
|
||||
to read.
|
||||
"""
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
repr(URL(scheme=u'http', host=u'foo', path=[u'bar'],
|
||||
query=[(u'baz', None), (u'k', u'v')],
|
||||
fragment=u'frob')),
|
||||
|
@ -188,7 +188,7 @@ class TestURL(TestCase):
|
|||
URL.
|
||||
"""
|
||||
urlpath = URL.fromText(theurl)
|
||||
self.assertEquals(theurl, urlpath.asText())
|
||||
self.assertEqual(theurl, urlpath.asText())
|
||||
|
||||
|
||||
def test_roundtrip(self):
|
||||
|
@ -213,7 +213,7 @@ class TestURL(TestCase):
|
|||
)
|
||||
for test in tests:
|
||||
result = URL.fromText(test).asText()
|
||||
self.assertEquals(test, result)
|
||||
self.assertEqual(test, result)
|
||||
|
||||
|
||||
def test_equality(self):
|
||||
|
@ -223,8 +223,8 @@ class TestURL(TestCase):
|
|||
strings.
|
||||
"""
|
||||
urlpath = URL.fromText(theurl)
|
||||
self.assertEquals(urlpath, URL.fromText(theurl))
|
||||
self.assertNotEquals(
|
||||
self.assertEqual(urlpath, URL.fromText(theurl))
|
||||
self.assertNotEqual(
|
||||
urlpath,
|
||||
URL.fromText('ftp://www.anotherinvaliddomain.com/'
|
||||
'foo/bar/baz/?zot=21&zut')
|
||||
|
@ -247,15 +247,15 @@ class TestURL(TestCase):
|
|||
or fragment.
|
||||
"""
|
||||
urlpath = URL.fromText(theurl)
|
||||
self.assertEquals("http://www.foo.com/a/nice/path/gong?zot=23&zut",
|
||||
self.assertEqual("http://www.foo.com/a/nice/path/gong?zot=23&zut",
|
||||
urlpath.child(u'gong').asText())
|
||||
self.assertEquals("http://www.foo.com/a/nice/path/gong%2F?zot=23&zut",
|
||||
self.assertEqual("http://www.foo.com/a/nice/path/gong%2F?zot=23&zut",
|
||||
urlpath.child(u'gong/').asText())
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/gong%2Fdouble?zot=23&zut",
|
||||
urlpath.child(u'gong/double').asText()
|
||||
)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/gong%2Fdouble%2F?zot=23&zut",
|
||||
urlpath.child(u'gong/double/').asText()
|
||||
)
|
||||
|
@ -277,8 +277,8 @@ class TestURL(TestCase):
|
|||
path segment.
|
||||
"""
|
||||
childURL = URL(host=u"www.foo.com").child(u"c")
|
||||
self.assertEquals(childURL.rooted, True)
|
||||
self.assertEquals("http://www.foo.com/c", childURL.asText())
|
||||
self.assertTrue(childURL.rooted)
|
||||
self.assertEqual("http://www.foo.com/c", childURL.asText())
|
||||
|
||||
|
||||
def test_sibling(self):
|
||||
|
@ -287,14 +287,14 @@ class TestURL(TestCase):
|
|||
affect the query or fragment.
|
||||
"""
|
||||
urlpath = URL.fromText(theurl)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/sister?zot=23&zut",
|
||||
urlpath.sibling(u'sister').asText()
|
||||
)
|
||||
# Use an url without trailing '/' to check child removal.
|
||||
theurl2 = "http://www.foo.com/a/nice/path?zot=23&zut"
|
||||
urlpath = URL.fromText(theurl2)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/sister?zot=23&zut",
|
||||
urlpath.sibling(u'sister').asText()
|
||||
)
|
||||
|
@ -307,16 +307,16 @@ class TestURL(TestCase):
|
|||
"""
|
||||
urlpath = URL.fromText(theurl)
|
||||
# A null uri should be valid (return here).
|
||||
self.assertEquals("http://www.foo.com/a/nice/path/?zot=23&zut",
|
||||
self.assertEqual("http://www.foo.com/a/nice/path/?zot=23&zut",
|
||||
urlpath.click("").asText())
|
||||
# A simple relative path remove the query.
|
||||
self.assertEquals("http://www.foo.com/a/nice/path/click",
|
||||
self.assertEqual("http://www.foo.com/a/nice/path/click",
|
||||
urlpath.click("click").asText())
|
||||
# An absolute path replace path and query.
|
||||
self.assertEquals("http://www.foo.com/click",
|
||||
self.assertEqual("http://www.foo.com/click",
|
||||
urlpath.click("/click").asText())
|
||||
# Replace just the query.
|
||||
self.assertEquals("http://www.foo.com/a/nice/path/?burp",
|
||||
self.assertEqual("http://www.foo.com/a/nice/path/?burp",
|
||||
urlpath.click("?burp").asText())
|
||||
# One full url to another should not generate '//' between authority.
|
||||
# and path
|
||||
|
@ -326,14 +326,14 @@ class TestURL(TestCase):
|
|||
# From a url with no query clicking a url with a query, the query
|
||||
# should be handled properly.
|
||||
u = URL.fromText('http://www.foo.com/me/noquery')
|
||||
self.failUnlessEqual('http://www.foo.com/me/17?spam=158',
|
||||
u.click('/me/17?spam=158').asText())
|
||||
self.assertEqual('http://www.foo.com/me/17?spam=158',
|
||||
u.click('/me/17?spam=158').asText())
|
||||
|
||||
# Check that everything from the path onward is removed when the click
|
||||
# link has no path.
|
||||
u = URL.fromText('http://localhost/foo?abc=def')
|
||||
self.failUnlessEqual(u.click('http://www.python.org').asText(),
|
||||
'http://www.python.org')
|
||||
self.assertEqual(u.click('http://www.python.org').asText(),
|
||||
'http://www.python.org')
|
||||
|
||||
|
||||
def test_clickRFC3986(self):
|
||||
|
@ -342,7 +342,7 @@ class TestURL(TestCase):
|
|||
"""
|
||||
base = URL.fromText(relativeLinkBaseForRFC3986)
|
||||
for (ref, expected) in relativeLinkTestsForRFC3986:
|
||||
self.failUnlessEqual(base.click(ref).asText(), expected)
|
||||
self.assertEqual(base.click(ref).asText(), expected)
|
||||
|
||||
|
||||
def test_clickSchemeRelPath(self):
|
||||
|
@ -397,7 +397,7 @@ class TestURL(TestCase):
|
|||
]
|
||||
for start, click, expected in tests:
|
||||
actual = URL.fromText(start).click(click).asText()
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
actual,
|
||||
expected,
|
||||
"{start}.click({click}) => {actual} not {expected}".format(
|
||||
|
@ -413,30 +413,30 @@ class TestURL(TestCase):
|
|||
"""
|
||||
L{URL.add} adds query parameters.
|
||||
"""
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?foo=bar",
|
||||
URL.fromText("http://www.foo.com/a/nice/path/")
|
||||
.add(u"foo", u"bar").asText())
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/?foo=bar",
|
||||
URL(host=u"www.foo.com").add(u"foo", u"bar")
|
||||
.asText())
|
||||
urlpath = URL.fromText(theurl)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=23&zut&burp",
|
||||
urlpath.add(u"burp").asText())
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx",
|
||||
urlpath.add(u"burp", u"xxx").asText())
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zing",
|
||||
urlpath.add(u"burp", u"xxx").add(u"zing").asText())
|
||||
# Note the inversion!
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=23&zut&zing&burp=xxx",
|
||||
urlpath.add(u"zing").add(u"burp", u"xxx").asText())
|
||||
# Note the two values for the same name.
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zot=32",
|
||||
urlpath.add(u"burp", u"xxx").add(u"zot", u'32')
|
||||
.asText())
|
||||
|
@ -447,17 +447,17 @@ class TestURL(TestCase):
|
|||
L{URL.set} replaces query parameters by name.
|
||||
"""
|
||||
urlpath = URL.fromText(theurl)
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=32&zut",
|
||||
urlpath.set(u"zot", u'32').asText())
|
||||
# Replace name without value with name/value and vice-versa.
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot&zut=itworked",
|
||||
urlpath.set(u"zot").set(u"zut", u"itworked").asText()
|
||||
)
|
||||
# Q: what happens when the query has two values and we replace?
|
||||
# A: we replace both values with a single one
|
||||
self.assertEquals(
|
||||
self.assertEqual(
|
||||
"http://www.foo.com/a/nice/path/?zot=32&zut",
|
||||
urlpath.add(u"zot", u"xxx").set(u"zot", u'32').asText()
|
||||
)
|
||||
|
@ -527,7 +527,7 @@ class TestURL(TestCase):
|
|||
"""
|
||||
u1 = URL.fromText('http://localhost/a')
|
||||
u2 = URL.fromText('http://localhost/b')
|
||||
self.failIf(u1 == u2, "%r != %r" % (u1, u2))
|
||||
self.assertFalse(u1 == u2, "%r != %r" % (u1, u2))
|
||||
self.assertNotEqual(u1, u2)
|
||||
|
||||
|
||||
|
@ -536,8 +536,8 @@ class TestURL(TestCase):
|
|||
L{URL} is not equal (C{==}) to other types.
|
||||
"""
|
||||
u = URL.fromText('http://localhost/')
|
||||
self.failIf(u == 42, "URL must not equal a number.")
|
||||
self.failIf(u == object(), "URL must not equal an object.")
|
||||
self.assertFalse(u == 42, "URL must not equal a number.")
|
||||
self.assertFalse(u == object(), "URL must not equal an object.")
|
||||
self.assertNotEqual(u, 42)
|
||||
self.assertNotEqual(u, object())
|
||||
|
||||
|
@ -547,7 +547,7 @@ class TestURL(TestCase):
|
|||
Identical L{URL}s are not unequal (C{!=}) to each other.
|
||||
"""
|
||||
u = URL.fromText('http://localhost/')
|
||||
self.failIf(u != u, "%r == itself" % u)
|
||||
self.assertFalse(u != u, "%r == itself" % u)
|
||||
|
||||
|
||||
def test_similarNotUnequal(self):
|
||||
|
@ -556,7 +556,7 @@ class TestURL(TestCase):
|
|||
"""
|
||||
u1 = URL.fromText('http://localhost/')
|
||||
u2 = URL.fromText('http://localhost/')
|
||||
self.failIf(u1 != u2, "%r == %r" % (u1, u2))
|
||||
self.assertFalse(u1 != u2, "%r == %r" % (u1, u2))
|
||||
|
||||
|
||||
def test_differentUnequal(self):
|
||||
|
@ -565,7 +565,7 @@ class TestURL(TestCase):
|
|||
"""
|
||||
u1 = URL.fromText('http://localhost/a')
|
||||
u2 = URL.fromText('http://localhost/b')
|
||||
self.failUnless(u1 != u2, "%r == %r" % (u1, u2))
|
||||
self.assertTrue(u1 != u2, "%r == %r" % (u1, u2))
|
||||
|
||||
|
||||
def test_otherTypesUnequal(self):
|
||||
|
@ -573,8 +573,8 @@ class TestURL(TestCase):
|
|||
L{URL} is unequal (C{!=}) to other types.
|
||||
"""
|
||||
u = URL.fromText('http://localhost/')
|
||||
self.failUnless(u != 42, "URL must differ from a number.")
|
||||
self.failUnless(u != object(), "URL must be differ from an object.")
|
||||
self.assertTrue(u != 42, "URL must differ from a number.")
|
||||
self.assertTrue(u != object(), "URL must be differ from an object.")
|
||||
|
||||
|
||||
def test_asURI(self):
|
|
@ -0,0 +1,2 @@
|
|||
pytest==2.9.2
|
||||
pytest-cov==2.3.0
|
|
@ -0,0 +1,60 @@
|
|||
"""The humble, but powerful, URL runs everything around us. Chances
|
||||
are you've used several just to read this text.
|
||||
|
||||
Hyperlink is a featureful, pure-Python implementation of the URL, with
|
||||
an emphasis on correctness. BSD licensed.
|
||||
"""
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
__author__ = 'Mahmoud Hashemi and Glyph Lefkowitz'
|
||||
__version__ = '17.0.0'
|
||||
__contact__ = 'mahmoud@hatnote.com'
|
||||
__url__ = 'https://github.com/mahmoud/hyperlink'
|
||||
__license__ = 'BSD'
|
||||
|
||||
|
||||
setup(name='hyperlink',
|
||||
version=__version__,
|
||||
description="A featureful, correct URL for Python.",
|
||||
long_description=__doc__,
|
||||
author=__author__,
|
||||
author_email=__contact__,
|
||||
url=__url__,
|
||||
packages=['hyperlink'],
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
license=__license__,
|
||||
platforms='any',
|
||||
classifiers=[
|
||||
'Topic :: Utilities',
|
||||
'Intended Audience :: Developers',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: Implementation :: PyPy', ]
|
||||
)
|
||||
|
||||
"""
|
||||
A brief checklist for release:
|
||||
|
||||
* tox
|
||||
* git commit (if applicable)
|
||||
* Bump setup.py version off of -dev
|
||||
* git commit -a -m "bump version for x.y.z release"
|
||||
* python setup.py sdist bdist_wheel upload
|
||||
* bump docs/conf.py version
|
||||
* git commit
|
||||
* git tag -a x.y.z -m "brief summary"
|
||||
* write CHANGELOG
|
||||
* git commit
|
||||
* bump setup.py version onto n+1 dev
|
||||
* git commit
|
||||
* git push
|
||||
|
||||
"""
|
|
@ -1,15 +0,0 @@
|
|||
# -*- test-case-name: twisted.python.test.test_url -*-
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
URL parsing, construction and rendering.
|
||||
|
||||
@see: L{URL}
|
||||
"""
|
||||
|
||||
from ._url import URL
|
||||
|
||||
__all__ = [
|
||||
"URL",
|
||||
]
|
|
@ -1 +0,0 @@
|
|||
twisted.python.url is a new abstraction for URLs, supporting RFC 3987 IRIs.
|
Loading…
Reference in New Issue