diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index b5b7e9e..4393175 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -181,7 +181,7 @@ jobs: timeout-minutes: 30 strategy: matrix: - python: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "pypy2", "pypy3"] + python: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9"]#, "pypy2.7", "pypy3.9"] steps: @@ -189,7 +189,7 @@ jobs: uses: actions/checkout@v2 - name: Install Python - uses: actions/setup-python@v1 + uses: MatteoH2O1999/setup-python@v4 with: python-version: ${{ matrix.python }} @@ -204,7 +204,7 @@ jobs: set -eux py="${{ matrix.python }}"; if [[ $py =~ pypy ]]; then # PyPy - py_test="${py}"; + py_test="${py/./}"; # remove "." else # CPython py_test="py${py/./}"; # Add "py" prefix, remove "." fi; @@ -215,7 +215,7 @@ jobs: - name: Upload pytest log artifact if: failure() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: pytest-logs path: pytest-logs.tgz diff --git a/src/hyperlink/_url.py b/src/hyperlink/_url.py index 8797b5c..e37dd83 100644 --- a/src/hyperlink/_url.py +++ b/src/hyperlink/_url.py @@ -1188,6 +1188,22 @@ def user(self): """ return self.userinfo.split(u":")[0] + @property + def _host_idna_error(self): + # type: () -> bool + """Whether idna can encode the host + + idna does not encode empty strings and ipv6 addresses. + This is by design. + """ + if not hasattr(self, "_host_is_ipv6_literal"): + try: + socket.inet_pton(socket.AF_INET6, self.host) + self._host_is_ipv6_literal = True + except OSError: + self._host_is_ipv6_literal = False + return self._host_is_ipv6_literal or not self.host + def authority(self, with_password=False, **kw): # type: (bool, Any) -> Text """Compute and return the appropriate host/port/userinfo combination. @@ -1669,7 +1685,7 @@ def to_uri(self): ) new_host = ( self.host - if not self.host + if self._host_idna_error else idna_encode(self.host, uts46=True).decode("ascii") ) return self.replace( diff --git a/tox.ini b/tox.ini index 8865d17..712c942 100644 --- a/tox.ini +++ b/tox.ini @@ -44,28 +44,28 @@ basepython = py39: python3.9 py310: python3.10 - pypy2: pypy - pypy3: pypy3 + pypy27: pypy + pypy39: pypy3 deps = {[default]deps} # In Python 2, we need to pull in typing, mock - py{26,27,py2}: typing==3.10.0.0 - py{26,27,py2}: mock==3.0.5 # rq.filter: <4 + py{26,27,py27}: typing==3.10.0.0 + py{26,27,py27}: mock==3.0.5 # rq.filter: <4 # For pytest - py{26,27,34,py2}: pytest==4.6.11 # rq.filter: <5 - py{35,36,37,38,39,py3}: pytest==5.2.4 + py{26,27,34,py27}: pytest==4.6.11 # rq.filter: <5 + py{35,36,37,38,39,py39}: pytest==5.2.4 # For code coverage {[testenv:coverage_report]deps} - py{26,27,34,py2}: pytest-cov==2.8.1 # rq.filter: <2.9 - py{35,36,37,38,39,py3}: pytest-cov==2.10.1 + py{26,27,34,py27}: pytest-cov==2.8.1 # rq.filter: <2.9 + py{35,36,37,38,39,py39}: pytest-cov==2.10.1 # For hypothesis. Note Python 3.4 isn't supported by hypothesis. - py{26,27,py2}: hypothesis==4.43.9 # rq.filter: <4.44 - py{35,36,37,38,39,py3}: hypothesis==5.8.6 + py{26,27,py27}: hypothesis==4.43.9 # rq.filter: <4.44 + py{35,36,37,38,39,py39}: hypothesis==5.8.6 setenv = {[default]setenv} @@ -93,7 +93,8 @@ basepython = {[default]basepython} skip_install = True deps = - black==21.7b0 + black==21.12b0 + click==8.0.4 setenv = BLACK_LINT_ARGS=--check @@ -325,6 +326,12 @@ basepython = {[default]basepython} deps = Sphinx==4.1.2 sphinx-rtd-theme==0.5.2 + sphinxcontrib-applehelp==1.0.4 + sphinxcontrib-devhelp==1.0.2 + sphinxcontrib-devhelp==1.0.2 + sphinxcontrib-htmlhelp==2.0.1 + sphinxcontrib-qthelp==1.0.3 + sphinxcontrib-serializinghtml==1.1.5 commands = sphinx-build \ @@ -367,6 +374,7 @@ deps = check-manifest==0.46 readme-renderer==29.0 twine==3.4.2 + bleach==4.1.0 commands = check-manifest