diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 93963c70a..9d6a59854 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -6,7 +6,12 @@ on:
       - master
   pull_request:
 
+
+env:
+  LIBRARY_NAME: 'ansys-pythonnet'
+
 jobs:
+
   build-test:
     name: Build and Test
     runs-on: ${{ matrix.os }}-latest
@@ -93,4 +98,14 @@ jobs:
           pip install --force --no-deps --target src/perf_tests/baseline/ pythonnet==2.5.2
           dotnet test --configuration Release --runtime any-${{ matrix.platform }} --logger "console;verbosity=detailed" src/perf_tests/
 
-      # TODO: Run mono tests on Windows?
+      - name: "Build library source and wheel artifacts"
+        run: |
+          python -m pip install build twine wheel
+          python -m build && python -m twine check dist/*
+
+      - name: "Upload distribution artifact"
+        uses: actions/upload-artifact@v3.1.0
+        with:
+          name: ${{ env.LIBRARY_NAME }}-py${{ matrix.python}}-${{ matrix.os }}-artifacts
+          path: dist/
+          retention-days: 7
diff --git a/.gitignore b/.gitignore
index 6159b1b14..cc7e4a651 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,3 +69,167 @@ cov-int/
 !.vscode/tasks.json
 !.vscode/launch.json
 !.vscode/extensions.json
+
+
+# Created by https://www.toptal.com/developers/gitignore/api/python
+# Edit at https://www.toptal.com/developers/gitignore?templates=python
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.cov
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+doc/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+.idea/
+
+# Visual Studio
+.vs/
+
+# End of https://www.toptal.com/developers/gitignore/api/python
diff --git a/README.rst b/README.rst
index f2907f43a..461672e4c 100644
--- a/README.rst
+++ b/README.rst
@@ -1,158 +1,6 @@
-pythonnet - Python.NET
-===========================
+Ansys fork of [pythonnet](https://github.com/pythonnet/pythonnet)
 
-|Join the chat at https://gitter.im/pythonnet/pythonnet| |stackexchange shield|
+We will try to keep this up-to-date with pythonnet and upstream changes that might benefit the pythonnet community
 
-|gh shield|
-
-|license shield|
-
-|pypi package version| |conda-forge version| |python supported shield|
-
-|nuget preview shield| |nuget release shield|
-
-Python.NET is a package that gives Python programmers nearly
-seamless integration with the .NET Common Language Runtime (CLR) and
-provides a powerful application scripting tool for .NET developers. It
-allows Python code to interact with the CLR, and may also be used to
-embed Python into a .NET application.
-
-Calling .NET code from Python
------------------------------
-
-Python.NET allows CLR namespaces to be treated essentially as Python packages.
-
-.. code-block:: python
-
-   import clr
-   from System import String
-   from System.Collections import *
-
-To load an assembly, use the ``AddReference`` function in the ``clr``
-module:
-
-.. code-block:: python
-
-   import clr
-   clr.AddReference("System.Windows.Forms")
-   from System.Windows.Forms import Form
-
-By default, Mono will be used on Linux and macOS, .NET Framework on Windows. For
-details on the loading of different runtimes, please refer to the documentation.
-
-.NET Core
-~~~~~~~~~
-
-If .NET Core is installed in a default location or the ``dotnet`` CLI tool is on
-the ``PATH``, loading it instead of the default (Mono/.NET Framework) runtime
-just requires setting either the environment variable
-``PYTHONNET_RUNTIME=coreclr`` or calling ``pythonnet.load`` explicitly:
-
-.. code-block:: python
-
-   from pythonnet import load
-   load("coreclr")
-
-   import clr
-
-
-Embedding Python in .NET
-------------------------
-
--  You must set ``Runtime.PythonDLL`` property or ``PYTHONNET_PYDLL`` environment variable
-   starting with version 3.0, otherwise you will receive ``BadPythonDllException``
-   (internal, derived from ``MissingMethodException``) upon calling ``Initialize``.
-   Typical values are ``python38.dll`` (Windows), ``libpython3.8.dylib`` (Mac),
-   ``libpython3.8.so`` (most other Unix-like operating systems).
--  Then call ``PythonEngine.Initialize()``. If you plan to use Python objects from
-   multiple threads, also call ``PythonEngine.BeginAllowThreads()``.
--  All calls to python should be inside a
-   ``using (Py.GIL()) {/* Your code here */}`` block.
--  Import python modules using ``dynamic mod = Py.Import("mod")``, then
-   you can call functions as normal, eg ``mod.func(args)``.
--  Use ``mod.func(args, Py.kw("keywordargname", keywordargvalue))`` or
-   ``mod.func(args, keywordargname: keywordargvalue)`` to apply keyword
-   arguments.
--  All python objects should be declared as ``dynamic`` type.
--  Mathematical operations involving python and literal/managed types
-   must have the python object first, eg. ``np.pi * 2`` works,
-   ``2 * np.pi`` doesn't.
-
-Example
-~~~~~~~
-
-.. code-block:: csharp
-
-   static void Main(string[] args)
-   {
-       PythonEngine.Initialize();
-       using (Py.GIL())
-       {
-           dynamic np = Py.Import("numpy");
-           Console.WriteLine(np.cos(np.pi * 2));
-
-           dynamic sin = np.sin;
-           Console.WriteLine(sin(5));
-
-           double c = (double)(np.cos(5) + sin(5));
-           Console.WriteLine(c);
-
-           dynamic a = np.array(new List<float> { 1, 2, 3 });
-           Console.WriteLine(a.dtype);
-
-           dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);
-           Console.WriteLine(b.dtype);
-
-           Console.WriteLine(a * b);
-           Console.ReadKey();
-       }
-   }
-
-Output:
-
-.. code:: csharp
-
-   1.0
-   -0.958924274663
-   -0.6752620892
-   float64
-   int32
-   [  6.  10.  12.]
-
-
-
-Resources
----------
-
-Information on installation, FAQ, troubleshooting, debugging, and
-projects using pythonnet can be found in the Wiki:
-
-https://github.com/pythonnet/pythonnet/wiki
-
-Mailing list
-    https://mail.python.org/mailman/listinfo/pythondotnet
-Chat
-    https://gitter.im/pythonnet/pythonnet
-
-.NET Foundation
----------------
-This project is supported by the `.NET Foundation <https://dotnetfoundation.org>`_.
-
-.. |Join the chat at https://gitter.im/pythonnet/pythonnet| image:: https://badges.gitter.im/pythonnet/pythonnet.svg
-   :target: https://gitter.im/pythonnet/pythonnet?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
-.. |license shield| image:: https://img.shields.io/badge/license-MIT-blue.svg?maxAge=3600
-   :target: ./LICENSE
-.. |pypi package version| image:: https://img.shields.io/pypi/v/pythonnet.svg
-   :target: https://pypi.python.org/pypi/pythonnet
-.. |python supported shield| image:: https://img.shields.io/pypi/pyversions/pythonnet.svg
-   :target: https://pypi.python.org/pypi/pythonnet
-.. |stackexchange shield| image:: https://img.shields.io/badge/StackOverflow-python.net-blue.svg
-   :target: http://stackoverflow.com/questions/tagged/python.net
-.. |conda-forge version| image:: https://img.shields.io/conda/vn/conda-forge/pythonnet.svg
-   :target: https://anaconda.org/conda-forge/pythonnet
-.. |nuget preview shield| image:: https://img.shields.io/nuget/vpre/pythonnet
-   :target: https://www.nuget.org/packages/pythonnet/
-.. |nuget release shield| image:: https://img.shields.io/nuget/v/pythonnet
-   :target: https://www.nuget.org/packages/pythonnet/
-.. |gh shield| image:: https://github.com/pythonnet/pythonnet/workflows/GitHub%20Actions/badge.svg
-   :target: https://github.com/pythonnet/pythonnet/actions?query=branch%3Amaster
+Changes relative to pythonnet:
+- Revert of [#1240](https://github.com/pythonnet/pythonnet/pull/1240)
diff --git a/pyproject.toml b/pyproject.toml
index 52f1adb18..bd564139f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,8 +3,8 @@ requires = ["setuptools>=61", "wheel"]
 build-backend = "setuptools.build_meta"
 
 [project]
-name = "pythonnet"
-description = ".NET and Mono integration for Python"
+name = "ansys-pythonnet"
+description = ".NET and Mono integration for Python (Ansys, Inc. fork)"
 license = {text = "MIT"}
 
 readme = "README.rst"
@@ -34,12 +34,12 @@ classifiers = [
 dynamic = ["version"]
 
 [[project.authors]]
-name = "The Contributors of the Python.NET Project"
-email = "pythonnet@python.org"
+name = "ANSYS, Inc."
+email = "pyansys.maintainers@ansys.com"
 
 [project.urls]
-Homepage = "https://pythonnet.github.io/"
-Sources = "https://github.com/pythonnet/pythonnet"
+Homepage = "pythonnet.docs.pyansys.com"
+Sources = "https://github.com/pyansys/ansys-pythonnet"
 
 [tool.setuptools]
 zip-safe = false
diff --git a/src/runtime/Converter.cs b/src/runtime/Converter.cs
index 73bbd4a3a..d5052682b 100644
--- a/src/runtime/Converter.cs
+++ b/src/runtime/Converter.cs
@@ -138,12 +138,6 @@ internal static NewReference ToPython(object? value, Type type)
                 }
             }
 
