author | Matt Mackall <mpm@selenic.com> |
Sat, 18 Jun 2011 17:03:01 -0500 | |
branch | stable |
changeset 14687 | 15200b46165b |
parent 14666 | 27b080aa880a |
child 15018 | e89f62dcd723 |
permissions | -rw-r--r-- |
12737
7adb1274a4f9
test-url: skip test when ssl module is unavailable
Augie Fackler <durin42@gmail.com>
parents:
12592
diff
changeset
|
1 |
import sys |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
2 |
|
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
3 |
def check(a, b): |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
4 |
if a != b: |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
5 |
print (a, b) |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
6 |
|
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
7 |
def cert(cn): |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
8 |
return dict(subject=((('commonName', cn),),)) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
9 |
|
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
14076
diff
changeset
|
10 |
from mercurial.sslutil import _verifycert |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
11 |
|
12724
66e7ba85585b
test-url: remove trailing whitespace
Augie Fackler <durin42@gmail.com>
parents:
12606
diff
changeset
|
12 |
# Test non-wildcard certificates |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
13 |
check(_verifycert(cert('example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
14 |
None) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
15 |
check(_verifycert(cert('example.com'), 'www.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
16 |
'certificate is for example.com') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
17 |
check(_verifycert(cert('www.example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
18 |
'certificate is for www.example.com') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
19 |
|
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
20 |
# Test wildcard certificates |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
21 |
check(_verifycert(cert('*.example.com'), 'www.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
22 |
None) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
23 |
check(_verifycert(cert('*.example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
24 |
'certificate is for *.example.com') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
25 |
check(_verifycert(cert('*.example.com'), 'w.w.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
26 |
'certificate is for *.example.com') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
27 |
|
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
28 |
# Test subjectAltName |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
29 |
san_cert = {'subject': ((('commonName', 'example.com'),),), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
30 |
'subjectAltName': (('DNS', '*.example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
31 |
('DNS', 'example.net'))} |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
32 |
check(_verifycert(san_cert, 'example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
33 |
None) |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
34 |
check(_verifycert(san_cert, 'foo.example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
35 |
None) |
14666
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
36 |
# no fallback to subject commonName when subjectAltName has DNS |
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
37 |
check(_verifycert(san_cert, 'example.com'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
38 |
'certificate is for *.example.net, example.net') |
14666
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
39 |
# fallback to subject commonName when no DNS in subjectAltName |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
40 |
san_cert = {'subject': ((('commonName', 'example.com'),),), |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
41 |
'subjectAltName': (('IP Address', '8.8.8.8'),)} |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
42 |
check(_verifycert(san_cert, 'example.com'), None) |
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
43 |
|
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
44 |
# Avoid some pitfalls |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
45 |
check(_verifycert(cert('*.foo'), 'foo'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
46 |
'certificate is for *.foo') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
47 |
check(_verifycert(cert('*o'), 'foo'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
48 |
'certificate is for *o') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
49 |
|
12742
6ab4a7d3c179
url: validity (notBefore/notAfter) is checked by OpenSSL (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
12738
diff
changeset
|
50 |
check(_verifycert({'subject': ()}, |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
51 |
'example.com'), |
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
52 |
'no commonName or subjectAltName found in certificate') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
53 |
check(_verifycert(None, 'example.com'), |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
54 |
'no certificate received') |
13248
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
55 |
|
14666
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
56 |
# Unicode (IDN) certname isn't supported |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
57 |
check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'), |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
58 |
'IDN in certificate not supported') |
27b080aa880a
sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents:
14313
diff
changeset
|
59 |
|
13770 | 60 |
import doctest |
61 |
||
62 |
def test_url(): |
|
63 |
""" |
|
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
13848
diff
changeset
|
64 |
>>> from mercurial.util import url |
13770 | 65 |
|
66 |
This tests for edge cases in url.URL's parsing algorithm. Most of |
|
67 |
these aren't useful for documentation purposes, so they aren't |
|
68 |
part of the class's doc tests. |
|
69 |
||
70 |
Query strings and fragments: |
|
71 |
||
72 |
>>> url('http://host/a?b#c') |
|
73 |
<url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'> |
|
74 |
>>> url('http://host/a?') |
|
75 |
<url scheme: 'http', host: 'host', path: 'a'> |
|
76 |
>>> url('http://host/a#b#c') |
|
77 |
<url scheme: 'http', host: 'host', path: 'a', fragment: 'b#c'> |
|
78 |
>>> url('http://host/a#b?c') |
|
79 |
<url scheme: 'http', host: 'host', path: 'a', fragment: 'b?c'> |
|
80 |
>>> url('http://host/?a#b') |
|
81 |
<url scheme: 'http', host: 'host', path: '', query: 'a', fragment: 'b'> |
|
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
82 |
>>> url('http://host/?a#b', parsequery=False) |
13770 | 83 |
<url scheme: 'http', host: 'host', path: '?a', fragment: 'b'> |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
84 |
>>> url('http://host/?a#b', parsefragment=False) |
13770 | 85 |
<url scheme: 'http', host: 'host', path: '', query: 'a#b'> |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
86 |
>>> url('http://host/?a#b', parsequery=False, parsefragment=False) |
13770 | 87 |
<url scheme: 'http', host: 'host', path: '?a#b'> |
88 |
||
89 |
IPv6 addresses: |
|
90 |
||
91 |
>>> url('ldap://[2001:db8::7]/c=GB?objectClass?one') |
|
92 |
<url scheme: 'ldap', host: '[2001:db8::7]', path: 'c=GB', |
|
93 |
query: 'objectClass?one'> |
|
94 |
>>> url('ldap://joe:xxx@[2001:db8::7]:80/c=GB?objectClass?one') |
|
95 |
<url scheme: 'ldap', user: 'joe', passwd: 'xxx', host: '[2001:db8::7]', |
|
96 |
port: '80', path: 'c=GB', query: 'objectClass?one'> |
|
97 |
||
98 |
Missing scheme, host, etc.: |
|
99 |
||
100 |
>>> url('://192.0.2.16:80/') |
|
101 |
<url path: '://192.0.2.16:80/'> |
|
102 |
>>> url('http://mercurial.selenic.com') |
|
103 |
<url scheme: 'http', host: 'mercurial.selenic.com'> |
|
104 |
>>> url('/foo') |
|
105 |
<url path: '/foo'> |
|
106 |
>>> url('bundle:/foo') |
|
107 |
<url scheme: 'bundle', path: '/foo'> |
|
108 |
>>> url('a?b#c') |
|
109 |
<url path: 'a?b', fragment: 'c'> |
|
110 |
>>> url('http://x.com?arg=/foo') |
|
111 |
<url scheme: 'http', host: 'x.com', query: 'arg=/foo'> |
|
112 |
>>> url('http://joe:xxx@/foo') |
|
113 |
<url scheme: 'http', user: 'joe', passwd: 'xxx', path: 'foo'> |
|
114 |
||
115 |
Just a scheme and a path: |
|
116 |
||
117 |
>>> url('mailto:John.Doe@example.com') |
|
118 |
<url scheme: 'mailto', path: 'John.Doe@example.com'> |
|
119 |
>>> url('a:b:c:d') |
|
13808 | 120 |
<url path: 'a:b:c:d'> |
121 |
>>> url('aa:bb:cc:dd') |
|
122 |
<url scheme: 'aa', path: 'bb:cc:dd'> |
|
13770 | 123 |
|
124 |
SSH examples: |
|
125 |
||
126 |
>>> url('ssh://joe@host//home/joe') |
|
127 |
<url scheme: 'ssh', user: 'joe', host: 'host', path: '/home/joe'> |
|
128 |
>>> url('ssh://joe:xxx@host/src') |
|
129 |
<url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', path: 'src'> |
|
130 |
>>> url('ssh://joe:xxx@host') |
|
131 |
<url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host'> |
|
132 |
>>> url('ssh://joe@host') |
|
133 |
<url scheme: 'ssh', user: 'joe', host: 'host'> |
|
134 |
>>> url('ssh://host') |
|
135 |
<url scheme: 'ssh', host: 'host'> |
|
136 |
>>> url('ssh://') |
|
137 |
<url scheme: 'ssh'> |
|
138 |
>>> url('ssh:') |
|
139 |
<url scheme: 'ssh'> |
|
140 |
||
141 |
Non-numeric port: |
|
142 |
||
143 |
>>> url('http://example.com:dd') |
|
144 |
<url scheme: 'http', host: 'example.com', port: 'dd'> |
|
145 |
>>> url('ssh://joe:xxx@host:ssh/foo') |
|
146 |
<url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', port: 'ssh', |
|
147 |
path: 'foo'> |
|
148 |
||
149 |
Bad authentication credentials: |
|
150 |
||
151 |
>>> url('http://joe@joeville:123@4:@host/a?b#c') |
|
152 |
<url scheme: 'http', user: 'joe@joeville', passwd: '123@4:', |
|
153 |
host: 'host', path: 'a', query: 'b', fragment: 'c'> |
|
154 |
>>> url('http://!*#?/@!*#?/:@host/a?b#c') |
|
155 |
<url scheme: 'http', host: '!*', fragment: '?/@!*#?/:@host/a?b#c'> |
|
156 |
>>> url('http://!*#?@!*#?:@host/a?b#c') |
|
157 |
<url scheme: 'http', host: '!*', fragment: '?@!*#?:@host/a?b#c'> |
|
158 |
>>> url('http://!*@:!*@@host/a?b#c') |
|
159 |
<url scheme: 'http', user: '!*@', passwd: '!*@', host: 'host', |
|
160 |
path: 'a', query: 'b', fragment: 'c'> |
|
161 |
||
162 |
File paths: |
|
163 |
||
164 |
>>> url('a/b/c/d.g.f') |
|
165 |
<url path: 'a/b/c/d.g.f'> |
|
166 |
>>> url('/x///z/y/') |
|
167 |
<url path: '/x///z/y/'> |
|
13848
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
168 |
>>> url('/foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
169 |
<url path: '/foo:bar'> |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
170 |
>>> url('\\\\foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
171 |
<url path: '\\\\foo:bar'> |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
172 |
>>> url('./foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
173 |
<url path: './foo:bar'> |
13770 | 174 |
|
13817
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
175 |
Non-localhost file URL: |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
176 |
|
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
177 |
>>> u = url('file://mercurial.selenic.com/foo') |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
178 |
Traceback (most recent call last): |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
179 |
File "<stdin>", line 1, in ? |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
180 |
Abort: file:// URLs can only refer to localhost |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
181 |
|
13770 | 182 |
Empty URL: |
183 |
||
184 |
>>> u = url('') |
|
185 |
>>> u |
|
186 |
<url path: ''> |
|
187 |
>>> str(u) |
|
188 |
'' |
|
189 |
||
190 |
Empty path with query string: |
|
191 |
||
192 |
>>> str(url('http://foo/?bar')) |
|
193 |
'http://foo/?bar' |
|
194 |
||
195 |
Invalid path: |
|
196 |
||
197 |
>>> u = url('http://foo/bar') |
|
198 |
>>> u.path = 'bar' |
|
199 |
>>> str(u) |
|
200 |
'http://foo/bar' |
|
201 |
||
14313
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
202 |
>>> u = url('file:/foo/bar/baz') |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
203 |
>>> u |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
204 |
<url scheme: 'file', path: '/foo/bar/baz'> |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
205 |
>>> str(u) |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
206 |
'file:///foo/bar/baz' |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
207 |
|
13770 | 208 |
>>> u = url('file:///foo/bar/baz') |
209 |
>>> u |
|
210 |
<url scheme: 'file', path: '/foo/bar/baz'> |
|
211 |
>>> str(u) |
|
14313
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
212 |
'file:///foo/bar/baz' |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
213 |
|
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
214 |
>>> u = url('file:foo/bar/baz') |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
215 |
>>> u |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
216 |
<url scheme: 'file', path: 'foo/bar/baz'> |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
217 |
>>> str(u) |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
218 |
'file:foo/bar/baz' |
13770 | 219 |
""" |
220 |
||
221 |
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE) |