test_url_parsing.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. import sys
  2. import pytest
  3. from yarl import URL
  4. class TestScheme:
  5. def test_scheme_path(self):
  6. u = URL("scheme:path")
  7. assert u.scheme == "scheme"
  8. assert u.host is None
  9. assert u.path == "path"
  10. assert u.query_string == ""
  11. assert u.fragment == ""
  12. def test_scheme_path_other(self):
  13. u = URL("scheme:path:other")
  14. assert u.scheme == "scheme"
  15. assert u.host is None
  16. assert u.path == "path:other"
  17. assert u.query_string == ""
  18. assert u.fragment == ""
  19. def test_complex_scheme(self):
  20. u = URL("allow+chars-33.:path")
  21. assert u.scheme == "allow+chars-33."
  22. assert u.host is None
  23. assert u.path == "path"
  24. assert u.query_string == ""
  25. assert u.fragment == ""
  26. def test_scheme_only(self):
  27. u = URL("simple:")
  28. assert u.scheme == "simple"
  29. assert u.host is None
  30. assert u.path == ""
  31. assert u.query_string == ""
  32. assert u.fragment == ""
  33. def test_no_scheme1(self):
  34. u = URL("google.com:80")
  35. # See: https://bugs.python.org/issue27657
  36. if (
  37. sys.version_info[:3] == (3, 7, 6)
  38. or sys.version_info[:3] == (3, 8, 1)
  39. or sys.version_info >= (3, 9, 0)
  40. ):
  41. assert u.scheme == "google.com"
  42. assert u.host is None
  43. assert u.path == "80"
  44. else:
  45. assert u.scheme == ""
  46. assert u.host is None
  47. assert u.path == "google.com:80"
  48. assert u.query_string == ""
  49. assert u.fragment == ""
  50. def test_no_scheme2(self):
  51. u = URL("google.com:80/root")
  52. assert u.scheme == "google.com"
  53. assert u.host is None
  54. assert u.path == "80/root"
  55. assert u.query_string == ""
  56. assert u.fragment == ""
  57. def test_not_a_scheme1(self):
  58. u = URL("not_cheme:path")
  59. assert u.scheme == ""
  60. assert u.host is None
  61. assert u.path == "not_cheme:path"
  62. assert u.query_string == ""
  63. assert u.fragment == ""
  64. def test_not_a_scheme2(self):
  65. u = URL("signals37:book")
  66. assert u.scheme == "signals37"
  67. assert u.host is None
  68. assert u.path == "book"
  69. assert u.query_string == ""
  70. assert u.fragment == ""
  71. def test_scheme_rel_path1(self):
  72. u = URL(":relative-path")
  73. assert u.scheme == ""
  74. assert u.host is None
  75. assert u.path == ":relative-path"
  76. assert u.query_string == ""
  77. assert u.fragment == ""
  78. def test_scheme_rel_path2(self):
  79. u = URL(":relative/path")
  80. assert u.scheme == ""
  81. assert u.host is None
  82. assert u.path == ":relative/path"
  83. assert u.query_string == ""
  84. assert u.fragment == ""
  85. def test_scheme_weird(self):
  86. u = URL("://and-this")
  87. assert u.scheme == ""
  88. assert u.host is None
  89. assert u.path == "://and-this"
  90. assert u.query_string == ""
  91. assert u.fragment == ""
  92. class TestHost:
  93. def test_canonical(self):
  94. u = URL("scheme://host/path")
  95. assert u.scheme == "scheme"
  96. assert u.host == "host"
  97. assert u.path == "/path"
  98. assert u.query_string == ""
  99. assert u.fragment == ""
  100. def test_absolute_no_scheme(self):
  101. u = URL("//host/path")
  102. assert u.scheme == ""
  103. assert u.host == "host"
  104. assert u.path == "/path"
  105. assert u.query_string == ""
  106. assert u.fragment == ""
  107. def test_absolute_no_scheme_complex_host(self):
  108. u = URL("//host+path")
  109. assert u.scheme == ""
  110. assert u.host == "host+path"
  111. assert u.path == "/"
  112. assert u.query_string == ""
  113. assert u.fragment == ""
  114. def test_absolute_no_scheme_simple_host(self):
  115. u = URL("//host")
  116. assert u.scheme == ""
  117. assert u.host == "host"
  118. assert u.path == "/"
  119. assert u.query_string == ""
  120. assert u.fragment == ""
  121. def test_weird_host(self):
  122. u = URL("//this+is$also&host!")
  123. assert u.scheme == ""
  124. assert u.host == "this+is$also&host!"
  125. assert u.path == "/"
  126. assert u.query_string == ""
  127. assert u.fragment == ""
  128. def test_scheme_no_host(self):
  129. u = URL("scheme:/host/path")
  130. assert u.scheme == "scheme"
  131. assert u.host is None
  132. assert u.path == "/host/path"
  133. assert u.query_string == ""
  134. assert u.fragment == ""
  135. def test_scheme_no_host2(self):
  136. u = URL("scheme:///host/path")
  137. assert u.scheme == "scheme"
  138. assert u.host is None
  139. assert u.path == "/host/path"
  140. assert u.query_string == ""
  141. assert u.fragment == ""
  142. def test_no_scheme_no_host(self):
  143. u = URL("scheme//host/path")
  144. assert u.scheme == ""
  145. assert u.host is None
  146. assert u.path == "scheme//host/path"
  147. assert u.query_string == ""
  148. assert u.fragment == ""
  149. def test_ipv4(self):
  150. u = URL("//127.0.0.1/")
  151. assert u.scheme == ""
  152. assert u.host == "127.0.0.1"
  153. assert u.path == "/"
  154. assert u.query_string == ""
  155. assert u.fragment == ""
  156. def test_ipv6(self):
  157. u = URL("//[::1]/")
  158. assert u.scheme == ""
  159. assert u.host == "::1"
  160. assert u.path == "/"
  161. assert u.query_string == ""
  162. assert u.fragment == ""
  163. def test_ipvfuture_address(self):
  164. u = URL("//[v1.-1]/")
  165. assert u.scheme == ""
  166. assert u.host == "v1.-1"
  167. assert u.path == "/"
  168. assert u.query_string == ""
  169. assert u.fragment == ""
  170. class TestPort:
  171. def test_canonical(self):
  172. u = URL("//host:80/path")
  173. assert u.scheme == ""
  174. assert u.host == "host"
  175. assert u.port == 80
  176. assert u.path == "/path"
  177. assert u.query_string == ""
  178. assert u.fragment == ""
  179. def test_no_path(self):
  180. u = URL("//host:80")
  181. assert u.scheme == ""
  182. assert u.host == "host"
  183. assert u.port == 80
  184. assert u.path == "/"
  185. assert u.query_string == ""
  186. assert u.fragment == ""
  187. @pytest.mark.xfail(
  188. # FIXME: remove "no cover" pragmas upon xfail marker deletion
  189. reason="https://github.com/aio-libs/yarl/issues/821",
  190. raises=ValueError,
  191. )
  192. def test_no_host(self):
  193. u = URL("//:80")
  194. assert u.scheme == "" # pragma: no cover
  195. assert u.host == "" # pragma: no cover
  196. assert u.port == 80 # pragma: no cover
  197. assert u.path == "/" # pragma: no cover
  198. assert u.query_string == "" # pragma: no cover
  199. assert u.fragment == "" # pragma: no cover
  200. def test_double_port(self):
  201. with pytest.raises(ValueError):
  202. URL("//h:22:80/")
  203. def test_bad_port(self):
  204. with pytest.raises(ValueError):
  205. URL("//h:no/path")
  206. def test_another_bad_port(self):
  207. with pytest.raises(ValueError):
  208. URL("//h:22:no/path")
  209. def test_bad_port_again(self):
  210. with pytest.raises(ValueError):
  211. URL("//h:-80/path")
  212. class TestUserInfo:
  213. def test_canonical(self):
  214. u = URL("sch://user@host/")
  215. assert u.scheme == "sch"
  216. assert u.user == "user"
  217. assert u.host == "host"
  218. assert u.path == "/"
  219. assert u.query_string == ""
  220. assert u.fragment == ""
  221. def test_user_pass(self):
  222. u = URL("//user:pass@host")
  223. assert u.scheme == ""
  224. assert u.user == "user"
  225. assert u.password == "pass"
  226. assert u.host == "host"
  227. assert u.path == "/"
  228. assert u.query_string == ""
  229. assert u.fragment == ""
  230. def test_complex_userinfo(self):
  231. u = URL("//user:pas:and:more@host")
  232. assert u.scheme == ""
  233. assert u.user == "user"
  234. assert u.password == "pas:and:more"
  235. assert u.host == "host"
  236. assert u.path == "/"
  237. assert u.query_string == ""
  238. assert u.fragment == ""
  239. def test_no_user(self):
  240. u = URL("//:pas:@host")
  241. assert u.scheme == ""
  242. assert u.user is None
  243. assert u.password == "pas:"
  244. assert u.host == "host"
  245. assert u.path == "/"
  246. assert u.query_string == ""
  247. assert u.fragment == ""
  248. def test_weird_user(self):
  249. u = URL("//!($&')*+,;=@host")
  250. assert u.scheme == ""
  251. assert u.user == "!($&')*+,;="
  252. assert u.password is None
  253. assert u.host == "host"
  254. assert u.path == "/"
  255. assert u.query_string == ""
  256. assert u.fragment == ""
  257. def test_weird_user2(self):
  258. u = URL("//user@info@ya.ru")
  259. assert u.scheme == ""
  260. assert u.user == "user@info"
  261. assert u.password is None
  262. assert u.host == "ya.ru"
  263. assert u.path == "/"
  264. assert u.query_string == ""
  265. assert u.fragment == ""
  266. def test_weird_user3(self):
  267. u = URL("//%5Bsome%5D@host")
  268. assert u.scheme == ""
  269. assert u.user == "[some]"
  270. assert u.password is None
  271. assert u.host == "host"
  272. assert u.path == "/"
  273. assert u.query_string == ""
  274. assert u.fragment == ""
  275. class TestQuery_String:
  276. def test_simple(self):
  277. u = URL("?query")
  278. assert u.scheme == ""
  279. assert u.user is None
  280. assert u.password is None
  281. assert u.host is None
  282. assert u.path == ""
  283. assert u.query_string == "query"
  284. assert u.fragment == ""
  285. def test_scheme_query(self):
  286. u = URL("http:?query")
  287. assert u.scheme == "http"
  288. assert u.user is None
  289. assert u.password is None
  290. assert u.host is None
  291. assert u.path == ""
  292. assert u.query_string == "query"
  293. assert u.fragment == ""
  294. def test_abs_url_query(self):
  295. u = URL("//host?query")
  296. assert u.scheme == ""
  297. assert u.user is None
  298. assert u.password is None
  299. assert u.host == "host"
  300. assert u.path == "/"
  301. assert u.query_string == "query"
  302. assert u.fragment == ""
  303. def test_abs_url_path_query(self):
  304. u = URL("//host/path?query")
  305. assert u.scheme == ""
  306. assert u.user is None
  307. assert u.password is None
  308. assert u.host == "host"
  309. assert u.path == "/path"
  310. assert u.query_string == "query"
  311. assert u.fragment == ""
  312. def test_double_question_mark(self):
  313. u = URL("//ho?st/path?query")
  314. assert u.scheme == ""
  315. assert u.user is None
  316. assert u.password is None
  317. assert u.host == "ho"
  318. assert u.path == "/"
  319. assert u.query_string == "st/path?query"
  320. assert u.fragment == ""
  321. def test_complex_query(self):
  322. u = URL("?a://b:c@d.e/f?g#h")
  323. assert u.scheme == ""
  324. assert u.user is None
  325. assert u.password is None
  326. assert u.host is None
  327. assert u.path == ""
  328. assert u.query_string == "a://b:c@d.e/f?g"
  329. assert u.fragment == "h"
  330. def test_query_in_fragment(self):
  331. u = URL("#?query")
  332. assert u.scheme == ""
  333. assert u.user is None
  334. assert u.password is None
  335. assert u.host is None
  336. assert u.path == ""
  337. assert u.query_string == ""
  338. assert u.fragment == "?query"
  339. class TestFragment:
  340. def test_simple(self):
  341. u = URL("#frag")
  342. assert u.scheme == ""
  343. assert u.user is None
  344. assert u.password is None
  345. assert u.host is None
  346. assert u.path == ""
  347. assert u.query_string == ""
  348. assert u.fragment == "frag"
  349. def test_scheme_frag(self):
  350. u = URL("http:#frag")
  351. assert u.scheme == "http"
  352. assert u.user is None
  353. assert u.password is None
  354. assert u.host is None
  355. assert u.path == ""
  356. assert u.query_string == ""
  357. assert u.fragment == "frag"
  358. def test_host_frag(self):
  359. u = URL("//host#frag")
  360. assert u.scheme == ""
  361. assert u.user is None
  362. assert u.password is None
  363. assert u.host == "host"
  364. assert u.path == "/"
  365. assert u.query_string == ""
  366. assert u.fragment == "frag"
  367. def test_scheme_path_frag(self):
  368. u = URL("//host/path#frag")
  369. assert u.scheme == ""
  370. assert u.user is None
  371. assert u.password is None
  372. assert u.host == "host"
  373. assert u.path == "/path"
  374. assert u.query_string == ""
  375. assert u.fragment == "frag"
  376. def test_scheme_query_frag(self):
  377. u = URL("//host?query#frag")
  378. assert u.scheme == ""
  379. assert u.user is None
  380. assert u.password is None
  381. assert u.host == "host"
  382. assert u.path == "/"
  383. assert u.query_string == "query"
  384. assert u.fragment == "frag"
  385. def test_host_frag_query(self):
  386. u = URL("//ho#st/path?query")
  387. assert u.scheme == ""
  388. assert u.user is None
  389. assert u.password is None
  390. assert u.host == "ho"
  391. assert u.path == "/"
  392. assert u.query_string == ""
  393. assert u.fragment == "st/path?query"
  394. def test_complex_frag(self):
  395. u = URL("#a://b:c@d.e/f?g#h")
  396. assert u.scheme == ""
  397. assert u.user is None
  398. assert u.password is None
  399. assert u.host is None
  400. assert u.path == ""
  401. assert u.query_string == ""
  402. assert u.fragment == "a://b:c@d.e/f?g#h"
  403. class TestStripEmptyParts:
  404. def test_all_empty(self):
  405. with pytest.raises(ValueError):
  406. URL("//@:?#")
  407. def test_path_only(self):
  408. u = URL("///path")
  409. assert u.scheme == ""
  410. assert u.user is None
  411. assert u.password is None
  412. assert u.host is None
  413. assert u.path == "/path"
  414. assert u.query_string == ""
  415. assert u.fragment == ""
  416. def test_empty_user(self):
  417. u = URL("//@host")
  418. assert u.scheme == ""
  419. assert u.user is None
  420. assert u.password is None
  421. assert u.host == "host"
  422. assert u.path == "/"
  423. assert u.query_string == ""
  424. assert u.fragment == ""
  425. def test_empty_port(self):
  426. u = URL("//host:")
  427. assert u.scheme == ""
  428. assert u.user is None
  429. assert u.password is None
  430. assert u.host == "host"
  431. assert u.path == "/"
  432. assert u.query_string == ""
  433. assert u.fragment == ""
  434. def test_empty_port_and_path(self):
  435. u = URL("//host:/")
  436. assert u.scheme == ""
  437. assert u.user is None
  438. assert u.password is None
  439. assert u.host == "host"
  440. assert u.path == "/"
  441. assert u.query_string == ""
  442. assert u.fragment == ""
  443. def test_empty_path_only(self):
  444. u = URL("/")
  445. assert u.scheme == ""
  446. assert u.user is None
  447. assert u.password is None
  448. assert u.host is None
  449. assert u.path == "/"
  450. assert u.query_string == ""
  451. assert u.fragment == ""
  452. def test_relative_path_only(self):
  453. u = URL("path")
  454. assert u.scheme == ""
  455. assert u.user is None
  456. assert u.password is None
  457. assert u.host is None
  458. assert u.path == "path"
  459. assert u.query_string == ""
  460. assert u.fragment == ""
  461. def test_path(self):
  462. u = URL("/path")
  463. assert u.scheme == ""
  464. assert u.user is None
  465. assert u.password is None
  466. assert u.host is None
  467. assert u.path == "/path"
  468. assert u.query_string == ""
  469. assert u.fragment == ""
  470. def test_empty_query_with_path(self):
  471. u = URL("/path?")
  472. assert u.scheme == ""
  473. assert u.user is None
  474. assert u.password is None
  475. assert u.host is None
  476. assert u.path == "/path"
  477. assert u.query_string == ""
  478. assert u.fragment == ""
  479. def test_empty_query(self):
  480. u = URL("?")
  481. assert u.scheme == ""
  482. assert u.user is None
  483. assert u.password is None
  484. assert u.host is None
  485. assert u.path == ""
  486. assert u.query_string == ""
  487. assert u.fragment == ""
  488. def test_empty_query_with_frag(self):
  489. u = URL("?#frag")
  490. assert u.scheme == ""
  491. assert u.user is None
  492. assert u.password is None
  493. assert u.host is None
  494. assert u.path == ""
  495. assert u.query_string == ""
  496. assert u.fragment == "frag"
  497. def test_path_empty_frag(self):
  498. u = URL("/path#")
  499. assert u.scheme == ""
  500. assert u.user is None
  501. assert u.password is None
  502. assert u.host is None
  503. assert u.path == "/path"
  504. assert u.query_string == ""
  505. assert u.fragment == ""
  506. def test_empty_path(self):
  507. u = URL("#")
  508. assert u.scheme == ""
  509. assert u.user is None
  510. assert u.password is None
  511. assert u.host is None
  512. assert u.path == ""
  513. assert u.query_string == ""
  514. assert u.fragment == ""