Repository: dropbox/stone (language: python)

Issue:
Remove distutils
**Describe the bug**
`distutils` is deprecated and slated for removal in Python 3.12

https://peps.python.org/pep-0632//#migration-advice

**To Reproduce**
Run with Python 3.12

```bash
============================= test session starts ==============================
platform linux -- Python 3.12.2, pytest-7.4.4, pluggy-1.4.0
rootdir: /build/source
collected 63 items / 10 errors / 1 deselected / 62 selected                    

==================================== ERRORS ====================================
____________________ ERROR collecting test/test_backend.py _____________________
ImportError while importing test module '/build/source/test/test_backend.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/nix/store/n3jf1lkdfakxskzsm4nlhss8mdgmcqhc-python3-3.12.2/lib/python3.12/importlib/__init__.py:90: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
test/test_backend.py:7: in <module>
    from stone.ir import (
stone/ir/__init__.py:1: in <module>
    from .api import *  # noqa: F401,F403
stone/ir/api.py:5: in <module>
    from distutils.version import StrictVersion
E   ModuleNotFoundError: No module named 'distutils'
___________________ ERROR collecting test/test_js_client.py ____________________
[...]
```



Discussion / hints:
Thanks! I'll ask the team to fix this.
+1

Fix patch:
diff --git a/ez_setup.py b/ez_setup.py
index eb9b690e..722496a6 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -23,7 +23,7 @@
 import tempfile
 import textwrap
 import zipfile
-from distutils import log
+from setuptools import log
 
 try:
     from site import USER_SITE
diff --git a/requirements.txt b/requirements.txt
index 657f7a07..07605c18 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
 ply>= 3.4
-six>= 1.12.0
\ No newline at end of file
+six>= 1.12.0
+packaging>=21.0
diff --git a/stone/ir/api.py b/stone/ir/api.py
index 654e004a..8cb74846 100644
--- a/stone/ir/api.py
+++ b/stone/ir/api.py
@@ -1,6 +1,6 @@
 from collections import OrderedDict
 # See <https://github.com/PyCQA/pylint/issues/73>
-from distutils.version import StrictVersion  # pylint: disable=deprecated-module
+from packaging.version import Version
 
 from .data_types import (
     doc_unwrap,
@@ -34,7 +34,7 @@ class Api:
     """
     def __init__(self, version):
         # type: (str) -> None
-        self.version = StrictVersion(version)
+        self.version = Version(version)
         self.namespaces = OrderedDict()  # type: NamespaceDict
         self.route_schema = None  # type: typing.Optional[Struct]
 


Test patch:
diff --git a/test/test_backend.py b/test/test_backend.py
index a123d641..57a68e6a 100755
--- a/test/test_backend.py
+++ b/test/test_backend.py
@@ -282,7 +282,7 @@ def test_strip_alias(self):
         self.assertIsInstance(string_type, String)
 
     def test_preserve_aliases_from_api(self):
-        api = Api(version=None)
+        api = Api(version="0.1b1")
         # Ensure imports come after 'preserve_alias' lexiographicaly
         # to catch namespace ordering bugs
         api.ensure_namespace('preserve_alias')
@@ -390,7 +390,7 @@ def test_preserve_aliases_from_api(self):
         self.assertIsInstance(field.data_type, Alias)
 
     def test_no_preserve_aliases_from_api(self):
-        api = Api(version=None)
+        api = Api(version="0.1b1")
         # Ensure imports come after 'preserve_alias' lexiographicaly
         # to catch namespace ordering bugs
         api.ensure_namespace('preserve_alias')