move MACContext to mac.py and eliminate interfaces.py (#3631)

* move MACContext to mac.py and eliminate interfaces.py finally

* improve title

* re-add and deprecate interfaces.MACContext

* use pytest.warns instead of deprecated_call

The pytest docs insist that deprecation warnings are handled differently
and that you should use deprecated_call, but this works so okay then
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index acb1862..f8aaa2b 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -539,7 +539,7 @@
 * Added
   :func:`~cryptography.hazmat.primitives.asymmetric.rsa.rsa_recover_prime_factors`
 * :class:`~cryptography.hazmat.primitives.kdf.KeyDerivationFunction` was moved
-  from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.kdf`.
 * Added support for parsing X.509 names. See the
   :doc:`X.509 documentation</x509/index>` for more information.
@@ -593,33 +593,33 @@
   :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKeyWithSerialization`.
 * :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` and
   :class:`~cryptography.hazmat.primitives.hashes.HashContext` were moved from
-  :mod:`~cryptography.hazmat.primitives.interfaces` to
+  ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.hashes`.
 * :class:`~cryptography.hazmat.primitives.ciphers.CipherContext`,
   :class:`~cryptography.hazmat.primitives.ciphers.AEADCipherContext`,
   :class:`~cryptography.hazmat.primitives.ciphers.AEADEncryptionContext`,
   :class:`~cryptography.hazmat.primitives.ciphers.CipherAlgorithm`, and
   :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm`
-  were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  were moved from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.ciphers`.
 * :class:`~cryptography.hazmat.primitives.ciphers.modes.Mode`,
   :class:`~cryptography.hazmat.primitives.ciphers.modes.ModeWithInitializationVector`,
   :class:`~cryptography.hazmat.primitives.ciphers.modes.ModeWithNonce`, and
   :class:`~cryptography.hazmat.primitives.ciphers.modes.ModeWithAuthenticationTag`
-  were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  were moved from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.ciphers.modes`.
 * :class:`~cryptography.hazmat.primitives.padding.PaddingContext` was moved
-  from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.padding`.
 *
   :class:`~cryptography.hazmat.primitives.asymmetric.padding.AsymmetricPadding`
-  was moved from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  was moved from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.asymmetric.padding`.
 *
   :class:`~cryptography.hazmat.primitives.asymmetric.AsymmetricSignatureContext`
   and
   :class:`~cryptography.hazmat.primitives.asymmetric.AsymmetricVerificationContext`
-  were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  were moved from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.asymmetric`.
 * :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAParameters`,
   :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAParametersWithNumbers`,
@@ -627,7 +627,7 @@
   ``DSAPrivateKeyWithNumbers``,
   :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey` and
   ``DSAPublicKeyWithNumbers`` were moved from
-  :mod:`~cryptography.hazmat.primitives.interfaces` to
+  ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.asymmetric.dsa`
 * :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve`,
   :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurveSignatureAlgorithm`,
@@ -635,13 +635,13 @@
   ``EllipticCurvePrivateKeyWithNumbers``,
   :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`,
   and ``EllipticCurvePublicKeyWithNumbers``
-  were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to
+  were moved from ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.asymmetric.ec`.
 * :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`,
   ``RSAPrivateKeyWithNumbers``,
   :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey` and
   ``RSAPublicKeyWithNumbers`` were moved from
-  :mod:`~cryptography.hazmat.primitives.interfaces` to
+  ``cryptography.hazmat.primitives.interfaces`` to
   :mod:`~cryptography.hazmat.primitives.asymmetric.rsa`.
 
 0.7.2 - 2015-01-16
@@ -669,7 +669,7 @@
   :class:`~cryptography.fernet.MultiFernet`.
 * More bit-lengths are now supported for ``p`` and ``q`` when loading DSA keys
   from numbers.
-* Added :class:`~cryptography.hazmat.primitives.interfaces.MACContext` as a
+* Added :class:`~cryptography.hazmat.primitives.mac.MACContext` as a
   common interface for CMAC and HMAC and deprecated ``CMACContext``.
 * Added support for encoding and decoding :rfc:`6979` signatures in
   :doc:`/hazmat/primitives/asymmetric/utils`.
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index e3c6747..4d0520f 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -159,14 +159,14 @@
     .. method:: create_cmac_ctx(algorithm)
 
         Create a
-        :class:`~cryptography.hazmat.primitives.interfaces.MACContext` that
+        :class:`~cryptography.hazmat.primitives.mac.MACContext` that
         uses the specified ``algorithm`` to calculate a message authentication code.
 
         :param algorithm: An instance of
             :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm`.
 
         :returns:
-            :class:`~cryptography.hazmat.primitives.interfaces.MACContext`
+            :class:`~cryptography.hazmat.primitives.mac.MACContext`
 
 
 .. class:: PBKDF2HMACBackend
diff --git a/docs/hazmat/primitives/index.rst b/docs/hazmat/primitives/index.rst
index cf27622..022cb9f 100644
--- a/docs/hazmat/primitives/index.rst
+++ b/docs/hazmat/primitives/index.rst
@@ -14,5 +14,4 @@
     keywrap
     asymmetric/index
     constant-time
-    interfaces
     twofactor
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
deleted file mode 100644
index d60fe18..0000000
--- a/docs/hazmat/primitives/interfaces.rst
+++ /dev/null
@@ -1,80 +0,0 @@
-.. hazmat::
-
-.. module:: cryptography.hazmat.primitives.interfaces
-
-Interfaces
-==========
-
-
-``cryptography`` uses `Abstract Base Classes`_ as interfaces to describe the
-properties and methods of most primitive constructs. Backends may also use
-this information to influence their operation. Interfaces should also be used
-to document argument and return types.
-
-.. _`Abstract Base Classes`: https://docs.python.org/3/library/abc.html
-
-
-Asymmetric interfaces
----------------------
-
-In 0.8 the asymmetric signature and verification interfaces were moved to the
-:mod:`cryptography.hazmat.primitives.asymmetric` module.
-
-In 0.8 the asymmetric padding interface was moved to the
-:mod:`cryptography.hazmat.primitives.asymmetric.padding` module.
-
-DSA
-~~~
-
-In 0.8 the DSA key interfaces were moved to the
-:mod:`cryptography.hazmat.primitives.asymmetric.dsa` module.
-
-
-RSA
-~~~
-
-In 0.8 the RSA key interfaces were moved to the
-:mod:`cryptography.hazmat.primitives.asymmetric.rsa` module.
-
-
-Elliptic Curve
-~~~~~~~~~~~~~~
-
-In 0.8 the EC key interfaces were moved to the
-:mod:`cryptography.hazmat.primitives.asymmetric.ec` module.
-
-
-Key derivation functions
-------------------------
-
-In 0.8 the key derivation function interface was moved to the
-:mod:`cryptography.hazmat.primitives.kdf` module.
-
-
-.. class:: MACContext
-
-    .. versionadded:: 0.7
-
-    .. method:: update(data)
-
-        :param bytes data: The data you want to authenticate.
-
-    .. method:: finalize()
-
-        :return: The message authentication code.
-
-    .. method:: copy()
-
-        :return: A
-            :class:`~cryptography.hazmat.primitives.interfaces.MACContext` that
-            is a copy of the current context.
-
-    .. method:: verify(signature)
-
-        :param bytes signature: The signature to verify.
-
-        :raises cryptography.exceptions.InvalidSignature: This is raised when
-            the provided signature does not match the expected signature.
-
-
-.. _`CMAC`: https://en.wikipedia.org/wiki/CMAC
diff --git a/docs/hazmat/primitives/mac/cmac.rst b/docs/hazmat/primitives/mac/cmac.rst
index e170db3..b316e4c 100644
--- a/docs/hazmat/primitives/mac/cmac.rst
+++ b/docs/hazmat/primitives/mac/cmac.rst
@@ -1,7 +1,7 @@
 .. hazmat::
 
-Cipher-based message authentication code
-========================================
+Cipher-based message authentication code (CMAC)
+===============================================
 
 .. currentmodule:: cryptography.hazmat.primitives.cmac
 
diff --git a/docs/hazmat/primitives/mac/hmac.rst b/docs/hazmat/primitives/mac/hmac.rst
index e00c4de..a0e2014 100644
--- a/docs/hazmat/primitives/mac/hmac.rst
+++ b/docs/hazmat/primitives/mac/hmac.rst
@@ -1,7 +1,7 @@
 .. hazmat::
 
-Hash-based message authentication codes
-=======================================
+Hash-based message authentication codes (HMAC)
+==============================================
 
 .. currentmodule:: cryptography.hazmat.primitives.hmac
 
diff --git a/docs/hazmat/primitives/mac/index.rst b/docs/hazmat/primitives/mac/index.rst
index 05db708..86c407c 100644
--- a/docs/hazmat/primitives/mac/index.rst
+++ b/docs/hazmat/primitives/mac/index.rst
@@ -9,6 +9,38 @@
 For more information on why HMAC is preferred, see `Use cases for CMAC vs.
 HMAC?`_
 
+HMAC and CMAC both use the ``MACContext`` interface:
+
+.. currentmodule:: cryptography.hazmat.primitives.mac
+
+.. class:: MACContext
+
+    .. versionadded:: 0.7
+
+    .. method:: update(data)
+
+        :param bytes data: The data you want to authenticate.
+
+    .. method:: finalize()
+
+        :return: The message authentication code.
+
+    .. method:: copy()
+
+        :return: A
+            :class:`~cryptography.hazmat.primitives.mac.MACContext` that
+            is a copy of the current context.
+
+    .. method:: verify(signature)
+
+        :param bytes signature: The signature to verify.
+
+        :raises cryptography.exceptions.InvalidSignature: This is raised when
+            the provided signature does not match the expected signature.
+
+
+
+.. _`CMAC`: https://en.wikipedia.org/wiki/CMAC
 .. _`Use cases for CMAC vs. HMAC?`: https://crypto.stackexchange.com/questions/15721/use-cases-for-cmac-vs-hmac
 
 .. toctree::
diff --git a/src/cryptography/hazmat/backends/openssl/cmac.py b/src/cryptography/hazmat/backends/openssl/cmac.py
index eaefc27..5919017 100644
--- a/src/cryptography/hazmat/backends/openssl/cmac.py
+++ b/src/cryptography/hazmat/backends/openssl/cmac.py
@@ -9,11 +9,11 @@
 from cryptography.exceptions import (
     InvalidSignature, UnsupportedAlgorithm, _Reasons
 )
-from cryptography.hazmat.primitives import constant_time, interfaces
+from cryptography.hazmat.primitives import constant_time, mac
 from cryptography.hazmat.primitives.ciphers.modes import CBC
 
 
-@utils.register_interface(interfaces.MACContext)
+@utils.register_interface(mac.MACContext)
 class _CMACContext(object):
     def __init__(self, backend, algorithm, ctx=None):
         if not backend.cmac_algorithm_supported(algorithm):
diff --git a/src/cryptography/hazmat/backends/openssl/hmac.py b/src/cryptography/hazmat/backends/openssl/hmac.py
index dff3742..ea83420 100644
--- a/src/cryptography/hazmat/backends/openssl/hmac.py
+++ b/src/cryptography/hazmat/backends/openssl/hmac.py
@@ -9,10 +9,10 @@
 from cryptography.exceptions import (
     InvalidSignature, UnsupportedAlgorithm, _Reasons
 )
-from cryptography.hazmat.primitives import constant_time, hashes, interfaces
+from cryptography.hazmat.primitives import constant_time, hashes, mac
 
 
-@utils.register_interface(interfaces.MACContext)
+@utils.register_interface(mac.MACContext)
 @utils.register_interface(hashes.HashContext)
 class _HMACContext(object):
     def __init__(self, backend, key, algorithm, ctx=None):
diff --git a/src/cryptography/hazmat/primitives/cmac.py b/src/cryptography/hazmat/primitives/cmac.py
index c2038a3..77537f0 100644
--- a/src/cryptography/hazmat/primitives/cmac.py
+++ b/src/cryptography/hazmat/primitives/cmac.py
@@ -9,10 +9,10 @@
     AlreadyFinalized, UnsupportedAlgorithm, _Reasons
 )
 from cryptography.hazmat.backends.interfaces import CMACBackend
-from cryptography.hazmat.primitives import ciphers, interfaces
+from cryptography.hazmat.primitives import ciphers, mac
 
 
-@utils.register_interface(interfaces.MACContext)
+@utils.register_interface(mac.MACContext)
 class CMAC(object):
     def __init__(self, algorithm, backend, ctx=None):
         if not isinstance(backend, CMACBackend):
diff --git a/src/cryptography/hazmat/primitives/hmac.py b/src/cryptography/hazmat/primitives/hmac.py
index 15b9ee6..2e9a4e2 100644
--- a/src/cryptography/hazmat/primitives/hmac.py
+++ b/src/cryptography/hazmat/primitives/hmac.py
@@ -9,10 +9,10 @@
     AlreadyFinalized, UnsupportedAlgorithm, _Reasons
 )
 from cryptography.hazmat.backends.interfaces import HMACBackend
-from cryptography.hazmat.primitives import hashes, interfaces
+from cryptography.hazmat.primitives import hashes, mac
 
 
-@utils.register_interface(interfaces.MACContext)
+@utils.register_interface(mac.MACContext)
 @utils.register_interface(hashes.HashContext)
 class HMAC(object):
     def __init__(self, key, algorithm, backend, ctx=None):
diff --git a/src/cryptography/hazmat/primitives/interfaces.py b/src/cryptography/hazmat/primitives/interfaces.py
new file mode 100644
index 0000000..c9fdb3b
--- /dev/null
+++ b/src/cryptography/hazmat/primitives/interfaces.py
@@ -0,0 +1,17 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+from cryptography import utils
+from cryptography.hazmat.primitives.mac import MACContext as _MACContext
+
+
+MACContext = utils.deprecated(
+    _MACContext,
+    __name__,
+    "MACContext was moved to cryptography.hazmat.primitives.mac.MACContext "
+    "in version 1.9.",
+    utils.DeprecatedIn19
+)
diff --git a/src/cryptography/hazmat/primitives/interfaces/__init__.py b/src/cryptography/hazmat/primitives/mac.py
similarity index 100%
rename from src/cryptography/hazmat/primitives/interfaces/__init__.py
rename to src/cryptography/hazmat/primitives/mac.py
diff --git a/tests/hazmat/primitives/test_mac.py b/tests/hazmat/primitives/test_mac.py
new file mode 100644
index 0000000..7263212
--- /dev/null
+++ b/tests/hazmat/primitives/test_mac.py
@@ -0,0 +1,15 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import pytest
+
+from cryptography import utils
+
+
+def test_deprecated_maccontext():
+    with pytest.warns(utils.DeprecatedIn19):
+        from cryptography.hazmat.primitives.interfaces import MACContext
+        assert MACContext