Repository: dbeatty10/dbt-mysql (language: python)

Issue:
Bump version of dbt-core to ~=1.2.0
### Describe the bug
I forgot to update the version of dbt-core.

Should fix this _and_ add applicable instructions to the `RELEASE` notes. Alternatively, can just upgrade to a more modern version of `setup.py` like [this](https://github.com/dbt-labs/dbt-redshift/blob/28d22bd8abf53882c7f4ddde6d4b611a5c924a9d/setup.py).

### Steps To Reproduce
Follow the install instructions in `CONTRIBUTING`.

### Screenshots and log output
```
ERROR: Cannot install -r requirements-dev.txt (line 4) and dbt-core~=1.1.0 because these package versions have conflicting dependencies.

The conflict is caused by:
    The user requested dbt-core~=1.1.0
    dbt-tests-adapter 1.2.4 depends on dbt-core==1.2.4

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts
```

**The output of `dbt --version`:**
```
Core:
  - installed: 1.2.4
```

dbt-mysql: 1.2.0a1

**The operating system you're using:**

**The output of `python --version`:**

### Additional context
This may have been prevented by just using a more modern version of `setup.py` like [this](https://github.com/dbt-labs/dbt-redshift/blob/28d22bd8abf53882c7f4ddde6d4b611a5c924a9d/setup.py).


Discussion / hints:

Fix patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index c290fe0..184be8b 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -22,10 +22,6 @@ values =
 [bumpversion:part:num]
 first_value = 1
 
-[bumpversion:file:setup.py]
-search = package_version = "{current_version}"
-replace = package_version = "{new_version}"
-
 [bumpversion:file:dbt/adapters/mysql/__version__.py]
 search = version = "{current_version}"
 replace = version = "{new_version}"
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index d08c7ea..3b8fd26 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -69,7 +69,7 @@ Ready to contribute? `Here's <https://jarv.is/notes/how-to-pull-request-fork-git
     $ python3 -m venv env
     $ source env/bin/activate
     $ python3 -m pip install --upgrade pip
-    $ python3 -m pip install -r requirements.txt -r requirements-dev.txt -r requirements-editable.txt
+    $ python3 -m pip install -r requirements-dev.txt -r requirements-editable.txt
     $ source env/bin/activate
 
 4. Create a branch for local development::
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index d2ea96c..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-dbt-core~=1.1.0
-mysql-connector-python>=8.0.0,<8.1
diff --git a/setup.py b/setup.py
index c7b195a..8e9cea1 100644
--- a/setup.py
+++ b/setup.py
@@ -1,97 +1,99 @@
 #!/usr/bin/env python
-import os
 import sys
-import re
 
-if sys.version_info < (3, 7) or sys.version_info >= (3, 10):
-    print('Error: dbt-mysql does not support this version of Python.')
-    print('Please install Python 3.7 or higher but less than 3.10.')
+if sys.version_info < (3, 7):
+    print("Error: dbt does not support this version of Python.")
+    print("Please upgrade to Python 3.7 or higher.")
     sys.exit(1)
 
 
-# require version of setuptools that supports find_namespace_packages
-from setuptools import setup
 try:
     from setuptools import find_namespace_packages
 except ImportError:
-    # the user has a downlevel version of setuptools.
-    print('Error: dbt requires setuptools v40.1.0 or higher.')
-    print('Please upgrade setuptools with "python -m pip install --upgrade setuptools" '
-          'and try again')
+    print("Error: dbt requires setuptools v40.1.0 or higher.")
+    print('Please upgrade setuptools with "pip install --upgrade setuptools" and try again')
     sys.exit(1)
 
 
-# pull long description from README
-this_directory = os.path.abspath(os.path.dirname(__file__))
-with open(os.path.join(this_directory, 'README.md')) as f:
-    long_description = f.read()
+from pathlib import Path
+from setuptools import setup
+
+
+# pull the long description from the README
+README = Path(__file__).parent / "README.md"
+
+
+# used for this adapter's version and in determining the compatible dbt-core version
+VERSION = Path(__file__).parent / "dbt/adapters/mysql/__version__.py"
 
 
-# get this package's version from dbt/adapters/<name>/__version__.py
-def _get_plugin_version_dict():
-    _version_path = os.path.join(
-        this_directory, 'dbt', 'adapters', 'mysql', '__version__.py'
-    )
-    _semver = r'''(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)'''
-    _pre = r'''((?P<prekind>a|b|rc)(?P<pre>\d+))?'''
-    _version_pattern = fr'''version\s*=\s*["']{_semver}{_pre}["']'''
-    with open(_version_path) as f:
-        match = re.search(_version_pattern, f.read().strip())
-        if match is None:
-            raise ValueError(f'invalid version at {_version_path}')
-        return match.groupdict()
+def _plugin_version() -> str:
+    """
+    Pull the package version from the main package version file
+    """
+    attributes = {}
+    exec(VERSION.read_text(), attributes)
+    return attributes["version"]
 
 
-def _get_plugin_version():
-    parts = _get_plugin_version_dict()
-    return "{major}.{minor}.{patch}{prekind}{pre}".format(**parts)
+def _core_patch(plugin_patch: str):
+    """
+    Determines the compatible dbt-core patch given this plugin's patch
 
+    Args:
+        plugin_patch: the version patch of this plugin
+    """
+    pre_release_phase = "".join([i for i in plugin_patch if not i.isdigit()])
+    if pre_release_phase:
+        if pre_release_phase not in ["a", "b", "rc"]:
+            raise ValueError(f"Invalid prerelease patch: {plugin_patch}")
+        return f"0{pre_release_phase}1"
+    return "0"
 
-# require a compatible minor version (~=), prerelease if this is a prerelease
-def _get_dbt_core_version():
-    parts = _get_plugin_version_dict()
-    minor = "{major}.{minor}.0".format(**parts)
-    pre = (parts["prekind"]+"1" if parts["prekind"] else "")
-    return f"{minor}{pre}"
 
+# require a compatible minor version (~=) and prerelease if this is a prerelease
+def _core_version(plugin_version: str = _plugin_version()) -> str:
+    """
+    Determine the compatible dbt-core version give this plugin's version.
 
-package_name = "dbt-mysql"
-package_version = "1.2.0a1"
-dbt_core_version = _get_dbt_core_version()
-description = """The MySQL adapter plugin for dbt"""
+    We assume that the plugin must agree with `dbt-core` down to the minor version.
+
+    Args:
+        plugin_version: the version of this plugin, this is an argument in case we ever want to unit test this
+    """
+    try:
+        major, minor, plugin_patch = plugin_version.split(".")
+    except ValueError:
+        raise ValueError(f"Invalid version: {plugin_version}")
+
+    return f"{major}.{minor}.{_core_patch(plugin_patch)}"
 
-this_directory = os.path.abspath(os.path.dirname(__file__))
-with open(os.path.join(this_directory, 'README.md')) as f:
-    long_description = f.read()
 
 setup(
-    name=package_name,
-    version=package_version,
-    description=description,
-    long_description=long_description,
-    long_description_content_type='text/markdown',
+    name="dbt-mysql",
+    version=_plugin_version(),
+    description="The MySQL adapter plugin for dbt",
+    long_description=README.read_text(),
+    long_description_content_type="text/markdown",
     author="Doug Beatty",
     author_email="doug.beatty@gmail.com",
     url="https://github.com/dbeatty10/dbt-mysql",
-    packages=find_namespace_packages(include=['dbt', 'dbt.*']),
+    packages=find_namespace_packages(include=["dbt", "dbt.*"]),
     include_package_data=True,
     install_requires=[
-        'dbt-core~={}'.format(dbt_core_version),
+        f"dbt-core~={_core_version()}",
         "mysql-connector-python>=8.0.0,<8.1",
     ],
     zip_safe=False,
     classifiers=[
         'Development Status :: 3 - Alpha',
-
         'License :: OSI Approved :: Apache Software License',
-
         'Operating System :: Microsoft :: Windows',
         'Operating System :: MacOS :: MacOS X',
         'Operating System :: POSIX :: Linux',
-
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
     ],
-    python_requires=">=3.7,<3.10",
+    python_requires=">=3.7",
 )
diff --git a/tox.ini b/tox.ini
index 32e1004..2a72f4d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -14,15 +14,14 @@ basepython = python3.9
 commands = /bin/bash -c '{envpython} -m pytest -v {posargs} tests/unit'
 passenv = DBT_INVOCATION_ENV
 deps =
-   -r{toxinidir}/requirements.txt
    -r{toxinidir}/requirements-dev.txt
+   -e.
 
 [testenv:integration-mysql-8.0]
 basepython = python3.9
 commands = {envpython} -m pytest -v --profile mysql {posargs} tests/functional
 passenv = DBT_INVOCATION_ENV DBT_MYSQL_SERVER_NAME DBT_MYSQL_80_PORT
 deps =
-   -r{toxinidir}/requirements.txt
    -r{toxinidir}/requirements-dev.txt
    -e.
 
@@ -31,7 +30,6 @@ basepython = python3.9
 commands = {envpython} -m pytest -v --profile mysql5 {posargs} tests/functional
 passenv = DBT_INVOCATION_ENV DBT_MYSQL_SERVER_NAME DBT_MYSQL_57_PORT
 deps =
-   -r{toxinidir}/requirements.txt
    -r{toxinidir}/requirements-dev.txt
    -e.
 
@@ -40,6 +38,5 @@ basepython = python3.9
 commands = {envpython} -m pytest -v --profile mariadb {posargs} tests/functional
 passenv = DBT_INVOCATION_ENV DBT_MYSQL_SERVER_NAME DBT_MARIADB_105_PORT
 deps =
-  -r{toxinidir}/requirements.txt
   -r{toxinidir}/requirements-dev.txt
   -e.


Test patch:
diff --git a/tests/README.md b/tests/README.md
index c2bac1e..fe8954c 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -101,3 +101,8 @@ tox -e integration-mariadb-10.5 && \
 tox -e integration-mysql-5.7 && \
 tox -e integration-mysql-8.0
 ```
+
+Run a single test
+```shell
+pytest -v --profile mysql tests/functional/adapter/test_basic.py::TestEmptyMySQL::test_empty
+```
diff --git a/tests/functional/adapter/test_basic.py b/tests/functional/adapter/test_basic.py
index d4af380..3a02960 100644
--- a/tests/functional/adapter/test_basic.py
+++ b/tests/functional/adapter/test_basic.py
@@ -47,6 +47,8 @@ class TestGenericTestsMySQL(BaseGenericTests):
     pass
 
 
+# TODO
+@pytest.mark.skip(reason="known failure to fix")
 class TestSnapshotCheckColsMySQL(BaseSnapshotCheckCols):
     pass