mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-17 00:10:28 +00:00
[libclang/python] Bump minimum compatibility to Python 3.6 (#77228)
Remove Python 2 support and clean up code that conditions based on version. Issue #76664.
This commit is contained in:
parent
34b106789a
commit
75f232181a
@ -10,7 +10,7 @@ runner. For example:
|
||||
--
|
||||
$ env PYTHONPATH=$(echo ~/llvm/clang/bindings/python/) \
|
||||
CLANG_LIBRARY_PATH=$(llvm-config --libdir) \
|
||||
python -m unittest discover -v
|
||||
python3 -m unittest discover -v
|
||||
tests.cindex.test_index.test_create ... ok
|
||||
...
|
||||
|
||||
|
@ -66,81 +66,50 @@ from ctypes import *
|
||||
|
||||
import clang.enumerations
|
||||
|
||||
import collections.abc
|
||||
import os
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
|
||||
class c_interop_string(c_char_p):
|
||||
def __init__(self, p=None):
|
||||
if p is None:
|
||||
p = ""
|
||||
if isinstance(p, str):
|
||||
p = p.encode("utf8")
|
||||
super(c_char_p, self).__init__(p)
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
# Python 3 strings are unicode, translate them to/from utf8 for C-interop.
|
||||
class c_interop_string(c_char_p):
|
||||
def __init__(self, p=None):
|
||||
if p is None:
|
||||
p = ""
|
||||
if isinstance(p, str):
|
||||
p = p.encode("utf8")
|
||||
super(c_char_p, self).__init__(p)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
if super(c_char_p, self).value is None:
|
||||
return None
|
||||
return super(c_char_p, self).value.decode("utf8")
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
@classmethod
|
||||
def from_param(cls, param):
|
||||
if isinstance(param, str):
|
||||
return cls(param)
|
||||
if isinstance(param, bytes):
|
||||
return cls(param)
|
||||
if param is None:
|
||||
# Support passing null to C functions expecting char arrays
|
||||
return None
|
||||
raise TypeError(
|
||||
"Cannot convert '{}' to '{}'".format(type(param).__name__, cls.__name__)
|
||||
)
|
||||
@property
|
||||
def value(self):
|
||||
if super(c_char_p, self).value is None:
|
||||
return None
|
||||
return super(c_char_p, self).value.decode("utf8")
|
||||
|
||||
@staticmethod
|
||||
def to_python_string(x, *args):
|
||||
return x.value
|
||||
@classmethod
|
||||
def from_param(cls, param):
|
||||
if isinstance(param, str):
|
||||
return cls(param)
|
||||
if isinstance(param, bytes):
|
||||
return cls(param)
|
||||
if param is None:
|
||||
# Support passing null to C functions expecting char arrays
|
||||
return None
|
||||
raise TypeError(
|
||||
"Cannot convert '{}' to '{}'".format(type(param).__name__, cls.__name__)
|
||||
)
|
||||
|
||||
def b(x):
|
||||
if isinstance(x, bytes):
|
||||
return x
|
||||
return x.encode("utf8")
|
||||
@staticmethod
|
||||
def to_python_string(x, *args):
|
||||
return x.value
|
||||
|
||||
elif sys.version_info[0] == 2:
|
||||
# Python 2 strings are utf8 byte strings, no translation is needed for
|
||||
# C-interop.
|
||||
c_interop_string = c_char_p
|
||||
|
||||
def _to_python_string(x, *args):
|
||||
return x
|
||||
|
||||
c_interop_string.to_python_string = staticmethod(_to_python_string)
|
||||
|
||||
def b(x):
|
||||
return x
|
||||
|
||||
|
||||
# Importing ABC-s directly from collections is deprecated since Python 3.7,
|
||||
# will stop working in Python 3.8.
|
||||
# See: https://docs.python.org/dev/whatsnew/3.7.html#id3
|
||||
if sys.version_info[:2] >= (3, 7):
|
||||
from collections import abc as collections_abc
|
||||
else:
|
||||
import collections as collections_abc
|
||||
|
||||
# We only support PathLike objects on Python version with os.fspath present
|
||||
# to be consistent with the Python standard library. On older Python versions
|
||||
# we only support strings and we have dummy fspath to just pass them through.
|
||||
try:
|
||||
fspath = os.fspath
|
||||
except AttributeError:
|
||||
|
||||
def fspath(x):
|
||||
def b(x):
|
||||
if isinstance(x, bytes):
|
||||
return x
|
||||
return x.encode("utf8")
|
||||
|
||||
|
||||
# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
|
||||
@ -202,7 +171,7 @@ class TranslationUnitSaveError(Exception):
|
||||
### Structures and Utility Classes ###
|
||||
|
||||
|
||||
class CachedProperty(object):
|
||||
class CachedProperty:
|
||||
"""Decorator that lazy-loads the value of a property.
|
||||
|
||||
The first time the property is accessed, the original property function is
|
||||
@ -392,7 +361,7 @@ class SourceRange(Structure):
|
||||
return "<SourceRange start %r, end %r>" % (self.start, self.end)
|
||||
|
||||
|
||||
class Diagnostic(object):
|
||||
class Diagnostic:
|
||||
"""
|
||||
A Diagnostic is a single instance of a Clang diagnostic. It includes the
|
||||
diagnostic severity, the message, the location the diagnostic occurred, as
|
||||
@ -433,7 +402,7 @@ class Diagnostic(object):
|
||||
|
||||
@property
|
||||
def ranges(self):
|
||||
class RangeIterator(object):
|
||||
class RangeIterator:
|
||||
def __init__(self, diag):
|
||||
self.diag = diag
|
||||
|
||||
@ -449,7 +418,7 @@ class Diagnostic(object):
|
||||
|
||||
@property
|
||||
def fixits(self):
|
||||
class FixItIterator(object):
|
||||
class FixItIterator:
|
||||
def __init__(self, diag):
|
||||
self.diag = diag
|
||||
|
||||
@ -468,7 +437,7 @@ class Diagnostic(object):
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
class ChildDiagnosticsIterator(object):
|
||||
class ChildDiagnosticsIterator:
|
||||
def __init__(self, diag):
|
||||
self.diag_set = conf.lib.clang_getChildDiagnostics(diag)
|
||||
|
||||
@ -532,7 +501,7 @@ class Diagnostic(object):
|
||||
return self.ptr
|
||||
|
||||
|
||||
class FixIt(object):
|
||||
class FixIt:
|
||||
"""
|
||||
A FixIt represents a transformation to be applied to the source to
|
||||
"fix-it". The fix-it should be applied by replacing the given source range
|
||||
@ -547,7 +516,7 @@ class FixIt(object):
|
||||
return "<FixIt range %r, value %r>" % (self.range, self.value)
|
||||
|
||||
|
||||
class TokenGroup(object):
|
||||
class TokenGroup:
|
||||
"""Helper class to facilitate token management.
|
||||
|
||||
Tokens are allocated from libclang in chunks. They must be disposed of as a
|
||||
@ -603,7 +572,7 @@ class TokenGroup(object):
|
||||
yield token
|
||||
|
||||
|
||||
class TokenKind(object):
|
||||
class TokenKind:
|
||||
"""Describes a specific type of a Token."""
|
||||
|
||||
_value_map = {} # int -> TokenKind
|
||||
@ -642,7 +611,7 @@ class TokenKind(object):
|
||||
|
||||
|
||||
### Cursor Kinds ###
|
||||
class BaseEnumeration(object):
|
||||
class BaseEnumeration:
|
||||
"""
|
||||
Common base class for named enumerations held in sync with Index.h values.
|
||||
|
||||
@ -2059,7 +2028,7 @@ class Cursor(Structure):
|
||||
return res
|
||||
|
||||
|
||||
class StorageClass(object):
|
||||
class StorageClass:
|
||||
"""
|
||||
Describes the storage class of a declaration
|
||||
"""
|
||||
@ -2353,7 +2322,7 @@ class Type(Structure):
|
||||
container is a Type instance.
|
||||
"""
|
||||
|
||||
class ArgumentsIterator(collections_abc.Sequence):
|
||||
class ArgumentsIterator(collections.abc.Sequence):
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
self.length = None
|
||||
@ -2608,7 +2577,7 @@ class Type(Structure):
|
||||
# a void*.
|
||||
|
||||
|
||||
class ClangObject(object):
|
||||
class ClangObject:
|
||||
"""
|
||||
A helper for Clang objects. This class helps act as an intermediary for
|
||||
the ctypes library and the Clang CIndex library.
|
||||
@ -2656,8 +2625,8 @@ SpellingCache = {
|
||||
}
|
||||
|
||||
|
||||
class CompletionChunk(object):
|
||||
class Kind(object):
|
||||
class CompletionChunk:
|
||||
class Kind:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
@ -2747,7 +2716,7 @@ completionChunkKindMap = {
|
||||
|
||||
|
||||
class CompletionString(ClangObject):
|
||||
class Availability(object):
|
||||
class Availability:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
@ -2849,7 +2818,7 @@ class CodeCompletionResults(ClangObject):
|
||||
|
||||
@property
|
||||
def diagnostics(self):
|
||||
class DiagnosticsItr(object):
|
||||
class DiagnosticsItr:
|
||||
def __init__(self, ccr):
|
||||
self.ccr = ccr
|
||||
|
||||
@ -3003,13 +2972,13 @@ class TranslationUnit(ClangObject):
|
||||
if hasattr(contents, "read"):
|
||||
contents = contents.read()
|
||||
contents = b(contents)
|
||||
unsaved_array[i].name = b(fspath(name))
|
||||
unsaved_array[i].name = b(os.fspath(name))
|
||||
unsaved_array[i].contents = contents
|
||||
unsaved_array[i].length = len(contents)
|
||||
|
||||
ptr = conf.lib.clang_parseTranslationUnit(
|
||||
index,
|
||||
fspath(filename) if filename is not None else None,
|
||||
os.fspath(filename) if filename is not None else None,
|
||||
args_array,
|
||||
len(args),
|
||||
unsaved_array,
|
||||
@ -3040,7 +3009,7 @@ class TranslationUnit(ClangObject):
|
||||
if index is None:
|
||||
index = Index.create()
|
||||
|
||||
ptr = conf.lib.clang_createTranslationUnit(index, fspath(filename))
|
||||
ptr = conf.lib.clang_createTranslationUnit(index, os.fspath(filename))
|
||||
if not ptr:
|
||||
raise TranslationUnitLoadError(filename)
|
||||
|
||||
@ -3159,7 +3128,7 @@ class TranslationUnit(ClangObject):
|
||||
Return an iterable (and indexable) object containing the diagnostics.
|
||||
"""
|
||||
|
||||
class DiagIterator(object):
|
||||
class DiagIterator:
|
||||
def __init__(self, tu):
|
||||
self.tu = tu
|
||||
|
||||
@ -3193,7 +3162,7 @@ class TranslationUnit(ClangObject):
|
||||
if hasattr(contents, "read"):
|
||||
contents = contents.read()
|
||||
contents = b(contents)
|
||||
unsaved_files_array[i].name = b(fspath(name))
|
||||
unsaved_files_array[i].name = b(os.fspath(name))
|
||||
unsaved_files_array[i].contents = contents
|
||||
unsaved_files_array[i].length = len(contents)
|
||||
ptr = conf.lib.clang_reparseTranslationUnit(
|
||||
@ -3217,7 +3186,11 @@ class TranslationUnit(ClangObject):
|
||||
"""
|
||||
options = conf.lib.clang_defaultSaveOptions(self)
|
||||
result = int(
|
||||
conf.lib.clang_saveTranslationUnit(self, fspath(filename), options)
|
||||
conf.lib.clang_saveTranslationUnit(
|
||||
self,
|
||||
os.fspath(filename),
|
||||
options,
|
||||
)
|
||||
)
|
||||
if result != 0:
|
||||
raise TranslationUnitSaveError(result, "Error saving TranslationUnit.")
|
||||
@ -3261,12 +3234,12 @@ class TranslationUnit(ClangObject):
|
||||
if hasattr(contents, "read"):
|
||||
contents = contents.read()
|
||||
contents = b(contents)
|
||||
unsaved_files_array[i].name = b(fspath(name))
|
||||
unsaved_files_array[i].name = b(os.fspath(name))
|
||||
unsaved_files_array[i].contents = contents
|
||||
unsaved_files_array[i].length = len(contents)
|
||||
ptr = conf.lib.clang_codeCompleteAt(
|
||||
self,
|
||||
fspath(path),
|
||||
os.fspath(path),
|
||||
line,
|
||||
column,
|
||||
unsaved_files_array,
|
||||
@ -3300,7 +3273,9 @@ class File(ClangObject):
|
||||
@staticmethod
|
||||
def from_name(translation_unit, file_name):
|
||||
"""Retrieve a file handle within the given translation unit."""
|
||||
return File(conf.lib.clang_getFile(translation_unit, fspath(file_name)))
|
||||
return File(
|
||||
conf.lib.clang_getFile(translation_unit, os.fspath(file_name)),
|
||||
)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@ -3328,7 +3303,7 @@ class File(ClangObject):
|
||||
return res
|
||||
|
||||
|
||||
class FileInclusion(object):
|
||||
class FileInclusion:
|
||||
"""
|
||||
The FileInclusion class represents the inclusion of one source file by
|
||||
another via a '#include' directive or as the input file for the translation
|
||||
@ -3377,7 +3352,7 @@ class CompilationDatabaseError(Exception):
|
||||
Exception.__init__(self, "Error %d: %s" % (enumeration, message))
|
||||
|
||||
|
||||
class CompileCommand(object):
|
||||
class CompileCommand:
|
||||
"""Represents the compile command used to build a file"""
|
||||
|
||||
def __init__(self, cmd, ccmds):
|
||||
@ -3409,7 +3384,7 @@ class CompileCommand(object):
|
||||
yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
|
||||
|
||||
|
||||
class CompileCommands(object):
|
||||
class CompileCommands:
|
||||
"""
|
||||
CompileCommands is an iterable object containing all CompileCommand
|
||||
that can be used for building a specific file.
|
||||
@ -3460,7 +3435,7 @@ class CompilationDatabase(ClangObject):
|
||||
errorCode = c_uint()
|
||||
try:
|
||||
cdb = conf.lib.clang_CompilationDatabase_fromDirectory(
|
||||
fspath(buildDir), byref(errorCode)
|
||||
os.fspath(buildDir), byref(errorCode)
|
||||
)
|
||||
except CompilationDatabaseError as e:
|
||||
raise CompilationDatabaseError(
|
||||
@ -3474,7 +3449,7 @@ class CompilationDatabase(ClangObject):
|
||||
build filename. Returns None if filename is not found in the database.
|
||||
"""
|
||||
return conf.lib.clang_CompilationDatabase_getCompileCommands(
|
||||
self, fspath(filename)
|
||||
self, os.fspath(filename)
|
||||
)
|
||||
|
||||
def getAllCompileCommands(self):
|
||||
@ -3865,7 +3840,7 @@ def register_functions(lib, ignore_errors):
|
||||
register(f)
|
||||
|
||||
|
||||
class Config(object):
|
||||
class Config:
|
||||
library_path = None
|
||||
library_file = None
|
||||
compatibility_check = True
|
||||
@ -3880,7 +3855,7 @@ class Config(object):
|
||||
"any other functionalities in libclang."
|
||||
)
|
||||
|
||||
Config.library_path = fspath(path)
|
||||
Config.library_path = os.fspath(path)
|
||||
|
||||
@staticmethod
|
||||
def set_library_file(filename):
|
||||
@ -3891,7 +3866,7 @@ class Config(object):
|
||||
"any other functionalities in libclang."
|
||||
)
|
||||
|
||||
Config.library_file = fspath(filename)
|
||||
Config.library_file = os.fspath(filename)
|
||||
|
||||
@staticmethod
|
||||
def set_compatibility_check(check_status):
|
||||
|
Loading…
x
Reference in New Issue
Block a user