lazr.uri-1.0.3/ 0000775 0001750 0001750 00000000000 11705552223 013517 5 ustar gavin gavin 0000000 0000000 lazr.uri-1.0.3/HACKING.txt 0000644 0001750 0001750 00000002260 11233347210 015314 0 ustar gavin gavin 0000000 0000000 ..
This file is part of lazr.uri.
lazr.uri is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, version 3 of the License.
lazr.uri is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with lazr.uri. If not, see .
This project uses zc.buildout for development.
============
Introduction
============
These are guidelines for hacking on the lazr.uri project. But first,
please see the common hacking guidelines at:
http://dev.launchpad.net/Hacking
Getting help
------------
If you find bugs in this package, you can report them here:
https://launchpad.net/lazr.uri
If you want to discuss this package, join the team and mailing list here:
https://launchpad.net/~lazr-developers
or send a message to:
lazr-developers@lists.launchpad.net
lazr.uri-1.0.3/ez_setup.py 0000644 0001750 0001750 00000022466 11233347210 015731 0 ustar gavin gavin 0000000 0000000 #!python
"""Bootstrap setuptools installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from ez_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c8"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
}
import sys, os
def _validate_md5(egg_name, data):
if egg_name in md5_data:
from md5 import md5
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
"md5 validation of %s failed! (Possible download problem?)"
% egg_name
)
sys.exit(2)
return data
def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
download_delay=15, min_version=None
):
"""Automatically find/download setuptools and make it available on sys.path
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end with
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
it is not already available. If `download_delay` is specified, it should
be the number of seconds that will be paused before initiating a download,
should one be required. If an older version of setuptools is installed,
this routine will print a message to ``sys.stderr`` and raise SystemExit in
an attempt to abort the calling script.
"""
# Work around a hack in the ez_setup.py file from simplejson==1.7.3.
if min_version:
version = min_version
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
def do_download():
egg = download_setuptools(version, download_base, to_dir, download_delay)
sys.path.insert(0, egg)
import setuptools; setuptools.bootstrap_install_from = egg
try:
import pkg_resources
except ImportError:
return do_download()
try:
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
if was_imported:
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)"
) % (version, e.args[0])
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return do_download()
except pkg_resources.DistributionNotFound:
return do_download()
def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
delay = 15
):
"""Download setuptools from a specified location and return its filename
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download attempt.
"""
import urllib2, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
from distutils import log
if delay:
log.warn("""
---------------------------------------------------------------------------
This script requires setuptools version %s to run (even to display
help). I will attempt to download it for you (from
%s), but
you may need to enable firewall access for this script first.
I will start the download in %d seconds.
(Note: if this machine does not have network access, please obtain the file
%s
and place it in this directory before rerunning this script.)
---------------------------------------------------------------------------""",
version, download_base, delay, url
); from time import sleep; sleep(delay)
log.warn("Downloading %s", url)
src = urllib2.urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = _validate_md5(egg_name, src.read())
dst = open(saveto,"wb"); dst.write(data)
finally:
if src: src.close()
if dst: dst.close()
return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
try:
import setuptools
except ImportError:
egg = None
try:
egg = download_setuptools(version, delay=0)
sys.path.insert(0,egg)
from setuptools.command.easy_install import main
return main(list(argv)+[egg]) # we're done here
finally:
if egg and os.path.exists(egg):
os.unlink(egg)
else:
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
)
sys.exit(2)
req = "setuptools>="+version
import pkg_resources
try:
pkg_resources.require(req)
except pkg_resources.VersionConflict:
try:
from setuptools.command.easy_install import main
except ImportError:
from easy_install import main
main(list(argv)+[download_setuptools(delay=0)])
sys.exit(0) # try to force an exit
else:
if argv:
from setuptools.command.easy_install import main
main(argv)
else:
print "Setuptools version",version,"or greater has been installed."
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
def update_md5(filenames):
"""Update our built-in md5 registry"""
import re
from md5 import md5
for name in filenames:
base = os.path.basename(name)
f = open(name,'rb')
md5_data[base] = md5(f.read()).hexdigest()
f.close()
data = [" %r: %r,\n" % it for it in md5_data.items()]
data.sort()
repl = "".join(data)
import inspect
srcfile = inspect.getsourcefile(sys.modules[__name__])
f = open(srcfile, 'rb'); src = f.read(); f.close()
match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match:
print >>sys.stderr, "Internal error!"
sys.exit(2)
src = src[:match.start(1)] + repl + src[match.end(1):]
f = open(srcfile,'w')
f.write(src)
f.close()
if __name__=='__main__':
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
update_md5(sys.argv[2:])
else:
main(sys.argv[1:])
lazr.uri-1.0.3/README.txt 0000644 0001750 0001750 00000001345 11705551374 015224 0 ustar gavin gavin 0000000 0000000 A self-contained, easily reusable library for parsing, manipulating,
and generating URIs.
..
This file is part of lazr.uri.
lazr.uri is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, version 3 of the License.
lazr.uri is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with lazr.uri. If not, see .
lazr.uri-1.0.3/src/ 0000775 0001750 0001750 00000000000 11705552223 014306 5 ustar gavin gavin 0000000 0000000 lazr.uri-1.0.3/src/lazr/ 0000775 0001750 0001750 00000000000 11705552223 015256 5 ustar gavin gavin 0000000 0000000 lazr.uri-1.0.3/src/lazr/uri/ 0000775 0001750 0001750 00000000000 11705552223 016055 5 ustar gavin gavin 0000000 0000000 lazr.uri-1.0.3/src/lazr/uri/tests/ 0000775 0001750 0001750 00000000000 11705552223 017217 5 ustar gavin gavin 0000000 0000000 lazr.uri-1.0.3/src/lazr/uri/tests/__init__.py 0000644 0001750 0001750 00000001302 11233347210 021314 0 ustar gavin gavin 0000000 0000000 # Copyright 2009 Canonical Ltd. All rights reserved.
#
# This file is part of lazr.uri
#
# lazr.uri is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# lazr.uri is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with lazr.uri. If not, see .
"""Test package."""
lazr.uri-1.0.3/src/lazr/uri/tests/test_uri.py 0000644 0001750 0001750 00000015540 11705531273 021434 0 ustar gavin gavin 0000000 0000000 # coding: utf-8
# Copyright 2006-2009 Canonical Ltd. All rights reserved.
#
# This file is part of lazr.uri
#
# lazr.uri is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# lazr.uri is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with lazr.uri. If not, see .
"""Unit tests."""
__metaclass__ = type
__all__ = [
'test_suite',
]
import unittest
from lazr.uri import (
InvalidURIError, URI, find_uris_in_text, merge, remove_dot_segments)
class URITestCase(unittest.TestCase):
def test_normalisation(self):
# URI normalisation examples from Section 6.2.2 of RFC 3986.
self.assertEqual(str(URI('eXAMPLE://a/./b/../b/%63/%7bfoo%7d')),
'example://a/b/c/%7Bfoo%7D')
self.assertEqual(str(URI('http://www.EXAMPLE.com/')),
'http://www.example.com/')
self.assertEqual(str(URI('http://www.gnome.org/%7ejamesh/')),
'http://www.gnome.org/~jamesh/')
# Port number normalisation, and adding missing slash for URIs
# with authority:
self.assertEqual(str(URI('http://example.com')),
'http://example.com/')
self.assertEqual(str(URI('http://example.com:/')),
'http://example.com/')
self.assertEqual(str(URI('http://example.com:80/')),
'http://example.com/')
def test_invalid_uri(self):
self.assertRaises(InvalidURIError, URI, 'http://€xample.com/')
def test_merge(self):
# Test that the merge() function performs as described in
# Section 5.2.3 of RFC 3986
self.assertEqual(merge('', 'foo', has_authority=True), '/foo')
self.assertEqual(merge('', 'foo', has_authority=False), 'foo')
self.assertEqual(merge('/a/b/c', 'foo', has_authority=True),
'/a/b/foo')
self.assertEqual(merge('/a/b/', 'foo', has_authority=True),
'/a/b/foo')
def test_remove_dot_segments(self):
# remove_dot_segments() examples from Section 5.2.4 of RFC 3986:
self.assertEqual(remove_dot_segments('/a/b/c/./../../g'), '/a/g')
self.assertEqual(remove_dot_segments('mid/content=5/../6'), 'mid/6')
def test_normal_resolution(self):
# Normal URI resolution examples from Section 5.4.1 of RFC 3986:
base = URI('http://a/b/c/d;p?q')
def resolve(relative):
return str(base.resolve(relative))
self.assertEqual(resolve('g:h'), 'g:h')
self.assertEqual(resolve('g'), 'http://a/b/c/g')
self.assertEqual(resolve('./g'), 'http://a/b/c/g')
self.assertEqual(resolve('g/'), 'http://a/b/c/g/')
self.assertEqual(resolve('/g'), 'http://a/g')
# The extra slash here comes from normalisation:
self.assertEqual(resolve('//g'), 'http://g/')
self.assertEqual(resolve('?y'), 'http://a/b/c/d;p?y')
self.assertEqual(resolve('g?y'), 'http://a/b/c/g?y')
self.assertEqual(resolve('#s'), 'http://a/b/c/d;p?q#s')
self.assertEqual(resolve('g#s'), 'http://a/b/c/g#s')
self.assertEqual(resolve('g?y#s'), 'http://a/b/c/g?y#s')
self.assertEqual(resolve(';x'), 'http://a/b/c/;x')
self.assertEqual(resolve('g;x'), 'http://a/b/c/g;x')
self.assertEqual(resolve('g;x?y#s'), 'http://a/b/c/g;x?y#s')
self.assertEqual(resolve(''), 'http://a/b/c/d;p?q')
self.assertEqual(resolve('.'), 'http://a/b/c/')
self.assertEqual(resolve('./'), 'http://a/b/c/')
self.assertEqual(resolve('..'), 'http://a/b/')
self.assertEqual(resolve('../'), 'http://a/b/')
self.assertEqual(resolve('../g'), 'http://a/b/g')
self.assertEqual(resolve('../..'), 'http://a/')
self.assertEqual(resolve('../../'), 'http://a/')
self.assertEqual(resolve('../../g'), 'http://a/g')
def test_abnormal_resolution(self):
# Abnormal URI resolution examples from Section 5.4.2 of RFC 3986:
base = URI('http://a/b/c/d;p?q')
def resolve(relative):
return str(base.resolve(relative))
self.assertEqual(resolve('../../../g'), 'http://a/g')
self.assertEqual(resolve('../../../../g'),'http://a/g')
self.assertEqual(resolve('/./g'), 'http://a/g')
self.assertEqual(resolve('/../g'), 'http://a/g')
self.assertEqual(resolve('g.'), 'http://a/b/c/g.')
self.assertEqual(resolve('.g'), 'http://a/b/c/.g')
self.assertEqual(resolve('g..'), 'http://a/b/c/g..')
self.assertEqual(resolve('..g'), 'http://a/b/c/..g')
self.assertEqual(resolve('./../g'), 'http://a/b/g')
self.assertEqual(resolve('./g/.'), 'http://a/b/c/g/')
self.assertEqual(resolve('g/./h'), 'http://a/b/c/g/h')
self.assertEqual(resolve('g/../h'), 'http://a/b/c/h')
self.assertEqual(resolve('g;x=1/./y'), 'http://a/b/c/g;x=1/y')
self.assertEqual(resolve('g;x=1/../y'), 'http://a/b/c/y')
self.assertEqual(resolve('g?y/./x'), 'http://a/b/c/g?y/./x')
self.assertEqual(resolve('g?y/../x'), 'http://a/b/c/g?y/../x')
self.assertEqual(resolve('g#s/./x'), 'http://a/b/c/g#s/./x')
self.assertEqual(resolve('g#s/../x'), 'http://a/b/c/g#s/../x')
# XXX 2009-01-30 jamesh:
# I've disabled this test since we refuse to accept HTTP URIs
# without a hostname component.
#self.assertEqual(resolve('http:g'), 'http:g')
def test_underDomain_matches_subdomain(self):
# URI.underDomain should return True when asked whether the url is
# under one of its parent domains.
uri = URI('http://code.launchpad.dev/foo')
self.assertTrue(uri.underDomain('code.launchpad.dev'))
self.assertTrue(uri.underDomain('launchpad.dev'))
self.assertTrue(uri.underDomain(''))
def test_underDomain_doesnt_match_non_subdomain(self):
# URI.underDomain should return False when asked whether the url is
# under a domain which isn't one of its parents.
uri = URI('http://code.launchpad.dev/foo')
self.assertFalse(uri.underDomain('beta.code.launchpad.dev'))
self.assertFalse(uri.underDomain('google.com'))
self.assertFalse(uri.underDomain('unchpad.dev'))
def additional_tests():
return unittest.TestLoader().loadTestsFromName(__name__)
lazr.uri-1.0.3/src/lazr/uri/tests/test_docs.py 0000644 0001750 0001750 00000003463 11705531273 021566 0 ustar gavin gavin 0000000 0000000 # Copyright 2009 Canonical Ltd. All rights reserved.
#
# This file is part of lazr.uri
#
# lazr.uri is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# lazr.uri is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with lazr.uri. If not, see .
"Test harness for doctests."
from __future__ import print_function
__metaclass__ = type
__all__ = [
'additional_tests',
]
import atexit
import doctest
import os
import pkg_resources
import unittest
DOCTEST_FLAGS = (
doctest.ELLIPSIS |
doctest.NORMALIZE_WHITESPACE |
doctest.REPORT_NDIFF)
def additional_tests():
"Run the doc tests (README.txt and docs/*, if any exist)"
doctest_files = [
os.path.abspath(
pkg_resources.resource_filename('lazr.uri', 'README.txt'))]
if pkg_resources.resource_exists('lazr.uri', 'docs'):
for name in pkg_resources.resource_listdir('lazr.uri', 'docs'):
if name.endswith('.txt'):
doctest_files.append(
os.path.abspath(
pkg_resources.resource_filename(
'lazr.uri', 'docs/%s' % name)))
kwargs = dict(
module_relative=False, optionflags=DOCTEST_FLAGS,
globs={"print_function": print_function},
)
atexit.register(pkg_resources.cleanup_resources)
return unittest.TestSuite((
doctest.DocFileSuite(*doctest_files, **kwargs)))
lazr.uri-1.0.3/src/lazr/uri/README.txt 0000644 0001750 0001750 00000007716 11705531273 017566 0 ustar gavin gavin 0000000 0000000 ..
This file is part of lazr.uri.
lazr.uri is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, version 3 of the License.
lazr.uri is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with lazr.uri. If not, see .
lazr.uri
********
The lazr.uri package includes code for parsing and dealing with URIs.
>>> import lazr.uri
>>> print('VERSION:', lazr.uri.__version__)
VERSION: ...
=============
The URI class
=============
>>> from lazr.uri import URI
>>> uri1 = URI('http://localhost/foo/bar?123')
>>> uri2 = URI('http://localhost/foo/bar/baz')
>>> uri1.contains(uri2)
True
These next two are equivalent, so the answer should be True, even through
the "outside" one is shorter than the "inside" one.
>>> uri1 = URI('http://localhost/foo/bar/')
>>> uri2 = URI('http://localhost/foo/bar')
>>> uri1.contains(uri2)
True
The next two are exactly the same. We consider a url to be inside itself.
>>> uri1 = URI('http://localhost/foo/bar/')
>>> uri2 = URI('http://localhost/foo/bar/')
>>> uri1.contains(uri2)
True
In the next case, the string of url2 starts with the string of url1. But,
because url2 continues within the same path step, url2 is not inside url1.
>>> uri1 = URI('http://localhost/foo/ba')
>>> uri2 = URI('http://localhost/foo/bar')
>>> uri1.contains(uri2)
False
Here, url2 is url1 plus an extra path step. So, url2 is inside url1.
>>> uri1 = URI('http://localhost/foo/bar/')
>>> uri2 = URI('http://localhost/foo/bar/baz')
>>> uri1.contains(uri2)
True
Once the URI is parsed, its parts are accessible.
>>> uri = URI('https://fish.tree:8666/blee/blah')
>>> uri.scheme
'https'
>>> uri.host
'fish.tree'
>>> uri.port
'8666'
>>> uri.authority
'fish.tree:8666'
>>> uri.path
'/blee/blah'
>>> uri = URI('https://localhost/blee/blah')
>>> uri.scheme
'https'
>>> uri.host
'localhost'
>>> uri.port is None
True
>>> uri.authority
'localhost'
>>> uri.path
'/blee/blah'
The grammar from RFC 3986 does not allow for square brackets in the
query component, but Section 3.4 does say how such delimeter
characters should be handled if found in the component.
>>> uri = URI('http://www.apple.com/store?delivery=[slow]#horse+cart')
>>> uri.scheme
'http'
>>> uri.host
'www.apple.com'
>>> uri.port is None
True
>>> uri.path
'/store'
>>> uri.query
'delivery=[slow]'
>>> uri.fragment
'horse+cart'
====================
Finding URIs in Text
====================
lazr.uri also knows how to retrieve a list of URIs from a block of
text. This is intended for uses like finding bug tracker URIs or
similar.
The find_uris_in_text() function returns an iterator that yields URI
objects for each URI found in the text. Note that the returned URIs
have been canonicalised by the URI class:
>>> from lazr.uri import find_uris_in_text
>>> text = '''
... A list of URIs:
... * http://localhost/a/b
... * http://launchpad.net
... * MAILTO:joe@example.com
... * xmpp:fred@example.org
... * http://bazaar.launchpad.net/%7ename12/firefox/foo
... * http://somewhere.in/time?track=[02]#wasted-years
... '''
>>> for uri in find_uris_in_text(text):
... print(uri)
http://localhost/a/b
http://launchpad.net/
mailto:joe@example.com
xmpp:fred@example.org
http://bazaar.launchpad.net/~name12/firefox/foo
http://somewhere.in/time?track=[02]#wasted-years
===============
Other Documents
===============
.. toctree::
:glob:
*
docs/*
lazr.uri-1.0.3/src/lazr/uri/configure.zcml 0000644 0001750 0001750 00000000720 11233347210 020714 0 ustar gavin gavin 0000000 0000000