diff -ur libxml2-2.9.2.old/python/setup.py libxml2-2.9.2/python/setup.py
--- libxml2-2.9.2.old/python/setup.py	2014-10-16 09:35:22.000000000 +0100
+++ libxml2-2.9.2/python/setup.py	2015-01-22 12:23:18.804795900 +0000
@@ -123,7 +123,7 @@
 
 with_xslt=0
 if missing("libxslt-py.c") or missing("libxslt.py"):
-    if missing("xsltgenerator.py") or missing("libxslt-api.xml"):
+    if missing("xsltgenerator.py") or missing("libxslt-python-api.xml"):
         print("libxslt stub generator not found, libxslt not built")
     else:
         try:
@@ -192,7 +192,6 @@
     includes.append(xslt_includes)
     modules.append('libxslt')
 
-
 extens=[Extension('libxml2mod', c_files, include_dirs=includes,
                   library_dirs=libdirs,
                   libraries=libs, define_macros=macros)]
diff -ur libxml2-2.9.2.old/python/setup.py.in libxml2-2.9.2/python/setup.py.in
--- libxml2-2.9.2.old/python/setup.py.in	2014-10-16 05:46:36.000000000 +0100
+++ libxml2-2.9.2/python/setup.py.in	2015-01-22 12:24:13.423100400 +0000
@@ -123,7 +123,7 @@
 
 with_xslt=0
 if missing("libxslt-py.c") or missing("libxslt.py"):
-    if missing("xsltgenerator.py") or missing("libxslt-api.xml"):
+    if missing("xsltgenerator.py") or missing("libxslt-python-api.xml"):
         print("libxslt stub generator not found, libxslt not built")
     else:
         try:
diff -ur libxml2-2.9.9/python/types.c.orig libxml2-2.9.9/python/types.c
--- libxml2-2.9.9/python/types.c.orig	2018-03-05 10:29:58.000000000 -0500
+++ libxml2-2.9.9/python/types.c	2019-06-09 02:48:44.150466800 -0400
@@ -26,14 +26,20 @@
 
 FILE *
 libxml_PyFileGet(PyObject *f) {
-    int fd, flags;
+    int fd;
     FILE *res;
     const char *mode;
+#ifdef _WIN32
+    PyObject *modeObj, *modeBytes;
+#else
+    int flags;
+#endif
 
     fd = PyObject_AsFileDescriptor(f);
     /*
      * Get the flags on the fd to understand how it was opened
      */
+#ifndef _WIN32
     flags = fcntl(fd, F_GETFL, 0);
     switch (flags & O_ACCMODE) {
         case O_RDWR:
@@ -76,6 +82,67 @@ libxml_PyFileGet(PyObject *f) {
 	return(NULL);
     }
     return(res);
+#else
+    /*
+     * The mode sniffing above isn't possible on windows - 
+     * the CRT simply doesn't expose an interface for 
+     * retreiving the mode of the fd (even though it supports 
+     * the same POSIX set at creation).
+     *
+     * So instead, we look for a .mode attribute on f.
+     *
+     * Python 3's open() always sets a .mode attribute 
+     * before returning a value (even when a custom opener
+     * is provided), so this covers the majority of cases.
+     *
+     * This won't work for callers passing other file-like 
+     * objects that don't implement .mode; they will just
+     * have to implement it somehow (hopefully they are
+     * just wrapping something that does know the mode).
+     */
+
+    modeObj = PyObject_GetAttrString(f, "mode");
+    if (!modeObj) {
+        return(NULL);
+    }
+
+    if (PyUnicode_Check(modeObj)) {
+        modeBytes = PyObject_CallMethod(
+            modeObj, "encode", "s", "ascii");
+        if (!modeBytes) {
+            Py_DECREF(modeObj);
+            return(NULL);
+        }
+        mode = PyBytes_AsString(modeBytes);
+        if (!mode) {
+            Py_DECREF(modeObj);
+            return(NULL);
+        }
+        Py_DECREF(modeBytes);
+    } else if (PyBytes_Check(modeObj)) {
+        mode = PyBytes_AsString(modeObj);
+        if (!mode) {
+            Py_DECREF(modeObj);
+            return(NULL);
+        }
+    } else {
+        Py_DECREF(modeObj);
+        return(NULL);
+    }
+
+    Py_DECREF(modeObj);
+
+    fd = _dup(fd);
+    if (fd == -1) {
+        return(NULL);
+    }
+    res = _fdopen(fd, mode);
+    if (res == NULL) {
+        _close(fd);
+	return(NULL);
+    }
+    return(res);
+#endif
 }
 
 void libxml_PyFileRelease(FILE *f) {
