Repository: microsoft/dlltracer-python (language: python)

Issue:
Does not support Python 3.7
Hello!

I was sent here from [another incident with a different package](https://github.com/blue-yonder/turbodbc/issues/315). I attempted to install both through the readme and git. However, I encountered issues with both even though I was running as administrator.

Below is what it looks like via terminal in VS Code
![image](https://user-images.githubusercontent.com/36700028/124339761-92315180-db7e-11eb-995e-488b60f00168.png)



Discussion / hints:
Yes, we didn't start with 3.7 support. It may be possible to go back and add it - will take a look.
Also sorry for the slow reply. Even though I created the repository (through one of our internal tools), I wasn't automatically subscribed to notifications :(

Fix patch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 12afd2d..e8ab7b7 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -39,7 +39,7 @@ jobs:
     strategy:
       matrix:
         os: [windows-latest]
-        python-version: [3.8, 3.9, 3.10-dev]
+        python-version: [3.7, 3.8, 3.9, 3.10-dev]
 
     steps:
     - uses: actions/checkout@v2
diff --git a/_msbuild.py b/_msbuild.py
index 3e99442..e304473 100644
--- a/_msbuild.py
+++ b/_msbuild.py
@@ -29,24 +29,35 @@
         "Intended Audience :: Developers",
         "License :: OSI Approved :: MIT License",
         "Operating System :: Microsoft :: Windows",
+        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
     ],
-    "Requires-Python": ">=3.8",
+    "Requires-Python": ">=3.7",
 }
 
+AUDIT_STUB = CSourceFile("dlltracer/audit_stub.c")
+
+PYD = CythonPydFile(
+    "_native",
+    ItemDefinition("ClCompile",
+        AdditionalIncludeDirectories=ConditionalValue(Path("src;").absolute(), prepend=True)
+    ),
+    ItemDefinition("Link",
+        GenerateDebugInformation=ConditionalValue("false", condition="$(Configuration) == 'Release'")),
+    PyxFile("dlltracer/_native.pyx", TargetExt=".cpp"),
+    IncludeFile("dlltracer/audit_stub.h"),
+    AUDIT_STUB,
+)
+
 PACKAGE = Package(
     "dlltracer",
     PyFile("dlltracer/__init__.py"),
-    CythonPydFile(
-        "_native",
-        ItemDefinition("ClCompile",
-            AdditionalIncludeDirectories=ConditionalValue(Path("src;").absolute(), prepend=True)
-        ),
-        ItemDefinition("Link",
-            GenerateDebugInformation=ConditionalValue("false", condition="$(Configuration) == 'Release'")),
-        PyxFile("dlltracer/_native.pyx", TargetExt=".cpp"),
-    ),
+    PYD,
     source="src",
 )
+
+def init_PACKAGE(wheel_tag):
+    if not wheel_tag.startswith("cp37"):
+        PYD.members.remove(AUDIT_STUB)
diff --git a/src/dlltracer/_native.pyx b/src/dlltracer/_native.pyx
index 20f464a..9ffa76b 100644
--- a/src/dlltracer/_native.pyx
+++ b/src/dlltracer/_native.pyx
@@ -2,17 +2,16 @@
 # cython: language_level=3
 
 from libc.string cimport memcpy, memset
+from cpython cimport version as sys_version
 from cpython.ref cimport PyObject, Py_INCREF
 
-from sys import audit as _sys_audit
 from threading import Thread as _Thread
 from uuid import UUID as _UUID
 
 _SystemTraceControlGuid = _UUID("9e814aad-3204-11d2-9a82-006008a86939")
 _LoadLibraryProvider = _UUID('2cb15d1d-5fc1-11d2-abe1-00a0c911f518')
 
-
-cdef extern from "Python.h":
+cdef extern from "dlltracer/audit_stub.h":
     cdef int PySys_Audit(const char* event, const char* fmt, ...) except -1
 
 
@@ -278,6 +277,8 @@ cdef class Trace:
         self._collect = [] if collect else None
         self._out = out
         self._audit = audit
+        if sys_version.PY_VERSION_HEX < 0x03080000 and audit:
+            raise NotImplementedError("audit hooks are not available on this version of Python")
         self._debug = debug
 
     def __enter__(self):
diff --git a/src/dlltracer/audit_stub.c b/src/dlltracer/audit_stub.c
new file mode 100644
index 0000000..1b7dcf2
--- /dev/null
+++ b/src/dlltracer/audit_stub.c
@@ -0,0 +1,4 @@
+
+int __stdcall PySys_Audit(const char* event, const char* fmt, ...) {
+    return 0;
+}
diff --git a/src/dlltracer/audit_stub.h b/src/dlltracer/audit_stub.h
new file mode 100644
index 0000000..dc3dba6
--- /dev/null
+++ b/src/dlltracer/audit_stub.h
@@ -0,0 +1,12 @@
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if PY_VERSION_HEX < 0x03080000
+int __stdcall PySys_Audit(const char* event, const char* fmt, ...);
+#endif
+
+#ifdef __cplusplus
+}
+#endif


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c95ab7e..de25994 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,7 +12,7 @@ jobs:
     strategy:
       matrix:
         os: [windows-latest]
-        python-version: [3.8, 3.9, 3.10-dev]
+        python-version: [3.7, 3.8, 3.9, 3.10-dev]
 
     steps:
     - uses: actions/checkout@v2
diff --git a/tests/test_basic.py b/tests/test_basic.py
index c120f86..07b961e 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -1,6 +1,7 @@
 import dlltracer
 import io
 import pathlib
+import pytest
 import sys
 
 
@@ -15,10 +16,10 @@ def test_out():
 
 
 def test_collect():
-    assert "_hashlib" not in sys.modules
+    assert "_msi" not in sys.modules
 
     with dlltracer.Trace(collect=True) as events:
-        import _hashlib
+        import _msi
 
     assert events
     names = set()
@@ -28,14 +29,17 @@ def test_collect():
         assert repr(e)
         assert str(e)
         names.add(pathlib.PurePath(e.path).stem.casefold())
-    assert "_hashlib" in names
+    assert "_msi" in names
 
 
 def test_audit():
     assert "_overlapped" not in sys.modules
 
-    with dlltracer.Trace(audit=True):
-        import _overlapped
+    try:
+        with dlltracer.Trace(audit=True):
+            import _overlapped
+    except NotImplementedError:
+        assert sys.version_info[:2] < (3, 8)
 
     # TODO: Collect and verify the hooked events in a subprocess
     # For now, we simply ensure that we do not crash when raising them