G_?ddlmZddlZddlZddlmZmZmZmZm Z m Z ddl m Z ddl mZmZddlmZmZej&ddk(Zed Zd Zd Zgd Zd ZGdde Zy))unicode_literalsN)AnyIterableOptionalTextTuplecast)HyperlinkTestCase)URL URLParseError) inet_ptonSCHEME_PORT_MAP*http://www.foo.com/a/nice/path/?zot=23&zuthttp://a/b/c/d;p?q)()ghttp://a/b/c/g)z./gr)zg/http://a/b/c/g/)z/g http://a/g)z//gzhttp://g)z?yzhttp://a/b/c/d;p?y)zg?yzhttp://a/b/c/g?y)z#szhttp://a/b/c/d;p?q#s)zg#szhttp://a/b/c/g#s)zg?y#szhttp://a/b/c/g?y#s)z;xzhttp://a/b/c/;x)zg;xzhttp://a/b/c/g;x)zg;x?y#szhttp://a/b/c/g;x?y#s)rr). http://a/b/c/)z./r).. http://a/b/)z../r)z../g http://a/b/g)z../.. http://a/)z../../r)z../../gr)z ../../../gr)z ../../../../gr)z/./gr)z/../gr)zg.zhttp://a/b/c/g.)z.gzhttp://a/b/c/.g)zg..zhttp://a/b/c/g..)z..gzhttp://a/b/c/..g)z./../gr)z./g/.r)zg/./hzhttp://a/b/c/g/h)zg/../hzhttp://a/b/c/h)z g;x=1/./yzhttp://a/b/c/g;x=1/y)z g;x=1/../yzhttp://a/b/c/y)zg?y/./xzhttp://a/b/c/g?y/./x)zg?y/../xzhttp://a/b/c/g?y/../x)zg#s/./xzhttp://a/b/c/g#s/./x)zg#s/../xzhttp://a/b/c/g#s/../x)6zhttp://localhosthttp://localhost/zhttp://127.0.0.1/zhttp://[::127.0.0.1]/z http://[::1]/zhttp://localhost/foozhttp://localhost/foo/zhttp://localhost/foo!!bar/zhttp://localhost/foo%20bar/zhttp://localhost/foo%2Fbar/zhttp://localhost/foo?nzhttp://localhost/foo?n=vzhttp://localhost/foo?n=/a/bz%http://example.com/foo!@$bar?b!@z=123z$http://localhost/asd?a=asd%20sdf/345z6http://(%2525)/(%2525)?(%2525)&(%2525)=(%2525)#(%2525)zd=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHdGZIdHZJdIZKdJZLdKZMdLZNyM)OTestURLz Tests for L{URL}. c|jt|jtxs|jdut ||jt|j txs|j dut ||j D]+}|jt|tt |-|jD]]\}}|jttt ||j|duxst|tt |_|jt|jtt |y)zl The given L{URL}'s components should be L{unicode}. @param u: The L{URL} to test. N) assertTrue isinstanceschemeunicodereprhostpath assertEqualtypequeryfragment)selfuseg_kvs 9/usr/lib/python3/dist-packages/hyperlink/test/test_url.pyassertUnicodedzTestURL.assertUnicodeds  qxx ) =QXX-=tAw   16673Eqvv~tAwO66 :C   T#Ya 9 :ww JGR   T#Ya 9 OOAI?Aw)?a I J ajj)7DG<c |j|j|j|j|j|j |j f} ||t|t||||j f} |j| | y)a The given L{URL} should have the given components. @param u: The actual L{URL} to examine. @param scheme: The expected scheme. @param host: The expected host. @param path: The expected path. @param query: The expected query. @param fragment: The expected fragment. @param port: The expected port. @param userinfo: The expected userinfo. N) r%r(r)r,r-portuserinfotupler*) r.r/r%r(r)r,r-r7r8actualexpecteds r3 assertURLzTestURL.assertURLsy@ HH FF FF GG JJ FF JJ    $K %L   JJ  *r5c fd}|tdd|tddgg|tddggdy)z@ L{URL} should have appropriate default values. c Xj|j|ddggdddy)NhttprP)r4r<)r/r.s r3checkz(TestURL.test_initDefaults..checks+    " NN1fb"b"b" =r5r?rN)r )r.rAs` r3test_initDefaultszTestURL.test_initDefaultss@  > c&"o c&"b"%& c&"b"b)*r5c tdddgddgd}|j||j|dddgddgdd|jtdd d gd gd dd d gd gd d y)z= L{URL} should accept L{unicode} parameters. shpkr2)rHNfNr?àé)uλuπu⊥r@r r4r<r.r/s r3 test_initzTestURL.test_inits S3%*k!:C @ A q#sSEJ +Dc4P  +?*@( K   H ! "   r5c ~tdddgddgd}|j||j|dddgddgddy)zN L{URL} should accept (and not interpret) percent characters. rDz%68z%70)%6Bz%76)rPNz%66NrLrMs r3test_initPercentzTestURL.test_initPercentsM UUGnm%De L A  sEE7^]$CUD r5c v|jttdddgddgddtd d y ) z L{URL.__repr__} will display the canonical form of the URL, wrapped in a L{URL.from_text} invocation, so that it is C{eval}-able but still easy to read. r?foobar)bazNrGfrobr%r(r)r,r-zURL.from_text(zhttp://foo/bar?baz&k=v#frob)N)r*r'r r.s r3 test_reprzTestURL.test_reprsF  !(*5#  $((E#F H r5c~tjt}|jt|j y)zc Round-tripping L{URL.from_text} with C{str} results in an equivalent URL. N)r from_text BASIC_URLr*to_textr.urlpaths r3test_from_textzTestURL.test_from_texts) -- * GOO$56r5ctD]9}tj|jd}|j ||;y)z@ L{URL.to_text} should invert L{URL.from_text}. T with_passwordN)ROUNDTRIP_TESTSr r\r^r*)r.testresults r3test_roundtripzTestURL.test_roundtrip%s? $ +D]]4(00t0DF   T6 * +r5ctD]i}tj|}|j}|j}||k(sJ|j d}|j d}||k(riJy)NTrc)rer r\to_irir^)r.rfurliri double_iriiri_textdouble_iri_texts r3test_roundtrip_double_iriz!TestURL.test_roundtrip_double_iri.sy# /D--%C**,CJ*$ $${{{6H(00t0DO. .. / r5ctjt}|j|tjt|j |tjdy)z Two URLs decoded using L{URL.from_text} will be equal (C{==}) if they decoded same URL string, and unequal (C{!=}) if they decoded different strings. z:ftp://www.anotherinvaliddomain.com/foo/bar/baz/?zot=21&zutN)r r\r]r*assertNotEqualr_s r3 test_equalityzTestURL.test_equality;sK-- * #-- ":;   MMO  r5c|jtdt|jtjdtjdy)z An URL created with the empty string for a fragment compares equal to an URL created with an unspecified fragment. r)r-zhttp://localhost/#rN)r*r r\rYs r3test_fragmentEqualityzTestURL.test_fragmentEqualityKsC b)351  MM. / MM- . r5ctjt}|jd|j dj |jd|j dj |jd|j dj |jd|j dj y ) zm L{URL.child} appends a new path segment, but does not affect the query or fragment. z.http://www.foo.com/a/nice/path/gong?zot=23&zutgongz1http://www.foo.com/a/nice/path/gong%2F?zot=23&zutzgong/z7http://www.foo.com/a/nice/path/gong%2Fdouble?zot=23&zutz gong/doublez:http://www.foo.com/a/nice/path/gong%2Fdouble%2F?zot=23&zutz gong/double/N)r r\r]r*childr^r_s r3 test_childzTestURL.test_childWs -- *  < MM& ! ) ) +   ? MM' " * * ,   E MM- ( 0 0 2   H MM. ) 1 1 3 r5ctjd}|j|jdddj dy)zg L{URL.child} receives multiple segments as C{*args} and appends each in turn. zhttp://example.com/a/bcdezhttp://example.com/a/b/c/d/eN)r r\r*rxr^r.rks r3test_multiChildzTestURL.test_multiChildos= mm45  IIc3 $ , , .0N r5ctdjd}|j|j|j d|j y)zo L{URL.child} of a L{URL} without a path produces a L{URL} with a single path segment. www.foo.comr(r{zhttp://www.foo.com/cN)r rxr#rootedr*r^)r.childURLs r3test_childInitRootzTestURL.test_childInitRootzsC M*005 ( /1A1A1CDr5c\td}|j|j|y)zT L{URL.child} without any new segments returns the original L{URL}. rrN)r r*rxr~s r3test_emptyChildzTestURL.test_emptyChilds$ }% c*r5c tjt}|jd|j dj d}tj|}|jd|j dj y)z L{URL.sibling} of a L{URL} replaces the last path segment, but does not affect the query or fragment. z0http://www.foo.com/a/nice/path/sister?zot=23&zutsisterz)http://www.foo.com/a/nice/path?zot=23&zutz+http://www.foo.com/a/nice/sister?zot=23&zutN)r r\r]r*siblingr^)r.r`url_texts r3 test_siblingzTestURL.test_siblingss -- *  > OOH % - - / ?--)  9 OOH % - - / r5ctjt}|jd|j dj |jd|j dj |jd|j dj |jd|j dj |j d |j d j vtjd }|jd |j d j tjd}|j|j dj dtjd}d}|j|j dj ||j|j j |tjd}tjd}|j |}|j|j dy)z L{URL.click} interprets the given string as a relative URI-reference and returns a new L{URL} interpreting C{self} as the base absolute URI. rrz$http://www.foo.com/a/nice/path/clickclickzhttp://www.foo.com/clickz/clickz$http://www.foo.com/a/nice/path/?burpz?burpz//foobarzhttp://www.foo.com/foobarzhttp://www.foo.com/me/noqueryz!http://www.foo.com/me/17?spam=158z/me/17?spam=158zhttp://localhost/foo?abc=defzhttp://www.python.orgz$http://hatnote.com/a/b/../c/./d/e/..zhttp://hatnote.com/a/c/d/zhttp://localhost/foo/?abc=defrTzhttp://localhost/foo/barN)r r\r]r*rr^r#fromText)r.r`r/resu2u3s r3 test_clickzTestURL.test_clicks -- *  8 MM"  % % '  2 MM' " * * ,  & h(?(G(G(I   2 MM' " * * ,  ==!<=EEG H  MM9 :  / GG% & . . 0  MM8 9  GG+ , 4 4 68O MM@ A) ,,.4 **,c2 LL8 9 ]]5 ! WWR[ 'ABr5ctjt}tD]4\}}|j |j |j |6y)zQ L{URL.click} should correctly resolve the examples in RFC 3986. N)r r\relativeLinkBaseForRFC3986relativeLinkTestsForRFC3986r*rr^)r.baserefr;s r3test_clickRFC3986zTestURL.test_clickRFC3986sI }}78: BOS(   TZZ_446 A Br5ctjt}|jt|j d|jt|j dy)zM L{URL.click} should not accept schemes with relative paths. zg:hzhttp:hN)r r\r assertRaisesNotImplementedErrorr)r.rs r3test_clickSchemeRelPathzTestURL.test_clickSchemeRelPathsA }}78 -tzz5A -tzz8Dr5c 2tjd}|j|j|j|j |j |j|j|j||j|j|y)zf Verify that L{URL.replace} doesn't change any of the arguments it is passed. zhttps://x:1/y?z=1#AN) r r\r*replacer%r(r)r,r-r7r_s r3test_cloneUnchangedzTestURL.test_cloneUnchangedsw -- 56  OO          *G4r5c.gdgdgdgdgdgdgdgdgd gd gd gd gd g }|D]g\}}}tj|j|j}|j ||dj |t |||iy)zd L{URL.click} collapses C{.} and C{..} according to RFC 3986 section 5.2.4. )rrr)rrr)http://localhost/a/b/crzhttp://localhost/a/b/)rrzhttp://localhost/a/)rz./d/ezhttp://localhost/a/b/d/e)r../d/ehttp://localhost/a/d/e)rz/./d/ehttp://localhost/d/e)rz/../d/er)zhttp://localhost/a/b/c/z ../../d/e/zhttp://localhost/a/d/e/)zhttp://localhost/a/./crr)zhttp://localhost/a/./c/rr)zhttp://localhost/a/b/c/dz ./e/../f/../gzhttp://localhost/a/b/c/g)rzd//ezhttp://localhost/a/b/d//ez1{start}.click({click}) => {actual} not {expected})startrr:r;N)r r\rr^r*formatr')r.testsrrr;r:s r3test_clickCollapsezTestURL.test_clickCollapses < < D C K J H I  I K  L+ .',  "E5(]]5)//6>>@F   CJJu+!% K  r5cj|jdtjdjddj |jdtdjddj tjt }|jd|jd j |jd |jd d j |jd |jd d jd j |jd|jd jd d j |jd|jd d jddj y)z3 L{URL.add} adds query parameters. z'http://www.foo.com/a/nice/path/?foo=barzhttp://www.foo.com/a/nice/path/rSrTzhttp://www.foo.com/?foo=barrrz/http://www.foo.com/a/nice/path/?zot=23&zut&burpburpz3http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxxxxxz8http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zingzingz8http://www.foo.com/a/nice/path/?zot=23&zut&zing&burp=xxxz:http://www.foo.com/a/nice/path/?zot=23&zut&burp=xxx&zot=32zot32N)r*r r\addr^r]r_s r3 test_queryAddzTestURL.test_queryAdd-sg  5 MM; < S  WY   ) ] # ' 'u 5 = = ? -- *  = KK  ' ' )   A KK & . . 0   F KK & * *6 2 : : <  F KK  # #FE 2 : : <  H KK & * *5$ 7 ? ? A r5ctjt}|jd|j ddj |jd|j dj ddj |jd|j ddj ddj y) z? L{URL.set} replaces query parameters by name. z*http://www.foo.com/a/nice/path/?zot=32&zutrrz0http://www.foo.com/a/nice/path/?zot&zut=itworkedzutitworkedrN)r r\r]r*setr^rr_s r3 test_querySetzTestURL.test_querySetTs -- *  8 KKt $ , , .  > KK  " "5* 5 = = ?  8 KKu % ) )% 6 > > @ r5ctjd}|j|jdtjd|j|jddtjd|j|jddtjd|j|jddd tjdy ) zG L{URL.remove} removes instances of a query parameter. z*https://example.com/a/b/?foo=1&bar=2&foo=3rSzhttps://example.com/a/b/?bar=21)namevaluez$https://example.com/a/b/?bar=2&foo=3r )rlimitr)rrrN)r r\r*remover~s r3test_queryRemovezTestURL.test_queryRemovejs mmHI  JJu s}}-MN   JJEJ - MM@ A  JJEJ + MM@ A  JJEAJ 6 MMF G r5cBtjd}|j|jddg|j|j dtjd}|j|j d|j|j dtjd}|j }|j|jddg|j|jjddgy ) z Every C{=}-sign after the first in a query parameter is simply included in the value of the parameter. zhttp://localhost/?=x=x=xrx=x=xz!http://localhost/?foo=x=x=x&bar=y))rSr)rTyz7https://example.com/?argument=3&argument=4&operator=%3Doperator=N)r r\r*getr^r,rjto_uri)r.r/rls r3test_parseEqualSignInParamValuez'TestURL.test_parseEqualSignInParamValues MM4 5 rWI. &@A MM= > "BC &IJ MM E hhj ,se4 ))*5u=r5cT|jtjdy)zG An empty L{URL} should serialize as the empty string. rN)r*r r^rYs r3 test_emptyzTestURL.test_emptys "-r5c^tdg}|j|jdy)zP An L{URL} with query text should serialize as just query text. helloworldr,z ?hello=worldN)r r*r^rMs r3test_justQueryTextzTestURL.test_justQueryTexts( )* + n5r5cRtjd}|j||y)z2 L{URL} compares equal to itself. rNr r\r*rMs r3test_identicalEqualzTestURL.test_identicalEquals# MM- . Ar5c|tjd}tjd}|j||y)zG URLs with equivalent components should compare equal. %http://u@localhost:8080/p/a/t/h?q=p#fNrr.u1rs r3test_similarEqualzTestURL.test_similarEquals2 ]]B C ]]B C R r5ctjd}tjd}|j||k(|d||j||y)z| L{URL}s that refer to different resources are both unequal (C{!=}) and also not equal (not C{==}). http://localhost/ahttp://localhost/b != N)r r\ assertFalserrrs r3test_differentNotEqualzTestURL.test_differentNotEqualsK ]]/ 0 ]]/ 0 rR#89 B#r5ctjd}|j|dk(d|j|tk(d|j |d|j |ty)z= L{URL} is not equal (C{==}) to other types. r*zURL must not equal a number.zURL must not equal an object.N)r r\robjectrrrMs r3test_otherTypesNotEqualzTestURL.test_otherTypesNotEqualsa MM- . b"@A fh(GH Ar" Avx(r5c^tjd}|j||k7d|zy)zJ Identical L{URL}s are not unequal (C{!=}) to each other. rz %r == itselfNr r\rrMs r3test_identicalNotUnequalz TestURL.test_identicalNotUnequals, MMA B a!!34r5ctjd}tjd}|j||k7|d|y)zU Structurally similar L{URL}s are not unequal (C{!=}) to each other. r == Nrrs r3test_similarNotUnequalzTestURL.test_similarNotUnequals; ]]B C ]]B C rR#89r5ctjd}tjd}|j||k7|d|y)zS Structurally different L{URL}s are unequal (C{!=}) to each other. rrrN)r r\r#rs r3test_differentUnequalzTestURL.test_differentUnequals9 ]]/ 0 ]]/ 0 bB"78r5ctjd}|j|dk7d|j|tk7dy)z; L{URL} is unequal (C{!=}) to other types. rrzURL must differ from a number.z"URL must be differ from an object.N)r r\r#rrMs r3test_otherTypesUnequalzTestURL.test_otherTypesUnequals; MM- . R!AB VX 'KLr5c\d}tj|}|j}|j|jd|j|j dd|j|j |d}|j }|j|||d|y)z L{URL.asURI} produces an URI which converts any URI unicode encoding into pure US-ASCII and returns a new L{URL}. http://é.com/é?á=í#úué.comrué.http://xn--9ca.com/%C3%A9?%C3%A1=%C3%AD#%C3%BArN)r r\asURIr*r(r)r^)r.unicodeyrluri expectedURI actualURIs r3 test_asURIzTestURL.test_asURIs B mmH%iik #LM  HHQKM  1F KKM   {)[$I r5c\d}tj|}|j}|j|jd|j|j dd|j|j |d}|j }|j|||d|y)z L{URL.asIRI} decodes any percent-encoded text in the URI, making it more suitable for reading by humans, and returns a new L{URL}. rz xn--9ca.comrz%C3%A9uhttp://é.com/é?á=í#úrN)r r\asIRIr*r(r)r^)r.asciiishrrl expectedIRI actualIRIs r3 test_asIRIzTestURL.test_asIRI s DmmH%iik =1 !h/ 1 3 KKM   {)[$I r5cd}tj|}|j}d}|j}|j |||d|y)z Bad UTF-8 in a path segment, query parameter, or fragment results in that portion of the URI remaining percent-encoded in the IRI. z http://xn--9ca.com/%00%FF/%C3%A9uhttp://é.com/%00%FF/érN)r r\rr^r*)r. urlWithBinaryrrlrrs r3test_badUTF8AsIRIzTestURL.test_badUTF8AsIRI#sS ; mmM*iik 2  KKM   {)[$I r5cd}tj|}|j}|j|j |y)zT A L{URL} composed of non-ASCII text will result in non-ASCII text. rN)r r\rr*r^)r.rrlalsoIRIs r3test_alreadyIRIAsIRIzTestURL.test_alreadyIRIAsIRI6s?  B mmH%))+ *H5r5cd}tj|}|jj}|j ||y)zH A L{URL} composed of encoded text will remain encoded. rN)r r\rr^r*)r.rrrs r3test_alreadyURIAsURIzTestURL.test_alreadyURIAsURIFs< G mmK(IIK'')  K0r5ctjd}|j|jdd|j|jdd|j|jd|j|j d|j|j d|j|jd j d y ) z{ L{URL.from_text} will parse the C{userinfo} portion of the URI separately from the host and port. z? :.  KKMM   KKK , 4 4 6 = r5ctjd}|j|jd|j|j dy)zJ L{URL.from_text} parses custom port numbers as integers. zhttp://www.example.com:8080/iN)r r\r*r7r^)r.portURLs r3 test_portTextzTestURL.test_portTextgs? -- >? t, *,JKr5cj|jtjdjdy)a Although L{URL} instances are mainly for dealing with HTTP, other schemes (such as C{mailto:}) should work as well. For example, L{URL.from_text}/L{URL.to_text} round-trips cleanly for a C{mailto:} URL representing an email address. zmailto:user@example.comN)r*r r\r^rYs r3 test_mailtozTestURL.test_mailtops+  MM3 4 < < > % r5ctjd}|j|jd|j|jd|j|j d|j|j dy)zj An HTTP URL without a hostname, but with a path, should also round-trip cleanly. zhttp:relative-pathr)z relative-pathFN)r r\r*r(r) uses_netlocr^)r. without_hosts r3test_httpWithoutHostzTestURL.test_httpWithoutHost}sp }}%9:  **B/ **,>? 1159 --/1EFr5cd}tdg}|j|j|tddi}|j|j|y)z When a L{URL} is created with a C{query} argument, the C{query} argument is converted into an N-tuple of 2-tuples, sensibly handling dictionaries. )alphabetarrrrN)r r*r,)r.r;rks r3test_queryIterablezTestURL.test_queryIterablesN(*+, H-&)* H-r5cXtddg}|j|jdy)zr When a L{URL} is created with a C{path} argument, the C{path} is converted into a tuple. rrr)rN)r r*r)r~s r3test_pathIterablezTestURL.test_pathIterables( )* #56r5c  Gddttturdnd}fd|ffd }|d|d|d |d d |d |d djt5}t t tgddd|djt5}t dt tfgddd||dzdjt5}t t tdfgddd||djt5t t tttfgdddjt5t t tttfdgdddjt5t t tttfdgdddt jd}jt5}|jt tddd||djt5}|jt tddd||djt5}|jt tddd||dy#1swY|xYw#1swY?xYw#1swYxYw#1swYxYw#1swY~xYw#1swYExYw#1swYxYw#1swYxYw#1swYzxYw)a 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. ceZdZdZdZy)1TestURL.test_invalidArguments..Unexpectedcy)NwrongrYs r3__str__z9TestURL.test_invalidArguments..Unexpected.__str__sr5cy)N rrYs r3__repr__z:TestURL.test_invalidArguments..Unexpected.__repr__s%r5N)__name__ __module__ __qualname__rr!rr5r3 Unexpectedrs   &r5r%r&strcrjt|jdj||dy)Nzexpected {0} for {1}, got {2}r )r*r& exceptionr)raised expectationrr.s r3 assertRaisedz3TestURL.test_invalidArguments..assertRaiseds4   F$$%/66~ r5cjt5}tdi|iddd||y#1swYxYw)Nr)r TypeErrorr )paramr*r)r%r+r.s r3rAz,TestURL.test_invalidArguments..checksH""9- -,ujl+, - e 4 - -s =Ar%r(r-rboolr8r7zint or NoneTyperNz path segmentrrz or NoneTypezquery parameter valuerzquery parameter name)rHr2vv)rHzhttps://valid.example.com/z relative URL)rbytesr&rr-r r rr ValueErrorr\rxrr)r.defaultExpectationrAr)rkr%r+s` @@r3test_invalidArgumentszTestURL.test_invalidArgumentss & &+03,YE &8 5 h f  j h j f'(   y ) 1V d4./ 0 1 V/@   y )  ?  z * C tE$*-/?@A B C  z * 9 tE$*-v67 8 9mm89   y ) 0V IId4. / 0V/@   y ) 2V KKT:<0 1 2V/@   y ) 0V IId4. / 0V/@K 1 1  < < = = ? ? C C 9 9 0 0 2 2 0 0sl8!L#L  #L-.L:")M()M%M!%M-%M9L L*-L7:MMM!M*-M69Nc|jt5}tdddd|jt j dj tdy#1swYGxYw)z Technically, L{str} (or L{unicode}, as appropriate) is iterable, but C{URL(path="foo")} resulting in C{URL.from_text("f/o/o")} is never what you want. rSrNz,expected iterable of text for path, not: {0})rr-r r*r&r(rr')r.r)s r3!test_technicallyTextIsIterableButz)TestURL.test_technicallyTextIsIterableButs^  y ) V UO     ! : A A$u+ N   s A))A2ctd}|j|jd|j|jd|jtjdjd|jtjdjd|jtjdjdtdd}|j|jd|j|jdtd }|j|jd|j|jd td }|j|jd|j|jd td }|j|jd|j|jdtjd}|j|jdtjd}|j|jdy)Nhttpsr%Tzhttps://zhttps:Fzhttps:/)r%r z git+httpsz git+https://mailtozmailto:ztpzztp:zztp://test.comz ztp:test:com)r r*r r^r\r~s r3 test_netloczTestURL.test_netlocs! $/  3 x0<>Ee4 %0 1% $/ 7" %0  2 $/ /mm,- $/mmN+ %0r5cd}tj|}|jdk(sJ|jdk(sJt|j |jk7sJy)Nz5https://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:80/z'2001:0db8:85a3:0000:0000:8a2e:0370:7334r@)r r\r(r7rr%)r.trks r3test_ipv6_with_portzTestURL.test_ipv6_with_port$sS CmmAxxDDDDxx2~~szz*chh666r5cHd}tj|}|jdk(sJ|jdk(sJ|jdk(sJ|j dk(sJ|j dk(sJd}tj|}|jdk(sJ|jdk(sJ|jdk(sJ|j dk(sJd }tj|}|jdk(sJ|jdk(sJ|jd k(sJ|j dk(sJy) Nz3https://user:pass@example.com/path/to/here?k=v#nicer8 user:pass example.com)r)toherenicez1https://user:pass@127.0.0.1/path/to/here?k=v#nicez 127.0.0.1z-https://user:pass@[::1]/path/to/here?k=v#nicez::1)r r\r%r8r(r)r-r.textrks r3 test_basiczTestURL.test_basic,s(DmmD!zzW$$$||{***xx=(((xx1111||v%%%BmmD!zzW$$$||{***xx;&&&xx1111>mmD!zzW$$$||{***xx5   xx1111r5cN|jttjdy)Nz# rrr r\rYs r3test_invalid_urlzTestURL.test_invalid_urlDs -@r5cN|jttjdy)Nzhttp://abc: /#rJrYs r3test_invalid_authority_urlz"TestURL.test_invalid_authority_urlHs -8KLr5cgd}|D]c}d|zdz}|jtjttj||jt t j|ey)N)z2001::0234:C1ab::A0:aabc:003Fz 2001::1::3F:z::::z ::256.0.0.1zhttp://[])rsocketerrorrAF_INET6rr r\)r.invalid_ipv6_ipsiprs r3test_invalid_ipv6zTestURL.test_invalid_ipv6Ls] # FB!B,H   fllIv K   mS]]H E Fr5c|jttjd|jttjdy)Nzftp://portmouth:smashz+http://reader.googlewebsite.com:neverforget)rrr r\r2rYs r3test_invalid_portzTestURL.test_invalid_portZs4 -8OP   MM 9 r5ctjd}|j|jd|j|j d|j|j j dtjd}|j|jd|j|j d|j|j j dy)Nuhttp://bücher.chu bücher.chzhttp://xn--bcher-kva.chrzxn--bcher-kva.chuhttps://bücher.ch)r r\r*r(r^rrjrs r3 test_idnazTestURL.test_idnacs ]]. / ,/ ':; ,,.0IJ ]]5 6 "45 'AB ,,.0DEr5ctjd}|j|jd|j|j dtjd}|j|jd|j|j dtjd}|j|jd|j|j dtjd}|j|jd|j|j dtjd }|j|jd |j|j d tjd }|j|jd |j|j d td dd}|j|j dtd ddd}|j|j dtjd}|j d}|j|j dd}tj|}|j d}|j|j d|j d}|j|j |y)Nzmailto:mahmoud@hatnote.comr:zhttp://hatnote.comr?znewscheme:a:b:c newschemeznewerscheme://a/b/c newerschemez%git+ftp://gitstub.biz/glyph/lefkowitzzgit+ftpz'what+mailto:freerealestate@enotuniq.orgz what+mailtor;)xrzT)r%r)rz ztp:/x/y/z)r^rr_r)r%r)rr zgit+ftp:///x/y/z/zfile:///path/to/heckr9zmailto:/path/to/heckzunregisteredscheme:///a/b/cF)r zunregisteredscheme:/a/b/c)r r\r*r%r^r)r.rkurl2r no_netloc_url netloc_urls r3test_netloc_slasheszTestURL.test_netloc_slashesos_mm89 X. (DEmm01 V, (<=mm-. [1 (9:mm12 ]3 (=>mmCD Y/ (OPmmEF ]3  KKMD _TB  5$   (;<mm23{{({+ )?@0mmH%  6  ..02MN[[T[2  ++-x8r5ctdg}|j|jd|jd}|j|jd|j ||y)z On host-relative URLs, the C{rooted} flag can be updated to indicate that the path should no longer be treated as absolute. rrT)rz/helloN)r r*r^rrr)r.abs r3test_rooted_to_relativezTestURL.test_rooted_to_relatives\ gY  g. IITI " h/ Aq!r5ctddgd}|j|jdtdgd}|j|jd|j||tddgd}tddg}|j|||j|jd|j|jdy ) a  The C{rooted} flag can be updated in some cases, but it cannot be made to conflict with other facts surrounding the URL; for example, all URLs involving an authority (host) are inherently rooted because it is not syntactically possible to express otherwise; also, once an unrooted URL gains a path that starts with an empty string, that empty string is elided and it becomes rooted, because these cases are syntactically indistinguisable in real URL text. rrSF)r)rTrT)r(r)r)r(r)N)r r*r)r.relative_path_rootedrelative_flag_rootedattempt_unrooted_absolutenormal_absolutes r3test_autorootedzTestURL.test_autorooteds #U EB -44d;"= -44d; -/CD$'U%$O!5w7 2OD //6 2994@r5ctddd}tdd}tddd}|j|jd|j|jd|j|jdtjd}|jt |t ||jt |t ||j|j |j |j|||j|||j|||j|||j||y) a URLs which include a ``://`` netloc-separator for any reason are inherently rooted, regardless of the value or presence of the ``rooted`` constructor argument. They may include a netloc-separator because their constructor was directly invoked with an explicit host or port, or because they were parsed from a string which included the literal ``://`` separator. udpi$F)r%r7r)r%r7Tz udp://:4900N)r r*rr\r&asText)r.directly_constructeddirectly_constructed_implictdirectly_constructed_rootedparseds r3!test_rooted_with_port_but_no_hostz)TestURL.test_rooted_with_port_but_no_hosts- #%d5I'*%d'C$&)T$&O# -44d; 5< 4f=r5c|jt5ttddd|jt5tddddy#1swY3xYw#1swYyxYw)NHTTP_____more_like_imHoTTeP)rr2r r]rYs r3test_wrong_constructorzTestURL.test_wrong_constructors_   z *   N   z * / - . / /   / /sA A$A!$A-c:tjd}|jdk(sJ|jd}|j }|j ddk(sJ|j dd k(sJ|j j dd k(sJy) Nzhttp://user:pass@example.comrAz us%20her:passrTrczhttp://us her:pass@example.comFzhttp://us her:@example.comz http://us%20her:pass@example.com)r r\r8rrjr^rr.rkrls r3test_encoded_userinfozTestURL.test_encoded_userinfosmm:;||{***kk?k3jjl KKdK +/O O O{{{/3OOOO JJL t 41 2  2r5cvi}tjd}t|t|k(sJd||<tjd}|jdd}d||<t |dk(sJt |j dgk(sJttttk(sJy)Nz.http://blog.hatnote.com/ask?utm_source=geocityr zhttp://blog.hatnote.com/ask utm_sourcegeocityr )r r\hashrlenlistvalues)r.url_mapurl1r`s r3 test_hashzTestURL.test_hashs}}MNDzT$Z''' }}:;xx i0 7|q   GNN$%!,,,CE{d35k)))r5c~t}t|}t|dkDsJd|vsJd|vsJd|vsJd|vsJy)Nrrprr)r dirr)r.rkrs r3test_dirzTestURL.test_dirsZe#h3x"}}$$$s"""c!!!c!!!r5ctjd}|jdk(sJ|jjdk(sJy)Nu"http://example.com/a%20té%C3%A9stz&http://example.com/a%20t%C3%A9%C3%A9st)r rrprr~s r3test_twisted_compatzTestURL.test_twisted_compatsDll?@zz|CCCCyy{!!#'OOOOr5ctjd}|jdd}|jdd}|j dk(sJy)Nzhttp://example.com/?a=b&cr^rz!http://example.com/?a=b&x=x&c&x=y)r r\rrr^r~s r3test_set_orderingzTestURL.test_set_ordering%sHmm78ggc3ggc3{{} CCCCr5ctjd}tj|j}||k(sJtj|jj}||k(sJ||k(sJtjd}|j}|jdk(sJtj|jj }||k(sJy)z See issue #4z#urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoobz1first-segment/urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoobz'first-segment/urn:ietf:wg:oauth:2.0:oobN)r r\r^rjr)r.rrru4u5u6s r3test_schemeless_pathzTestURL.test_schemeless_path0s]]@ A ]]2::< (Rxx ]]299;..0 1RxxRxx]]N O YY[zz|HHHH ]]2::< ( / / 1Rxxr5cntjd}|j}|jy)z4See issue #7, affecting only narrow builds (2.6-3.3)zhttps://xn--vi8hiv.wsN)r r\rjr^rzs r3test_emoji_domainzTestURL.test_emoji_domainCs'mm34jjl r5c|jttdd|jttd|jttd|jttdy ) zPer issue #6 and #8r?za/c)r%r()?r)#)&rfrN)rr2r rYs r3test_delim_in_paramzTestURL.test_delim_in_paramKsZ *c&uE *c7 *c7 *c-Ar5ctjd}tjd}||k(sJtjd}tjd}||k(sJtjd}tjd}||k(sJtjd}tjd}||k(sJy)Nzhttp://example.com/zhttp://example.com)r r\rs r3test_empty_paths_eqzTestURL.test_empty_paths_eqSs ]]0 1 ]]/ 0Rxx ]]/ 0 ]]/ 0Rxx ]]/ 0 ]]0 1Rxx ]]0 1 ]]0 1Rxxr5ctjdjdk(sJ|jttjd|jttjt y)Nz#okoks bytes://x.y.z)r r\r-rr-rrYs r3test_from_text_typezTestURL.test_from_text_typeisN}}U#,,444 )S]]4DE )S]]FH=r5c |jttjd|jttjd|jttjd|jttjd|jttjd|jttjd|jttjdy)Nz http://[::1/z http://::1]/zhttp://[[::1]/zhttp://[::1]]/zhttp://127.0.0.1:zhttp://127.0.0.1:hizhttp://127.0.0.1::80rJrYs r3test_from_text_bad_authorityz$TestURL.test_from_text_bad_authorityos -G -G -8HI -8HI -8KL -8MN -8NOr5c4tjd}|jdgk(sJ|jddgk(sJt|jdk(sJ|j }|j dk(sJ|jdk(sJ|jdk(sJ|jdd gk(sJ|jd k(sJ|jd k(sJ|j d d d d d }||k(sJtjd}|j }|jdk(sJtjd}|j }|jdk(sJtdj d jdk(sJtdj jdk(sJtdddgdgdd}|jdd k(sJ|j jdd!k(sJy)"Nz0HTTP://Example.com/A%61/./../A%61?B%62=C%63#D%64BbzB%62zC%63r?rB)AaCcDdzhttp://example.com/Aa?Bb=Cc#DdFrWzhttp://example.iozhttp://example.io/z/a%2fb/cd%3f?k%3d=v%23#testz/a%2Fb/cd%3F?k%3D=v%23#test)rz%te%stsr)percentsz/%te%stsz /%25te%25stsftpz%%%z%a%b)%z%%rz%:%)r%r)r,r-r8Trczftp://%:%@/%%%/%a%b?%=%%#%z0ftp://%25:%25@/%25%25%25/%25a%25b?%25=%25%25#%25) r r\rrr) normalizer%r(r-r^) r.rknorm_url noop_norm_url slashless_url slashful_url delimited_urlnorm_delimited_url percenty_urls r3test_normalizezTestURL.test_normalizesJmmNOwwt}"""wwv6(***388}!!!==?&(((}} ---}}'''||D!dV+++  D(((!%EEEE u5& ### &9: $..0 ##%)==== &CD *446!))+/LLLL _ % / / / ? G G I   (224<<>.PPP-    t 4+ ,  ,  " " $ , ,4 , @A B  Br5cXd}tj|}t||k(sJt|dk(sJtr7t t |tsJt t|tsJyt t |tsJt t|tsJy)Nu&http://example.com/á/y%20a%20y/?b=%25s*http://example.com/%C3%A1/y%20a%20y/?b=%25)r r\r&r1PY2r$r&rFs r3test_strzTestURL.test_strs8mmD!s|t###SzJJJJ c#h. ..gclG4 44c#h0 00eCj%0 00r5c.tjd}|jjdk(sJ|j jdk(sJtjd}|jjdk(sJ|j jdk(sJ|j j jdk(sJd}tj|j j jdk(sJy) Nuhttp://abé.com/uabé.comzxn--ab-cja.comu(http://ドメイン.テスト.co.jp#testuドメイン.テスト.co.jpzxn--eckwd4c7c.xn--zckzah.co.jpzhttp://Example.comrB)r r\rjr(rget_decoded_url)r.rkrGs r3test_idna_cornerszTestURL.test_idna_cornerssmm./zz|  J...zz|  $4444mmFGzz|  $BBBBzz|  $DDDDzz|++-226TTTT# MM$  & & ( 8 8 : ? ?= P Pr5N)r)Or"r#r$__doc__r4r<rBrNrQrZrarhrprsruryrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr r rrrr4r6r<r?rHrKrMrVrXrZrcrgrmrurxr{rrrrrrrrrrrrrrr5r3r!r!s=61+f + &   (7+    0  E+ &<C|BE5((T% N , 2>*.6! $ )5:9M 4 0 &6 1 .L   G .7SAj   1D720AM F  F9v "A.>6/  *$ "PD&B,> P 7 r1  r5r!) __future__rsysrQtypingrrrrrr commonr rr r_urlrr version_inforr+r&r]rrrer!rr5r3rso ( ==%!- qQ r( 9 21hAHF F r5