New Upstream Snapshot - python-rfc6555

Ready changes

Summary

Merged new upstream version: 0.1.0 (was: 0.0~git20190913.1a181b4).

Resulting package

Built on 2022-10-23T22:34 (took 6m28s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots python3-rfc6555

Lintian Result

Diff

diff --git a/.appveyor/install.ps1 b/.appveyor/install.ps1
deleted file mode 100644
index 94d6f01..0000000
--- a/.appveyor/install.ps1
+++ /dev/null
@@ -1,229 +0,0 @@
-# Sample script to install Python and pip under Windows
-# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
-# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-
-$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
-$BASE_URL = "https://www.python.org/ftp/python/"
-$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
-$GET_PIP_PATH = "C:\get-pip.py"
-
-$PYTHON_PRERELEASE_REGEX = @"
-(?x)
-(?<major>\d+)
-\.
-(?<minor>\d+)
-\.
-(?<micro>\d+)
-(?<prerelease>[a-z]{1,2}\d+)
-"@
-
-
-function Download ($filename, $url) {
-    $webclient = New-Object System.Net.WebClient
-
-    $basedir = $pwd.Path + "\"
-    $filepath = $basedir + $filename
-    if (Test-Path $filename) {
-        Write-Host "Reusing" $filepath
-        return $filepath
-    }
-
-    # Download and retry up to 3 times in case of network transient errors.
-    Write-Host "Downloading" $filename "from" $url
-    $retry_attempts = 2
-    for ($i = 0; $i -lt $retry_attempts; $i++) {
-        try {
-            $webclient.DownloadFile($url, $filepath)
-            break
-        }
-        Catch [Exception]{
-            Start-Sleep 1
-        }
-    }
-    if (Test-Path $filepath) {
-        Write-Host "File saved at" $filepath
-    } else {
-        # Retry once to get the error message if any at the last try
-        $webclient.DownloadFile($url, $filepath)
-    }
-    return $filepath
-}
-
-
-function ParsePythonVersion ($python_version) {
-    if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
-        return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
-                $matches.prerelease)
-    }
-    $version_obj = [version]$python_version
-    return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
-}
-
-
-function DownloadPython ($python_version, $platform_suffix) {
-    $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
-
-    if (($major -le 2 -and $micro -eq 0) `
-        -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
-        ) {
-        $dir = "$major.$minor"
-        $python_version = "$major.$minor$prerelease"
-    } else {
-        $dir = "$major.$minor.$micro"
-    }
-
-    if ($prerelease) {
-        if (($major -le 2) `
-            -or ($major -eq 3 -and $minor -eq 1) `
-            -or ($major -eq 3 -and $minor -eq 2) `
-            -or ($major -eq 3 -and $minor -eq 3) `
-            ) {
-            $dir = "$dir/prev"
-        }
-    }
-
-    if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
-        $ext = "msi"
-        if ($platform_suffix) {
-            $platform_suffix = ".$platform_suffix"
-        }
-    } else {
-        $ext = "exe"
-        if ($platform_suffix) {
-            $platform_suffix = "-$platform_suffix"
-        }
-    }
-
-    $filename = "python-$python_version$platform_suffix.$ext"
-    $url = "$BASE_URL$dir/$filename"
-    $filepath = Download $filename $url
-    return $filepath
-}
-
-
-function InstallPython ($python_version, $architecture, $python_home) {
-    Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
-    if (Test-Path $python_home) {
-        Write-Host $python_home "already exists, skipping."
-        return $false
-    }
-    if ($architecture -eq "32") {
-        $platform_suffix = ""
-    } else {
-        $platform_suffix = "amd64"
-    }
-    $installer_path = DownloadPython $python_version $platform_suffix
-    $installer_ext = [System.IO.Path]::GetExtension($installer_path)
-    Write-Host "Installing $installer_path to $python_home"
-    $install_log = $python_home + ".log"
-    if ($installer_ext -eq '.msi') {
-        InstallPythonMSI $installer_path $python_home $install_log
-    } else {
-        InstallPythonEXE $installer_path $python_home $install_log
-    }
-    if (Test-Path $python_home) {
-        Write-Host "Python $python_version ($architecture) installation complete"
-    } else {
-        Write-Host "Failed to install Python in $python_home"
-        Get-Content -Path $install_log
-        Exit 1
-    }
-}
-
-
-function InstallPythonEXE ($exepath, $python_home, $install_log) {
-    $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
-    RunCommand $exepath $install_args
-}
-
-
-function InstallPythonMSI ($msipath, $python_home, $install_log) {
-    $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
-    $uninstall_args = "/qn /x $msipath"
-    RunCommand "msiexec.exe" $install_args
-    if (-not(Test-Path $python_home)) {
-        Write-Host "Python seems to be installed else-where, reinstalling."
-        RunCommand "msiexec.exe" $uninstall_args
-        RunCommand "msiexec.exe" $install_args
-    }
-}
-
-function RunCommand ($command, $command_args) {
-    Write-Host $command $command_args
-    Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
-}
-
-
-function InstallPip ($python_home) {
-    $pip_path = $python_home + "\Scripts\pip.exe"
-    $python_path = $python_home + "\python.exe"
-    if (-not(Test-Path $pip_path)) {
-        Write-Host "Installing pip..."
-        $webclient = New-Object System.Net.WebClient
-        $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
-        Write-Host "Executing:" $python_path $GET_PIP_PATH
-        & $python_path $GET_PIP_PATH
-    } else {
-        Write-Host "pip already installed."
-    }
-}
-
-
-function DownloadMiniconda ($python_version, $platform_suffix) {
-    if ($python_version -eq "3.4") {
-        $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
-    } else {
-        $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
-    }
-    $url = $MINICONDA_URL + $filename
-    $filepath = Download $filename $url
-    return $filepath
-}
-
-
-function InstallMiniconda ($python_version, $architecture, $python_home) {
-    Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
-    if (Test-Path $python_home) {
-        Write-Host $python_home "already exists, skipping."
-        return $false
-    }
-    if ($architecture -eq "32") {
-        $platform_suffix = "x86"
-    } else {
-        $platform_suffix = "x86_64"
-    }
-    $filepath = DownloadMiniconda $python_version $platform_suffix
-    Write-Host "Installing" $filepath "to" $python_home
-    $install_log = $python_home + ".log"
-    $args = "/S /D=$python_home"
-    Write-Host $filepath $args
-    Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
-    if (Test-Path $python_home) {
-        Write-Host "Python $python_version ($architecture) installation complete"
-    } else {
-        Write-Host "Failed to install Python in $python_home"
-        Get-Content -Path $install_log
-        Exit 1
-    }
-}
-
-
-function InstallMinicondaPip ($python_home) {
-    $pip_path = $python_home + "\Scripts\pip.exe"
-    $conda_path = $python_home + "\Scripts\conda.exe"
-    if (-not(Test-Path $pip_path)) {
-        Write-Host "Installing pip..."
-        $args = "install --yes pip"
-        Write-Host $conda_path $args
-        Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
-    } else {
-        Write-Host "pip already installed."
-    }
-}
-
-function main () {
-    InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
-    InstallPip $env:PYTHON
-}
-
-main
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index b4764a9..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,95 +0,0 @@
-# Created by .ignore support plugin (hsz.mobi)
-### Python template
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-env/
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-*.egg-info/
-.installed.cfg
-*.egg
-
-# PyInstaller
-#  Usually these files are written by a python script from a template
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*,cover
-.hypothesis/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
-
-# IPython Notebook
-.ipynb_checkpoints
-
-# pyenv
-.python-version
-
-# celery beat schedule file
-celerybeat-schedule
-
-# dotenv
-.env
-
-# virtualenv
-venv/
-ENV/
-
-# Spyder project settings
-.spyderproject
-
-# Rope project settings
-.ropeproject
-
-# PyCharm
-.idea/
-
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index fcf216d..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-language: python
-sudo: false
-
-matrix:
-  include:
-    # Miscellaneous Builds
-    - python: 3.6
-      env: TOXENV=lint
-    - python: 3.6
-      env: TOXENV=packaging
-
-    # Linux Builds
-    - python: 2.6
-      env: TOXENV=py26
-    - python: 2.7
-      env: TOXENV=py27
-    - python: 3.3
-      env: TOXENV=py33
-    - python: 3.4
-      env: TOXENV=py34
-    - python: 3.5
-      env: TOXENV=py35
-    - python: 3.6
-      env: TOXENV=py36
-    - python: nightly
-      env: TOXENV=py37
-
-cache:
-  - pip
-  - directories:
-    - ${HOME}/.cache
-
-install:
-  - pip install tox
-
-script:
-  - tox
-
-after_success:
-  - source .tox/${TOXENV}/bin/activate
-  - pip install codecov
-  - codecov --env TRAVIS_OS_NAME,TOXENV
-
-notifications:
-  email: false
diff --git a/CHANGES.rst b/CHANGES.rst
index 72dc027..8f1f789 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,7 +1,8 @@
 Changelog
 =========
 
-1.0.0
+0.1.0
 -----
 
-- Initial release of ``rfc6555``.
+- Use ``selectors`` instead of ``selectors2`` for Python 3.5+
+- Dropped support for Python 2.6, 3.3, and 3.4
diff --git a/MANIFEST.in b/MANIFEST.in
index e188e8a..57dae7a 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,14 +1,3 @@
-include *.md
 include *.rst
-include *.txt
 include LICENSE
 include .coveragerc
-include tox.ini
-include artisanci/packages/virtualbox/LICENSE
-include artisanci/packages/README.md
-exclude build_docs.py
-exclude .mention-bot
-recursive-include docs *
-recursive-exclude docs/build *
-recursive-include docs Makefile
-recursive-include tests *.py
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..4a45a13
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,112 @@
+Metadata-Version: 2.1
+Name: rfc6555
+Version: 0.1.0
+Summary: Python implementation of the Happy Eyeballs Algorithm described in RFC 6555.
+Home-page: https://www.github.com/sethmlarson/rfc6555
+Author: Seth Michael Larson
+Author-email: sethmichaellarson@gmail.com
+Maintainer: Seth Michael Larson
+Maintainer-email: sethmichaellarson@gmail.com
+License: Apache-2.0
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+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 :: 3.10
+Classifier: Topic :: Internet
+Classifier: Topic :: System :: Networking
+License-File: LICENSE
+
+Happy Eyeballs in Python (RFC 6555)
+===================================
+
+.. image:: https://github.com/sethmlarson/rfc6555/actions/workflows/ci.yml/badge.svg
+    :target: https://github.com/sethmlarson/rfc6555/actions/workflows/ci.yml
+
+.. image:: https://codecov.io/gh/sethmlarson/rfc6555/branch/master/graph/badge.svg?token=Xn7oQWErjc
+    :target: https://codecov.io/gh/sethmlarson/rfc6555    
+
+.. image:: https://img.shields.io/pypi/v/rfc6555.svg?style=flat-square
+    :target: https://pypi.python.org/pypi/rfc6555
+
+Synchronous Python implementation of the Happy Eyeballs Algorithm described in `RFC 6555 <https://tools.ietf.org/html/rfc6555>`_.
+Provided with a single file and dead-simple API to allow easy vendoring
+and integration into other projects.
+
+Abstract
+--------
+
+When a server's IPv4 path and protocol are working, but the server's
+IPv6 path and protocol are not working, a dual-stack client
+application experiences significant connection delay compared to an
+IPv4-only client.  This is undesirable because it causes the dual-
+stack client to have a worse user experience.  This document
+specifies requirements for algorithms that reduce this user-visible
+delay and provides an algorithm.
+
+Installation
+------------
+
+ .. code-block:: bash
+
+    $ python -m pip install rfc6555
+
+Usage
+-----
+
+The main API for the ``rfc6555`` module is via ``rfc6555.create_connection()`` which
+functions identically to ``socket.create_connection()`` with the same arguments.
+This function will automatically fall back on a ``socket.create_connection()`` call if
+RFC 6555 is not supported (for instance on platforms not capable of IPv6) or if
+RFC 6555 is disabled via setting ``rfc6555.RFC6555_ENABLED`` equal to ``False``.
+
+**IMPORTANT:** Caching is **NOT** thread-safe by default. If you require thread-safe caching
+one should create their own implementation of ``rfc6555._RFC6555CacheManager`` object that
+is thread-safe and assign an instance to ``rfc6555.cache``.
+
+ .. code-block:: python
+ 
+  import rfc6555
+  sock = rfc6555.create_connection(('www.google.com', 80), timeout=10, source_address=('::1', 0))
+
+  # This will disable the Happy Eyeballs algorithm for future
+  # calls to create_connection()
+  rfc6555.RFC6555_ENABLED = False
+  
+  # Use this to set a different duration for cache entries.
+  rfc6555.cache.validity_duration = 10  # 10 second validity time.
+
+  # Use this to disable caching.
+  rfc6555.cache.enabled = False
+
+Support
+-------
+
+This module supports Python 2.7 or newer and supports all major platforms.
+Additionally if you have ``selectors2>=2.0.0`` installed this module will
+also support Jython in addition to CPython.
+
+License
+-------
+
+The ``rfc6555`` package is released under the ``Apache-2.0`` license.
+
+See `full license text in LICENSE file <https://github.com/sethmlarson/rfc6555/blob/master/LICENSE>`_ for more information.
+
+
+Changelog
+=========
+
+0.1.0
+-----
+
+- Use ``selectors`` instead of ``selectors2`` for Python 3.5+
+- Dropped support for Python 2.6, 3.3, and 3.4
diff --git a/README.rst b/README.rst
index ad99647..cbdf10b 100644
--- a/README.rst
+++ b/README.rst
@@ -1,22 +1,16 @@
-rfc6555
-=======
+Happy Eyeballs in Python (RFC 6555)
+===================================
 
-.. image:: https://img.shields.io/travis/SethMichaelLarson/rfc6555/master.svg?style=flat-square
-    :target: https://travis-ci.org/SethMichaelLarson/rfc6555
+.. image:: https://github.com/sethmlarson/rfc6555/actions/workflows/ci.yml/badge.svg
+    :target: https://github.com/sethmlarson/rfc6555/actions/workflows/ci.yml
 
-.. image:: https://img.shields.io/appveyor/ci/SethMichaelLarson/rfc6555/master.svg?style=flat-square
-    :target: https://ci.appveyor.com/project/SethMichaelLarson/rfc6555
-
-.. image:: https://img.shields.io/codecov/c/github/SethMichaelLarson/rfc6555/master.svg?style=flat-square
-    :target: https://codecov.io/gh/SethMichaelLarson/rfc6555
+.. image:: https://codecov.io/gh/sethmlarson/rfc6555/branch/master/graph/badge.svg?token=Xn7oQWErjc
+    :target: https://codecov.io/gh/sethmlarson/rfc6555    
 
 .. image:: https://img.shields.io/pypi/v/rfc6555.svg?style=flat-square
     :target: https://pypi.python.org/pypi/rfc6555
 
-.. image:: https://img.shields.io/badge/say-thanks-ff69b4.svg?style=flat-square
-    :target: https://saythanks.io/to/SethMichaelLarson
-
-Python implementation of the Happy Eyeballs Algorithm described in `RFC 6555 <https://tools.ietf.org/html/rfc6555>`_.
+Synchronous Python implementation of the Happy Eyeballs Algorithm described in `RFC 6555 <https://tools.ietf.org/html/rfc6555>`_.
 Provided with a single file and dead-simple API to allow easy vendoring
 and integration into other projects.
 
@@ -31,12 +25,12 @@ stack client to have a worse user experience.  This document
 specifies requirements for algorithms that reduce this user-visible
 delay and provides an algorithm.
 
-~ `Abstract from RFC 6555 <https://tools.ietf.org/html/rfc6555>`_
-
 Installation
 ------------
 
-``$ python -m pip install rfc6555``
+ .. code-block:: bash
+
+    $ python -m pip install rfc6555
 
 Usage
 -----
@@ -69,7 +63,7 @@ is thread-safe and assign an instance to ``rfc6555.cache``.
 Support
 -------
 
-This module supports Python 2.6 or newer and supports all major platforms.
+This module supports Python 2.7 or newer and supports all major platforms.
 Additionally if you have ``selectors2>=2.0.0`` installed this module will
 also support Jython in addition to CPython.
 
@@ -78,25 +72,4 @@ License
 
 The ``rfc6555`` package is released under the ``Apache-2.0`` license.
 
-See `full license text in LICENSE file <https://github.com/SethMichaelLarson/rfc6555/blob/master/LICENSE>`_ for more information.
-
- .. code-block::
-
-                Copyright 2017 Seth Michael Larson
-  
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-  
-            http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-
-Alternatives
-------------
-
-For asyncio support check out https://pypi.org/project/async-stagger/
+See `full license text in LICENSE file <https://github.com/sethmlarson/rfc6555/blob/master/LICENSE>`_ for more information.
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index ab361ed..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-# AppVeyor.yml from https://github.com/ogrisel/python-appveyor-demo
-# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
-
-build: off
-
-environment:
-  matrix:
-    - PYTHON: "C:\\Python266-x64"
-      PYTHON_VERSION: "2.6.6"
-      PYTHON_ARCH: "64"
-      TOXENV: "py26"
-
-    - PYTHON: "C:\\Python27-x64"
-      PYTHON_VERSION: "2.7.x"
-      PYTHON_ARCH: "64"
-      TOXENV: "py27"
-
-    - PYTHON: "C:\\Python33-x64"
-      PYTHON_VERSION: "3.3.x"
-      PYTHON_ARCH: "64"
-      TOXENV: "py33"
-
-    - PYTHON: "C:\\Python34-x64"
-      PYTHON_VERSION: "3.4.x"
-      PYTHON_ARCH: "64"
-      TOXENV: "py34"
-
-    - PYTHON: "C:\\Python35-x64"
-      PYTHON_VERSION: "3.5.x"
-      PYTHON_ARCH: "64"
-      TOXENV: "py35"
-
-    - PYTHON: "C:\\Python36-x64"
-      PYTHON_VERSION: "3.6.x"
-      PYTHON_ARCH: "64"
-      TOXENV: "py36"
-
-install:
-  # Install Python (from the official .msi of http://python.org) and pip when
-  # not already installed.
-  - ps: if (-not(Test-Path($env:PYTHON))) { & .appveyor\install.ps1 }
-
-  # Prepend newly installed Python to the PATH of this build (this cannot be
-  # done from inside the powershell script as it would require to restart
-  # the parent CMD process).
-  - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
-
-  # Check that we have the expected version and architecture for Python
-  - "python --version"
-  - "python -c \"import struct; print(struct.calcsize('P') * 8)\""
-
-  # Upgrade to the latest version of pip to avoid it displaying warnings
-  # about it being out of date.
-  - "pip install --disable-pip-version-check --user --upgrade pip"
-  - "pip install tox"
-
-  - "python setup.py install"
-
-test_script:
-  - "tox"
-
-on_success:
-  - ".tox\\%TOXENV%\\Scripts\\activate"
-  - "pip install codecov"
-  - "codecov --env PLATFORM,TOXENV"
-
-branches:
-  only:
-    - master
-    - release
diff --git a/debian/changelog b/debian/changelog
index 8d0428d..c95ed40 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-rfc6555 (0.1.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 23 Oct 2022 22:28:36 -0000
+
 python-rfc6555 (0.0~git20190913.1a181b4-3) unstable; urgency=medium
 
   [ Debian Janitor ]
diff --git a/dev-requirements.txt b/dev-requirements.txt
deleted file mode 100644
index 036dbb4..0000000
--- a/dev-requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-pytest==3.1.1
-check-manifest==0.35
-readme_renderer==17.2
-mock==2.0.0
-codecov==2.0.9
diff --git a/rfc6555.egg-info/PKG-INFO b/rfc6555.egg-info/PKG-INFO
new file mode 100644
index 0000000..4a45a13
--- /dev/null
+++ b/rfc6555.egg-info/PKG-INFO
@@ -0,0 +1,112 @@
+Metadata-Version: 2.1
+Name: rfc6555
+Version: 0.1.0
+Summary: Python implementation of the Happy Eyeballs Algorithm described in RFC 6555.
+Home-page: https://www.github.com/sethmlarson/rfc6555
+Author: Seth Michael Larson
+Author-email: sethmichaellarson@gmail.com
+Maintainer: Seth Michael Larson
+Maintainer-email: sethmichaellarson@gmail.com
+License: Apache-2.0
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+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 :: 3.10
+Classifier: Topic :: Internet
+Classifier: Topic :: System :: Networking
+License-File: LICENSE
+
+Happy Eyeballs in Python (RFC 6555)
+===================================
+
+.. image:: https://github.com/sethmlarson/rfc6555/actions/workflows/ci.yml/badge.svg
+    :target: https://github.com/sethmlarson/rfc6555/actions/workflows/ci.yml
+
+.. image:: https://codecov.io/gh/sethmlarson/rfc6555/branch/master/graph/badge.svg?token=Xn7oQWErjc
+    :target: https://codecov.io/gh/sethmlarson/rfc6555    
+
+.. image:: https://img.shields.io/pypi/v/rfc6555.svg?style=flat-square
+    :target: https://pypi.python.org/pypi/rfc6555
+
+Synchronous Python implementation of the Happy Eyeballs Algorithm described in `RFC 6555 <https://tools.ietf.org/html/rfc6555>`_.
+Provided with a single file and dead-simple API to allow easy vendoring
+and integration into other projects.
+
+Abstract
+--------
+
+When a server's IPv4 path and protocol are working, but the server's
+IPv6 path and protocol are not working, a dual-stack client
+application experiences significant connection delay compared to an
+IPv4-only client.  This is undesirable because it causes the dual-
+stack client to have a worse user experience.  This document
+specifies requirements for algorithms that reduce this user-visible
+delay and provides an algorithm.
+
+Installation
+------------
+
+ .. code-block:: bash
+
+    $ python -m pip install rfc6555
+
+Usage
+-----
+
+The main API for the ``rfc6555`` module is via ``rfc6555.create_connection()`` which
+functions identically to ``socket.create_connection()`` with the same arguments.
+This function will automatically fall back on a ``socket.create_connection()`` call if
+RFC 6555 is not supported (for instance on platforms not capable of IPv6) or if
+RFC 6555 is disabled via setting ``rfc6555.RFC6555_ENABLED`` equal to ``False``.
+
+**IMPORTANT:** Caching is **NOT** thread-safe by default. If you require thread-safe caching
+one should create their own implementation of ``rfc6555._RFC6555CacheManager`` object that
+is thread-safe and assign an instance to ``rfc6555.cache``.
+
+ .. code-block:: python
+ 
+  import rfc6555
+  sock = rfc6555.create_connection(('www.google.com', 80), timeout=10, source_address=('::1', 0))
+
+  # This will disable the Happy Eyeballs algorithm for future
+  # calls to create_connection()
+  rfc6555.RFC6555_ENABLED = False
+  
+  # Use this to set a different duration for cache entries.
+  rfc6555.cache.validity_duration = 10  # 10 second validity time.
+
+  # Use this to disable caching.
+  rfc6555.cache.enabled = False
+
+Support
+-------
+
+This module supports Python 2.7 or newer and supports all major platforms.
+Additionally if you have ``selectors2>=2.0.0`` installed this module will
+also support Jython in addition to CPython.
+
+License
+-------
+
+The ``rfc6555`` package is released under the ``Apache-2.0`` license.
+
+See `full license text in LICENSE file <https://github.com/sethmlarson/rfc6555/blob/master/LICENSE>`_ for more information.
+
+
+Changelog
+=========
+
+0.1.0
+-----
+
+- Use ``selectors`` instead of ``selectors2`` for Python 3.5+
+- Dropped support for Python 2.6, 3.3, and 3.4
diff --git a/rfc6555.egg-info/SOURCES.txt b/rfc6555.egg-info/SOURCES.txt
new file mode 100644
index 0000000..1acd639
--- /dev/null
+++ b/rfc6555.egg-info/SOURCES.txt
@@ -0,0 +1,14 @@
+.coveragerc
+CHANGES.rst
+LICENSE
+MANIFEST.in
+README.rst
+rfc6555.py
+setup.cfg
+setup.py
+rfc6555.egg-info/PKG-INFO
+rfc6555.egg-info/SOURCES.txt
+rfc6555.egg-info/dependency_links.txt
+rfc6555.egg-info/not-zip-safe
+rfc6555.egg-info/requires.txt
+rfc6555.egg-info/top_level.txt
\ No newline at end of file
diff --git a/rfc6555.egg-info/dependency_links.txt b/rfc6555.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/rfc6555.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/rfc6555.egg-info/not-zip-safe b/rfc6555.egg-info/not-zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/rfc6555.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
diff --git a/rfc6555.egg-info/requires.txt b/rfc6555.egg-info/requires.txt
new file mode 100644
index 0000000..cc33fd5
--- /dev/null
+++ b/rfc6555.egg-info/requires.txt
@@ -0,0 +1,3 @@
+
+[:python_version < "3.4"]
+selectors2
diff --git a/rfc6555.egg-info/top_level.txt b/rfc6555.egg-info/top_level.txt
new file mode 100644
index 0000000..21c6a4b
--- /dev/null
+++ b/rfc6555.egg-info/top_level.txt
@@ -0,0 +1 @@
+rfc6555
diff --git a/rfc6555.py b/rfc6555.py
index 222fe6c..1a93f14 100644
--- a/rfc6555.py
+++ b/rfc6555.py
@@ -1,6 +1,4 @@
-""" Python implementation of the Happy Eyeballs Algorithm described in RFC 6555. """
-
-# Copyright 2017 Seth Michael Larson
+# Copyright 2021 Seth Michael Larson
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,12 +12,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""Python implementation of the Happy Eyeballs Algorithm described in RFC 6555"""
+
 import errno
 import socket
+
 try:
-    from selectors  import DefaultSelector, EVENT_WRITE
+    from selectors import EVENT_WRITE, DefaultSelector
 except (ImportError, AttributeError):
-    from selectors2 import DefaultSelector, EVENT_WRITE
+    from selectors2 import EVENT_WRITE, DefaultSelector
 
 # time.perf_counter() is defined in Python 3.3
 try:
@@ -35,11 +36,11 @@ _SOCKET_ERRORS = (socket.error, OSError, IOError)
 
 # Detects whether an IPv6 socket can be allocated.
 def _detect_ipv6():
-    if getattr(socket, 'has_ipv6', False) and hasattr(socket, 'AF_INET6'):
+    if getattr(socket, "has_ipv6", False) and hasattr(socket, "AF_INET6"):
         _sock = None
         try:
             _sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
-            _sock.bind(('::1', 0))
+            _sock.bind(("::1", 0))
             return True
         except _SOCKET_ERRORS:
             if _sock:
@@ -51,10 +52,8 @@ _HAS_IPV6 = _detect_ipv6()
 
 # These are error numbers for asynchronous operations which can
 # be safely ignored by RFC 6555 as being non-errors.
-_ASYNC_ERRNOS = set([errno.EINPROGRESS,
-                     errno.EAGAIN,
-                     errno.EWOULDBLOCK])
-if hasattr(errno, 'WSAWOULDBLOCK'):
+_ASYNC_ERRNOS = set([errno.EINPROGRESS, errno.EAGAIN, errno.EWOULDBLOCK])
+if hasattr(errno, "WSAWOULDBLOCK"):
     _ASYNC_ERRNOS.add(errno.WSAWOULDBLOCK)
 
 _DEFAULT_CACHE_DURATION = 60 * 10  # 10 minutes according to the RFC.
@@ -62,14 +61,12 @@ _DEFAULT_CACHE_DURATION = 60 * 10  # 10 minutes according to the RFC.
 # This value that can be used to disable RFC 6555 globally.
 RFC6555_ENABLED = _HAS_IPV6
 
-__all__ = ['RFC6555_ENABLED',
-           'create_connection',
-           'cache']
+__all__ = ["RFC6555_ENABLED", "create_connection", "cache"]
 
-__version__ = '1.0.0'
-__author__ = 'Seth Michael Larson'
-__email__ = 'sethmichaellarson@protonmail.com'
-__license__ = 'Apache-2.0'
+__version__ = "0.1.0"
+__author__ = "Seth Michael Larson"
+__email__ = "sethmichaellarson@gmail.com"
+__license__ = "Apache-2.0"
 
 
 class _RFC6555CacheManager(object):
@@ -102,7 +99,9 @@ cache = _RFC6555CacheManager()
 
 
 class _RFC6555ConnectionManager(object):
-    def __init__(self, address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None):
+    def __init__(
+        self, address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None
+    ):
         self.address = address
         self.timeout = timeout
         self.source_address = source_address
@@ -128,7 +127,7 @@ class _RFC6555ConnectionManager(object):
 
         # If we don't get any results back then just skip to the end.
         if not addr_info:
-            raise socket.error('getaddrinfo returns an empty list')
+            raise socket.error("getaddrinfo returns an empty list")
 
         sock = self._attempt_connect_with_addr_info(addr_info)
 
@@ -283,7 +282,9 @@ class _RFC6555ConnectionManager(object):
         self._sockets = []
 
 
-def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None):
+def create_connection(
+    address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None
+):
     if RFC6555_ENABLED and _HAS_IPV6:
         manager = _RFC6555ConnectionManager(address, timeout, source_address)
         return manager.create_connection()
@@ -296,7 +297,7 @@ def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_ad
         host, port = address
         err = None
         for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
-            af, socktype, proto, canonname, sa = res
+            af, socktype, proto, _, sa = res
             sock = None
             try:
                 sock = socket.socket(af, socktype, proto)
diff --git a/setup.cfg b/setup.cfg
index 2a9acf1..adf5ed7 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,2 +1,7 @@
 [bdist_wheel]
 universal = 1
+
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff --git a/setup.py b/setup.py
index f6f087a..899241a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,45 +1,48 @@
 import os
 import re
+
 from setuptools import setup
 
 # Get the version (borrowed from SQLAlchemy)
 base_path = os.path.dirname(os.path.abspath(__file__))
-with open(os.path.join(base_path, 'rfc6555.py')) as f:
-    VERSION = re.compile(r'.*__version__ = \'(.*?)\'', re.S).match(f.read()).group(1)
+with open(os.path.join(base_path, "rfc6555.py")) as f:
+    VERSION = re.compile(r".*__version__ = \"(.*?)\"", re.S).match(f.read()).group(1)
 
-with open(os.path.join(base_path, 'README.rst')) as f:
+with open(os.path.join(base_path, "README.rst")) as f:
     long_description = f.read()
 
-with open(os.path.join(base_path, 'CHANGES.rst')) as f:
+with open(os.path.join(base_path, "CHANGES.rst")) as f:
     changes = f.read()
 
-if __name__ == '__main__':
-    setup(name='rfc6555',
-          description='Python implementation of the Happy Eyeballs Algorithm described in RFC 6555.',
-          long_description=long_description + '\n\n' + changes,
-          license='Apache-2.0',
-          url='https://www.github.com/SethMichaelLarson/rfc6555',
-          version=VERSION,
-          author='Seth Michael Larson',
-          author_email='sethmichaellarson@protonmail.com',
-          maintainer='Seth Michael Larson',
-          maintainer_email='sethmichaellarson@protonmail.com',
-          install_requires=[
-              'selectors2;python_version<"3.4"'
-          ],
-          py_modules=['rfc6555'],
-          zip_safe=False,
-          classifiers=['Intended Audience :: Developers',
-                       'License :: OSI Approved :: Apache Software License',
-                       'Natural Language :: English',
-                       'Operating System :: OS Independent',
-                       'Programming Language :: Python :: 2',
-                       'Programming Language :: Python :: 2.6',
-                       'Programming Language :: Python :: 2.7',
-                       'Programming Language :: Python :: 3',
-                       'Programming Language :: Python :: 3.3',
-                       'Programming Language :: Python :: 3.4',
-                       'Programming Language :: Python :: 3.5',
-                       'Programming Language :: Python :: 3.6',
-                       'Topic :: Internet',
-                       'Topic :: System :: Networking'])
+setup(
+    name="rfc6555",
+    description="Python implementation of the Happy Eyeballs Algorithm described in RFC 6555.",
+    long_description=long_description + "\n\n" + changes,
+    license="Apache-2.0",
+    url="https://www.github.com/sethmlarson/rfc6555",
+    version=VERSION,
+    author="Seth Michael Larson",
+    author_email="sethmichaellarson@gmail.com",
+    maintainer="Seth Michael Larson",
+    maintainer_email="sethmichaellarson@gmail.com",
+    install_requires=['selectors2;python_version<"3.4"'],
+    py_modules=["rfc6555"],
+    zip_safe=False,
+    classifiers=[
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: Apache Software License",
+        "Natural Language :: English",
+        "Operating System :: OS Independent",
+        "Programming Language :: Python :: 2",
+        "Programming Language :: Python :: 2.7",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+        "Topic :: Internet",
+        "Topic :: System :: Networking",
+    ],
+)
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/test_create_connection.py b/tests/test_create_connection.py
deleted file mode 100644
index 0603546..0000000
--- a/tests/test_create_connection.py
+++ /dev/null
@@ -1,63 +0,0 @@
-try:
-    from unittest import mock
-except (ImportError, AttributeError):
-    import mock
-
-import pytest
-import socket
-import rfc6555
-from .test_utils import requires_network
-
-
-class _BasicCreateConnectionTests(object):
-    @requires_network
-    def test_create_connection_google(self):
-        sock = rfc6555.create_connection(('www.google.com', 80))
-
-    @pytest.mark.parametrize('timeout', [None, 5.0])
-    def test_create_connection_has_proper_timeout(self, timeout):
-        sock = rfc6555.create_connection(('www.google.com', 80), timeout=timeout)
-
-        assert sock.gettimeout() == timeout
-
-    def test_create_connection_with_source_address_calls_bind(self):
-        sock = mock.Mock()
-        with mock.patch('socket.socket') as fake_socket:
-            fake_socket.return_value = sock
-
-            sock.getsockopt.return_value = 0
-            sock.connect_ex.return_value = 0
-            sock.gettimeout.return_value = None
-
-            try:
-                rfc6555.create_connection(('::1', 0), source_address=('::1', 123))
-            except Exception:
-                pass
-
-            sock.bind.assert_called_with(('::1', 123))
-
-    def test_getaddr_info_empty_list(self):
-        with mock.patch('socket.getaddrinfo') as fake_getaddrinfo:
-            fake_getaddrinfo.return_value = []
-
-            with pytest.raises(socket.error):
-                rfc6555.create_connection(('::1', 0))
-
-    @requires_network
-    def test_create_connection_cached_value(self):
-        sock = rfc6555.create_connection(('www.google.com', 80))
-        sock2 = rfc6555.create_connection(('www.google.com', 80))
-
-
-class TestCreateConnectionTestRFC6555Default(_BasicCreateConnectionTests):
-    pass
-
-
-class TestCreateConnectionTestRFC6555Enabled(_BasicCreateConnectionTests):
-    def setup_method(self, test_method):
-        rfc6555.RFC6555_ENABLED = True
-
-
-class TestCreateConnectionTestRFC6555Disabled(_BasicCreateConnectionTests):
-    def setup_method(self, test_method):
-        rfc6555.RFC6555_ENABLED = False
diff --git a/tests/test_ipv6.py b/tests/test_ipv6.py
deleted file mode 100644
index d58286c..0000000
--- a/tests/test_ipv6.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import socket
-import rfc6555
-
-try:
-    from unittest import mock
-except (ImportError, AttributeError):
-    import mock
-
-
-def test_ipv6_available():
-    assert rfc6555._detect_ipv6()
-
-
-def test_ipv6_not_available_socket_has_ipv6_false():
-    old_has_ipv6 = socket.has_ipv6
-    socket.has_ipv6 = False
-    assert not rfc6555._detect_ipv6()
-    socket.has_ipv6 = old_has_ipv6
-
-
-def test_ipv6_not_available_socket_exception_on_init():
-    with mock.patch('socket.socket') as fake_socket:
-        fake_socket.side_effect = OSError
-
-        assert not rfc6555._detect_ipv6()
-
-
-def test_ipv6_not_available_socket_exception_on_bind():
-    sock = mock.Mock()
-    with mock.patch('socket.socket') as fake_socket:
-        fake_socket.return_value = sock
-        sock.bind.side_effect = OSError
-
-        assert not rfc6555._detect_ipv6()
-
-
-def test_ipv6_not_available_socket_AF_INET6_not_defined():
-    old_AF_INET6 = socket.AF_INET6
-    try:
-        delattr(socket, 'AF_INET6')
-        assert not rfc6555._detect_ipv6()
-    finally:
-        socket.AF_INET6 = old_AF_INET6
diff --git a/tests/test_utils.py b/tests/test_utils.py
deleted file mode 100644
index e2f84ec..0000000
--- a/tests/test_utils.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import pytest
-import socket
-
-
-def _check_network():
-    sock = None
-    try:
-        sock = socket.create_connection(('www.google.com', 80))
-        sock.close()
-        return True
-    except Exception:
-        if sock:
-            sock.close()
-        return False
-
-
-requires_network = pytest.mark.skipif(not _check_network(), reason='This test requires a network connection.')
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 29a7f2f..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,27 +0,0 @@
-[tox]
-envlist = lint, packaging, py26, py27, py33, py34, py35, py36, py37
-skip_missing_interpreters = true
-
-[testenv]
-deps= -r{toxinidir}/dev-requirements.txt
-commands=
-    coverage run -m pytest tests/
-    coverage report -m
-    coverage html
-passenv = TRAVIS APPVEYOR
-
-[testenv:py26]
-# Additional dependency on unittest2 for Python 2.6
-deps=
-    {[testenv]deps}
-    unittest2
-
-[testenv:lint]
-commands =
-    python -m pip install flake8
-    flake8 --max-line-length 100 rfc6555.py
-
-[testenv:packaging]
-commands =
-    check-manifest --ignore *.yml,.mention-bot,.appveyor*,.travis*,.github*
-    python setup.py check --metadata --restructuredtext --strict

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-0.1.0.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-0.1.0.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-0.1.0.egg-info/not-zip-safe
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-0.1.0.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-0.1.0.egg-info/top_level.txt

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-1.0.0.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-1.0.0.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-1.0.0.egg-info/not-zip-safe
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-1.0.0.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/rfc6555-1.0.0.egg-info/top_level.txt

No differences were encountered in the control files

More details

Full run details