Skip to content

Possible support for older framework versions #2695

Closed

Description

@Metadorius

Reposting as a new issue for visibility.

Are there any actual blockers which prevent at least limited support of 4.6.1 as a part of .NET Standard 2.0?

I needed that and while I know that 4.6.1/Standard 2.0 situation is messy in .NET in general, I've:

  1. patched CLR Loader to compile for net461 (LPUTF8Str -> IntPtr with manual conversion, ValueTuple -> Tuple),
  2. referenced ValueTuple and InteropServices in Python.Runtime.csproj,
  3. made a build step to copy netstandard.dll assembly to the OutDir,

and only if I switch the target framework to net461 for Python.Runtime.csproj, then I am able to run a simple hello world successfully from Python in a 4.6.2 environment. If I switch target back to netstandard2.0 -- the assemblies disappear from the output, and even if I add them back - I for some reason get errors on loading them which I currently am not sure how to resolve:

Failed to initialize pythonnet: System.TypeInitializationException: The type initializer for 'Delegates' threw an exception. ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime.InteropServices.RuntimeInformation, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
   at Python.Runtime.Platform.LibraryLoader.get_Instance()
   at Python.Runtime.Runtime.Delegates..cctor()
   --- End of inner exception stack trace ---
   at Python.Runtime.Runtime.Delegates.get_PyGILState_Ensure()
   at Python.Runtime.Runtime.PyGILState_Ensure()
   at Python.Runtime.Py.GIL()
   at Python.Runtime.Loader.Initialize(IntPtr data, Int32 size)
   at Python.Runtime.Runtime.Delegates.get_PyGILState_Ensure()
   at Python.Runtime.Runtime.PyGILState_Ensure()
   at Python.Runtime.Py.GIL()
   at Python.Runtime.Loader.Initialize(IntPtr data, Int32 size)

I am not sure how to properly make netstandard2.0 assembly to reference and copy those DLLs properly for running on 4.6.1, would appreciate some insight on what I am doing wrong.

If this is reasonably solvable, will there be opposition to allowing 4.6.1 (with a strong recommendation to update to 4.7.2) potentially, if, say, I submit the PR fitting the requirements?

Also, outside of that, are there any blockers for going even lower theoretically (if I don't need to support anything else than .NET Framework)? Not as a part of the upstream/mainline.

Originally posted by @Metadorius in #1299

Activity

  1. lostmsu commented on Mar 10, 2026

    @lostmsu
    Member

    This is not a bug in Python.NET support of 4.6.2, this is a known bug in .NET 4.6.2 with known solutions.
    Please, only report bugs in pythonnet.

  2. Metadorius commented on Mar 10, 2026

    @Metadorius
    ContributorAuthor

    @lostmsu

    Thanks for the link, I'll look into it when I continue on the issue.

    This is not a bug report, but rather a "feature request", to which I am willing to contribute, hence I am asking a question and posting my research and experimentation results. Your docs state "no support for anything lower than 4.7.2", and I am experimenting on lowering that and asking if it's possible to properly achieve or there are some hidden blockers, before I commit to it. You, maintainers, know the matter better than I, a first-time contributor, do, and you make the final decision, so it's natural for me to ask your informed opinion.

    I would appreciate reopening the issue.

  3. Metadorius commented on Mar 16, 2026

    @Metadorius
    ContributorAuthor

    Bump.

  4. Metadorius commented on Mar 25, 2026

    @Metadorius
    ContributorAuthor

    This is not a bug in Python.NET support of 4.6.2, this is a known bug in .NET 4.6.2 with known solutions. Please, only report bugs in pythonnet.

    @lostmsu this didn't change anything. I ensured the .config file with that gets embedded inside the wheel, same issue.

    Also, asking for your attention once again, I think you misunderstood my original post.

  5. filmor commented on Mar 25, 2026

    @filmor
    Member

    If you manage to provide a patch or documentation on how to get Python.NET to work with older framework versions, we can merge it if it doesn't complicate things too much (e.g. by being thoroughly isolated). Frameworks before 4.7.2 are really broken, we don't say we don't support them out of spite but out of necessity to keep a halfway sane build process.

  6. Metadorius commented on Mar 25, 2026

    @Metadorius
    ContributorAuthor

    If you manage to provide a patch or documentation on how to get Python.NET to work with older framework versions, we can merge it if it doesn't complicate things too much (e.g. by being thoroughly isolated). Frameworks before 4.7.2 are really broken, we don't say we don't support them out of spite but out of necessity to keep a halfway sane build process.

    I understand and sympathise with not wanting to deal with broken mess, however, end users, as in my case, usually don't care about technical details, so I have to go through this, oh well.

    I have succeeded on targeting Framework 4.6.1 with a few simple tweaks and downgrades, like tens of lines (change target, downgrade clr-loader to net461, add DLLs to wheel); I got a simple C#/Python hello world working. However, when targeting Standard 2.0 it just goes to smithereens when launched on an actual 4.6.2 installation (couldn't find how to get 4.6.1 Docker image), the error is in the first post.

    Do you have an idea of the possible causes or in which direction to dig? It doesn't seem like something in the clr-loader that prevents finding the assembly file.

  7. Metadorius commented on Mar 26, 2026

    @Metadorius
    ContributorAuthor

    Ooookay, so the issue was indeed in the assembly resolving. Adding binding redirects didn't help because they never get loaded for the .dll.config files, and screwing with runtime changing of config path didn't help, however, what did help is adding an assembly resolver.

    I'll be submitting a PR later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions