Skip to content
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
4 changes: 2 additions & 2 deletions clang/bindings/python/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

This directory implements Python bindings for Clang.

You may need to set CLANG_LIBRARY_PATH so that the Clang library can be
You may need to set LIBCLANG_LIBRARY_PATH so that the Clang library can be
found. The unit tests are designed to be run with any standard test
runner. For example:
--
$ env PYTHONPATH=$(echo ~/llvm/clang/bindings/python/) \
CLANG_LIBRARY_PATH=$(llvm-config --libdir) \
LIBCLANG_LIBRARY_PATH=$(llvm-config --libdir) \
python3 -m unittest discover -v
tests.cindex.test_index.test_create ... ok
...
Expand Down
13 changes: 7 additions & 6 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -4383,8 +4383,8 @@ def register(item: LibFunc) -> None:


class Config:
library_path = None
library_file: str | None = None
library_path: str | None = os.environ.get("LIBCLANG_LIBRARY_PATH")
library_file: str | None = os.environ.get("LIBCLANG_LIBRARY_FILE")
compatibility_check = True
loaded = False

Expand Down Expand Up @@ -4468,10 +4468,11 @@ def get_cindex_library(self) -> CDLL:
try:
library = cdll.LoadLibrary(self.get_filename())
except OSError as e:
msg = (
str(e) + ". To provide a path to libclang use "
"Config.set_library_path() or "
"Config.set_library_file()."
msg = str(e) + (
"To provide the path to the directory containing libclang, you can use the environment variable "
"LIBCLANG_LIBRARY_PATH or call Config.set_library_path(). "
"Alternatively, you can specify the path of the library file using "
"LIBCLANG_LIBRARY_FILE or Config.set_library_file()."
)
raise LibclangError(msg)

Expand Down
2 changes: 1 addition & 1 deletion clang/bindings/python/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
add_custom_target(check-clang-python
COMMAND ${CMAKE_COMMAND} -E env
CLANG_NO_DEFAULT_CONFIG=1
CLANG_LIBRARY_PATH=$<TARGET_FILE_DIR:libclang>
LIBCLANG_LIBRARY_PATH=$<TARGET_FILE_DIR:libclang>
"${Python3_EXECUTABLE}" -m unittest discover
DEPENDS libclang
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import AccessSpecifier

from clang.cindex import AccessSpecifier, Config

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
4 changes: 1 addition & 3 deletions clang/bindings/python/tests/cindex/test_cdb.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import os

from clang.cindex import CompilationDatabase, CompilationDatabaseError, Config
from clang.cindex import CompilationDatabase, CompilationDatabaseError

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import gc
import unittest
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import TranslationUnit

from clang.cindex import Config, TranslationUnit

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest
from pathlib import Path
Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_comment.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import TranslationUnit

from clang.cindex import Config, TranslationUnit

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
5 changes: 0 additions & 5 deletions clang/bindings/python/tests/cindex/test_cursor.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import os

from clang.cindex import (
AvailabilityKind,
BinaryOperator,
Config,
Cursor,
CursorKind,
PrintingPolicy,
Expand All @@ -15,8 +12,6 @@
conf,
)

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import gc
import unittest
Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_cursor_kind.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import CursorKind

from clang.cindex import Config, CursorKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import LanguageKind

from clang.cindex import Config, LanguageKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_diagnostics.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import Diagnostic

from clang.cindex import Config, Diagnostic

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
63 changes: 63 additions & 0 deletions clang/bindings/python/tests/cindex/test_environment_variable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import unittest
import unittest.mock
import sys
import os


def reset_import_and_get_fresh_config():
# Reloads the clang.cindex module to reset any class-level state in Config.
sys.modules.pop("clang.cindex", None)
sys.modules.pop("clang", None)
from clang.cindex import Config

return Config()


class TestEnvironementVariable(unittest.TestCase):
def test_working_libclang_library_file(self):
ref_libclang_library_file = reset_import_and_get_fresh_config().get_filename()
with unittest.mock.patch.dict(
os.environ, {"LIBCLANG_LIBRARY_FILE": ref_libclang_library_file}
):
reset_import_and_get_fresh_config().lib

@unittest.mock.patch.dict("os.environ", {"LIBCLANG_LIBRARY_FILE": "/dev/null"})
def test_non_working_libclang_library_file(self):
config = reset_import_and_get_fresh_config()
import clang.cindex

with self.assertRaises(clang.cindex.LibclangError):
config.lib

def test_working_libclang_library_path(self):
# Get adequate libclang path
ref_libclang_library_file = reset_import_and_get_fresh_config().get_filename()
ref_libclang_library_path, filename = os.path.split(ref_libclang_library_file)
filename_root, filename_ext = os.path.splitext(filename)

# Config only recognizes the default libclang filename.
# If LIBCLANG_LIBRARY_FILE points to a non-standard name, skip this test.

if not (
filename_root == "libclang" and filename_ext in (".so", ".dll", ".dylib")
):
self.skipTest(f"Skipping because {filename} is not a default libclang name")

with unittest.mock.patch.dict(
os.environ, {"LIBCLANG_LIBRARY_PATH": ref_libclang_library_path}
):
# Remove LIBCLANG_LIBRARY_FILE to avoid it taking precedence if set by the user
# Need to be in the mocked environement
os.environ.pop("LIBCLANG_LIBRARY_FILE", None)
reset_import_and_get_fresh_config().lib

@unittest.mock.patch.dict("os.environ", {"LIBCLANG_LIBRARY_PATH": "not_a_real_dir"})
def test_non_working_libclang_library_path(self):
# Remove LIBCLANG_LIBRARY_FILE to avoid it taking precedence if set by the user
os.environ.pop("LIBCLANG_LIBRARY_FILE", None)

config = reset_import_and_get_fresh_config()
import clang.cindex

with self.assertRaises(clang.cindex.LibclangError):
config.lib
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import CursorKind, ExceptionSpecificationKind

from clang.cindex import Config, CursorKind, ExceptionSpecificationKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
4 changes: 1 addition & 3 deletions clang/bindings/python/tests/cindex/test_file.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import os

from clang.cindex import Config, File, Index, TranslationUnit
from clang.cindex import File, Index, TranslationUnit

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
4 changes: 1 addition & 3 deletions clang/bindings/python/tests/cindex/test_index.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import os

from clang.cindex import Config, Index, TranslationUnit
from clang.cindex import Index, TranslationUnit

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
4 changes: 0 additions & 4 deletions clang/bindings/python/tests/cindex/test_lib.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os

import clang.cindex

if "CLANG_LIBRARY_PATH" in os.environ:
clang.cindex.Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest
import ast
Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_linkage.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import LinkageKind

from clang.cindex import Config, LinkageKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
3 changes: 0 additions & 3 deletions clang/bindings/python/tests/cindex/test_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
from pathlib import Path

from clang.cindex import (
Config,
Cursor,
File,
SourceLocation,
SourceRange,
TranslationUnit,
)

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
5 changes: 1 addition & 4 deletions clang/bindings/python/tests/cindex/test_source_range.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import os
from pathlib import Path

from clang.cindex import Config, SourceLocation, SourceRange, TranslationUnit
from clang.cindex import SourceLocation, SourceRange, TranslationUnit

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_tls_kind.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import TLSKind

from clang.cindex import Config, TLSKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_token_kind.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import TokenKind

from clang.cindex import Config, TokenKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
6 changes: 1 addition & 5 deletions clang/bindings/python/tests/cindex/test_tokens.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import os
from clang.cindex import CursorKind, SourceLocation, SourceRange, TokenKind

from clang.cindex import Config, CursorKind, SourceLocation, SourceRange, TokenKind

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import unittest

Expand Down
3 changes: 0 additions & 3 deletions clang/bindings/python/tests/cindex/test_translation_unit.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import os

from clang.cindex import (
Config,
Cursor,
CursorKind,
File,
Expand All @@ -13,8 +12,6 @@
TranslationUnitSaveError,
)

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import gc
import tempfile
Expand Down
5 changes: 0 additions & 5 deletions clang/bindings/python/tests/cindex/test_type.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import os

from clang.cindex import (
Config,
CursorKind,
PrintingPolicy,
PrintingPolicyProperty,
Expand All @@ -10,8 +7,6 @@
TypeKind,
)

if "CLANG_LIBRARY_PATH" in os.environ:
Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])

import gc
import unittest
Expand Down
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ Clang Python Bindings Potentially Breaking Changes
ElaboratedTypes. The value becomes unused, and all the existing users should
expect the former underlying type to be reported instead.
- Remove ``AccessSpecifier.NONE`` kind. No libclang interfaces ever returned this kind.
- Allow setting the path to the libclang library via environment variables: ``LIBCLANG_LIBRARY_PATH``
to specifiy the path to the containing folder, or ``LIBCLANG_LIBRARY_FILE`` to specify the path to
the library file

What's New in Clang |release|?
==============================
Expand Down
Loading