-            if (type.IsInterface)
-            {
-                var ifaceObj = (InterfaceObject)ClassManager.GetClassImpl(type);
-                return ifaceObj.TryWrapObject(value);
-            }
-
             if (type.IsArray || type.IsEnum)
             {
                 return CLRObject.GetReference(value, type);
diff --git a/src/runtime/MethodBinder.cs b/src/runtime/MethodBinder.cs
index 07ed4fe22..205c35f49 100644
--- a/src/runtime/MethodBinder.cs
+++ b/src/runtime/MethodBinder.cs
@@ -945,7 +945,7 @@ internal virtual NewReference Invoke(BorrowedReference inst, BorrowedReference a
                     Type pt = pi[i].ParameterType;
                     if (pt.IsByRef)
                     {
-                        using var v = Converter.ToPython(binding.args[i], pt.GetElementType());
+                        using var v = Converter.ToPython(binding.args[i], pt);
                         Runtime.PyTuple_SetItem(t.Borrow(), n, v.Steal());
                         n++;
                     }
diff --git a/src/testing/subclasstest.cs b/src/testing/subclasstest.cs
index ab0b73368..9817d865e 100644
--- a/src/testing/subclasstest.cs
+++ b/src/testing/subclasstest.cs
@@ -89,24 +89,13 @@ public static string test_bar(IInterfaceTest x, string s, int i)
         }
 
         // test instances can be constructed in managed code
-        public static SubClassTest create_instance(Type t)
-        {
-            return (SubClassTest)t.GetConstructor(new Type[] { }).Invoke(new object[] { });
-        }
-
-        public static IInterfaceTest create_instance_interface(Type t)
+        public static IInterfaceTest create_instance(Type t)
         {
             return (IInterfaceTest)t.GetConstructor(new Type[] { }).Invoke(new object[] { });
         }
 
-        // test instances pass through managed code unchanged ...
-        public static SubClassTest pass_through(SubClassTest s)
-        {
-            return s;
-        }
-
-        // ... but the return type is an interface type, objects get wrapped
-        public static IInterfaceTest pass_through_interface(IInterfaceTest s)
+        // test instances pass through managed code unchanged
+        public static IInterfaceTest pass_through(IInterfaceTest s)
         {
             return s;
         }
diff --git a/tests/test_array.py b/tests/test_array.py
index d207a36fb..80c60383f 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -1335,10 +1335,9 @@ def test_special_array_creation():
     assert value[1].__class__ == inst.__class__
     assert value.Length == 2
 
-    iface_class = ISayHello1(inst).__class__
     value = Array[ISayHello1]([inst, inst])
-    assert value[0].__class__ == iface_class
-    assert value[1].__class__ == iface_class
+    assert value[0].__class__ == inst.__class__
+    assert value[1].__class__ == inst.__class__
     assert value.Length == 2
 
     inst = System.Exception("badness")
diff --git a/tests/test_generic.py b/tests/test_generic.py
index 6d514d638..6364878b8 100644
--- a/tests/test_generic.py
+++ b/tests/test_generic.py
@@ -330,6 +330,7 @@ def test_generic_method_type_handling():
     assert_generic_method_by_type(ShortEnum, ShortEnum.Zero)
     assert_generic_method_by_type(System.Object, InterfaceTest())
     assert_generic_method_by_type(InterfaceTest, InterfaceTest(), 1)
+    assert_generic_method_by_type(ISayHello1, InterfaceTest(), 1)
 
 
 def test_correct_overload_selection():
@@ -558,11 +559,10 @@ def test_method_overload_selection_with_generic_types():
     value = MethodTest.Overloaded.__overloads__[vtype](input_)
     assert value.value.__class__ == inst.__class__
 
-    iface_class = ISayHello1(inst).__class__
     vtype = GenericWrapper[ISayHello1]
     input_ = vtype(inst)
     value = MethodTest.Overloaded.__overloads__[vtype](input_)
-    assert value.value.__class__ == iface_class
+    assert value.value.__class__ == inst.__class__
 
     vtype = System.Array[GenericWrapper[int]]
     input_ = vtype([GenericWrapper[int](0), GenericWrapper[int](1)])
@@ -737,12 +737,11 @@ def test_overload_selection_with_arrays_of_generic_types():
     assert value[0].value.__class__ == inst.__class__
     assert value.Length == 2
 
-    iface_class = ISayHello1(inst).__class__
     gtype = GenericWrapper[ISayHello1]
     vtype = System.Array[gtype]
     input_ = vtype([gtype(inst), gtype(inst)])
     value = MethodTest.Overloaded.__overloads__[vtype](input_)
-    assert value[0].value.__class__ == iface_class
+    assert value[0].value.__class__ == inst.__class__
     assert value.Length == 2
 
 
diff --git a/tests/test_interface.py b/tests/test_interface.py
index ac620684d..bab59322d 100644
--- a/tests/test_interface.py
+++ b/tests/test_interface.py
@@ -72,15 +72,15 @@ def test_explicit_cast_to_interface():
 
 
 def test_interface_object_returned_through_method():
-    """Test interface type is used if method return type is interface"""
+    """Test concrete type is used if method return type is interface"""
     from Python.Test import InterfaceTest
 
     ob = InterfaceTest()
     hello1 = ob.GetISayHello1()
-    assert type(hello1).__name__ == 'ISayHello1'
-    assert hello1.__implementation__.__class__.__name__ == "InterfaceTest"
+    assert type(hello1).__name__ == 'InterfaceTest'
 
-    assert hello1.SayHello() == 'hello 1'
+    # This doesn't work yet
+    # assert hello1.SayHello() == 'hello 1'
 
 
 def test_interface_object_returned_through_out_param():
@@ -89,9 +89,10 @@ def test_interface_object_returned_through_out_param():
 
     ob = InterfaceTest()
     hello2 = ob.GetISayHello2(None)
-    assert type(hello2).__name__ == 'ISayHello2'
+    assert type(hello2).__name__ == 'InterfaceTest'
 
-    assert hello2.SayHello() == 'hello 2'
+    # This doesn't work yet
+    # assert hello2.SayHello() == 'hello 2'
 
 def test_interface_out_param_python_impl():
     from Python.Test import IOutArg, OutArgCaller
@@ -118,13 +119,12 @@ def test_null_interface_object_returned():
     assert hello2 is None
 
 def test_interface_array_returned():
-    """Test interface type used for methods returning interface arrays"""
+    """Test concrete type used for methods returning interface arrays"""
     from Python.Test import InterfaceTest
 
     ob = InterfaceTest()
     hellos = ob.GetISayHello1Array()
-    assert type(hellos[0]).__name__ == 'ISayHello1'
-    assert hellos[0].__implementation__.__class__.__name__ == "InterfaceTest"
+    assert type(hellos[0]).__name__ == 'InterfaceTest'
 
 def test_implementation_access():
     """Test the __implementation__ and __raw_implementation__ properties"""
@@ -137,14 +137,14 @@ def test_implementation_access():
 
 
 def test_interface_collection_iteration():
-    """Test interface type is used when iterating over interface collection"""
+    """Test concrete type is used when iterating over interface collection"""
     import System
     from System.Collections.Generic import List
     elem = System.IComparable(System.Int32(100))
     typed_list = List[System.IComparable]()
     typed_list.Add(elem)
     for e in typed_list:
-        assert type(e).__name__ == "IComparable"
+        assert type(e).__name__ == "int"
 
     untyped_list = System.Collections.ArrayList()
     untyped_list.Add(elem)
diff --git a/tests/test_method.py b/tests/test_method.py
index b86bbd6b4..eee359c1b 100644
--- a/tests/test_method.py
+++ b/tests/test_method.py
@@ -583,10 +583,8 @@ def test_explicit_overload_selection():
     value = MethodTest.Overloaded.__overloads__[InterfaceTest](inst)
     assert value.__class__ == inst.__class__
 
-    iface_class = ISayHello1(InterfaceTest()).__class__
     value = MethodTest.Overloaded.__overloads__[ISayHello1](inst)
-    assert value.__class__ != inst.__class__
-    assert value.__class__ == iface_class
+    assert value.__class__ == inst.__class__
 
     atype = Array[System.Object]
     value = MethodTest.Overloaded.__overloads__[str, int, atype](
@@ -739,12 +737,11 @@ def test_overload_selection_with_array_types():
     assert value[0].__class__ == inst.__class__
     assert value[1].__class__ == inst.__class__
 
-    iface_class = ISayHello1(inst).__class__
     vtype = Array[ISayHello1]
     input_ = vtype([inst, inst])
     value = MethodTest.Overloaded.__overloads__[vtype](input_)
-    assert value[0].__class__ == iface_class
-    assert value[1].__class__ == iface_class
+    assert value[0].__class__ == inst.__class__
+    assert value[1].__class__ == inst.__class__
 
 
 def test_explicit_overload_selection_failure():
diff --git a/tests/test_subclass.py b/tests/test_subclass.py
index 504b82548..015c52613 100644
--- a/tests/test_subclass.py
+++ b/tests/test_subclass.py
@@ -123,10 +123,8 @@ def test_interface():
     assert ob.bar("bar", 2) == "bar/bar"
     assert FunctionsTest.test_bar(ob, "bar", 2) == "bar/bar"
 
-    # pass_through will convert from InterfaceTestClass -> IInterfaceTest,
-    # causing a new wrapper object to be created. Hence id will differ.
-    x = FunctionsTest.pass_through_interface(ob)
-    assert id(x) != id(ob)
+    x = FunctionsTest.pass_through(ob)
+    assert id(x) == id(ob)
 
 
 def test_derived_class():
@@ -199,14 +197,14 @@ def test_create_instance():
     assert id(x) == id(ob)
 
     InterfaceTestClass = interface_test_class_fixture(test_create_instance.__name__)
-    ob2 = FunctionsTest.create_instance_interface(InterfaceTestClass)
+    ob2 = FunctionsTest.create_instance(InterfaceTestClass)
     assert ob2.foo() == "InterfaceTestClass"
     assert FunctionsTest.test_foo(ob2) == "InterfaceTestClass"
     assert ob2.bar("bar", 2) == "bar/bar"
     assert FunctionsTest.test_bar(ob2, "bar", 2) == "bar/bar"
 
-    y = FunctionsTest.pass_through_interface(ob2)
-    assert id(y) != id(ob2)
+    y = FunctionsTest.pass_through(ob2)
+    assert id(y) == id(ob2)
 
 
 def test_events():