Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-99948: Support ctypes.util.find_library in emscripten environment #138519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ryanking13 wants to merge 3 commits into python:main
base: main
Choose a base branch
Loading
from ryanking13:ctypes-emscripten
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Lib/ctypes/util.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,28 @@ def find_library(name):
fname = f"{directory}/lib{name}.so"
return fname if os.path.isfile(fname) else None

elif sys.platform == "emscripten":
def _is_wasm(filename):
# Return True if the given file is an WASM module
wasm_header = b"\x00asm"
with open(filename, 'br') as thefile:
return thefile.read(4) == wasm_header

def find_library(name):
candidates = [f"lib{name}.so", f"lib{name}.wasm"]
paths = os.environ.get("LD_LIBRARY_PATH", "")
for libdir in paths.split(":"):
for name in candidates:
libfile = os.path.join(libdir, name)

if os.path.isfile(libfile):
if not _is_wasm(libfile):
continue

return libfile
Comment on lines +190 to +194
Copy link
Contributor

@freakboy3742 freakboy3742 Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems overly complicated; suggest:

Suggested change
if os.path.isfile(libfile):
if not _is_wasm(libfile):
continue
return libfile
if os.path.isfile(libfile) and _is_wasm(libfile):
return libfile


return None

elif os.name == "posix":
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
import re, tempfile
Expand Down
32 changes: 32 additions & 0 deletions Lib/test/test_ctypes/test_find.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,37 @@ def test_find(self):
self.assertIsNone(find_library(name))


@unittest.skipUnless(test.support.is_emscripten,
'Test only valid for Emscripten')
class FindLibraryEmscripten(unittest.TestCase):
def test_find_on_libpath(self):
Copy link
Contributor

@freakboy3742 freakboy3742 Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a few cases missing from this test suite, including:

  • Ignoring non-WASM files
  • Finding a libdummy.wasm file
  • Finding nothing if LD_LIBRARY_PATH isn't defined
  • Finding nothing if LD_LIBRARY_PATH is defined, but doesn't include a WASM file.

It might be worth setting up a directory that contains libdummy.so and libother.wasm as a class-based startup fixture, and then adding tests that manipulate LD_LIBRARY_PATH to find (or not find) those two files.

import tempfile

# A very simple wasm module
# In WAT format: (module)
wasm_module = b'\x00asm\x01\x00\x00\x00\x00\x08\x04name\x02\x01\x00'

with tempfile.TemporaryDirectory() as d:
libname = 'dummy'
dstname = os.path.join(d, 'lib%s.so' % libname)
with open(dstname, 'wb') as f:
f.write(wasm_module)

# now check that the .so can't be found (since not in
# LD_LIBRARY_PATH)
self.assertIsNone(find_library(libname))
# now add the location to LD_LIBRARY_PATH
with os_helper.EnvironmentVarGuard() as env:
KEY = 'LD_LIBRARY_PATH'
if KEY not in env:
v = d
else:
v = '%s:%s' % (env[KEY], d)
env.set(KEY, v)
# now check that the .so can be found (since in
# LD_LIBRARY_PATH)
self.assertEqual(find_library(libname), dstname)


if __name__ == "__main__":
unittest.main()
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:func:`ctypes.util.find_library` now works in Emscripten build.
Loading

AltStyle によって変換されたページ (->オリジナル) /