THRIFT-5899: Python tests fail for the Appveyor MSVC builds (#3229)

* Temporarily switch off shared build

- See THRIFT-5898

* Skip type_hints tests for python lower than 3.7

- PR#2929 called out that the changes breaks Python 3.5 since types came in in 3.6
- Python 3.6 errors out with 'from __future__ import annotations' since it looks like it was only added in 3.7

* More appveyer issues on Windows due to old python

* Remove enum tests for old python versions

- Getting `raise TApplicationException(TApplicationException.MISSING_RESULT, "testEnum failed: unknown result"` error
- PR#2825 state it is a breaking change, not sure why and for what version of Python

* Disable SSL tests for old Python

- Appveyor error: ` AttributeError: module 'ssl' has no attribute 'PROTOCOL_TLS_CLIENT'`

* Can't get the test to skip so revert the change that broke it

- See PR#3050

* THRIFT-5900: Pin the cross test stage to python 3.13

- See https://issues.apache.org/jira/browse/THRIFT-5900
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 25a625f..c991336 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -638,7 +638,7 @@
 
       - uses: actions/setup-python@v6
         with:
-          python-version: "3.x"
+          python-version: "3.13" # Pin to 3.13 for now -> see THRIFT-5900
 
       - uses: actions/setup-java@v5
         with:
diff --git a/appveyor.yml b/appveyor.yml
index ff35d52..07bf2ca 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -40,7 +40,7 @@
      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
      PLATFORM: x64
      CONFIGURATION: Release
-     BUILD_SHARED_LIBS: ON
+     BUILD_SHARED_LIBS: OFF
      BOOST_VERSION: 1.67.0
      LIBEVENT_VERSION: 2.1.8
      PYTHON_VERSION: 3.6
diff --git a/lib/py/src/transport/TSSLSocket.py b/lib/py/src/transport/TSSLSocket.py
index d3263c6..dc6c1fb 100644
--- a/lib/py/src/transport/TSSLSocket.py
+++ b/lib/py/src/transport/TSSLSocket.py
@@ -47,8 +47,13 @@
     # SSL 2.0 and 3.0 are disabled via ssl.OP_NO_SSLv2 and ssl.OP_NO_SSLv3.
     # For python < 2.7.9, use TLS 1.0 since TLSv1_X nor OP_NO_SSLvX is
     # unavailable.
-    _default_protocol = ssl.PROTOCOL_TLS_CLIENT if _has_ssl_context else \
-        ssl.PROTOCOL_TLSv1
+    # For python < 3.6, use SSLv23 since TLS is not available
+    if sys.version_info < (3, 6):
+        _default_protocol = ssl.PROTOCOL_SSLv23 if _has_ssl_context else \
+            ssl.PROTOCOL_TLSv1
+    else:
+        _default_protocol = ssl.PROTOCOL_TLS_CLIENT if _has_ssl_context else \
+            ssl.PROTOCOL_TLSv1
 
     def _init_context(self, ssl_version):
         if self._has_ssl_context:
diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py
index 51ea7e3..327dae0 100644
--- a/lib/py/src/transport/TSocket.py
+++ b/lib/py/src/transport/TSocket.py
@@ -22,6 +22,7 @@
 import os
 import socket
 import sys
+import platform
 
 from .TTransport import TTransportBase, TTransportException, TServerTransportBase
 
@@ -234,7 +235,10 @@
 
         self.handle = s = socket.socket(res[0], res[1])
         if s.family is socket.AF_INET6:
-            s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
+            if platform.system() == 'Windows' and sys.version_info < (3, 8):
+                logger.warning('Windows socket defaulting to IPv4 for Python < 3.8: See https://github.com/python/cpython/issues/73701')
+            else:
+                s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         if hasattr(s, 'settimeout'):
             s.settimeout(None)
diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py
index f48224f..ede6a30 100755
--- a/test/py/RunClientServer.py
+++ b/test/py/RunClientServer.py
@@ -212,6 +212,9 @@
         # skip any servers that don't work with SSL
         if with_ssl and try_server in SKIP_SSL:
             return False
+        if with_ssl and (sys.version_info < (3,7)):
+            print('Skipping \'with_ssl\' test since python 3.7 or later is required')
+            return False
         if self.verbose > 0:
             print('\nTest run #%d:  (includes %s) Server=%s,  Proto=%s,  zlib=%s,  SSL=%s'
                   % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl))
@@ -243,6 +246,9 @@
                             # skip any servers that don't work with SSL
                             if with_ssl and try_server in SKIP_SSL:
                                 continue
+                            if with_ssl and (sys.version_info < (3,7)):
+                                print('Skipping \'with_ssl\' test since python 3.7 or later is required')
+                                continue
                             test_count += 1
                             if self.verbose > 0:
                                 print('\nTest run #%d:  (includes %s) Server=%s,  Proto=%s,  zlib=%s,  SSL=%s'
@@ -277,6 +283,12 @@
 
     generated_dirs = []
     for gp_dir in options.genpydirs.split(','):
+        if gp_dir == 'type_hints' and (sys.version_info < (3,7)):
+            print('Skipping \'type_hints\' test since python 3.7 or later is required')
+            continue
+        if gp_dir == 'enum' and (sys.version_info < (3,7)):
+            print('Skipping \'enum\' test since python 3.7 or later is required')
+            continue
         generated_dirs.append('gen-py-%s' % (gp_dir))
 
     # commandline permits a single class name to be specified to override SERVERS=[...]