Repository: dbt-labs/dbt-core

Issue:
[CT-30] Add Support for Python 3.10
### Is there an existing feature request for this?

- [X] I have searched the existing issues

### Describe the Feature

Officially support Python 3.10




Discussion:
This will require us to resolve, at minimum, the mess of deprecation warnings emitted from the legacy logger, as described in https://github.com/dbt-labs/dbt-core/issues/4537. It's not obvious to me which sub-team is best suited to that work, so I've just added the `tech debt` label for now.

Going forward, we should seek to support each new python minor version, after its official release, in the subsequent minor version of dbt. (Do we need to support it in patch releases, too?)
Goal: 
- Handle deprecation warnings that are emitted (suppress legacy logger warnings since we will eventually be removing it)
- Look for any 3.10 reported bugs

Resolving patch:
diff --git a/core/dbt/events/base_types.py b/core/dbt/events/base_types.py
--- a/core/dbt/events/base_types.py
+++ b/core/dbt/events/base_types.py
@@ -64,7 +64,7 @@ def get_pid(self) -> int:
 
     # in theory threads can change so we don't cache them.
     def get_thread_name(self) -> str:
-        return threading.current_thread().getName()
+        return threading.current_thread().name
 
     @classmethod
     def get_invocation_id(cls) -> str:
diff --git a/core/dbt/events/functions.py b/core/dbt/events/functions.py
--- a/core/dbt/events/functions.py
+++ b/core/dbt/events/functions.py
@@ -194,8 +194,8 @@ def create_debug_text_log_line(e: T_Event) -> str:
     scrubbed_msg: str = scrub_secrets(e.message(), env_secrets())
     level: str = e.level_tag() if len(e.level_tag()) == 5 else f"{e.level_tag()} "
     thread = ""
-    if threading.current_thread().getName():
-        thread_name = threading.current_thread().getName()
+    if threading.current_thread().name:
+        thread_name = threading.current_thread().name
         thread_name = thread_name[:10]
         thread_name = thread_name.ljust(10, " ")
         thread = f" [{thread_name}]:"
diff --git a/core/dbt/main.py b/core/dbt/main.py
--- a/core/dbt/main.py
+++ b/core/dbt/main.py
@@ -5,6 +5,7 @@
 import os.path
 import sys
 import traceback
+import warnings
 from contextlib import contextmanager
 from pathlib import Path
 
@@ -118,6 +119,9 @@ def add_optional_argument_inverse(
 
 
 def main(args=None):
+    # Logbook warnings are ignored so we don't have to fork logbook to support python 3.10.
+    # This _only_ works for regular cli invocations.
+    warnings.filterwarnings("ignore", category=DeprecationWarning, module="logbook")
     if args is None:
         args = sys.argv[1:]
     with log_manager.applicationbound():


Test patch:
diff --git a/core/dbt/tests/fixtures/project.py b/core/dbt/tests/fixtures/project.py
--- a/core/dbt/tests/fixtures/project.py
+++ b/core/dbt/tests/fixtures/project.py
@@ -3,6 +3,7 @@
 import random
 from argparse import Namespace
 from datetime import datetime
+import warnings
 import yaml
 
 import dbt.flags as flags
@@ -319,6 +320,9 @@ def project(
     test_data_dir,
     logs_dir,
 ):
+    # Logbook warnings are ignored so we don't have to fork logbook to support python 3.10.
+    # This _only_ works for tests in `tests/` that use the project fixture.
+    warnings.filterwarnings("ignore", category=DeprecationWarning, module="logbook")
     setup_event_logger(logs_dir)
     orig_cwd = os.getcwd()
     os.chdir(project_root)
diff --git a/core/dbt/tests/util.py b/core/dbt/tests/util.py
--- a/core/dbt/tests/util.py
+++ b/core/dbt/tests/util.py
@@ -2,6 +2,7 @@
 import shutil
 import yaml
 import json
+import warnings
 from typing import List
 
 from dbt.main import handle_and_check
@@ -15,6 +16,10 @@
 
 # This is used in pytest tests to run dbt
 def run_dbt(args: List[str] = None, expect_pass=True):
+    # Logbook warnings are ignored so we don't have to fork logbook to support python 3.10.
+    # This _only_ works for tests in `tests/` that use the run_dbt method.
+    warnings.filterwarnings("ignore", category=DeprecationWarning, module="logbook")
+
     # The logger will complain about already being initialized if
     # we don't do this.
     log_manager.reset_handlers()
diff --git a/test/integration/base.py b/test/integration/base.py
--- a/test/integration/base.py
+++ b/test/integration/base.py
@@ -8,6 +8,7 @@
 import time
 import traceback
 import unittest
+import warnings
 from contextlib import contextmanager
 from datetime import datetime
 from functools import wraps
@@ -310,6 +311,13 @@ def _generate_test_root_dir(self):
         return normalize(tempfile.mkdtemp(prefix='dbt-int-test-'))
 
     def setUp(self):
+        # Logbook warnings are ignored so we don't have to fork logbook to support python 3.10. 
+        # This _only_ works for tests in `test/integration`.
+        warnings.filterwarnings(
+            "ignore",
+            category=DeprecationWarning,
+            module="logbook"
+        )
         self.dbt_core_install_root = os.path.dirname(dbt.__file__)
         log_manager.reset_handlers()
         self.initial_dir = INITIAL_ROOT