Hello community,

here is the log from the commit of package python-pyhibp for openSUSE:Factory 
checked in at 2019-07-02 10:39:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyhibp (Old)
 and      /work/SRC/openSUSE:Factory/.python-pyhibp.new.4615 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pyhibp"

Tue Jul  2 10:39:46 2019 rev:2 rq:712996 version:3.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyhibp/python-pyhibp.changes      
2019-02-01 11:45:44.184534553 +0100
+++ /work/SRC/openSUSE:Factory/.python-pyhibp.new.4615/python-pyhibp.changes    
2019-07-02 10:39:47.186708781 +0200
@@ -1,0 +2,24 @@
+Mon Jul  1 12:34:45 UTC 2019 - Martin Hauke <[email protected]>
+
+- Update to version 3.1.0
+  * New function: pwnedpasswords.suffix_search(hash_prefix=prefix)
+    was created in order to have a dedicated function return the
+    suffix list.
+  * Function modification notice: pwnedpasswords.is_password_breached
+    will be modified in an upcoming release to remove the ability
+    to search for suffixes; use suffix_search(hash_prefix=prefix)
+    instead. The parameter first_5_hash_chars will be removed as a
+    consequence.
+  * Upcoming return type change for empty sets: For the functions
+    get_account_breaches, get_all_breaches, get_single_breach, and
+    get_pastes--all contained in the pyhibp module--when no items
+    would be returned from the HIBP backend, the returned item will
+    be an empty object matching the standard return type for the
+    function, and not a Boolean False.
+    This will occur when v4.0.0 is released. Return types will be:
+    - get_account_breaches -> [] / list
+    - get_all_breaches -> [] / list
+    - get_single_breach -> {} / dict
+    - get_pastes -> [] / list
+
+-------------------------------------------------------------------

Old:
----
  pyhibp-3.0.0.tar.gz

New:
----
  pyhibp-3.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pyhibp.spec ++++++
--- /var/tmp/diff_new_pack.YoruMU/_old  2019-07-02 10:39:47.642709476 +0200
+++ /var/tmp/diff_new_pack.YoruMU/_new  2019-07-02 10:39:47.646709481 +0200
@@ -1,5 +1,5 @@
 #
-# spec file for package python-pyHIBP
+# spec file for package python-pyhibp
 #
 # Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
@@ -12,12 +12,13 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-pyhibp
-Version:        3.0.0
+Version:        3.1.0
 Release:        0
 Summary:        An interface to Troy Hunt's 'Have I Been Pwned' public API
 License:        AGPL-3.0-or-later
@@ -50,7 +51,7 @@
 
 ### Tests need network access to https://haveibeenpwned.com
 #%%check
-#%%python_expand PYTHONPATH=%%{buildroot}%%{$python_sitelib} 
py.test-%%{$python_version}
+#%%pytest
 
 %files %{python_files}
 %license LICENSE

++++++ pyhibp-3.0.0.tar.gz -> pyhibp-3.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/CHANGELOG.md 
new/pyhibp-3.1.0/CHANGELOG.md
--- old/pyhibp-3.0.0/CHANGELOG.md       2018-11-10 01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/CHANGELOG.md       2019-06-30 10:46:01.000000000 +0200
@@ -1,11 +1,34 @@
 pyHIBP Changelog
 ================
-v3.0.0 (UNRELEASED)
+v3.1.0 (In progress...)
+-----------------------
+- **New function**: ``pwnedpasswords.suffix_search(hash_prefix=prefix)`` was 
created in order to have a dedicated function
+  return the suffix list.
+- **Function modification notice**: ``pwnedpasswords.is_password_breached`` 
will be modified in an upcoming release to
+  remove the ability to search for suffixes; use 
``suffix_search(hash_prefix=prefix)`` instead. The parameter
+  ``first_5_hash_chars`` will be removed as a consequence.
+- **Upcoming return type change for empty sets**: For the functions 
``get_account_breaches``, ``get_all_breaches``,
+  ``get_single_breach``, and ``get_pastes``--all contained in the ``pyhibp`` 
module--when no items would be returned
+  from the HIBP backend, the returned item will be an empty object matching 
the standard return type for the function,
+  and not a Boolean ``False``. This will occur when ``v4.0.0`` is released. 
Return types will be:
+    - ``get_account_breaches`` -> ``[] / list``
+    - ``get_all_breaches`` -> ``[] / list``
+    - ``get_single_breach`` -> ``{} / dict``
+    - ``get_pastes`` -> ``[] / list``
+- As a reminder, Python 2.7 support will be dropped from support in the near 
future. This will occur at the same time
+  as the removal of the range search functionality available via 
``pwnedpasswords.is_password_breached(first_5_hash_chars=prefix)``
+  so as to minimize disruption.
+
+v3.0.0 (2018-11-10)
 -------------------
