hyperlink-21.0.0/ 0000775 0001750 0001750 00000000000 13775771330 014724 5 ustar mahmoud mahmoud 0000000 0000000 hyperlink-21.0.0/.coveragerc 0000664 0001750 0001750 00000000050 13611444563 017032 0 ustar mahmoud mahmoud 0000000 0000000 [run]
branch = True
omit = */flycheck_*
hyperlink-21.0.0/CHANGELOG.md 0000664 0001750 0001750 00000012764 13712424472 016540 0 ustar mahmoud mahmoud 0000000 0000000 # Hyperlink Changelog
## 20.0.1
*(August 4, 2020)*
Rerelease to fix packaging metadata around conditional requirements.
See [issue #133](https://github.com/python-hyper/hyperlink/issues/133)
for more details.
## 20.0.0
*(August 3, 2020)*
* CPython 3.7 and 3.8 and PyPy3 added to test matrix
* Hyperlink now has type hints and they are now exported per
[PEP 561](https://www.python.org/dev/peps/pep-0561/).
* Several bugs related to hidden state were fixed, making it so that all data
on a `URL` object (including `rooted` and `uses_netloc`) is reflected by and
consistent with its textual representation.
This does mean that sometimes these constructor arguments are ignored, if it
would create invalid or unparseable URL text.
## 19.0.0
*(April 7, 2019)*
A query parameter-centric release, with two enhancements:
* "equals sign" characters in query parameter values are no longer
escaped. (see
[#39](https://github.com/python-hyper/hyperlink/pull/39))
* `URL.remove()` now accepts *value* and *limit* parameters, allowing
for removal of specific name-value pairs, as well as limiting the
number of removals.
(See [#71](https://github.com/python-hyper/hyperlink/pull/71))
## 18.0.0
*(February 25, 2018)*
Maybe the biggest release since the original. Big thanks to @glyph,
@wsanchez, @Julian, @wbolster, and of course, @markrwilliams, for all
the reports, reviews, and other contributions.
* When passed to `str()` URLs now stringify to usable URL
strings. (See #49)
* Switched off of Python's built-in IDNA facilities to using the
[idna](https://pypi.python.org/pypi/idna) package. Not only is it
much more modern, it's also much more strict and correct in its
output. (See #19 and #56)
* Added new `DecodedURL` type with almost-identical API to the normal
`URL`, except that it automatically handles reserved characters in
argument values passed to its methods. (See #6, #11, #44)
* Added top-level `parse()` convenience function that now represents
the main entrypoint to hyperlink.
* Accept dictionaries as ‘query=’ arguments, in addition to
sequences of tuples (see #50)
* `URL.child()` will no longer fail when child gets no segments (#42 and #43)
* `URL.normalize()` now supports encoding stray/unmatched `%` characters
in character-encoded fields (userinfo, path, query string, fragment)
(see #61, #62)
## 17.3.1
*(August 19, 2017)*
* Add `URL.normalize()` method, which applies five normalizations from
RFC 3986 (sections 2.3, 2.1, 3.2.2, 6.2.2.3, 6.2.3). See [the docs](http://hyperlink.readthedocs.io/en/latest/api.html#hyperlink.URL.normalize)
for more details.
* Enable `URL.click()` to accept a URL object as a target.
## 17.3.0
*(July 18, 2017)*
Fixed a couple major decoding issues and simplified the URL API.
* limit types accepted by `URL.from_text()` to just text (str on py3,
unicode on py2), see #20
* fix percent decoding issues surrounding multiple calls to
`URL.to_iri()` (see #16)
* remove the `socket`-inspired `family` argument from `URL`'s APIs. It
was never consistently implemented and leaked slightly more problems
than it solved.
* Improve authority parsing (see #26)
* include LICENSE, README, docs, and other resources in the package
## 17.2.1
*(June 18, 2017)*
A small bugfix release after yesterday's big changes. This patch
version simply reverts an exception message for parameters expecting
strings on Python 3, returning to compliance with Twisted's test
suite.
## 17.2.0
*(June 17, 2017)*
Fixed a great round of issues based on the amazing community review
(@wsanchez and @jvanasco) after our first listserv announcement and
[PyConWeb talk](https://www.youtube.com/watch?v=EIkmADO-r10).
* Add checking for invalid unescaped delimiters in parameters to the
`URL` constructor. No more slashes and question marks allowed in
path segments themselves.
* More robust support for IDNA decoding on "narrow"/UCS-2 Python
builds (e.g., Mac's built-in Python).
* Correctly encode colons in the first segment of relative paths for
URLs with no scheme set.
* Make URLs with empty paths compare as equal (`http://example.com`
vs. `http://example.com/`) per RFC 3986. If you need the stricter
check, you can check the attributes directly or compare the strings.
* Automatically escape the arguments to `.child()` and `.sibling()`
* Fix some IPv6 and port parsing corner cases.
## 17.1.1
* Python 2.6 support
* Added LICENSE
* Automated CI and code coverage
* When a host and a query string are present, empty paths are now
rendered as a single slash. This is slightly more in line with RFC
3986 section 6.2.3, but might need to go further and use an empty
slash whenever the authority is present. This also better replicates
Twisted URL's old behavior.
## 17.1.0
* Correct encoding for username/password part of URL (userinfo)
* Dot segments are resolved on empty URL.click
* Many, many more schemes and default ports
* Faster percent-encoding with segment-specific functions
* Better detection and inference of scheme netloc usage (the presence
of `//` in URLs)
* IPv6 support with IP literal validation
* Faster, regex-based parsing
* URLParseError type for errors while parsing URLs
* URL is now hashable, so feel free to use URLs as keys in dicts
* Improved error on invalid scheme, directing users to URL.from_text
in the event that they used the wrong constructor
* PEP8-compatible API, with full, transparent backwards compatibility
for Twisted APIs, guaranteed.
* Extensive docstring expansion.
## Pre-17.0.0
* Lots of good features! Used to be called twisted.python.url
hyperlink-21.0.0/LICENSE 0000664 0001750 0001750 00000002317 13712176305 015724 0 ustar mahmoud mahmoud 0000000 0000000 Copyright (c) 2017
Glyph Lefkowitz
Itamar Turner-Trauring
Jean Paul Calderone
Adi Roiban
Amber Hawkie Brown
Mahmoud Hashemi
Wilfredo Sanchez Vega
and others that have contributed code to the public domain.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
hyperlink-21.0.0/MANIFEST.in 0000664 0001750 0001750 00000000307 13712176305 016452 0 ustar mahmoud mahmoud 0000000 0000000 include README.md LICENSE CHANGELOG.md
include tox.ini pytest.ini .coveragerc
exclude TODO.md
exclude .appveyor.yml
include src/hyperlink/idna-tables-properties.csv.gz
graft docs
prune docs/_build
hyperlink-21.0.0/PKG-INFO 0000664 0001750 0001750 00000002712 13775771330 016023 0 ustar mahmoud mahmoud 0000000 0000000 Metadata-Version: 1.2
Name: hyperlink
Version: 21.0.0
Summary: A featureful, immutable, and correct URL for Python.
Home-page: https://github.com/python-hyper/hyperlink
Author: Mahmoud Hashemi and Glyph Lefkowitz
Author-email: mahmoud@hatnote.com
License: MIT
Description: 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. MIT licensed.
See the docs at http://hyperlink.readthedocs.io.
Platform: any
Classifier: Topic :: Utilities
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
hyperlink-21.0.0/README.md 0000664 0001750 0001750 00000004542 13712200657 016176 0 ustar mahmoud mahmoud 0000000 0000000 # Hyperlink
*Cool URLs that don't change.*
Hyperlink provides a pure-Python implementation of immutable
URLs. Based on [RFC 3986][rfc3986] and [3987][rfc3987], the Hyperlink URL
makes working with both URIs and IRIs easy.
Hyperlink is tested against Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, and PyPy.
Full documentation is available on [Read the Docs][docs].
[rfc3986]: https://tools.ietf.org/html/rfc3986
[rfc3987]: https://tools.ietf.org/html/rfc3987
[docs]: http://hyperlink.readthedocs.io/en/latest/
## Installation
Hyperlink is a pure-Python package and requires nothing but
Python. The easiest way to install is with pip:
```
pip install hyperlink
```
Then, hyperlink away!
```python
from hyperlink import URL
url = URL.from_text(u'http://github.com/python-hyper/hyperlink?utm_source=README')
utm_source = url.get(u'utm_source')
better_url = url.replace(scheme=u'https', port=443)
org_url = better_url.click(u'.')
```
See the full API docs on [Read the Docs][docs].
## More information
Hyperlink would not have been possible without the help of
[Glyph Lefkowitz](https://glyph.twistedmatrix.com/) and many other
community members, especially considering that it started as an
extract from the Twisted networking library. Thanks to them,
Hyperlink's URL has been production-grade for well over a decade.
Still, should you encounter any issues, do file an issue, or submit a
pull request.
hyperlink-21.0.0/docs/ 0000775 0001750 0001750 00000000000 13775771330 015654 5 ustar mahmoud mahmoud 0000000 0000000 hyperlink-21.0.0/docs/Makefile 0000644 0001750 0001750 00000016375 13072750046 017315 0 ustar mahmoud mahmoud 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/hyperlink.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/hyperlink.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/hyperlink"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/hyperlink"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
hyperlink-21.0.0/docs/_templates/ 0000775 0001750 0001750 00000000000 13775771330 020011 5 ustar mahmoud mahmoud 0000000 0000000 hyperlink-21.0.0/docs/_templates/page.html 0000644 0001750 0001750 00000000455 13114223650 021575 0 ustar mahmoud mahmoud 0000000 0000000 {% extends "!page.html" %}
{% block menu %}
{{ super() }}
{% endblock %}
hyperlink-21.0.0/docs/api.rst 0000664 0001750 0001750 00000004721 13712176305 017153 0 ustar mahmoud mahmoud 0000000 0000000 .. _hyperlink_api:
Hyperlink API
=============
.. automodule:: hyperlink._url
.. contents::
:local:
Creation
--------
Before you can work with URLs, you must create URLs.
Parsing Text
^^^^^^^^^^^^
If you already have a textual URL, the easiest way to get URL objects
is with the :func:`parse()` function:
.. autofunction:: hyperlink.parse
By default, :func:`~hyperlink.parse()` returns an instance of
:class:`DecodedURL`, a URL type that handles all encoding for you, by
wrapping the lower-level :class:`URL`.
DecodedURL
^^^^^^^^^^
.. autoclass:: hyperlink.DecodedURL
.. automethod:: hyperlink.DecodedURL.from_text
The Encoded URL
^^^^^^^^^^^^^^^
The lower-level :class:`URL` looks very similar to the
:class:`DecodedURL`, but does not handle all encoding cases for
you. Use with caution.
.. note::
:class:`URL` is also available as an alias,
``hyperlink.EncodedURL`` for more explicit usage.
.. autoclass:: hyperlink.URL
.. automethod:: hyperlink.URL.from_text
Transformation
--------------
Once a URL is created, some of the most common tasks are to transform
it into other URLs and text.
.. automethod:: hyperlink.URL.to_text
.. automethod:: hyperlink.URL.to_uri
.. automethod:: hyperlink.URL.to_iri
.. automethod:: hyperlink.URL.replace
.. automethod:: hyperlink.URL.normalize
Navigation
----------
Go places with URLs. Simulate browser behavior and perform semantic
path operations.
.. automethod:: hyperlink.URL.click
.. automethod:: hyperlink.URL.sibling
.. automethod:: hyperlink.URL.child
Query Parameters
----------------
CRUD operations on the query string multimap.
.. automethod:: hyperlink.URL.get
.. automethod:: hyperlink.URL.add
.. automethod:: hyperlink.URL.set
.. automethod:: hyperlink.URL.remove
Attributes
----------
URLs have many parts, and URL objects have many attributes to represent them.
.. autoattribute:: hyperlink.URL.absolute
.. autoattribute:: hyperlink.URL.scheme
.. autoattribute:: hyperlink.URL.host
.. autoattribute:: hyperlink.URL.port
.. autoattribute:: hyperlink.URL.path
.. autoattribute:: hyperlink.URL.query
.. autoattribute:: hyperlink.URL.fragment
.. autoattribute:: hyperlink.URL.userinfo
.. autoattribute:: hyperlink.URL.user
.. autoattribute:: hyperlink.URL.rooted
Low-level functions
-------------------
A couple of notable helpers used by the :class:`~hyperlink.URL` type.
.. autoclass:: hyperlink.URLParseError
.. autofunction:: hyperlink.register_scheme
.. autofunction:: hyperlink.parse
.. TODO: run doctests in docs?
hyperlink-21.0.0/docs/conf.py 0000664 0001750 0001750 00000020676 13712424332 017152 0 ustar mahmoud mahmoud 0000000 0000000 # -*- coding: utf-8 -*-
#
# hyperlink documentation build configuration file, created by
# sphinx-quickstart on Sat Mar 21 00:34:18 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import sys
import sphinx
from pprint import pprint
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
CUR_PATH = os.path.dirname(os.path.abspath(__file__))
PROJECT_PATH = os.path.abspath(CUR_PATH + '/../')
PACKAGE_PATH = os.path.abspath(CUR_PATH + '/../hyperlink')
sys.path.insert(0, PROJECT_PATH)
sys.path.insert(0, PACKAGE_PATH)
pprint(os.environ)
# -- General configuration ------------------------------------------------
autosummary_generate = True
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
]
# Read the Docs is version 1.2 as of writing
if sphinx.version_info[:2] < (1, 3):
extensions.append('sphinxcontrib.napoleon')
else:
extensions.append('sphinx.ext.napoleon')
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'hyperlink'
copyright = u'2018, Mahmoud Hashemi'
author = u'Mahmoud Hashemi'
version = '20.0'
release = '20.0.1'
if os.name != 'nt':
today_fmt = '%B %d, %Y'
exclude_patterns = ['_build']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('https://docs.python.org/3.7', None)}
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if on_rtd:
html_theme = 'default'
else: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = ['_themes', sphinx_rtd_theme.get_html_theme_path()]
html_theme_options = {'navigation_depth': 3,
'collapse_navigation': False}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# TEMP: see https://github.com/rtfd/readthedocs.org/issues/1692
# Add RTD Theme Path.
#if 'html_theme_path' in globals():
# html_theme_path.append('/home/docs/checkouts/readthedocs.org/readthedocs/templates/sphinx')
#else:
# html_theme_path = ['_themes', '/home/docs/checkouts/readthedocs.org/readthedocs/templates/sphinx']
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'hyperlinkdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'hyperlink.tex', u'hyperlink Documentation',
u'Mahmoud Hashemi', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'hyperlink', u'hyperlink Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'hyperlink', u'hyperlink Documentation',
author, 'hyperlink', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
hyperlink-21.0.0/docs/design.rst 0000664 0001750 0001750 00000012740 13446451726 017662 0 ustar mahmoud mahmoud 0000000 0000000 Hyperlink Design
================
The URL is a nuanced format with a long history. Suitably, a lot of
work has gone into translating the standards, `RFC 3986`_ and `RFC
3987`_, into a Pythonic interface. Hyperlink's design strikes a unique
balance of correctness and usability.
.. _uris_and_iris:
A Tale of Two Representations
-----------------------------
The URL is a powerful construct, designed to be used by both humans
and computers.
This dual purpose has resulted in two canonical representations: the
URI and the IRI.
Even though the W3C themselves have `recognized the confusion`_ this can
cause, Hyperlink's URL makes the distinction quite natural. Simply:
* **URI**: Fully-encoded, ASCII-only, suitable for network transfer
* **IRI**: Fully-decoded, Unicode-friendly, suitable for display (e.g., in a browser bar)
We can use Hyperlink to very easily demonstrate the difference::
>>> url = URL.from_text('http://example.com/café')
>>> url.to_uri().to_text()
u'http://example.com/caf%C3%A9'
We construct a URL from text containing Unicode (``é``), then
transform it using :meth:`~URL.to_uri()`. This results in ASCII-only
percent-encoding familiar to all web developers, and a common
characteristic of URIs.
Still, Hyperlink's distinction between URIs and IRIs is pragmatic, and
only limited to output. Input can contain *any mix* of percent
encoding and Unicode, without issue:
>>> url = URL.from_text("http://example.com/caf%C3%A9 au lait/s'il vous plaît!")
>>> print(url.to_iri().to_text())
http://example.com/café au lait/s'il vous plaît!
>>> print(url.to_uri().to_text())
http://example.com/caf%C3%A9%20au%20lait/s'il%20vous%20pla%C3%AEt!
Note that even when a URI and IRI point to the same resource, they
will often be different URLs:
>>> url.to_uri() == url.to_iri()
False
And with that caveat out of the way, you're qualified to correct other
people (and their code) on the nuances of URI vs IRI.
.. _recognized the confusion: https://www.w3.org/TR/uri-clarification/
Immutability
------------
Hyperlink's URL is notable for being an `immutable`_ representation. Once
constructed, instances are not changed. Methods like
:meth:`~URL.click()`, :meth:`~URL.set()`, and :meth:`~URL.replace()`,
all return new URL objects. This enables URLs to be used in sets, as
well as dictionary keys.
.. _immutable: https://docs.python.org/2/glossary.html#term-immutable
.. _multidict: https://en.wikipedia.org/wiki/Multimap
.. _query string: https://en.wikipedia.org/wiki/Query_string
.. _GET parameters: http://php.net/manual/en/reserved.variables.get.php
.. _twisted.python.url.URL: https://twistedmatrix.com/documents/current/api/twisted.python.url.URL.html
.. _boltons.urlutils: http://boltons.readthedocs.io/en/latest/urlutils.html
.. _uri clarification: https://www.w3.org/TR/uri-clarification/
.. _BNF grammar: https://tools.ietf.org/html/rfc3986#appendix-A
.. _RFC 3986: https://tools.ietf.org/html/rfc3986
.. _RFC 3987: https://tools.ietf.org/html/rfc3987
.. _section 5.4: https://tools.ietf.org/html/rfc3986#section-5.4
.. _section 3.4: https://tools.ietf.org/html/rfc3986#section-3.4
.. _section 5.2.4: https://tools.ietf.org/html/rfc3986#section-5.2.4
.. _section 2.2: https://tools.ietf.org/html/rfc3986#section-2.2
.. _section 2.3: https://tools.ietf.org/html/rfc3986#section-2.3
.. _section 3.2.1: https://tools.ietf.org/html/rfc3986#section-3.2.1
Query parameters
----------------
One of the URL format's most useful features is the mapping formed
by the query parameters, sometimes called "query arguments" or "GET
parameters". Regardless of what you call them, they are encoded in
the query string portion of the URL, and they are very powerful.
In the simplest case, these query parameters can be provided as a
dictionary:
>>> url = URL.from_text('http://example.com/')
>>> url = url.replace(query={'a': 'b', 'c': 'd'})
>>> url.to_text()
u'http://example.com/?a=b&c=d'
Query parameters are actually a type of "multidict", where a given key
can have multiple values. This is why the :meth:`~URL.get()` method
returns a list of strings. Keys can also have no value, which is
conventionally interpreted as a truthy flag.
>>> url = URL.from_text('http://example.com/?a=b&c')
>>> url.get(u'a')
['b']
>>> url.get(u'c')
[None]
>>> url.get('missing') # returns None
[]
Values can be modified and added using :meth:`~URL.set()` and
:meth:`~URL.add()`.
>>> url = url.add(u'x', u'x')
>>> url = url.add(u'x', u'y')
>>> url.to_text()
u'http://example.com/?a=b&c&x=x&x=y'
>>> url = url.set(u'x', u'z')
>>> url.to_text()
u'http://example.com/?a=b&c&x=z'
Values can be unset with :meth:`~URL.remove()`.
>>> url = url.remove(u'a')
>>> url = url.remove(u'c')
>>> url.to_text()
u'http://example.com/?x=z'
Note how all modifying methods return copies of the URL and do not
mutate the URL in place, much like methods on strings.
Origins and backwards-compatibility
-----------------------------------
Hyperlink's URL is descended directly from `twisted.python.url.URL`_,
in all but the literal code-inheritance sense. While a lot of
functionality has been incorporated from `boltons.urlutils`_, extra
care has been taken to maintain backwards-compatibility for legacy
APIs, making Hyperlink's URL a drop-in replacement for Twisted's URL type.
If you are porting a Twisted project to use Hyperlink's URL, and
encounter any sort of incompatibility, please do not hesitate to `file
an issue`_.
.. _file an issue: https://github.com/python-hyper/hyperlink/issues
hyperlink-21.0.0/docs/faq.rst 0000664 0001750 0001750 00000007251 13074463145 017154 0 ustar mahmoud mahmoud 0000000 0000000 FAQ
===
There were bound to be questions.
.. contents::
:local:
Why not just use text?
----------------------
URLs were designed as a text format, so, apart from the principle of
structuring structured data, why use URL objects?
There are two major advantages of using :class:`~hyperlink.URL` over
representing URLs as strings. The first is that it's really easy to
evaluate a relative hyperlink, for example, when crawling documents,
to figure out what is linked::
>>> URL.from_text(u'https://example.com/base/uri/').click(u"/absolute")
URL.from_text(u'https://example.com/absolute')
>>> URL.from_text(u'https://example.com/base/uri/').click(u"rel/path")
URL.from_text(u'https://example.com/base/uri/rel/path')
The other is that URLs have two normalizations. One representation is
suitable for humans to read, because it can represent data from many
character sets - this is the Internationalized, or IRI, normalization.
The other is the older, US-ASCII-only representation, which is
necessary for most contexts where you would need to put a URI. You
can convert *between* these representations according to certain
rules. :class:`~hyperlink.URL` exposes these conversions as methods::
>>> URL.from_text(u"https://→example.com/foo⇧bar/").to_uri()
URL.from_text(u'https://xn--example-dk9c.com/foo%E2%87%A7bar/')
>>> URL.from_text(u'https://xn--example-dk9c.com/foo%E2%87%A7bar/').to_iri()
URL.from_text(u'https://\\u2192example.com/foo\\u21e7bar/')
For more info, see A Tale of Two Representations, above.
How does Hyperlink compare to other libraries?
----------------------------------------------
Hyperlink certainly isn't the first library to provide a Python model
for URLs. It just happens to be among the best.
urlparse: Built-in to the standard library (merged into urllib for
Python 3). No URL type, requires user to juggle a bunch of
strings. Overly simple approach makes it easy to make mistakes.
boltons.urlutils: Shares some underlying implementation. Two key
differences. First, the boltons URL is mutable, intended to work like
a string factory for URL text. Second, the boltons URL has advanced
query parameter mapping type. Complete implementation in a single
file.
furl: Not a single URL type, but types for many parts of the
URL. Similar approach to boltons for query parameters. Poor netloc
handling (support for non-network schemes like mailto). Unlicensed.
purl: Another immutable implementation. Method-heavy API.
rfc3986: Very heavily focused on various types of validation. Large
for a URL library, if that matters to you. Exclusively supports URIs,
`lacking IRI support`_ at the time of writing.
In reality, any of the third-party libraries above do a better job
than the standard library, and much of the hastily thrown together
code in a corner of a util.py deep in a project. URLs are easy to mess
up, make sure you use a tested implementation.
.. _lacking IRI support: https://github.com/sigmavirus24/rfc3986/issues/23
Are URLs really a big deal in 201X?
-----------------------------------
Hyperlink's first release, in 2017, comes somewhere between 23 and 30
years after URLs were already in use. Is the URL really still that big
of a deal?
Look, buddy, I don't know how you got this document, but I'm pretty
sure you (and your computer) used one if not many URLs to get
here. URLs are only getting more relevant. Buy stock in URLs.
And if you're worried that URLs are just another technology with an
obsoletion date planned in advance, I'll direct your attention to the
``IPvFuture`` rule in the `BNF grammar`_. If it has plans to outlast
IPv6, the URL will probably outlast you and me, too.
.. _BNF grammar: https://tools.ietf.org/html/rfc3986#appendix-A
hyperlink-21.0.0/docs/hyperlink_logo_proto.png 0000664 0001750 0001750 00000013776 13073343175 022641 0 ustar mahmoud mahmoud 0000000 0000000 PNG
IHDR R \ rDu sBITO tEXtSoftware gnome-screenshot> IDATx\ɒ29sf$YRƟ5MGx#Cm8O92^<YAb \܃ʺ몪ʲnӧOEQH)
0뺮?_2MSl6q]ײ꺶,KJҌ|=yY=>>>>>J)o_7o?q&HKɱeYZilلaxh4Z8s@ lvin[4m6ò,aFn름I}iR(9E9[Eb.QJIvS{{Dnj|O07]jd4gV*,K}LHyV/Bxjbcuo
cu!0,/tv;]8-6A+:4'oOE[2