diff --git a/META.json b/META.json
index 303ff38..021289e 100644
--- a/META.json
+++ b/META.json
@@ -4,13 +4,13 @@
       "Neil Watkiss <NEILW@cpan.org>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150005",
+   "generated_by" : "ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010",
    "license" : [
       "perl_5"
    ],
    "meta-spec" : {
       "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
-      "version" : "2"
+      "version" : 2
    },
    "name" : "Inline-Python",
    "no_index" : {
@@ -34,6 +34,7 @@
          "requires" : {
             "Data::Dumper" : "0",
             "Digest::MD5" : "2.5",
+            "File::Spec" : "0",
             "Inline" : "0.46"
          }
       },
@@ -56,5 +57,5 @@
       }
    },
    "version" : "0.56",
-   "x_serialization_backend" : "JSON::PP version 2.27300_01"
+   "x_serialization_backend" : "JSON::PP version 4.06"
 }
diff --git a/META.yml b/META.yml
index 3ec49cb..ac1ec57 100644
--- a/META.yml
+++ b/META.yml
@@ -12,7 +12,7 @@ build_requires:
 configure_requires:
   ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150005'
+generated_by: 'ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -25,6 +25,7 @@ no_index:
 requires:
   Data::Dumper: '0'
   Digest::MD5: '2.5'
+  File::Spec: '0'
   Inline: '0.46'
 resources:
   repository: http://github.com/niner/inline-python-pm.git
diff --git a/Makefile.PL b/Makefile.PL
index 98b5631..7d1a1b4 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -3,6 +3,8 @@ use Config;
 use Cwd qw(abs_path);
 use ExtUtils::MakeMaker 6.64;
 use Getopt::Long;