-- **Backwards Incompatible Change**: The package name has been changed to fall 
in-line with the PEP 8 guideline calling for [all lowercase characters in 
package/module 
names](https://www.python.org/dev/peps/pep-0008/#package-and-module-names). 
Existing code will need to change invocations of ``pyHIBP`` to ``pyhibp``.
-  - We will, however, still refer to the package/module as _pyHIBP_ when it is 
used outside of the context of Python code.
-- **Future Python 2 Deprecation**: As per PEP 373, [Python 2.7.x support ends 
on 2020-01-01](https://www.python.org/dev/peps/pep-0373/#maintenance-releases). 
That being said, we will be dropping Python 2 as a supported version _prior_ to 
this date.
-- The `requests` dependency has been bumped to require versions at or above 
`2.20.0` (due to CVE-2018-18074 affecting the `requests` package for older 
versions).
+- **Backwards Incompatible Change**: The package name has been changed to fall 
in-line with the PEP 8 guideline calling
+  for [all lowercase characters in package/module 
names](https://www.python.org/dev/peps/pep-0008/#package-and-module-names).
+  Existing code will need to change invocations of ``pyHIBP`` to ``pyhibp``.
+    - We will, however, still refer to the package/module as _pyHIBP_ when it 
is used outside of the context of Python code.
+- **Future Python 2 Deprecation**: As per PEP 373, [Python 2.7.x support ends 
on 2020-01-01](https://www.python.org/dev/peps/pep-0373/#maintenance-releases).
+  That being said, we will be dropping Python 2 as a supported version _prior_ 
to this date.
+- The `requests` dependency has been bumped to require versions at or above 
`2.20.0` (due to CVE-2018-18074 affecting
+  the `requests` package for older versions).
 
 v2.1.1 (2018-09-18)
 -------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/PKG-INFO new/pyhibp-3.1.0/PKG-INFO
--- old/pyhibp-3.0.0/PKG-INFO   2018-11-10 02:56:39.000000000 +0100
+++ new/pyhibp-3.1.0/PKG-INFO   2019-06-30 11:17:16.000000000 +0200
@@ -1,102 +1,102 @@
-Metadata-Version: 2.1
-Name: pyhibp
-Version: 3.0.0
-Summary: An interface to Troy Hunt's 'Have I Been Pwned' public API
-Home-page: https://gitlab.com/kitsunix/pyHIBP/pyHIBP
-Author: Kyra F. Kitsune
-License: UNKNOWN
-Description: pyHIBP (pyHave I Been Pwned)
-        ============================
-        
[![image](https://img.shields.io/pypi/v/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
-        
[![image](https://img.shields.io/pypi/l/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
-        
[![image](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master)
-        
-        
-        A Python interface to Troy Hunt's 'Have I Been Pwned?' (HIBP) public 
API. A full reference to the API
-        specification can be found at the [HIBP API 
Reference](https://haveibeenpwned.com/API/v2).
-        
-        This module detects when the rate limit of the API has been hit, and 
raises a RuntimeError when the limit is exceeded,
-        or when another API-defined error condition is encountered based on 
the submitted data. Calls
-        to the module returning Boolean `True` or the object as decoded from 
the API query (currently, lists), represent
-        a detection that a breached account/paste/password was found; Boolean 
`False` means that the item was not found.
-        
-        Note that the `pwnedpasswords` API backend does not have a rate limit. 
If you are intending to bulk-query passwords or
-        hashes, you may also consider downloading the raw data files 
accessible via the [Pwned Passwords](https://haveibeenpwned.com/Passwords) page.
-        
-        Installing
-        ----------
-        ```bash
-        $ pip install pyhibp
-        ```
-        
-        Example usage
-        -------------
-        For an interactive example, check out the Jupyter Notebook for 
[`pyhibp`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.ipynb),
-        as well as 
[`pyhibp.pwnedpasswords`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.pwnedpasswords.ipynb).
-        
-        ```python
-        import pyhibp
-        from pyhibp import pwnedpasswords as pw
-        
-        # Check a password to see if it has been disclosed in a public breach 
corpus
-        resp = pw.is_password_breached(password="secret")
-        if resp:
-            print("Password breached!")
-            print("This password was used {0} time(s) before.".format(resp))
-        
-        # Get breaches that affect a given account
-        resp = pyhibp.get_account_breaches(account="[email protected]", 
truncate_response=True)
-        
-        # Get all breach information
-        resp = pyhibp.get_all_breaches()
-        
-        # Get a single breach
-        resp = pyhibp.get_single_breach(breach_name="Adobe")
-        
-        # Get pastes affecting a given email address
-        resp = pyhibp.get_pastes(email_address="[email protected]")
-        
-        # Get data classes in the HIBP system
-        resp = pyhibp.get_data_classes()
-        ```
-        
-        Developing
-        ----------
-        This project is currently intended to be compatible with Python 2 and 
Python 3. As such, we use virtual environments via `pipenv`.
-        To develop or test, execute the following:
-        
-        ```bash
-        # Install the prerequisite virtual environment provider
-        $ pip install pipenv
-        # Initialize the pipenv environment and install the module within it
-        $ make dev
-        # To run PEP8, tests, and check the manifest
-        $ make tox
-        ```
-        
-        Other commands can be found in the `Makefile`.
-        
-        Goals
-        -----
-        - Synchronize to the latest HIBP API(s), implementing endpoint 
accessing functions where it makes sense. For instance,
-          in the interest of security, the ability to submit a SHA-1 to the 
Pwned Passwords endpoint is not implemented. See
-          "Regarding password checking" below for further details.
-        - For breaches and pastes, act as an intermediary; return the JSON as 
received from the service.
-        
-        Regarding password checking
-        ---------------------------
-        - For passwords, the option to supply a plaintext password to check is 
provided as an implementation convenience.
-        - For added security, `pwnedpasswords.is_password_breached()` only 
transmits the first five characters of the SHA-1
-          hash to the Pwned Passwords API endpoint; a secure password will 
remain secure without disclosing the full hash.
-        
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or 
later (AGPLv3+)
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
-Description-Content-Type: text/markdown
-Provides-Extra: dev
+Metadata-Version: 2.1
+Name: pyhibp
+Version: 3.1.0
+Summary: An interface to Troy Hunt's 'Have I Been Pwned' public API
+Home-page: https://gitlab.com/kitsunix/pyHIBP/pyHIBP
+Author: Kyra F. Kitsune
+License: UNKNOWN
+Description: pyHIBP (pyHave I Been Pwned)
+        ============================
+        
[![image](https://img.shields.io/pypi/v/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
+        
[![image](https://img.shields.io/pypi/l/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
+        
[![image](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master)
+        
+        
+        A Python interface to Troy Hunt's 'Have I Been Pwned?' (HIBP) public 
API. A full reference to the API
+        specification can be found at the [HIBP API 
Reference](https://haveibeenpwned.com/API/v2).
+        
+        This module detects when the rate limit of the API has been hit, and 
raises a RuntimeError when the limit
+        is exceeded, or when another API-defined error condition is 
encountered based on the submitted data. When
+        data is found from a call, the data returned will be in the format as 
retrieved from the endpoint, documented
+        in the return-type information for the relevant function.
+        
+        Note that the `pwnedpasswords` API backend does not have a rate limit. 
If you are intending to bulk-query passwords or
+        hashes, you should consider downloading the raw data files accessible 
via the [Pwned Passwords](https://haveibeenpwned.com/Passwords) page.
+        
+        Installing
+        ----------
+        ```bash
+        $ pip install pyhibp
+        ```
+        
+        Example usage
+        -------------
+        For an interactive example, check out the Jupyter Notebook for 
[`pyhibp`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.ipynb),
+        as well as 
[`pyhibp.pwnedpasswords`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.pwnedpasswords.ipynb).
+        
+        ```python
+        import pyhibp
+        from pyhibp import pwnedpasswords as pw
+        
+        # Check a password to see if it has been disclosed in a public breach 
corpus
+        resp = pw.is_password_breached(password="secret")
+        if resp:
+            print("Password breached!")
+            print("This password was used {0} time(s) before.".format(resp))
+        
+        # Get breaches that affect a given account
+        resp = pyhibp.get_account_breaches(account="[email protected]", 
truncate_response=True)
+        
+        # Get all breach information
+        resp = pyhibp.get_all_breaches()
+        
+        # Get a single breach
+        resp = pyhibp.get_single_breach(breach_name="Adobe")
+        
+        # Get pastes affecting a given email address
+        resp = pyhibp.get_pastes(email_address="[email protected]")
+        
+        # Get data classes in the HIBP system
+        resp = pyhibp.get_data_classes()
+        ```
+        
+        Developing
+        ----------
+        This project is currently intended to be compatible with Python 2 and 
Python 3. As such, we use virtual environments via `pipenv`.
+        To develop or test, execute the following:
+        
+        ```bash
+        # Install the prerequisite virtual environment provider
+        $ pip install pipenv
+        # Initialize the pipenv environment and install the module within it
+        $ make dev
+        # To run PEP8, tests, and check the manifest
+        $ make tox
+        ```
+        
+        Other commands can be found in the `Makefile`.
+        
+        Goals
+        -----
+        - Synchronize to the latest HIBP API(s), implementing endpoint 
accessing functions where it makes sense. For instance,
+          in the interest of security, the ability to submit a SHA-1 to the 
Pwned Passwords endpoint is not implemented. See
+          "Regarding password checking" below for further details.
+        - For breaches and pastes, act as an intermediary; return the JSON as 
received from the service.
+        
+        Regarding password checking
+        ---------------------------
+        - For passwords, the option to supply a plaintext password to check is 
provided as an implementation convenience.
+        - For added security, `pwnedpasswords.is_password_breached()` only 
transmits the first five characters of the SHA-1
+          hash to the Pwned Passwords API endpoint; a secure password will 
remain secure without disclosing the full hash.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or 
later (AGPLv3+)
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Description-Content-Type: text/markdown
+Provides-Extra: dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/Pipfile new/pyhibp-3.1.0/Pipfile
--- old/pyhibp-3.0.0/Pipfile    2018-11-10 01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/Pipfile    2019-06-30 10:46:01.000000000 +0200
@@ -1,18 +1,13 @@
 [[source]]
-
 verify_ssl = true
 url = "https://pypi.python.org/simple";
 name = "pypi"
 
-
 [packages]
-
 requests = ">=2.20.0"
 six = ">=1.11.0"
 
-
 [dev-packages]
-
 tox = "*"
 pytest = "*"
 pytest-cov = "*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/README.md new/pyhibp-3.1.0/README.md
--- old/pyhibp-3.0.0/README.md  2018-11-10 01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/README.md  2019-06-30 10:46:01.000000000 +0200
@@ -8,13 +8,13 @@
 A Python interface to Troy Hunt's 'Have I Been Pwned?' (HIBP) public API. A 
full reference to the API
 specification can be found at the [HIBP API 
Reference](https://haveibeenpwned.com/API/v2).
 
-This module detects when the rate limit of the API has been hit, and raises a 
RuntimeError when the limit is exceeded,
-or when another API-defined error condition is encountered based on the 
submitted data. Calls
-to the module returning Boolean `True` or the object as decoded from the API 
query (currently, lists), represent
-a detection that a breached account/paste/password was found; Boolean `False` 
means that the item was not found.
+This module detects when the rate limit of the API has been hit, and raises a 
RuntimeError when the limit
+is exceeded, or when another API-defined error condition is encountered based 
on the submitted data. When
+data is found from a call, the data returned will be in the format as 
retrieved from the endpoint, documented
+in the return-type information for the relevant function.
 
 Note that the `pwnedpasswords` API backend does not have a rate limit. If you 
are intending to bulk-query passwords or
-hashes, you may also consider downloading the raw data files accessible via 
the [Pwned Passwords](https://haveibeenpwned.com/Passwords) page.
+hashes, you should consider downloading the raw data files accessible via the 
[Pwned Passwords](https://haveibeenpwned.com/Passwords) page.
 
 Installing
 ----------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/setup.cfg new/pyhibp-3.1.0/setup.cfg
--- old/pyhibp-3.0.0/setup.cfg  2018-11-10 02:56:39.000000000 +0100
+++ new/pyhibp-3.1.0/setup.cfg  2019-06-30 11:17:16.000000000 +0200
@@ -1,11 +1,11 @@
-[bdist_wheel]
-universal = 1
-
-[flake8]
-exclude = .git
-ignore = E501
-
-[egg_info]
-tag_build = 
-tag_date = 0
-
+[bdist_wheel]
+universal = 1
+
+[flake8]
+exclude = .git
+ignore = E501
+
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/src/pyhibp/__init__.py 
new/pyhibp-3.1.0/src/pyhibp/__init__.py
--- old/pyhibp-3.0.0/src/pyhibp/__init__.py     2018-11-10 02:28:07.000000000 
+0100
+++ new/pyhibp-3.1.0/src/pyhibp/__init__.py     2019-06-30 10:46:01.000000000 
+0200
@@ -23,6 +23,7 @@
     :param response: The response object from a call to `requests`
     :return: True if HTTP Status 200, False if 404. Raises RuntimeError on 
API-defined status codes of
     400, 403, 429; NotImplementedError if the API returns an unexpected HTTP 
status code.
+    :rtype: bool
     """
     if response.status_code == 200:
         # The request was successful (we found an item)
@@ -52,14 +53,15 @@
     Gets breaches for a specified account from the HIBP system, optionally 
restricting the returned results
     to a specified domain.
 
-    :param account: The user's account name (such as an email address or a 
user-name). Default None.
-    :param domain: The domain to check for breaches. Default None.
+    :param account: The user's account name (such as an email address or a 
user-name). Default None. `str` type.
+    :param domain: The domain to check for breaches. Default None. `str` type.
     :param truncate_response: If ``account`` is specified, truncates the 
response down to the breach names.
-    Default False.
-    :param include_unverified: If set to True, unverified breaches are 
included in the result. Default False.
+    Default False. `bool` type.
+    :param include_unverified: If set to True, unverified breaches are 
included in the result. Default False. `bool` type
     :return: A list object containing one or more dict objects, based on the 
information being requested,
     provided there was matching information. Boolean False returned if no 
information was found according to
     the HIBP API.
+    :rtype: list
     """
     # Account/Domain don't need to be specified, but they must be text if so.
     if account is None or not isinstance(account, six.string_types):
@@ -80,6 +82,7 @@
     if _process_response(response=resp):
         return resp.json()
     else:
+        # TODO: v4.0.0: return []
         return False
 
 
@@ -87,9 +90,10 @@
     """
     Returns a listing of all sites breached in the HIBP database.
 
-    :param domain: Optional, default None. If specified, get all breaches for 
the domain with the specified name.
+    :param domain: Optional, default None. If specified, get all breaches for 
the domain with the specified name. `str` type.
     :return: A list object containing one or more dict objects if breaches are 
present. Returns Boolean False
     if ``domain`` is specified, but the resultant list would be length zero.
+    :rtype: list
     """
     if domain is not None and not isinstance(domain, six.string_types):
         raise AttributeError("The domain parameter, if specified, must be a 
string.")
@@ -101,6 +105,7 @@
     if _process_response(response=resp) and len(resp.json()) > 0:
         return resp.json()
     else:
+        # TODO: v4.0.0: return []
         return False
 
 
@@ -108,9 +113,10 @@
     """
     Returns a single breach's information from the HIBP's database.
 
-    :param breach_name: The breach to retrieve. Required.
+    :param breach_name: The breach to retrieve. Required. `str` type.
     :return: A dict object containing the information for the specified breach 
name, if it exists in the HIBP
     database. Boolean False is returned if the specified breach was not found.
+    :rtype: dict
     """
     if not isinstance(breach_name, six.string_types):
         raise AttributeError("The breach_name must be specified, and be a 
string.")
@@ -120,6 +126,7 @@
     if _process_response(response=resp):
         return resp.json()
     else:
+        # TODO: v4.0.0: return {}
         return False
 
 
@@ -127,9 +134,10 @@
     """
     Retrieve all pastes for a specified email address.
 
-    :param email_address: The email address to search. Required.
+    :param email_address: The email address to search. Required. `str` type.
     :return: A list object containing one or more dict objects corresponding 
to the pastes the specified email
     address was found in. Boolean False returned if no pastes are detected for 
the given account.
+    :rtype: list
     """
     if not isinstance(email_address, six.string_types):
         raise AttributeError("The email address supplied must be provided, and 
be a string.")
@@ -139,6 +147,7 @@
     if _process_response(response=resp):
         return resp.json()
     else:
+        # TODO: v4.0.0: return []
         return False
 
 
@@ -148,6 +157,7 @@
 
     :return: A list object containing available data classes, corresponding to 
attributes found in breaches.
     A given breach will have one or more of the data classes in the list.
+    :rtype: list
     """
     uri = HIBP_API_BASE_URI + HIBP_API_ENDPOINT_DATA_CLASSES
     resp = requests.get(url=uri, headers=pyHIBP_HEADERS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/src/pyhibp/__version__.py 
new/pyhibp-3.1.0/src/pyhibp/__version__.py
--- old/pyhibp-3.0.0/src/pyhibp/__version__.py  2018-11-10 02:40:10.000000000 
+0100
+++ new/pyhibp-3.1.0/src/pyhibp/__version__.py  2019-06-30 11:09:11.000000000 
+0200
@@ -4,5 +4,5 @@
 # |)\/| |||)|
 # | /
 
-__version__ = '3.0.0'
+__version__ = '3.1.0'
 __url__ = 'https://gitlab.com/kitsunix/pyHIBP/pyHIBP'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/src/pyhibp/pwnedpasswords.py 
new/pyhibp-3.1.0/src/pyhibp/pwnedpasswords.py
--- old/pyhibp-3.0.0/src/pyhibp/pwnedpasswords.py       2018-11-10 
01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/src/pyhibp/pwnedpasswords.py       2019-06-30 
10:46:02.000000000 +0200
@@ -1,4 +1,5 @@
 import hashlib
+import warnings
 
 import requests
 import six
@@ -20,29 +21,26 @@
     number of times that hash appears in the data set. In doing so, the API is 
not provided the information
     required to reconstruct the password (e.g., by brute-forcing the hash).
 
-    Either ```password``, `first_5_hash_chars``, or ``sha1_hash`` must be 
specified. Only one parameter should be provided.
+    Either ```password`` or ``sha1_hash`` must be specified. Only one 
parameter should be provided.
 
     The precedence of parameters is as follows:
-    1) password - Computes the remaining two parameters.
-    2) sha1_hash - Computes the following parameter, and will determine if a 
match was found.
-    3) first_5_hash_chars - Returns a list of partial hashes for the calling 
application to process.
-
-    If ``password`` is provided,
-    the password will be converted to a SHA-1 hash, then the first five 
characters checked against the API's returned
-    information, much like as if a full `sha1_hash` were supplied.
-
-    Suffix example: 0018A45C4D1DEF81644B54AB7F969B88D65:1
-
-    :param password: The password to check. Will be converted to a SHA-1 
string.
-    :param first_5_hash_chars: The first five characters of a SHA-1 hash 
string.
-    :param sha1_hash: A full SHA-1 hash.
-    :return: If ``first_5_hash_chars`` is supplied, a [list] of hash suffixes. 
If ``password`` or ``sha1_hash`` is supplied,
-    and the password was found in the corpus, an Integer representing the 
number of times the password is in
-    the data set; if not found, Integer zero (0) is returned.
+    1) password - Used to compute the SHA-1 hash of the password.
+    2) sha1_hash - The hash prefix (hash[0:5]) is passed to the HIBP API, and 
this function will check the returned list of
+    hash suffixes to determine if a breached password was in the HIBP database.
+
+    Note: Suffix searches, that is, to retrieve a list of hash suffixes by 
supplying a hash prefix, have moved to
+    `suffix_search()` as of this release (v3.1.0). A compatability shim has 
been left for this release, but will be removed on the
+    next major version release.
+
+    :param password: The password to check. Will be converted to a SHA-1 
string. `str` type.
+    :param sha1_hash: A full SHA-1 hash. `str` type.
+    :return: An Integer representing the number of times the password is in 
the data set; if not found,
+    Integer zero (0) is returned.
+    :rtype: int
     """
     # Parameter validation section
     if not any([password, first_5_hash_chars, sha1_hash]):
-        raise AttributeError("One of password, first_5_hash_chars, or 
sha1_hash must be provided.")
+        raise AttributeError("One of password, sha1_hash, or 
first_5_hash_chars must be provided.")
     elif password is not None and not isinstance(password, six.string_types):
         raise AttributeError("password must be a string type.")
     elif sha1_hash is not None and not isinstance(sha1_hash, six.string_types):
@@ -59,27 +57,66 @@
         sha1_hash = sha1_hash.upper()
         first_5_hash_chars = sha1_hash[0:5]
 
-    uri = PWNED_PASSWORDS_API_BASE_URI + 
PWNED_PASSWORDS_API_ENDPOINT_RANGE_SEARCH + first_5_hash_chars
+    suffix_list = suffix_search(hash_prefix=first_5_hash_chars)
 
-    resp = requests.get(url=uri, headers=pyhibp.pyHIBP_HEADERS)
-
-    # The server response will have a BOM if we don't do this.
-    resp.encoding = RESPONSE_ENCODING
-
-    if resp.status_code != 200:
-        # The HTTP Status should always be 200 for this request
-        raise RuntimeError("Response from the endpoint was not HTTP200; this 
should not happen. Code was: {0}".format(resp.status_code))
-    elif not sha1_hash:
+    if not sha1_hash:
+        # TODO: v4.0.0: Remove this codepath (first_5_hash_chars)
+        warnings.warn("""
+            Hash suffix searching is being moved to its own discrete function, 
`suffix_search()`. Call `suffix_search(hash_prefix=prefix)`
+            instead. Hash prefixes will not return from is_password_breached() 
in a future release.
+        """)
         # Return the list of hash suffixes.
-        return resp.text.split()
+        return suffix_list
     else:
         # Since the full SHA-1 hash was provided, check to see if it was in 
the resultant hash suffixes returned.
-        response_lines = resp.text.split()
-
-        for hash_suffix in response_lines:
+        for hash_suffix in suffix_list:
             if sha1_hash[5:] in hash_suffix:
                 # We found the full hash, so return
                 return int(hash_suffix.split(':')[1])
 
         # If we get here, there was no match to the supplied SHA-1 hash; 
return zero.
         return 0
+
+
+def suffix_search(hash_prefix=None):
+    """
+    Returns a list of SHA-1 hash suffixes, consisting of the SHA-1 hash 
characters after position five,
+    and the number of times that password hash was found in the HIBP database, 
colon separated.
+
+    Leveraging the k-Anonymity model, a list of hashes matching a specified 
SHA-1 prefix are returned.
+    From this list, the calling application may determine if a given password 
was breached by comparing
+    the remainder of the SHA-1 hash against the returned results. As an 
example, for the hash prefix of
+    '42042', the hash suffixes would be:
+
+    ```
+    005F4A4B9265A2BABE10B1A9AB9409EA3F0:1
+    00D6F0319225107BD5736B72717BD381660:8
+    01355DCE0B54F0E8DBBBA8F7B9A9872858A:15
+    0163E1C872A64A62625F5EB2F3807B7F90B:2
+    020DDE278E6A9C05B356C929F254CE6AED5:1
+    021EFB4FAE348050D9EDCD10F8B6A87C957:4
+    ...
+    ```
+
+    If the `prefix` and `suffix` form a complete SHA-1 hash for the password 
being compared, then it
+    indicates the password has been found in the HIBP database.
+
+    :param hash_prefix: The first five characters of a SHA-1 hash. `str` type.
+    :return: A list of hash suffixes.
+    :rtype: list
+    """
+    if not hash_prefix or not isinstance(hash_prefix, six.string_types):
+        raise AttributeError("hash_prefix must be a supplied, and be a 
string-type.")
+    if hash_prefix and len(hash_prefix) != 5:
+        raise AttributeError("hash_prefix must be of length 5.")
+
+    uri = PWNED_PASSWORDS_API_BASE_URI + 
PWNED_PASSWORDS_API_ENDPOINT_RANGE_SEARCH + hash_prefix
+
+    resp = requests.get(url=uri, headers=pyhibp.pyHIBP_HEADERS)
+    if resp.status_code != 200:
+        # The HTTP Status should always be 200 for this request
+        raise RuntimeError("Response from the endpoint was not HTTP200; this 
should not happen. Code was: {0}".format(resp.status_code))
+    # The server response will have a BOM if we don't do this.
+    resp.encoding = RESPONSE_ENCODING
+
+    return resp.text.split()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/src/pyhibp.egg-info/PKG-INFO 
new/pyhibp-3.1.0/src/pyhibp.egg-info/PKG-INFO
--- old/pyhibp-3.0.0/src/pyhibp.egg-info/PKG-INFO       2018-11-10 
02:56:39.000000000 +0100
+++ new/pyhibp-3.1.0/src/pyhibp.egg-info/PKG-INFO       2019-06-30 
11:17:15.000000000 +0200
@@ -1,102 +1,102 @@
-Metadata-Version: 2.1
-Name: pyhibp
-Version: 3.0.0
-Summary: An interface to Troy Hunt's 'Have I Been Pwned' public API
-Home-page: https://gitlab.com/kitsunix/pyHIBP/pyHIBP
-Author: Kyra F. Kitsune
-License: UNKNOWN
-Description: pyHIBP (pyHave I Been Pwned)
-        ============================
-        
[![image](https://img.shields.io/pypi/v/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
-        
[![image](https://img.shields.io/pypi/l/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
-        
[![image](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master)
-        
-        
-        A Python interface to Troy Hunt's 'Have I Been Pwned?' (HIBP) public 
API. A full reference to the API
-        specification can be found at the [HIBP API 
Reference](https://haveibeenpwned.com/API/v2).
-        
-        This module detects when the rate limit of the API has been hit, and 
raises a RuntimeError when the limit is exceeded,
-        or when another API-defined error condition is encountered based on 
the submitted data. Calls
-        to the module returning Boolean `True` or the object as decoded from 
the API query (currently, lists), represent
-        a detection that a breached account/paste/password was found; Boolean 
`False` means that the item was not found.
-        
-        Note that the `pwnedpasswords` API backend does not have a rate limit. 
If you are intending to bulk-query passwords or
-        hashes, you may also consider downloading the raw data files 
accessible via the [Pwned Passwords](https://haveibeenpwned.com/Passwords) page.
-        
-        Installing
-        ----------
-        ```bash
-        $ pip install pyhibp
-        ```
-        
-        Example usage
-        -------------
-        For an interactive example, check out the Jupyter Notebook for 
[`pyhibp`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.ipynb),
-        as well as 
[`pyhibp.pwnedpasswords`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.pwnedpasswords.ipynb).
-        
-        ```python
-        import pyhibp
-        from pyhibp import pwnedpasswords as pw
-        
-        # Check a password to see if it has been disclosed in a public breach 
corpus
-        resp = pw.is_password_breached(password="secret")
-        if resp:
-            print("Password breached!")
-            print("This password was used {0} time(s) before.".format(resp))
-        
-        # Get breaches that affect a given account
-        resp = pyhibp.get_account_breaches(account="[email protected]", 
truncate_response=True)
-        
-        # Get all breach information
-        resp = pyhibp.get_all_breaches()
-        
-        # Get a single breach
-        resp = pyhibp.get_single_breach(breach_name="Adobe")
-        
-        # Get pastes affecting a given email address
-        resp = pyhibp.get_pastes(email_address="[email protected]")
-        
-        # Get data classes in the HIBP system
-        resp = pyhibp.get_data_classes()
-        ```
-        
-        Developing
-        ----------
-        This project is currently intended to be compatible with Python 2 and 
Python 3. As such, we use virtual environments via `pipenv`.
-        To develop or test, execute the following:
-        
-        ```bash
-        # Install the prerequisite virtual environment provider
-        $ pip install pipenv
-        # Initialize the pipenv environment and install the module within it
-        $ make dev
-        # To run PEP8, tests, and check the manifest
-        $ make tox
-        ```
-        
-        Other commands can be found in the `Makefile`.
-        
-        Goals
-        -----
-        - Synchronize to the latest HIBP API(s), implementing endpoint 
accessing functions where it makes sense. For instance,
-          in the interest of security, the ability to submit a SHA-1 to the 
Pwned Passwords endpoint is not implemented. See
-          "Regarding password checking" below for further details.
-        - For breaches and pastes, act as an intermediary; return the JSON as 
received from the service.
-        
-        Regarding password checking
-        ---------------------------
-        - For passwords, the option to supply a plaintext password to check is 
provided as an implementation convenience.
-        - For added security, `pwnedpasswords.is_password_breached()` only 
transmits the first five characters of the SHA-1
-          hash to the Pwned Passwords API endpoint; a secure password will 
remain secure without disclosing the full hash.
-        
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or 
later (AGPLv3+)
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.5
-Description-Content-Type: text/markdown
-Provides-Extra: dev
+Metadata-Version: 2.1
+Name: pyhibp
+Version: 3.1.0
+Summary: An interface to Troy Hunt's 'Have I Been Pwned' public API
+Home-page: https://gitlab.com/kitsunix/pyHIBP/pyHIBP
+Author: Kyra F. Kitsune
+License: UNKNOWN
+Description: pyHIBP (pyHave I Been Pwned)
+        ============================
+        
[![image](https://img.shields.io/pypi/v/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
+        
[![image](https://img.shields.io/pypi/l/pyHIBP.svg)](https://pypi.org/project/pyHIBP/)
+        
[![image](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master)
+        
+        
+        A Python interface to Troy Hunt's 'Have I Been Pwned?' (HIBP) public 
API. A full reference to the API
+        specification can be found at the [HIBP API 
Reference](https://haveibeenpwned.com/API/v2).
+        
+        This module detects when the rate limit of the API has been hit, and 
raises a RuntimeError when the limit
+        is exceeded, or when another API-defined error condition is 
encountered based on the submitted data. When
+        data is found from a call, the data returned will be in the format as 
retrieved from the endpoint, documented
+        in the return-type information for the relevant function.
+        
+        Note that the `pwnedpasswords` API backend does not have a rate limit. 
If you are intending to bulk-query passwords or
+        hashes, you should consider downloading the raw data files accessible 
via the [Pwned Passwords](https://haveibeenpwned.com/Passwords) page.
+        
+        Installing
+        ----------
+        ```bash
+        $ pip install pyhibp
+        ```
+        
+        Example usage
+        -------------
+        For an interactive example, check out the Jupyter Notebook for 
[`pyhibp`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.ipynb),
+        as well as 
[`pyhibp.pwnedpasswords`](https://mybinder.org/v2/gl/kitsunix%2FpyHIBP%2FpyHIBP-binder/master?filepath=/pyHIBP.pwnedpasswords.ipynb).
+        
+        ```python
+        import pyhibp
+        from pyhibp import pwnedpasswords as pw
+        
+        # Check a password to see if it has been disclosed in a public breach 
corpus
+        resp = pw.is_password_breached(password="secret")
+        if resp:
+            print("Password breached!")
+            print("This password was used {0} time(s) before.".format(resp))
+        
+        # Get breaches that affect a given account
+        resp = pyhibp.get_account_breaches(account="[email protected]", 
truncate_response=True)
+        
+        # Get all breach information
+        resp = pyhibp.get_all_breaches()
+        
+        # Get a single breach
+        resp = pyhibp.get_single_breach(breach_name="Adobe")
+        
+        # Get pastes affecting a given email address
+        resp = pyhibp.get_pastes(email_address="[email protected]")
+        
+        # Get data classes in the HIBP system
+        resp = pyhibp.get_data_classes()
+        ```
+        
+        Developing
+        ----------
+        This project is currently intended to be compatible with Python 2 and 
Python 3. As such, we use virtual environments via `pipenv`.
+        To develop or test, execute the following:
+        
+        ```bash
+        # Install the prerequisite virtual environment provider
+        $ pip install pipenv
+        # Initialize the pipenv environment and install the module within it
+        $ make dev
+        # To run PEP8, tests, and check the manifest
+        $ make tox
+        ```
+        
+        Other commands can be found in the `Makefile`.
+        
+        Goals
+        -----
+        - Synchronize to the latest HIBP API(s), implementing endpoint 
accessing functions where it makes sense. For instance,
+          in the interest of security, the ability to submit a SHA-1 to the 
Pwned Passwords endpoint is not implemented. See
+          "Regarding password checking" below for further details.
+        - For breaches and pastes, act as an intermediary; return the JSON as 
received from the service.
+        
+        Regarding password checking
+        ---------------------------
+        - For passwords, the option to supply a plaintext password to check is 
provided as an implementation convenience.
+        - For added security, `pwnedpasswords.is_password_breached()` only 
transmits the first five characters of the SHA-1
+          hash to the Pwned Passwords API endpoint; a secure password will 
remain secure without disclosing the full hash.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or 
later (AGPLv3+)
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Description-Content-Type: text/markdown
+Provides-Extra: dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/test/conftest.py 
new/pyhibp-3.1.0/test/conftest.py
--- old/pyhibp-3.0.0/test/conftest.py   2018-11-10 01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/test/conftest.py   2019-06-30 10:46:02.000000000 +0200
@@ -1,3 +1,5 @@
+import time
+
 import pytest
 
 import pyhibp
@@ -7,3 +9,16 @@
 def dev_user_agent(monkeypatch):
     ua_string = pyhibp.pyHIBP_USERAGENT
     monkeypatch.setattr(pyhibp, 'pyHIBP_USERAGENT', ua_string + " (Testing 
Suite)")
+
+
[email protected](name="sleep")
+def sleep_test(request):
+    """
+    For the endpoints where a rate limit is specified, or we want to be kind 
to the endpoint and not
+    needlessly execute requests too quickly, this specifies a test 
module-configurable sleep duration.
+
+    Usage: Specify a module-level variable named `_PYTEST_SLEEP_DURATION`, and 
the value is an int,
+    specifying the number of seconds to sleep between test invocations.
+    """
+    sleep_duration = getattr(request.module, "_PYTEST_SLEEP_DURATION", 0)
+    time.sleep(sleep_duration)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/test/test_pwnedpasswords.py 
new/pyhibp-3.1.0/test/test_pwnedpasswords.py
--- old/pyhibp-3.0.0/test/test_pwnedpasswords.py        2018-11-10 
01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/test/test_pwnedpasswords.py        2019-06-30 
10:46:02.000000000 +0200
@@ -1,10 +1,11 @@
 import hashlib
-import time
 
 import pytest
 
 from pyhibp import pwnedpasswords as pw
 
+# While the pwnedpasswords endpoint does not have a limit, be kind anyway. 1 
second sleep.
+_PYTEST_SLEEP_DURATION = 1
 
 TEST_PASSWORD = "password"
 TEST_PASSWORD_SHA1_HASH = 
hashlib.sha1(TEST_PASSWORD.encode('utf-8')).hexdigest()
@@ -13,18 +14,12 @@
 TEST_PASSWORD_LIKELY_NOT_COMPROMISED_HASH = 
hashlib.sha1(TEST_PASSWORD_LIKELY_NOT_COMPROMISED.encode('utf-8')).hexdigest()
 
 
[email protected](autouse=True)
-def rate_limit():
-    # There's no rate limit on passwords, but be nice anyway.
-    time.sleep(1)
-
-
 class TestIsPasswordBreached(object):
     def test_no_params_provided_raises(self):
         # is_password_breached(password=None, first_5_hash_chars=None, 
sha1_hash=None):
         with pytest.raises(AttributeError) as execinfo:
             pw.is_password_breached()
-        assert "One of password, first_5_hash_chars, or sha1_hash must be 
provided." in str(execinfo.value)
+        assert "One of password, sha1_hash, or first_5_hash_chars must be 
provided." in str(execinfo.value)
 
     def test_password_not_string_raises(self):
         # is_password_breached(password=123, first_5_hash_chars=None, 
sha1_hash=None):
@@ -33,12 +28,14 @@
         assert "password must be a string type." in str(execinfo.value)
 
     def test_first_5_hash_chars_not_string_raises(self):
+        # TODO: Deprecated: To be removed in next major release in favor of 
pw.suffix_search()
         # is_password_breached(password=None, first_5_hash_chars=123, 
sha1_hash=None):
         with pytest.raises(AttributeError) as execinfo:
             pw.is_password_breached(first_5_hash_chars=123)
         assert "first_5_hash_chars must be a string type." in 
str(execinfo.value)
 
     def test_first_5_hash_chars_not_length_five_raises(self):
+        # TODO: Deprecated: To be removed in next major release in favor of 
pw.suffix_search()
         # is_password_breached(password=None, first_5_hash_chars="123456", 
sha1_hash=None):
         with pytest.raises(AttributeError) as execinfo:
             pw.is_password_breached(first_5_hash_chars="123456")
@@ -50,7 +47,9 @@
             pw.is_password_breached(sha1_hash=123)
         assert "sha1_hash must be a string type." in str(execinfo.value)
 
+    @pytest.mark.usefixtures('sleep')
     def test_list_of_partial_hashes_returned_with_5chars(self):
+        # TODO: Deprecated: To be removed in next major release in favor of 
pw.suffix_search()
         # is_password_breached(password=None, 
first_5_hash_chars=TEST_PASSWORD_SHA1_HASH[0:5], sha1_hash=None):
         resp = 
pw.is_password_breached(first_5_hash_chars=TEST_PASSWORD_SHA1_HASH[0:5])
         assert isinstance(resp, list)
@@ -62,11 +61,13 @@
                 break
         assert match_found
 
+    @pytest.mark.usefixtures('sleep')
     def test_provide_password_to_function(self):
         resp = pw.is_password_breached(password="password")
         assert isinstance(resp, int)
         assert resp > 100
 
+    @pytest.mark.usefixtures('sleep')
     def test_ensure_case_sensitivity_of_hash_does_not_matter(self):
         resp_one = 
pw.is_password_breached(sha1_hash=TEST_PASSWORD_SHA1_HASH.lower())
         assert isinstance(resp_one, int)
@@ -78,7 +79,44 @@
 
         assert resp_one == resp_two
 
+    @pytest.mark.usefixtures('sleep')
     def test_zero_count_result_for_non_breached_password(self):
         resp = 
pw.is_password_breached(password=TEST_PASSWORD_LIKELY_NOT_COMPROMISED)
         assert isinstance(resp, int)
         assert resp == 0
+
+
+class TestSuffixSearch(object):
+    def test_no_param_provided_raises(self):
+        # def suffix_search(hash_prefix=None):
+        with pytest.raises(AttributeError) as execinfo:
+            pw.suffix_search()
+        assert "hash_prefix must be a supplied, and be a string-type." in 
str(execinfo.value)
+
+    def test_hash_prefix_not_string_raises(self):
+        # def suffix_search(hash_prefix=123):
+        with pytest.raises(AttributeError) as execinfo:
+            pw.suffix_search(hash_prefix=123)
+        assert "hash_prefix must be a supplied, and be a string-type." in 
str(execinfo.value)
+
+    def test_first_5_hash_chars_not_length_five_raises(self):
+        # suffix_search(hash_prefix="123456"):
+        with pytest.raises(AttributeError) as execinfo:
+            pw.suffix_search(hash_prefix="123456")
+        assert "hash_prefix must be of length 5." in str(execinfo.value)
+
+    @pytest.mark.usefixtures('sleep')
+    def test_list_of_hashes_returned(self):
+        """
+        Test all parameters: The response format for all parameters is the 
same.
+        """
+        resp = pw.suffix_search(hash_prefix=TEST_PASSWORD_SHA1_HASH[0:5])
+
+        assert isinstance(resp, list)
+        assert len(resp) > 100
+        match_found = False
+        for entry in resp:
+            if TEST_PASSWORD_SHA1_HASH[5:] in entry.lower():
+                match_found = True
+                break
+        assert match_found
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/test/test_pyHIBP.py 
new/pyhibp-3.1.0/test/test_pyHIBP.py
--- old/pyhibp-3.0.0/test/test_pyHIBP.py        2018-11-10 01:39:46.000000000 
+0100
+++ new/pyhibp-3.1.0/test/test_pyHIBP.py        2019-06-30 10:46:02.000000000 
+0200
@@ -1,4 +1,3 @@
-import time
 import uuid
 
 import pytest
@@ -6,6 +5,9 @@
 import pyhibp
 
 
+# The breach/paste endpoints enforce a 1500 ms rate limit; so sleep 2 seconds.
+_PYTEST_SLEEP_DURATION = 2
+
 TEST_ACCOUNT = "[email protected]"
 TEST_DOMAIN = "adobe.com"
 TEST_DOMAIN_NAME = "Adobe"
@@ -13,13 +15,8 @@
 TEST_NONEXISTENT_ACCOUNT_NAME = "353e8061f2befecb6818ba0c034c632fb0bcae1b"
 
 
[email protected](autouse=True)
-def rate_limit():
-    # The HIBP API has a rate-limit of 1500ms. Sleep for 2 seconds between 
each test.
-    time.sleep(2)
-
-
-class TestGetBreaches(object):
+class TestGetAccountBreaches(object):
+    @pytest.mark.usefixtures('sleep')
     def test_get_breaches_account(self):
         # get_account_breaches(account=TEST_ACCOUNT, domain=None, 
truncate_response=False, include_unverified=False):
         resp = pyhibp.get_account_breaches(account=TEST_ACCOUNT)
@@ -28,6 +25,7 @@
         assert len(resp) >= 20
         assert isinstance(resp[0], dict)
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_breaches_account_with_domain(self):
         # get_account_breaches(account=TEST_ACCOUNT, domain=TEST_DOMAIN, 
truncate_response=False, include_unverified=False):
         resp = pyhibp.get_account_breaches(account=TEST_ACCOUNT, 
domain=TEST_DOMAIN)
@@ -37,6 +35,7 @@
         assert isinstance(resp[0], dict)
         assert resp[0]['Name'] == TEST_DOMAIN_NAME
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_breaches_account_with_truncation(self):
         # get_account_breaches(account=TEST_ACCOUNT, domain=None, 
truncate_response=True, include_unverified=False):
         resp = pyhibp.get_account_breaches(account=TEST_ACCOUNT, 
truncate_response=True)
@@ -49,6 +48,7 @@
         assert 'Name' in item
         assert 'DataClasses' not in item
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_breaches_retrieve_all_breaches_with_unverified(self):
         # get_account_breaches(account=TEST_ACCOUNT, domain=None, 
truncate_response=False, include_unverified=True):
         resp = pyhibp.get_account_breaches(account=TEST_ACCOUNT, 
include_unverified=True)
@@ -62,11 +62,15 @@
                 break
         assert has_unverified
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_breaches_return_false_if_no_accounts(self):
         # get_account_breaches(account=TEST_PASSWORD_SHA1_HASH, domain=None, 
truncate_response=False, include_unverified=False):
         resp = 
pyhibp.get_account_breaches(account=TEST_NONEXISTENT_ACCOUNT_NAME)
         assert not resp
         assert isinstance(resp, bool)
+        # TODO: v4.0.0:
+        # assert not resp
+        # assert isinstance(resp, list)
 
     def test_get_breaches_raise_if_account_is_not_specified(self):
         # get_account_breaches(account=1, domain=None, 
truncate_response=False, include_unverified=False):
@@ -91,6 +95,7 @@
 
 
 class TestGetAllBreaches(object):
+    @pytest.mark.usefixtures('sleep')
     def test_get_all_breaches(self):
         # def get_all_breaches(domain=None):
         resp = pyhibp.get_all_breaches()
@@ -98,6 +103,7 @@
         assert len(resp) > 50
         assert isinstance(resp[0], dict)
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_all_breaches_filter_to_domain(self):
         # def get_all_breaches(domain=TEST_DOMAIN):
         resp = pyhibp.get_all_breaches(domain=TEST_DOMAIN)
@@ -107,10 +113,14 @@
         assert isinstance(resp[0], dict)
         assert resp[0]['Name'] == TEST_DOMAIN_NAME
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_all_breaches_false_if_domain_does_not_exist(self):
         resp = pyhibp.get_all_breaches(domain=TEST_NONEXISTENT_ACCOUNT_NAME)
         assert not resp
         assert isinstance(resp, bool)
+        # TODO: v4.0.0:
+        # assert not resp
+        # assert isinstance(resp, list)
 
     def test_get_all_breaches_raise_if_not_string(self):
         # def get_all_breaches(domain=1):
@@ -121,17 +131,22 @@
 
 
 class TestGetSingleBreach(object):
+    @pytest.mark.usefixtures('sleep')
     def test_get_single_breach(self):
         # get_single_breach(breach_name=TEST_DOMAIN_NAME)
         resp = pyhibp.get_single_breach(breach_name=TEST_DOMAIN_NAME)
         assert isinstance(resp, dict)
         assert resp['Name'] == TEST_DOMAIN_NAME
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_single_breach_when_breach_does_not_exist(self):
         # get_single_breach(breach_name="ThisShouldNotExist")
         resp = pyhibp.get_single_breach(breach_name="ThisShouldNotExist")
         # Boolean False will be returned from the above (as there is no breach 
named what we gave it).
         assert not resp
+        # TODO: v4.0.0:
+        # assert not resp
+        # assert isinstance(resp, dict)
 
     def test_get_single_breach_raise_when_breach_name_not_specified(self):
         # get_single_breach()
@@ -149,6 +164,7 @@
 
 
 class TestGetPastes(object):
+    @pytest.mark.usefixtures('sleep')
     def test_get_pastes(self):
         # get_pastes(email_address=TEST_ACCOUNT):
         resp = pyhibp.get_pastes(email_address=TEST_ACCOUNT)
@@ -162,7 +178,11 @@
         resp = pyhibp.get_pastes(email_address=TEST_NONEXISTENT_ACCOUNT_NAME + 
"@example.invalid")
         assert not resp
         assert isinstance(resp, bool)
+        # TODO: v4.0.0:
+        # assert not resp
+        # assert isinstance(resp, list)
 
+    @pytest.mark.usefixtures('sleep')
     def test_get_pastes_raise_if_email_not_specified(self):
         # get_pastes():
         with pytest.raises(AttributeError) as excinfo:
@@ -177,6 +197,7 @@
 
 
 class TestGetDataClasses(object):
+    @pytest.mark.usefixtures('sleep')
     def test_get_data_classes(self):
         # get_data_classes():
         resp = pyhibp.get_data_classes()
@@ -187,6 +208,7 @@
 
 class TestMiscellaneous(object):
     @pytest.mark.xfail(reason="The rate limit exists in the API docs, but 
responses are cached, and even attempting to manually (via browser) hit the 
limit isn't happening.")
+    @pytest.mark.usefixtures('sleep')
     def test_raise_if_rate_limit_exceeded(self):
         """ The API will respond the same to all exceeded rate limits across 
all endpoints """
         # The rate limit exists, however all responses are cached; so we need 
to generate some random "accounts".
@@ -197,6 +219,7 @@
                 pyhibp.get_account_breaches(account=item, 
truncate_response=True)
         assert "HTTP 429" in str(excinfo.value)
 
+    @pytest.mark.usefixtures('sleep')
     def test_raise_if_useragent_is_not_set(self, monkeypatch):
         # This should never be encountered normally, since we have the 
module-level variable/constant;
         # That said, test it, since we can, and since we might as well cover 
the line of code.
@@ -206,6 +229,7 @@
             
pyhibp.get_account_breaches(account="{0}@test-suite.pyhibp.example.com".format(str(uuid.uuid4())))
         assert "HTTP 403" in str(excinfo.value)
 
+    @pytest.mark.usefixtures('sleep')
     def test_raise_if_invalid_format_submitted(self):
         # For example, if a null (0x00) character is submitted to an endpoint.
         with pytest.raises(RuntimeError) as execinfo:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyhibp-3.0.0/tox.ini new/pyhibp-3.1.0/tox.ini
--- old/pyhibp-3.0.0/tox.ini    2018-11-10 01:39:46.000000000 +0100
+++ new/pyhibp-3.1.0/tox.ini    2019-06-30 10:46:02.000000000 +0200
@@ -1,11 +1,12 @@
 [tox]
-envlist = py{27,35,36}
+envlist = py{27,35,36,37}
 
 [testenv]
 basepython =
     py27: python2.7
     py35: python3.5
     py36: python3.6
+    py37: python3.7
 passenv =
     TOXENV
     PIP_CACHE_DIR


Reply via email to