diff --git a/CREDITS b/CREDITS
index 53fdef1..ca9a781 100644
--- a/CREDITS
+++ b/CREDITS
@@ -23,6 +23,7 @@ The project has received contributions from (in alphabetical order):
 * Michael Hrivnak <mhrivnak@hrivnak.org> (https://github.com/mhrivnak)
 * William Minchin <w_minchin@hotmail.com> (https://github.com/minchinweb)
 * Dave Hall <skwadhd@gmail.com> (https://github.com/skwashd)
+* Martin Ek <mail@ekmartin.com> (https://github.com/ekmartin)
 
 
 Contributor license agreement
diff --git a/semantic_version/base.py b/semantic_version/base.py
index 1504642..83a9c25 100644
--- a/semantic_version/base.py
+++ b/semantic_version/base.py
@@ -405,6 +405,7 @@ class SpecItem(object):
     KIND_NEQ = '!='
     KIND_CARET = '^'
     KIND_TILDE = '~'
+    KIND_COMPATIBLE = '~='
 
     # Map a kind alias to its full version
     KIND_ALIASES = {
@@ -412,7 +413,7 @@ class SpecItem(object):
         KIND_EMPTY: KIND_EQUAL,
     }
 
-    re_spec = re.compile(r'^(<|<=||=|==|>=|>|!=|\^|~)(\d.*)$')
+    re_spec = re.compile(r'^(<|<=||=|==|>=|>|!=|\^|~|~=)(\d.*)$')
 
     def __init__(self, requirement_string):
         kind, spec = self.parse(requirement_string)
@@ -468,6 +469,12 @@ class SpecItem(object):
             return self.spec <= version < upper
         elif self.kind == self.KIND_TILDE:
             return self.spec <= version < self.spec.next_minor()
+        elif self.kind == self.KIND_COMPATIBLE:
+            if self.spec.patch:
+                upper = self.spec.next_minor()
+            else:
+                upper = self.spec.next_major()
+            return self.spec <= version < upper
         else:  # pragma: no cover
             raise ValueError('Unexpected match kind: %r' % self.kind)
 

Support compatible release clauses (~=)
Hi!
Here's an example:
```python
Spec('~=1.5.6') # results in a ValueError
```

https://www.python.org/dev/peps/pep-0440/#compatible-release
diff --git a/tests/test_base.py b/tests/test_base.py
index 24bf86e..0675b24 100755
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -514,6 +514,14 @@ class SpecItemTestCase(unittest.TestCase):
             ['0.0.2', '0.0.2-alpha', '0.0.2+abb'],
             ['0.1.0', '0.0.3', '1.0.0'],
         ),
+        '~=1.4.5': (
+            ['1.4.5', '1.4.10-alpha', '1.4.10'],
+            ['1.3.6', '1.4.4', '1.5.0'],
+        ),
+        '~=1.4': (
+            ['1.4.0', '1.6.10-alpha', '1.6.10'],
+            ['1.3.0', '2.0.0'],
+        ),
     }
 
     def test_matches(self):
diff --git a/tests/test_match.py b/tests/test_match.py
index 49464f8..4d1a96f 100755
--- a/tests/test_match.py
+++ b/tests/test_match.py
@@ -31,6 +31,7 @@ class MatchTestCase(unittest.TestCase):
         '!=0.1.2-rc1.3-14.15+build.2012-01-01.11h34',
         '^0.1.2',
         '~0.1.2',
+        '~=0.1.2',
     ]
 
     matches = {
@@ -113,6 +114,16 @@ class MatchTestCase(unittest.TestCase):
             '0.1.2+build4.5',
             '0.1.3-rc1.3',
         ],
+        '~=1.4.5': (
+            '1.4.5',
+            '1.4.10-alpha',
+            '1.4.10',
+        ),
+        '~=1.4': [
+            '1.4.0',
+            '1.6.10-alpha',
+            '1.6.10',
+        ],
     }
 
     def test_invalid(self):

pip install -e .
parse_log_pytest
requirements.txt
pytest
3.5
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
importlib-metadata==4.8.3
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
-e git+https://github.com/rbarrois/python-semanticversion.git@d10ab4cb1d1ca8090132f205017dfc90473c91cc#egg=semantic_version
tomli==1.2.3
typing_extensions==4.1.1
zipp==3.6.0

name: python-semanticversion
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/python-semanticversion

tests/test_base.py::SpecItemTestCase::test_matches tests/test_match.py::MatchTestCase::test_match tests/test_match.py::MatchTestCase::test_simple
tests/test_base.py::ComparisonTestCase::test_identifier_cmp tests/test_base.py::ComparisonTestCase::test_identifier_list_cmp tests/test_base.py::TopLevelTestCase::test_compare tests/test_base.py::TopLevelTestCase::test_match tests/test_base.py::TopLevelTestCase::test_validate_invalid tests/test_base.py::TopLevelTestCase::test_validate_valid tests/test_base.py::VersionTestCase::test_bump_clean_versions tests/test_base.py::VersionTestCase::test_bump_prerelease_versions tests/test_base.py::VersionTestCase::test_compare_partial_to_self tests/test_base.py::VersionTestCase::test_compare_to_self tests/test_base.py::VersionTestCase::test_hash tests/test_base.py::VersionTestCase::test_invalid_comparisons tests/test_base.py::VersionTestCase::test_parsing tests/test_base.py::VersionTestCase::test_parsing_partials tests/test_base.py::VersionTestCase::test_str tests/test_base.py::VersionTestCase::test_str_partials tests/test_base.py::SpecItemTestCase::test_components tests/test_base.py::SpecItemTestCase::test_equality tests/test_base.py::SpecItemTestCase::test_hash tests/test_base.py::SpecItemTestCase::test_invalids tests/test_base.py::SpecItemTestCase::test_to_string tests/test_base.py::CoerceTestCase::test_coerce tests/test_base.py::CoerceTestCase::test_invalid tests/test_base.py::SpecTestCase::test_contains tests/test_base.py::SpecTestCase::test_equality tests/test_base.py::SpecTestCase::test_filter_compatible tests/test_base.py::SpecTestCase::test_filter_empty tests/test_base.py::SpecTestCase::test_filter_incompatible tests/test_base.py::SpecTestCase::test_hash tests/test_base.py::SpecTestCase::test_matches tests/test_base.py::SpecTestCase::test_parsing tests/test_base.py::SpecTestCase::test_parsing_split tests/test_base.py::SpecTestCase::test_select_compatible tests/test_base.py::SpecTestCase::test_select_empty tests/test_base.py::SpecTestCase::test_select_incompatible tests/test_match.py::MatchTestCase::test_build_check tests/test_match.py::MatchTestCase::test_contains tests/test_match.py::MatchTestCase::test_invalid tests/test_match.py::MatchTestCase::test_prerelease_check
CREDITS semantic_version/base.py
CREDITS semantic_version/base.py