+use File::Spec;
+use File::Basename;
 
 GetOptions(
 	   'gdb:s' => \$gdb,
@@ -16,16 +18,22 @@ usage() if $help;
 # What python are we going to try?
 #============================================================================
 my $sel = $ENV{INLINE_PYTHON_EXECUTABLE};
+my $num_python3 = 0;
 unless ($sel) {
     my @pythons;
     my %pythons;
     my $sep = $^O eq 'MSWin32' ? ";" : ":";
+    my $exe = $^O eq 'MSWin32' ? ".exe" : "";
     for $p (split /$sep/, $ENV{PATH}) {
         $p =~ s/^~/$ENV{HOME}/;
-        $p .= "/python";
-        next unless -f $p and -x $p;
-        next if $pythons{abs_path($p)}++; # filter symlinked duplicates
-        push @pythons, { path => $p };
+        for $exe_version ('3', '') {
+            my $py = File::Spec->catfile($p, "python$exe_version$exe");
+            next unless -f $py and -x $py;
+            next if $pythons{abs_path($py)}++; # filter symlinked duplicates
+            my $version = get_python_major_version($py);
+            push @pythons, { path => $py, version => $version };
+            $num_python3++ if ($version == 3);
+        }
     }
 
     # Keep them in PATH order.
@@ -40,6 +48,16 @@ unless ($sel) {
         print "Using the only python executable I could find\n";
         print 'Set the INLINE_PYTHON_EXECUTABLE environment variable to'
             . " the full path to your python executable to override this selection.\n";
+    } elsif ($num_python3 == 1) {   # Prefer python 3
+        for my $python (@pythons) {
+            if ($python->{version} == 3) {
+                $sel = $python;
+                print "Using the only python 3 executable I could find even though python 2 was also found\n";
+                print 'Set the INLINE_PYTHON_EXECUTABLE environment variable to'
+                    . " the full path to your python executable to override this selection.\n";
+                last;
+            }
+        }
     }
     unless ($sel) {
         $sel = prompt("Use which?", '1');
@@ -56,6 +74,7 @@ unless ($sel) {
 $sel = { path => $sel } unless ref $sel eq 'HASH'; # in case the user entered a path
 
 print "Using $sel->{path}\n";
+my $py_major_version = get_python_major_version($sel->{path});
 
 #============================================================================
 # Interrogate the python interpreter (or the user) for required flags
@@ -63,7 +82,9 @@ print "Using $sel->{path}\n";
 interrogate($sel);
 
 # Fix up the libpath and libpython
-die "Could not find Python.h in include path. make will not work" unless -e "$sel->{incpath}/Python.h";
+die "Could not find Python.h in include path. make will not work"
+  unless -e File::Spec->catfile($sel->{incpath}, "Python.h");
+
 substr($sel->{incpath}, 0, 0) = "-I";
 substr($sel->{libpath}, 0, 0) = "-L";
 $sel->{libpython} =~ s/lib(.*)(?:\.\Q$Config{dlext}\E|\Q$Config{_a}\E)/-l$1/;
@@ -71,7 +92,9 @@ $sel->{libpython} =~ s/lib(.*)(?:\.\Q$Config{dlext}\E|\Q$Config{_a}\E)/-l$1/;
 my @flags;
 push @flags, debug_flag() if defined $gdb;
 push @flags, '-DI_PY_DEBUG' if $debug;
+push @flags, "-DPY_MAJOR_VERSION=$py_major_version";
 push @flags, 'none (perl Makefile.PL --help for details)' unless @flags;
+$sel->{syslib} = '' if $sel->{syslib} eq "None";
 print <<END;
 Using These Settings:
    Extra Libs:  $sel->{syslibs}
@@ -100,6 +123,7 @@ WriteMakefile(
                             'Inline'       => 0.46,
                             'Digest::MD5'  => 2.50,
                             'Data::Dumper' => 0,
+                            'File::Spec'   => 0,
 			  },
         TEST_REQUIRES => {
                             'Test'                => 0,
@@ -120,11 +144,114 @@ WriteMakefile(
 			    },
 			   },
 	      clean => {FILES => 'blib_test/'},
+         dynamic_lib => {
+             OTHERLDFLAGS => ($sel->{rpath} ? "-Wl,-rpath,$sel->{rpath}" : ''),
+          },
+
 	     );
 
 #============================================================================
 # Tries to ask the python interpreter what libraries we need, where its
 # include directories are, etc.
+# Typical values of the Python sysconfig variables:
+#
+# - VERSION
+#
+#   - Ubuntu : 3.10
+#   - Windows: 310
+#   - macOS  : 3.10
+#
+# - BINDIR
+#
+#   - Ubuntu :
+#    - system version: /usr/bin
+#    - pyenv version : /home/username/.pyenv/versions/3.9.4/bin
+#  - Windows : C:\Python\Python310  (NOTE: missing trailing "bin")
+#  - macOS   :
+#    - system version : /Applications/Xcode.app/Contents/Developer/Library
+#                        /Frameworks/Python3.framework/Versions/3.8/bin
+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/bin
+#
+# - LIBS:
+#
+#   - Ubuntu : -lcrypt -lpthread -ldl  -lutil -lm
+#   - Windows: [None]
+#   - macOS  :
+#    - system version : -ldl -lSystem -framework CoreFoundation
+#    - pyenv version  : -ldl -framework CoreFoundation
+#
+# - INCLUDEPY
+#
+#   - Ubuntu : /usr/include/python3.9
+#   - Windows: C:\Python\Python310\Include
+#   - macOS
+#    - system version : /Applications/Xcode.app/Contents/Developer/Library
+#                        /Frameworks/Python3.framework/Versions/3.8/Headers
+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/include/python3.10d
+#
+# - LIBPL
+#
+#   - Ubuntu :
+#    - system version : /usr/lib/python3.9/config-3.9-x86_64-linux-gnu
+#    - pyenv version  : /home/username/.pyenv/versions/3.8.9
+#                         /lib/python3.8/config-3.8-x86_64-linux-gnu (NOTE: this folder does
+#                              not contain a shared library even if python was built with
+#                              --enable-shared. However, the folder LIBDIR, see below, does)
+#   - Windows: [None]  (NOTE: this should be "$BINDIR/libs" on windows)
+#   - macOS  :
+#    - system version : /Applications/Xcode.app/Contents/Developer/Library/Frameworks
+#                        /Python3.framework/Versions/3.8/lib/python3.8/config-3.8-darwin
+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/lib
+#                           /python3.10/config-3.10d-darwin
+#
+# - LDLIBRARY
+#
+#   - Ubuntu :
+#     - if python was built with --enable-shared : libpython3.9.so
+#     - else                                     : libpython3.9.a
+#   - Windows: [None] (NOTE: this should be "python310.lib" on windows,
+#                      where a .lib file is a so-called import-library on Windows. The
+#                      import library reference a .dll library in $BINDIR.
+#                      On Windows there is also a stable-across-versions-subset library
+#                      called "python3.lib" (which references "python3.dll" in $BINDIR,
+#                      see https://www.python.org/dev/peps/pep-0384/ for more information.)
+#   - macOS  :
+#    - system version: Python3.framework/Versions/3.8/Python3 (NOTE: this is a .dylib
+#                           i.e. a shared library)
+#    - pyenv version :
+#     - if built with --enable-shared : libpython3.10d.dylib
+#     - else                          : libpython3.10d.a
+#
+# - LIBRARY
+#
+#   - Ubuntu : libpython3.9.a
+#   - Windows: [None]  (NOTE: static library is not available but import library exists
+#                        see note on LDLIBRARY above)
+#   - macOS  : libpython3.10d.a
+#
+# - LIBDEST
+#
+#   - Ubuntu : /home/username/.pyenv/versions/3.9.4/lib/python3.9
+#   - Windows: C:\Python310\Lib (NOTE: this folder does not contain anything interesting
+#                            to us. No static or shared libraries here, but the import
+#                            library is in the libs folder C:\Python310\libs and the
+#                            .dll library is in the BINDIR C:\Python310)
+#   - macOS  :
+#    - system version : /Applications/Xcode.app/Contents/Developer/Library
+#                          /Frameworks/Python3.framework/Versions/3.8/lib/python3.8
+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/lib/python3.10
+#
+# - LIBDIR
+#
+#   - Ubuntu  :
+#    - system version : /usr/lib/x86_64-linux-gnu
+#    - pyenv version  : /home/username/.pyenv/versions/3.9.4/lib
+#   - Windows : [None]
+#   - macOS   :
+#    - system version: /Applications/Xcode.app/Contents/Developer/Library
+#                          /Frameworks/Python3.framework/Versions/3.8/lib
+#    - pyenv version : /Users/username/.pyenv/versions/3.10.0-debug/lib
+#
 #============================================================================
 sub interrogate {
     my $ref = shift;
@@ -134,23 +261,190 @@ sub interrogate {
     $ref->{libpath}   = get_config_var($ref, "LIBPL");
     $ref->{ldlib}     = get_config_var($ref, "LDLIBRARY");
     $ref->{libpython} = get_config_var($ref, "LIBRARY");
-    my $tmp = rindex($ref->{libpython}, '/') + 1;
-    $ref->{libpython} = substr($ref->{libpython}, $tmp);
-    $ref->{libpath} = join '/', (get_config_var($ref, "LIBDEST"),
-				 'config')
-      if ($ref->{libpath} eq 'None');
+    my $tmp = File::Spec->canonpath($ref->{libpython});
+    my @dirs = File::Spec->splitdir( $tmp );
+    $ref->{libpython} = $dirs[-1];
+    # On Windows, Python config var "LIBRARY" is not defined
+    if ($ref->{libpython} eq 'None') {
+        special_get_libpath($ref);
+    }
+    $ref->{libpath} = File::Spec->catfile(get_config_var($ref, "LIBDEST"), 'config')
+        if ($ref->{libpath} eq 'None');
+    $ref->{rpath} = ''; # only used if we are linking with a shared library, see below.
+    $ref->{cflags} = get_config_var($ref, 'CFLAGS');
+    $ref->{config_args} = get_config_var($ref, 'CONFIG_ARGS');
+    $ref->{enable_shared} = (get_config_var($ref, 'Py_ENABLE_SHARED') eq "1");
+    if (using_macos_system_python($ref)) {
+        add_rpath_for_macos_system_python($ref);
+    }
+    elsif ($^O ne "MSWin32") {  # we use the import library on Windows,
+                                   # see special_get_libpath() below
+        special_non_windows_check_shared_static_libs($ref);
+    }
     return query_options($ref) unless sanity_check($ref);
 }
 
+# on macOS using the system python, the path to the shared and static libraries
+#   is given by "libpath" (LIBPL). In this directory there exists two files:
+#   - libpythonxxx.a
+#   - libpythonxxx.dylib
+# the first name (the static library libpythonxxx.a) is given by the python sysconfig
+# variable "libpython" (LIBRARY). However, both these files are symlinks to a shared
+# library called "Python" which is located relative to LIBPL with path:
+# ../../../Python3. This file "Python3" (or "Python2" ??), is a dylib with an embedded
+#  @rpath magic search path given by: @rpath/Python3.framework/Versions/3.8/Python3 which
+#  is also the ID of the library (LC_ID_DYLIB) which means that Python.so (the Perl
+#  generated interface) must include an rpath to the directory 3 levels above the
+# location of "Python3" (which is 6 levels above libpythonxxx.dylib in LIBPL).
+#  This directory is fortunately given by the config variable
+#  PYTHONFRAMEWORKPREFIX.
+#
+sub add_rpath_for_macos_system_python {
+    my ($ref) = @_;
+
+    $ref->{rpath} = get_config_var($ref, 'PYTHONFRAMEWORKPREFIX');
+};
+
+sub special_non_windows_check_shared_static_libs {
+    my ($ref) = @_;
+
+    if (shared_lib_priority($ref)) {
+        $ref->{libpython} = $ref->{ldlib};
+        my $shared_lib = File::Spec->catfile($ref->{libpath}, $ref->{libpython});
+        if (!-f $shared_lib) {
+            # Special case for pyenv. The shared library exists in $LIBDIR instead of in
+            #   $LIBPL
+            $ref->{libpath} = get_config_var($ref, "LIBDIR");
+        }
+        $ref->{rpath} = $ref->{libpath};
+    }
+    else {
+        if (!check_static_library_ok($ref)) {
+            # In this case we may find a shared library to link with in
+            #  $LIBDIR instead of in $LIBPL, this happens if you install Python
+            #  with pyenv (on the other hand for the system python there will
+            #  a shared library in both $LIBDIR and $LIBPL, see issue #29 for more information.
+            # TODO: However, this still does not work for pyenv (tested on Ubuntu). For some
+            #   reason this shared library does not behave well unless python was also compiled
+            #   with -fPIC option.
+            if (( $ref->{cflags} !~ /\Q-fPIC\E/i)  && ($ref->{path} !~ m{^/(?:usr/)?bin/python})) {
+                if ($ref->{enable_shared}) {
+                    warn "WARNING: This python's shared library was compiled with --enable-shared but not "
+                    ." with -fPIC option, this might lead to strange runtime behavior.\n";
+                }
+                else {
+                    # TODO: strangely this seems to work fine on macOS.
+                    #   More investigation is needed here...
+                    warn "WARNING: This python was not compiled with --enable-shared and not "
+                        . "with -fPIC.\n"
+                        . "WARNING: This is known to not work on linux.\n";
+                }
+            }
+            $ref->{libpath} = get_config_var($ref, "LIBDIR");
+            $ref->{libpython} = $ref->{ldlib};
+            $ref->{rpath} = $ref->{libpath};
+        }
+    }
+}
+
+sub shared_lib_priority {
+    my ($ref) = @_;
+
+    if ($ref->{libpython} ne $ref->{ldlib}) {
+        # This should happen if python was compiled with --enable-shared
+        #  In this case the linker will prefer the shared library
+        my $static_lib = File::Spec->catfile($ref->{libpath}, $ref->{libpython});
+        my $shared_lib = File::Spec->catfile($ref->{libpath}, $ref->{ldlib});
+        return 1 if (-f $static_lib) && (-f $shared_lib);
+    }
+    return 0;
+}
+
+sub check_static_library_ok {
+    my ($ref) = @_;
+
+    # We should check if the static library was compiled with -fPIC, or else
+    #  we cannot create a shared Python.so from it.
+    #  TODO: It seem like it is possible to build python with --enable-shared
+    #    and without CFLAGS=-fPIC, and this will make both libpythonxx.so and
+    #    libpythonxx.a  position independent, but in this case strange things
+    #    may happen at runtime (i.e. when running "make test"), see issue #29
+    #    for more information. This should be investigated futher to determine what
+    #    is actually going on.
+    #    This seems to not be a problem on macOS though.
+    return 1 if $ref->{cflags} =~ /\Q-fPIC\E/i;
+    warn "WARNING: The static python library seems not to be position indepenent.\n"
+         . "WARNING: If this does not work you should try again with a "
+         . "python version that was compiled with CFLAGS=-fPIC\n";
+    return 0;
+}
+
+sub using_macos_system_python {
+    my ($ref) = @_;
+
+    return ($^O eq "darwin") && ($ref->{path} =~ m{^/usr/bin/python});
+}
+
+sub check_shared_lib_support() {
+    my ($ref) = @_;
+
+    # Windows python always have a shared lib
+    return 1 if $^O eq "MSWin32";
+    # The system python always have a shared lib on macOS
+    return 1 if using_macos_system_python($ref);
+    # See https://stackoverflow.com/a/23202055/2173773
+    return $ref->{enable_shared};
+}
+
+sub get_python_version {
+    my $ref = shift;
+    my $major = `$ref->{path} -c "import sys; print(sys.version_info[0])"`;
+    my $minor = `$ref->{path} -c "import sys; print(sys.version_info[1])"`;
+    return ($major, $minor);
+}
+
+# On Windows, Python config var "LIBRARY" is not defined, so we try another method
+#  to obtain the library path name
+sub special_get_libpath {
+    my $ref = shift;
+    my ($major, $minor) = get_python_version($ref);
+    my $cmd;
+    if (($major == 3 && $minor >=10) || $major > 3 ) {
+        $cmd = 'import setuptools.command.build_ext; d=setuptools.dist.Distribution();'
+              .'b=setuptools.command.build_ext.build_ext(d)';
+    }
+    else {
+        $cmd = 'import distutils.command.build_ext; d=distutils.core.Distribution();'
+              . 'b=distutils.command.build_ext.build_ext(d)';
+    }
+    my @lines = `$ref->{path} -c "$cmd;b.finalize_options();print(b.library_dirs[0])" 2>&1`;
+    my $val = $lines[-1];
+    chomp $val;
+    return '' if !$val;
+    # On Windows, $val should now be equal to $BINDIR/libs
+    my $pyscript = "import sysconfig; "
+                  . "print(sysconfig.get_config_var('VERSION'))";
+    my $version = `$ref->{path} -c "$pyscript"`;
+    chomp $version;
+    $ref->{libpath} = $val;
+    $ref->{libpython} = "python${version}.lib"; # Note: on Windows this is an import library,
+                                                #  that referes to a shared library
+                                                #  (not a static library)
+    # The above file should always exist, alternatively we could
+    #  set libpath to $BINDIR and libpython to python$version.dll and use the shared library
+    #  directly instead of using the import library.
+    return $val;
+}
+
 sub test_interrogate {
     my $ref = shift;
-    `$ref->{path} -c "import distutils.sysconfig; distutils.sysconfig.get_config_var" 2>&1`;
+    `$ref->{path} -c "import sysconfig; sysconfig.get_config_var" 2>&1`;
     print <<END if $?;
 
 This python is so old it doesn't know how to answer my questions.
 
-Instead, you will be asked a series of questions about it. If possible, 
-I will give you a set of reasonable options to choose from. You can 
+Instead, you will be asked a series of questions about it. If possible,
+I will give you a set of reasonable options to choose from. You can
 always enter the complete answer yourself if none of mine are correct.
 END
     #' stupid vim.
@@ -161,32 +455,40 @@ sub sanity_check {
     my $ref = shift;
 
     $ref->{libpython} = $ref->{ldlib}
-        if not -f join '/', $ref->{libpath}, $ref->{libpython}
-           and -f join '/', $ref->{libpath}, $ref->{ldlib};
-
+        if not -f File::Spec->catfile($ref->{libpath}, $ref->{libpython})
+           and -f File::Spec->catfile($ref->{libpath}, $ref->{ldlib});
+    my $libpath = File::Spec->catfile($ref->{libpath}, $ref->{libpython});
     unless (-d $ref->{libpath} &&
 	    -d $ref->{incpath} &&
-	    (-f join '/', $ref->{libpath}, $ref->{libpython})
+	    (-f File::Spec->catfile($ref->{libpath}, $ref->{libpython}))
 	   ) {
 	print <<END and return 0;
 
 This python's configuration files are messed up. You'll have have to
 answer the questions yourself. Here is what Python said:
 
-   Extra Libs:  $sel->{syslibs}
-   Python Library:  $sel->{libpath}/$sel->{libpython}
-   Include Path:    $sel->{incpath}
+   Extra Libs:  $ref->{syslibs}
+   Python Library:  $libpath
+   Include Path:    $ref->{incpath}
 END
     # ' stupid vim.
     }
     return 1;
 }
 
+sub get_python_major_version {
+    my $exe = shift;
+    my $version = `$exe --version 2>&1`;
+
+    $version =~ /(\d+)\./;
+    return $1;
+}
+
 sub get_config_var {
     my $ref = shift;
     my $key = shift;
     my $exe = $ref->{path};
-    my $val = `$exe -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('$key'))"`;
+    my $val = `$exe -c "import sysconfig; print(sysconfig.get_config_var('$key'))"`;
     chomp $val;
     return $val;
 }
@@ -195,21 +497,21 @@ sub query_options {
     my $ref = shift;
 
     # Every python I've seen needs pthreads. Obviously not on windows.
-    my $libs_guess = $ref->{syslibs} ? $ref->{syslibs} : 
+    my $libs_guess = $ref->{syslibs} ? $ref->{syslibs} :
 		     $^O eq 'MSWin32' ? '' : '-lpthread';
     print <<END;
 
-	1. LIBS option. I need to know what extra libraries, if any,  
+	1. LIBS option. I need to know what extra libraries, if any,
 	   are required by this build of python. I recommend this:
 	   ${ $libs_guess ? \$libs_guess : \"No extra libraries" }
 
 END
-    $ref->{syslibs} = prompt("Enter extra libraries (e.g. -lfoo -lbar)", 
+    $ref->{syslibs} = prompt("Enter extra libraries (e.g. -lfoo -lbar)",
 			     $libs_guess);
 
     print <<END;
 
-	2. LIBRARY option. The location of the python library. 
+	2. LIBRARY option. The location of the python library.
 	   Inline::Python needs to link against it to use Python.
 
 	Here are the libraries I know about:
@@ -218,8 +520,9 @@ END
     my $lib = prompt("Which? Or enter another.", '1');
     $lib = $libs[$lib-1] if $lib =~ /^\d+$/;
     $lib =~ s|\\|/|g;
-    $ref->{libpath} = substr($lib, 0, rindex($lib, '/'));
-    $ref->{libpython} = substr($lib, rindex($lib, '/')+1);
+    my ($volume, $directories, $file) = File::Spec->splitpath( $lib );
+    $ref->{libpath} = File::Spec->canonpath(File::Spec->catpath($volume, $directories));
+    $ref->{libpython} = $file;
 
     print <<END;
 
@@ -245,7 +548,7 @@ sub show_python_libs {
   $exe =~ s|[^/]+$||;
   $exe .= "../lib/python*/config/libpython*";
 
-  my @py_libs = 
+  my @py_libs =
    (
    (map { $exe . $_ } '.a', '.so', '.lib'),
    '/usr/lib64/libpython*.a',
@@ -286,17 +589,21 @@ sub show_python_incs {
   $exe =~ s|[^/]+$||;
   $exe .= "../include/python*";
 
-  my @py_incs = 
-   (
-   $exe,
-   '/usr/local/ActivePython-*/include/python*',
-   '/usr/include/python*',
-   '/usr/local/include/python*',
-
-   # Win32 support
-   'C:/Python*/include',
-   'C:/Program Files/Python*/include',
-   );
+  my @py_incs;
+  if ($^O eq "MSWin32") {
+    @py_incs = (
+      'C:\Python*\include',
+      'C:\Program Files\Python*\include'
+    );
+  }
+  else {
+    @py_incs = (
+      $exe,
+      '/usr/local/ActivePython-*/include/python*',
+      '/usr/include/python*',
+      '/usr/local/include/python*',
+    );
+  }
 
   my (@found, %found);
   push @found, grep { -d && $found{abspath($_)}++ == 0 } glob for @py_incs;
@@ -312,12 +619,12 @@ sub abspath {
     use Cwd qw(abs_path);
     my ($path, $file) = shift;
     if (-f $path) {
-	my @p = split '/', $path;
-        $path = join '/', @p[0..$#p-1]; # can't use -2 in a range
-	$file = $p[-1];
+        my @parts = File::Spec->splitpath($path);
+        $path = File::Spec->canonpath(File::Spec->catpath(@parts[0..1]));
+    	$file = $parts[-1];
     }
     $path = abs_path($path);
-    return defined $file ? join '/', $path, $file : $path;
+    return defined $file ? File::Spec->catfile($path, $file) : $path;
 }
 
 sub debug_flag {
diff --git a/Python.xs b/Python.xs
index 63b32ce..7a3c793 100644
--- a/Python.xs
+++ b/Python.xs
@@ -25,14 +25,6 @@ void do_pyinit() {
 #ifdef EXPOSE_PERL
     PyObject *main_dict;
     PyObject *perl_obj;
-
-#if PY_MAJOR_VERSION >= 3
-    PyObject *dummy1 = PyBytes_FromString(""),
-             *dummy2 = PyBytes_FromString("main");
-#else
-    PyObject *dummy1 = PyString_FromString(""),
-             *dummy2 = PyString_FromString("main");
-#endif
 #endif
     /* sometimes Python needs to know about argc and argv to be happy */
     int _python_argc = 1;
@@ -48,6 +40,14 @@ void do_pyinit() {
     PySys_SetArgv(_python_argc, _python_argv);  /* Tk needs this */
 
 #ifdef EXPOSE_PERL
+#if PY_MAJOR_VERSION >= 3
+    PyObject *dummy1 = PyBytes_FromString(""),
+             *dummy2 = PyBytes_FromString("main");
+#else
+    PyObject *dummy1 = PyString_FromString(""),
+             *dummy2 = PyString_FromString("main");
+#endif
+
     /* create the perl module and add functions */
     initperl();
 
@@ -430,6 +430,7 @@ py_call_method(_inst, mname, ...)
     PyObject *tuple;     /* the parameters */
     PyObject *py_retval; /* the return value */
     int i;
+    int is_string;
     SV *ret;
 
   PPCODE:
@@ -446,13 +447,9 @@ py_call_method(_inst, mname, ...)
 
     Printf(("inst {%p} successfully passed the PVMG test\n", inst));
 
+    is_string = PY_IS_STRING(inst);
 
-    if (!(
-#if PY_MAJOR_VERSION < 3
-        PyInstance_Check(inst) ||
-#endif
-        inst->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE)
-    ) {
+    if (!PY_IS_OBJECT(inst)) {
         croak("Attempted to call method '%s' on a non-instance", mname);
         XSRETURN_EMPTY;
     }
diff --git a/debian/changelog b/debian/changelog
index b926e70..35907e5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+libinline-python-perl (0.56+git20211214.1.5d4b1ff-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+  * Drop patch 0001-Call-Py_Initialize-before-calling-PyBytes_FromString.patch,
+    present upstream.
+  * Drop patch python3.10.-distutils-deprecation.patch, present upstream.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 28 Mar 2022 20:12:51 -0000
+
 libinline-python-perl (0.56-3) unstable; urgency=medium
 
   [ gregor herrmann ]
diff --git a/debian/patches/0001-Call-Py_Initialize-before-calling-PyBytes_FromString.patch b/debian/patches/0001-Call-Py_Initialize-before-calling-PyBytes_FromString.patch
deleted file mode 100644
index 2e9cdfa..0000000
--- a/debian/patches/0001-Call-Py_Initialize-before-calling-PyBytes_FromString.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 90b68bdf370c07b1d3fdd46bbdf1b154ed74b91b Mon Sep 17 00:00:00 2001
-From: Mattias Ellert <mattias.ellert@physics.uu.se>
-Date: Wed, 18 Aug 2021 16:41:10 +0200
-Subject: [PATCH] Call Py_Initialize() before calling PyBytes_FromString()
-
-Not doing this gives a segmentation fault with Python 3.10
----
- Python.xs | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/Python.xs b/Python.xs
-index 11d5033..7a3c793 100644
---- a/Python.xs
-+++ b/Python.xs
-@@ -25,14 +25,6 @@ void do_pyinit() {
- #ifdef EXPOSE_PERL
-     PyObject *main_dict;
-     PyObject *perl_obj;
--
--#if PY_MAJOR_VERSION >= 3
--    PyObject *dummy1 = PyBytes_FromString(""),
--             *dummy2 = PyBytes_FromString("main");
--#else
--    PyObject *dummy1 = PyString_FromString(""),
--             *dummy2 = PyString_FromString("main");
--#endif
- #endif
-     /* sometimes Python needs to know about argc and argv to be happy */
-     int _python_argc = 1;
-@@ -48,6 +40,14 @@ void do_pyinit() {
-     PySys_SetArgv(_python_argc, _python_argv);  /* Tk needs this */
- 
- #ifdef EXPOSE_PERL
-+#if PY_MAJOR_VERSION >= 3
-+    PyObject *dummy1 = PyBytes_FromString(""),
-+             *dummy2 = PyBytes_FromString("main");
-+#else
-+    PyObject *dummy1 = PyString_FromString(""),
-+             *dummy2 = PyString_FromString("main");
-+#endif
-+
-     /* create the perl module and add functions */
-     initperl();
- 
--- 
-2.35.1
-
diff --git a/debian/patches/python3.10.-distutils-deprecation.patch b/debian/patches/python3.10.-distutils-deprecation.patch
deleted file mode 100644
index c300899..0000000
--- a/debian/patches/python3.10.-distutils-deprecation.patch
+++ /dev/null
@@ -1,562 +0,0 @@
-Description: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12.
-Origin: https://github.com/niner/inline-python-pm
- current HEAD as of today
- cf. https://github.com/niner/inline-python-pm/issues/34 and
- https://github.com/niner/inline-python-pm/issues/35
-Reviewed-by: gregor herrmann <gregoa@debian.org>
-Last-Update: 2022-03-28
-
-diff --git a/Makefile.PL b/Makefile.PL
-index 98b5631..7d1a1b4 100644
---- a/Makefile.PL
-+++ b/Makefile.PL
-@@ -3,6 +3,8 @@ use Config;
- use Cwd qw(abs_path);
- use ExtUtils::MakeMaker 6.64;
- use Getopt::Long;
-+use File::Spec;
-+use File::Basename;
- 
- GetOptions(
- 	   'gdb:s' => \$gdb,
-@@ -16,16 +18,22 @@ usage() if $help;
- # What python are we going to try?
- #============================================================================
- my $sel = $ENV{INLINE_PYTHON_EXECUTABLE};
-+my $num_python3 = 0;
- unless ($sel) {
-     my @pythons;
-     my %pythons;
-     my $sep = $^O eq 'MSWin32' ? ";" : ":";
-+    my $exe = $^O eq 'MSWin32' ? ".exe" : "";
-     for $p (split /$sep/, $ENV{PATH}) {
-         $p =~ s/^~/$ENV{HOME}/;
--        $p .= "/python";
--        next unless -f $p and -x $p;
--        next if $pythons{abs_path($p)}++; # filter symlinked duplicates
--        push @pythons, { path => $p };
-+        for $exe_version ('3', '') {
-+            my $py = File::Spec->catfile($p, "python$exe_version$exe");
-+            next unless -f $py and -x $py;
-+            next if $pythons{abs_path($py)}++; # filter symlinked duplicates
-+            my $version = get_python_major_version($py);
-+            push @pythons, { path => $py, version => $version };
-+            $num_python3++ if ($version == 3);
-+        }
-     }
- 
-     # Keep them in PATH order.
-@@ -40,6 +48,16 @@ unless ($sel) {
-         print "Using the only python executable I could find\n";
-         print 'Set the INLINE_PYTHON_EXECUTABLE environment variable to'
-             . " the full path to your python executable to override this selection.\n";
-+    } elsif ($num_python3 == 1) {   # Prefer python 3
-+        for my $python (@pythons) {
-+            if ($python->{version} == 3) {
-+                $sel = $python;
-+                print "Using the only python 3 executable I could find even though python 2 was also found\n";
-+                print 'Set the INLINE_PYTHON_EXECUTABLE environment variable to'
-+                    . " the full path to your python executable to override this selection.\n";
-+                last;
-+            }
-+        }
-     }
-     unless ($sel) {
-         $sel = prompt("Use which?", '1');
-@@ -56,6 +74,7 @@ unless ($sel) {
- $sel = { path => $sel } unless ref $sel eq 'HASH'; # in case the user entered a path
- 
- print "Using $sel->{path}\n";
-+my $py_major_version = get_python_major_version($sel->{path});
- 
- #============================================================================
- # Interrogate the python interpreter (or the user) for required flags
-@@ -63,7 +82,9 @@ print "Using $sel->{path}\n";
- interrogate($sel);
- 
- # Fix up the libpath and libpython
--die "Could not find Python.h in include path. make will not work" unless -e "$sel->{incpath}/Python.h";
-+die "Could not find Python.h in include path. make will not work"
-+  unless -e File::Spec->catfile($sel->{incpath}, "Python.h");
-+
- substr($sel->{incpath}, 0, 0) = "-I";
- substr($sel->{libpath}, 0, 0) = "-L";
- $sel->{libpython} =~ s/lib(.*)(?:\.\Q$Config{dlext}\E|\Q$Config{_a}\E)/-l$1/;
-@@ -71,7 +92,9 @@ $sel->{libpython} =~ s/lib(.*)(?:\.\Q$Config{dlext}\E|\Q$Config{_a}\E)/-l$1/;
- my @flags;
- push @flags, debug_flag() if defined $gdb;
- push @flags, '-DI_PY_DEBUG' if $debug;
-+push @flags, "-DPY_MAJOR_VERSION=$py_major_version";
- push @flags, 'none (perl Makefile.PL --help for details)' unless @flags;
-+$sel->{syslib} = '' if $sel->{syslib} eq "None";
- print <<END;
- Using These Settings:
-    Extra Libs:  $sel->{syslibs}
-@@ -100,6 +123,7 @@ WriteMakefile(
-                             'Inline'       => 0.46,
-                             'Digest::MD5'  => 2.50,
-                             'Data::Dumper' => 0,
-+                            'File::Spec'   => 0,
- 			  },
-         TEST_REQUIRES => {
-                             'Test'                => 0,
-@@ -120,11 +144,114 @@ WriteMakefile(
- 			    },
- 			   },
- 	      clean => {FILES => 'blib_test/'},
-+         dynamic_lib => {
-+             OTHERLDFLAGS => ($sel->{rpath} ? "-Wl,-rpath,$sel->{rpath}" : ''),
-+          },
-+
- 	     );
- 
- #============================================================================
- # Tries to ask the python interpreter what libraries we need, where its
- # include directories are, etc.
-+# Typical values of the Python sysconfig variables:
-+#
-+# - VERSION
-+#
-+#   - Ubuntu : 3.10
-+#   - Windows: 310
-+#   - macOS  : 3.10
-+#
-+# - BINDIR
-+#
-+#   - Ubuntu :
-+#    - system version: /usr/bin
-+#    - pyenv version : /home/username/.pyenv/versions/3.9.4/bin
-+#  - Windows : C:\Python\Python310  (NOTE: missing trailing "bin")
-+#  - macOS   :
-+#    - system version : /Applications/Xcode.app/Contents/Developer/Library
-+#                        /Frameworks/Python3.framework/Versions/3.8/bin
-+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/bin
-+#
-+# - LIBS:
-+#
-+#   - Ubuntu : -lcrypt -lpthread -ldl  -lutil -lm
-+#   - Windows: [None]
-+#   - macOS  :
-+#    - system version : -ldl -lSystem -framework CoreFoundation
-+#    - pyenv version  : -ldl -framework CoreFoundation
-+#
-+# - INCLUDEPY
-+#
-+#   - Ubuntu : /usr/include/python3.9
-+#   - Windows: C:\Python\Python310\Include
-+#   - macOS
-+#    - system version : /Applications/Xcode.app/Contents/Developer/Library
-+#                        /Frameworks/Python3.framework/Versions/3.8/Headers
-+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/include/python3.10d
-+#
-+# - LIBPL
-+#
-+#   - Ubuntu :
-+#    - system version : /usr/lib/python3.9/config-3.9-x86_64-linux-gnu
-+#    - pyenv version  : /home/username/.pyenv/versions/3.8.9
-+#                         /lib/python3.8/config-3.8-x86_64-linux-gnu (NOTE: this folder does
-+#                              not contain a shared library even if python was built with
-+#                              --enable-shared. However, the folder LIBDIR, see below, does)
-+#   - Windows: [None]  (NOTE: this should be "$BINDIR/libs" on windows)
-+#   - macOS  :
-+#    - system version : /Applications/Xcode.app/Contents/Developer/Library/Frameworks
-+#                        /Python3.framework/Versions/3.8/lib/python3.8/config-3.8-darwin
-+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/lib
-+#                           /python3.10/config-3.10d-darwin
-+#
-+# - LDLIBRARY
-+#
-+#   - Ubuntu :
-+#     - if python was built with --enable-shared : libpython3.9.so
-+#     - else                                     : libpython3.9.a
-+#   - Windows: [None] (NOTE: this should be "python310.lib" on windows,
-+#                      where a .lib file is a so-called import-library on Windows. The
-+#                      import library reference a .dll library in $BINDIR.
-+#                      On Windows there is also a stable-across-versions-subset library
-+#                      called "python3.lib" (which references "python3.dll" in $BINDIR,
-+#                      see https://www.python.org/dev/peps/pep-0384/ for more information.)
-+#   - macOS  :
-+#    - system version: Python3.framework/Versions/3.8/Python3 (NOTE: this is a .dylib
-+#                           i.e. a shared library)
-+#    - pyenv version :
-+#     - if built with --enable-shared : libpython3.10d.dylib
-+#     - else                          : libpython3.10d.a
-+#
-+# - LIBRARY
-+#
-+#   - Ubuntu : libpython3.9.a
-+#   - Windows: [None]  (NOTE: static library is not available but import library exists
-+#                        see note on LDLIBRARY above)
-+#   - macOS  : libpython3.10d.a
-+#
-+# - LIBDEST
-+#
-+#   - Ubuntu : /home/username/.pyenv/versions/3.9.4/lib/python3.9
-+#   - Windows: C:\Python310\Lib (NOTE: this folder does not contain anything interesting
-+#                            to us. No static or shared libraries here, but the import
-+#                            library is in the libs folder C:\Python310\libs and the
-+#                            .dll library is in the BINDIR C:\Python310)
-+#   - macOS  :
-+#    - system version : /Applications/Xcode.app/Contents/Developer/Library
-+#                          /Frameworks/Python3.framework/Versions/3.8/lib/python3.8
-+#    - pyenv version  : /Users/username/.pyenv/versions/3.10.0-debug/lib/python3.10
-+#
-+# - LIBDIR
-+#
-+#   - Ubuntu  :
-+#    - system version : /usr/lib/x86_64-linux-gnu
-+#    - pyenv version  : /home/username/.pyenv/versions/3.9.4/lib
-+#   - Windows : [None]
-+#   - macOS   :
-+#    - system version: /Applications/Xcode.app/Contents/Developer/Library
-+#                          /Frameworks/Python3.framework/Versions/3.8/lib
-+#    - pyenv version : /Users/username/.pyenv/versions/3.10.0-debug/lib
-+#
- #============================================================================
- sub interrogate {
-     my $ref = shift;
-@@ -134,23 +261,190 @@ sub interrogate {
-     $ref->{libpath}   = get_config_var($ref, "LIBPL");
-     $ref->{ldlib}     = get_config_var($ref, "LDLIBRARY");
-     $ref->{libpython} = get_config_var($ref, "LIBRARY");
--    my $tmp = rindex($ref->{libpython}, '/') + 1;
--    $ref->{libpython} = substr($ref->{libpython}, $tmp);
--    $ref->{libpath} = join '/', (get_config_var($ref, "LIBDEST"),
--				 'config')
--      if ($ref->{libpath} eq 'None');
-+    my $tmp = File::Spec->canonpath($ref->{libpython});
-+    my @dirs = File::Spec->splitdir( $tmp );
-+    $ref->{libpython} = $dirs[-1];
-+    # On Windows, Python config var "LIBRARY" is not defined
-+    if ($ref->{libpython} eq 'None') {
-+        special_get_libpath($ref);
-+    }
-+    $ref->{libpath} = File::Spec->catfile(get_config_var($ref, "LIBDEST"), 'config')
-+        if ($ref->{libpath} eq 'None');
-+    $ref->{rpath} = ''; # only used if we are linking with a shared library, see below.
-+    $ref->{cflags} = get_config_var($ref, 'CFLAGS');
-+    $ref->{config_args} = get_config_var($ref, 'CONFIG_ARGS');
-+    $ref->{enable_shared} = (get_config_var($ref, 'Py_ENABLE_SHARED') eq "1");
-+    if (using_macos_system_python($ref)) {
-+        add_rpath_for_macos_system_python($ref);
-+    }
-+    elsif ($^O ne "MSWin32") {  # we use the import library on Windows,
-+                                   # see special_get_libpath() below
-+        special_non_windows_check_shared_static_libs($ref);
-+    }
-     return query_options($ref) unless sanity_check($ref);
- }
- 
-+# on macOS using the system python, the path to the shared and static libraries
-+#   is given by "libpath" (LIBPL). In this directory there exists two files:
-+#   - libpythonxxx.a
-+#   - libpythonxxx.dylib
-+# the first name (the static library libpythonxxx.a) is given by the python sysconfig
-+# variable "libpython" (LIBRARY). However, both these files are symlinks to a shared
-+# library called "Python" which is located relative to LIBPL with path:
-+# ../../../Python3. This file "Python3" (or "Python2" ??), is a dylib with an embedded
-+#  @rpath magic search path given by: @rpath/Python3.framework/Versions/3.8/Python3 which
-+#  is also the ID of the library (LC_ID_DYLIB) which means that Python.so (the Perl
-+#  generated interface) must include an rpath to the directory 3 levels above the
-+# location of "Python3" (which is 6 levels above libpythonxxx.dylib in LIBPL).
-+#  This directory is fortunately given by the config variable
-+#  PYTHONFRAMEWORKPREFIX.
-+#
-+sub add_rpath_for_macos_system_python {
-+    my ($ref) = @_;
-+
-+    $ref->{rpath} = get_config_var($ref, 'PYTHONFRAMEWORKPREFIX');
-+};
-+
-+sub special_non_windows_check_shared_static_libs {
-+    my ($ref) = @_;
-+
-+    if (shared_lib_priority($ref)) {
-+        $ref->{libpython} = $ref->{ldlib};
-+        my $shared_lib = File::Spec->catfile($ref->{libpath}, $ref->{libpython});
-+        if (!-f $shared_lib) {
-+            # Special case for pyenv. The shared library exists in $LIBDIR instead of in
-+            #   $LIBPL
-+            $ref->{libpath} = get_config_var($ref, "LIBDIR");
-+        }
-+        $ref->{rpath} = $ref->{libpath};
-+    }
-+    else {
-+        if (!check_static_library_ok($ref)) {
-+            # In this case we may find a shared library to link with in
-+            #  $LIBDIR instead of in $LIBPL, this happens if you install Python
-+            #  with pyenv (on the other hand for the system python there will
-+            #  a shared library in both $LIBDIR and $LIBPL, see issue #29 for more information.
-+            # TODO: However, this still does not work for pyenv (tested on Ubuntu). For some
-+            #   reason this shared library does not behave well unless python was also compiled
-+            #   with -fPIC option.
-+            if (( $ref->{cflags} !~ /\Q-fPIC\E/i)  && ($ref->{path} !~ m{^/(?:usr/)?bin/python})) {
-+                if ($ref->{enable_shared}) {
-+                    warn "WARNING: This python's shared library was compiled with --enable-shared but not "
-+                    ." with -fPIC option, this might lead to strange runtime behavior.\n";
-+                }
-+                else {
-+                    # TODO: strangely this seems to work fine on macOS.
-+                    #   More investigation is needed here...
-+                    warn "WARNING: This python was not compiled with --enable-shared and not "
-+                        . "with -fPIC.\n"
-+                        . "WARNING: This is known to not work on linux.\n";
-+                }
-+            }
-+            $ref->{libpath} = get_config_var($ref, "LIBDIR");
-+            $ref->{libpython} = $ref->{ldlib};
-+            $ref->{rpath} = $ref->{libpath};
-+        }
-+    }
-+}
-+
-+sub shared_lib_priority {
-+    my ($ref) = @_;
-+
-+    if ($ref->{libpython} ne $ref->{ldlib}) {
-+        # This should happen if python was compiled with --enable-shared
-+        #  In this case the linker will prefer the shared library
-+        my $static_lib = File::Spec->catfile($ref->{libpath}, $ref->{libpython});
-+        my $shared_lib = File::Spec->catfile($ref->{libpath}, $ref->{ldlib});
-+        return 1 if (-f $static_lib) && (-f $shared_lib);
-+    }
-+    return 0;
-+}
-+
-+sub check_static_library_ok {
-+    my ($ref) = @_;
-+
-+    # We should check if the static library was compiled with -fPIC, or else
-+    #  we cannot create a shared Python.so from it.
-+    #  TODO: It seem like it is possible to build python with --enable-shared
-+    #    and without CFLAGS=-fPIC, and this will make both libpythonxx.so and
-+    #    libpythonxx.a  position independent, but in this case strange things
-+    #    may happen at runtime (i.e. when running "make test"), see issue #29
-+    #    for more information. This should be investigated futher to determine what
-+    #    is actually going on.
-+    #    This seems to not be a problem on macOS though.
-+    return 1 if $ref->{cflags} =~ /\Q-fPIC\E/i;
-+    warn "WARNING: The static python library seems not to be position indepenent.\n"
-+         . "WARNING: If this does not work you should try again with a "
-+         . "python version that was compiled with CFLAGS=-fPIC\n";
-+    return 0;
-+}
-+
-+sub using_macos_system_python {
-+    my ($ref) = @_;
-+
-+    return ($^O eq "darwin") && ($ref->{path} =~ m{^/usr/bin/python});
-+}
-+
-+sub check_shared_lib_support() {
-+    my ($ref) = @_;
-+
-+    # Windows python always have a shared lib
-+    return 1 if $^O eq "MSWin32";
-+    # The system python always have a shared lib on macOS
-+    return 1 if using_macos_system_python($ref);
-+    # See https://stackoverflow.com/a/23202055/2173773
-+    return $ref->{enable_shared};
-+}
-+
-+sub get_python_version {
-+    my $ref = shift;
-+    my $major = `$ref->{path} -c "import sys; print(sys.version_info[0])"`;
-+    my $minor = `$ref->{path} -c "import sys; print(sys.version_info[1])"`;
-+    return ($major, $minor);
-+}
-+
-+# On Windows, Python config var "LIBRARY" is not defined, so we try another method
-+#  to obtain the library path name
-+sub special_get_libpath {
-+    my $ref = shift;
-+    my ($major, $minor) = get_python_version($ref);
-+    my $cmd;
-+    if (($major == 3 && $minor >=10) || $major > 3 ) {
-+        $cmd = 'import setuptools.command.build_ext; d=setuptools.dist.Distribution();'
-+              .'b=setuptools.command.build_ext.build_ext(d)';
-+    }
-+    else {
-+        $cmd = 'import distutils.command.build_ext; d=distutils.core.Distribution();'
-+              . 'b=distutils.command.build_ext.build_ext(d)';
-+    }
-+    my @lines = `$ref->{path} -c "$cmd;b.finalize_options();print(b.library_dirs[0])" 2>&1`;
-+    my $val = $lines[-1];
-+    chomp $val;
-+    return '' if !$val;
-+    # On Windows, $val should now be equal to $BINDIR/libs
-+    my $pyscript = "import sysconfig; "
-+                  . "print(sysconfig.get_config_var('VERSION'))";
-+    my $version = `$ref->{path} -c "$pyscript"`;
-+    chomp $version;
-+    $ref->{libpath} = $val;
-+    $ref->{libpython} = "python${version}.lib"; # Note: on Windows this is an import library,
-+                                                #  that referes to a shared library
-+                                                #  (not a static library)
-+    # The above file should always exist, alternatively we could
-+    #  set libpath to $BINDIR and libpython to python$version.dll and use the shared library
-+    #  directly instead of using the import library.
-+    return $val;
-+}
-+
- sub test_interrogate {
-     my $ref = shift;
--    `$ref->{path} -c "import distutils.sysconfig; distutils.sysconfig.get_config_var" 2>&1`;
-+    `$ref->{path} -c "import sysconfig; sysconfig.get_config_var" 2>&1`;
-     print <<END if $?;
- 
- This python is so old it doesn't know how to answer my questions.
- 
--Instead, you will be asked a series of questions about it. If possible, 
--I will give you a set of reasonable options to choose from. You can 
-+Instead, you will be asked a series of questions about it. If possible,
-+I will give you a set of reasonable options to choose from. You can
- always enter the complete answer yourself if none of mine are correct.
- END
-     #' stupid vim.
-@@ -161,32 +455,40 @@ sub sanity_check {
-     my $ref = shift;
- 
-     $ref->{libpython} = $ref->{ldlib}
--        if not -f join '/', $ref->{libpath}, $ref->{libpython}
--           and -f join '/', $ref->{libpath}, $ref->{ldlib};
--
-+        if not -f File::Spec->catfile($ref->{libpath}, $ref->{libpython})
-+           and -f File::Spec->catfile($ref->{libpath}, $ref->{ldlib});
-+    my $libpath = File::Spec->catfile($ref->{libpath}, $ref->{libpython});
-     unless (-d $ref->{libpath} &&
- 	    -d $ref->{incpath} &&
--	    (-f join '/', $ref->{libpath}, $ref->{libpython})
-+	    (-f File::Spec->catfile($ref->{libpath}, $ref->{libpython}))
- 	   ) {
- 	print <<END and return 0;
- 
- This python's configuration files are messed up. You'll have have to
- answer the questions yourself. Here is what Python said:
- 
--   Extra Libs:  $sel->{syslibs}
--   Python Library:  $sel->{libpath}/$sel->{libpython}
--   Include Path:    $sel->{incpath}
-+   Extra Libs:  $ref->{syslibs}
-+   Python Library:  $libpath
-+   Include Path:    $ref->{incpath}
- END
-     # ' stupid vim.
-     }
-     return 1;
- }
- 
-+sub get_python_major_version {
-+    my $exe = shift;
-+    my $version = `$exe --version 2>&1`;
-+
-+    $version =~ /(\d+)\./;
-+    return $1;
-+}
-+
- sub get_config_var {
-     my $ref = shift;
-     my $key = shift;
-     my $exe = $ref->{path};
--    my $val = `$exe -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('$key'))"`;
-+    my $val = `$exe -c "import sysconfig; print(sysconfig.get_config_var('$key'))"`;
-     chomp $val;
-     return $val;
- }
-@@ -195,21 +497,21 @@ sub query_options {
-     my $ref = shift;
- 
-     # Every python I've seen needs pthreads. Obviously not on windows.
--    my $libs_guess = $ref->{syslibs} ? $ref->{syslibs} : 
-+    my $libs_guess = $ref->{syslibs} ? $ref->{syslibs} :
- 		     $^O eq 'MSWin32' ? '' : '-lpthread';
-     print <<END;
- 
--	1. LIBS option. I need to know what extra libraries, if any,  
-+	1. LIBS option. I need to know what extra libraries, if any,
- 	   are required by this build of python. I recommend this:
- 	   ${ $libs_guess ? \$libs_guess : \"No extra libraries" }
- 
- END
--    $ref->{syslibs} = prompt("Enter extra libraries (e.g. -lfoo -lbar)", 
-+    $ref->{syslibs} = prompt("Enter extra libraries (e.g. -lfoo -lbar)",
- 			     $libs_guess);
- 
-     print <<END;
- 
--	2. LIBRARY option. The location of the python library. 
-+	2. LIBRARY option. The location of the python library.
- 	   Inline::Python needs to link against it to use Python.
- 
- 	Here are the libraries I know about:
-@@ -218,8 +520,9 @@ END
-     my $lib = prompt("Which? Or enter another.", '1');
-     $lib = $libs[$lib-1] if $lib =~ /^\d+$/;
-     $lib =~ s|\\|/|g;
--    $ref->{libpath} = substr($lib, 0, rindex($lib, '/'));
--    $ref->{libpython} = substr($lib, rindex($lib, '/')+1);
-+    my ($volume, $directories, $file) = File::Spec->splitpath( $lib );
-+    $ref->{libpath} = File::Spec->canonpath(File::Spec->catpath($volume, $directories));
-+    $ref->{libpython} = $file;
- 
-     print <<END;
- 
-@@ -245,7 +548,7 @@ sub show_python_libs {
-   $exe =~ s|[^/]+$||;
-   $exe .= "../lib/python*/config/libpython*";
- 
--  my @py_libs = 
-+  my @py_libs =
-    (
-    (map { $exe . $_ } '.a', '.so', '.lib'),
-    '/usr/lib64/libpython*.a',
-@@ -286,17 +589,21 @@ sub show_python_incs {
-   $exe =~ s|[^/]+$||;
-   $exe .= "../include/python*";
- 
--  my @py_incs = 
--   (
--   $exe,
--   '/usr/local/ActivePython-*/include/python*',
--   '/usr/include/python*',
--   '/usr/local/include/python*',
--
--   # Win32 support
--   'C:/Python*/include',
--   'C:/Program Files/Python*/include',
--   );
-+  my @py_incs;
-+  if ($^O eq "MSWin32") {
-+    @py_incs = (
-+      'C:\Python*\include',
-+      'C:\Program Files\Python*\include'
-+    );
-+  }
-+  else {
-+    @py_incs = (
-+      $exe,
-+      '/usr/local/ActivePython-*/include/python*',
-+      '/usr/include/python*',
-+      '/usr/local/include/python*',
-+    );
-+  }
- 
-   my (@found, %found);
-   push @found, grep { -d && $found{abspath($_)}++ == 0 } glob for @py_incs;
-@@ -312,12 +619,12 @@ sub abspath {
-     use Cwd qw(abs_path);
-     my ($path, $file) = shift;
-     if (-f $path) {
--	my @p = split '/', $path;
--        $path = join '/', @p[0..$#p-1]; # can't use -2 in a range
--	$file = $p[-1];
-+        my @parts = File::Spec->splitpath($path);
-+        $path = File::Spec->canonpath(File::Spec->catpath(@parts[0..1]));
-+    	$file = $parts[-1];
-     }
-     $path = abs_path($path);
--    return defined $file ? join '/', $path, $file : $path;
-+    return defined $file ? File::Spec->catfile($path, $file) : $path;
- }
- 
- sub debug_flag {
diff --git a/debian/patches/series b/debian/patches/series
index c70615d..e69de29 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +0,0 @@
-0001-Call-Py_Initialize-before-calling-PyBytes_FromString.patch
-python3.10.-distutils-deprecation.patch
diff --git a/py2pl.c b/py2pl.c
index 7930b71..e63eeb7 100644
--- a/py2pl.c
+++ b/py2pl.c
@@ -24,11 +24,7 @@ SV* py_false;
  ****************************/
 SV *Py2Pl(PyObject * const obj) {
     /* elw: see what python says things are */
-#if PY_MAJOR_VERSION >= 3
-    int const is_string = PyBytes_Check(obj) || PyUnicode_Check(obj);
-#else
-    int const is_string = PyString_Check(obj) || PyUnicode_Check(obj);
-#endif
+    int const is_string = PY_IS_STRING(obj);
 #ifdef I_PY_DEBUG
     PyObject *this_type = PyObject_Type(obj); /* new reference */
     PyObject *t_string = PyObject_Str(this_type); /* new reference */
@@ -118,12 +114,7 @@ SV *Py2Pl(PyObject * const obj) {
 
     /* wrap an instance of a Python class */
     /* elw: here we need to make these look like instances: */
-    if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE)
-#if PY_MAJOR_VERSION < 3
-        || PyInstance_Check(obj)
-#endif
-    ) {
-
+    if (PY_IS_OBJECT(obj)) {
         /* This is a Python class instance -- bless it into an
          * Inline::Python::Object. If we're being called from an
          * Inline::Python class, it will be re-blessed into whatever
@@ -176,9 +167,8 @@ SV *Py2Pl(PyObject * const obj) {
         return newRV_noinc((SV *) retval);
     }
 
-    /* a dictionary or fake Mapping object */
-    /* elw: PyMapping_Check() now returns true for strings */
-    else if (! is_string && PyMapping_Check(obj)) {
+    /* a real plain dictionary  */
+    else if (obj->ob_type == &PyDict_Type) {
         HV * const retval = newHV();
         int i;
         int const sz = PyMapping_Length(obj);
@@ -437,7 +427,7 @@ PyObject *Pl2Py(SV * const obj) {
         Printf(("string = "));
         Printf(("%s\n", str));
 #if PY_MAJOR_VERSION >= 3
-        if (SvUTF8(obj))
+        if (SvUTF8(obj) || is_ascii_string((U8*) str, len))
             o = PyUnicode_DecodeUTF8(str, len, "replace");
         else
             o = PyBytes_FromStringAndSize(str, len);
@@ -511,7 +501,7 @@ PyObject *Pl2Py(SV * const obj) {
             char * const key_str = SvPV(key, len);
             PyObject *py_key;
 #if PY_MAJOR_VERSION >= 3
-            if (SvUTF8(key))
+            if (SvUTF8(key) || is_ascii_string((U8*) key_str, len))
                 py_key = PyUnicode_DecodeUTF8(key_str, len, "replace");
             else
                 py_key = PyBytes_FromStringAndSize(key_str, len);
diff --git a/py2pl.h b/py2pl.h
index 80d93e0..97b820e 100644
--- a/py2pl.h
+++ b/py2pl.h
@@ -7,6 +7,18 @@ extern void croak_python_exception();
 extern SV* py_true;
 extern SV* py_false;
 extern PyObject *PyExc_Perl;
+#if PY_MAJOR_VERSION < 3
+#define PY_INSTANCE_CHECK(obj) PyInstance_Check((obj))
+#define PY_IS_STRING(obj) (PyString_Check((obj)) || PyUnicode_Check((obj)))
+#else
+#define PY_INSTANCE_CHECK(obj) 0
+#define PY_IS_STRING(obj) (PyBytes_Check((obj)) || PyUnicode_Check((obj)))
+#endif
+#define PY_IS_OBJECT(obj) \
+    (((obj)->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) \
+        || PY_INSTANCE_CHECK((obj)) \
+        || (! is_string && PyMapping_Check((obj)) && ((obj)->ob_type != &PyDict_Type) && \
+            ((obj)->ob_type != &PyList_Type) && ((obj)->ob_type != &PyTuple_Type)) )
 
 #endif
 
diff --git a/t/05JAxH.t b/t/05JAxH.t
index f569237..92d6c80 100644
--- a/t/05JAxH.t
+++ b/t/05JAxH.t
@@ -5,11 +5,7 @@ BEGIN {
 }
 
 use Inline Python => <<'END';
-import sys
-if sys.version_info[0] < 3:
-    def JAxH(x): return "Just Another %s Hacker" % x
-else:
-    def JAxH(x): return "Just Another %s Hacker" % x.decode('utf-8')
+def JAxH(x): return "Just Another %s Hacker" % x
 END
 
 print "not " unless JAxH('Inline') eq "Just Another Inline Hacker";
diff --git a/t/19testref.t b/t/19testref.t
index ad56600..0fda89c 100644
--- a/t/19testref.t
+++ b/t/19testref.t
@@ -317,8 +317,8 @@ TEST_FUNC
 
 my $test_func_p3 = <<'TEST_FUNC';
 def test_func(context):
-    foo = context[b'foo']
-    context[b'bar'] = foo.new()
+    foo = context['foo']
+    context['bar'] = foo.new()
     return foo
 TEST_FUNC
 
diff --git a/t/22int.t b/t/22int.t
index 44ad6bf..dc672db 100644
--- a/t/22int.t
+++ b/t/22int.t
@@ -17,7 +17,7 @@ END
 ok(py_call_function('__main__', 'get_int'), 10, 'int arrives as int');
 if (PyVersion() == 3) {
 	ok(py_call_function('__main__', 'test', 4), "<class 'int'>", 'int arrives as int');
-	ok(py_call_function('__main__', 'test', '4'), "<class 'bytes'>", 'string that looks like a number arrives as string');
+	ok(py_call_function('__main__', 'test', '4'), "<class 'str'>", 'string that looks like a number arrives as string');
 	ok(py_call_function('__main__', 'test', py_call_function('__main__', 'get_int')), "<class 'int'>", 'int from python to perl to python is still an int');
 }
 else {
diff --git a/t/26undef.t b/t/26undef.t
index 60bb8d9..8b2315c 100644
--- a/t/26undef.t
+++ b/t/26undef.t
@@ -6,14 +6,10 @@ use Inline Config => DIRECTORY => './blib_test';
 use Inline Python => <<'END';
 def debug(x):
     return str(x)
-
-def PyVersion(): import sys; return sys.version_info[0]
-
 END
 
 my @a = ('foo' , 'bar', 'baz');
 delete $a[1];
 
 ok(debug(undef) eq 'None');
-ok(debug(\@a) eq "['foo', None, 'baz']") if PyVersion() == 2;
-ok(debug(\@a) eq "[b'foo', None, b'baz']") if PyVersion() == 3;
+ok(debug(\@a) eq "['foo', None, 'baz']");
diff --git a/t/35dictunicodememleak.t b/t/35dictunicodememleak.t
index 95c1c86..c01e754 100644
--- a/t/35dictunicodememleak.t
+++ b/t/35dictunicodememleak.t
@@ -9,6 +9,8 @@ use warnings;
 use Test::More;
 eval { require Proc::ProcessTable; require Test::Deep; };
 plan skip_all => "Test requires Proc::ProcessTable and Test::Deep: $@" if $@;
+plan skip_all => "Process rss information not supported by Proc::ProcessTable on Windows"
+    if $^O eq "MSWin32";
 plan tests => 2;
 
 use Inline Config => DIRECTORY => './blib_test';