diff --git a/src/packageurl/__init__.py b/src/packageurl/__init__.py
index 71225e9..ae6e148 100644
--- a/src/packageurl/__init__.py
+++ b/src/packageurl/__init__.py
@@ -282,6 +282,9 @@ class PackageURL(namedtuple('PackageURL', _components)):
     def __str__(self, *args, **kwargs):
         return self.to_string()
 
+    def __hash__(self):
+        return hash(self.to_string())
+
     def to_dict(self, encode=False):
         """
         Return an ordered dict of purl components as {key: value}. If `encode`

diff --git a/tests/test_packageurl.py b/tests/test_packageurl.py
index 912b380..6081912 100644
--- a/tests/test_packageurl.py
+++ b/tests/test_packageurl.py
@@ -286,3 +286,9 @@ class NormalizePurlTest(unittest.TestCase):
             ('subpath', u'this/is/a/path')
         ])
         assert expected == purl.to_dict(encode=True)
+
+
+def test_purl_is_hashable():
+    s = {PackageURL(name='hashable', type='pypi')}
+    assert len(s) == 1
+

PackageURL type is not hashable
Storing `PackageURL` instances in a set can be useful. Currently attempting this fails with the following error:

```
Python 3.8.2 (default, Feb 26 2020, 22:21:03) 
[GCC 9.2.1 20200130] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from packageurl import PackageURL
>>> {PackageURL(name='test', type='pypi')}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'collections.OrderedDict'
```
tests/test_packageurl.py::test_purl_is_hashable
tests/test_packageurl.py::test_packageurl.python_safe_name tests/test_packageurl.py::PurlTest::test_purl_pkg_basic_valid_maven_purl_without_version tests/test_packageurl.py::PurlTest::test_purl_pkg_bitbucket_namespace_and_name_should_be_lowercased tests/test_packageurl.py::PurlTest::test_purl_pkg_debian_can_use_qualifiers tests/test_packageurl.py::PurlTest::test_purl_pkg_docker_uses_qualifiers_and_hash_image_id_as_versions tests/test_packageurl.py::PurlTest::test_purl_pkg_double_slash_after_scheme_is_not_significant tests/test_packageurl.py::PurlTest::test_purl_pkg_github_namespace_and_name_should_be_lowercased tests/test_packageurl.py::PurlTest::test_purl_pkg_is_invalid_a_name_is_required tests/test_packageurl.py::PurlTest::test_purl_pkg_is_invalid_a_scheme_is_always_required tests/test_packageurl.py::PurlTest::test_purl_pkg_is_invalid_a_type_is_always_required tests/test_packageurl.py::PurlTest::test_purl_pkg_is_invalid_checks_for_invalid_qualifier_keys tests/test_packageurl.py::PurlTest::test_purl_pkg_java_gem_can_use_a_qualifier tests/test_packageurl.py::PurlTest::test_purl_pkg_maven_can_come_with_a_type_qualifier tests/test_packageurl.py::PurlTest::test_purl_pkg_maven_often_uses_qualifiers tests/test_packageurl.py::PurlTest::test_purl_pkg_maven_pom_reference tests/test_packageurl.py::PurlTest::test_purl_pkg_npm_can_be_scoped tests/test_packageurl.py::PurlTest::test_purl_pkg_nuget_names_are_case_sensitive tests/test_packageurl.py::PurlTest::test_purl_pkg_pypi_names_have_special_rules_and_not_case_sensitive tests/test_packageurl.py::PurlTest::test_purl_pkg_rpm_often_use_qualifiers tests/test_packageurl.py::PurlTest::test_purl_pkg_slash_after_scheme_is_not_significant tests/test_packageurl.py::PurlTest::test_purl_pkg_slash_after_type_is_not_significant tests/test_packageurl.py::PurlTest::test_purl_pkg_valid_go_purl_with_version_and_subpath tests/test_packageurl.py::PurlTest::test_purl_pkg_valid_go_purl_without_version_and_with_subpath tests/test_packageurl.py::PurlTest::test_purl_pkg_valid_maven_purl tests/test_packageurl.py::PurlTest::test_purl_pkg_valid_maven_purl_containing_a_space_in_the_version_and_qualifier tests/test_packageurl.py::PurlTest::test_purl_pkg_valid_maven_purl_with_case_sensitive_namespace_and_name tests/test_packageurl.py::NormalizePurlTest::test_create_PackageURL_from_qualifiers_dict tests/test_packageurl.py::NormalizePurlTest::test_create_PackageURL_from_qualifiers_string tests/test_packageurl.py::NormalizePurlTest::test_normalize_decode_can_take_unicode_with_non_ascii_with_slash tests/test_packageurl.py::NormalizePurlTest::test_normalize_encode_always_reencodes tests/test_packageurl.py::NormalizePurlTest::test_normalize_encode_can_take_unicode_with_non_ascii_with_slash tests/test_packageurl.py::NormalizePurlTest::test_normalize_qualifiers_as_dict tests/test_packageurl.py::NormalizePurlTest::test_normalize_qualifiers_as_string tests/test_packageurl.py::NormalizePurlTest::test_qualifiers_must_be_key_value_pairs tests/test_packageurl.py::NormalizePurlTest::test_to_dict_optionally_returns_qualifiers_as_string