-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libclang/python] Add equality comparison operators for File #130383
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
Conversation
@llvm/pr-subscribers-clang Author: Jannick Kremer (DeinAlptraum) ChangesThis covers the Full diff: https://github.com/llvm/llvm-project/pull/130383.diff 3 Files Affected:
diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py
index 879a0a3c5c58c..bc8fb7c27fdac 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -3470,6 +3470,12 @@ def __str__(self):
def __repr__(self):
return "<File: %s>" % (self.name)
+ def __eq__(self, other) -> bool:
+ return isinstance(other, File) and bool(conf.lib.clang_File_isEqual(self, other))
+
+ def __ne__(self, other) -> bool:
+ return not self.__eq__(other)
+
@staticmethod
def from_result(res, arg):
assert isinstance(res, c_object_p)
@@ -3956,6 +3962,7 @@ def set_property(self, property, value):
("clang_getFile", [TranslationUnit, c_interop_string], c_object_p),
("clang_getFileName", [File], _CXString),
("clang_getFileTime", [File], c_uint),
+ ("clang_File_isEqual", [File, File], bool),
("clang_getIBOutletCollectionType", [Cursor], Type),
("clang_getIncludedFile", [Cursor], c_object_p),
(
diff --git a/clang/bindings/python/tests/cindex/test_file.py b/clang/bindings/python/tests/cindex/test_file.py
index 14a3084ee2b47..0e8431054e951 100644
--- a/clang/bindings/python/tests/cindex/test_file.py
+++ b/clang/bindings/python/tests/cindex/test_file.py
@@ -16,3 +16,18 @@ def test_file(self):
self.assertEqual(str(file), "t.c")
self.assertEqual(file.name, "t.c")
self.assertEqual(repr(file), "<File: t.c>")
+
+ def test_file_eq(self):
+ index = Index.create()
+ tu = index.parse(
+ "t.c",
+ unsaved_files=[
+ ("t.c", "int a = 729;"),
+ ("s.c", "int a = 729;"),
+ ],
+ )
+ file1 = File.from_name(tu, "t.c")
+ file2 = File.from_name(tu, "s.c")
+ self.assertEqual(file1, file1)
+ self.assertNotEqual(file1, file2)
+ self.assertNotEqual(file1, "t.c")
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a25808e36bd51..a2f10f20ce716 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -444,6 +444,7 @@ Python Binding Changes
----------------------
- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which
allows visiting the methods of a class.
+- Add equality comparison operators for ``File`` type
OpenMP Support
--------------
|
✅ With the latest revision this PR passed the Python code formatter. |
@Endilll do you understand where this test failure might come from? It passes for me locally... |
I think the failure in question is
and I have to idea why this happens. |
@Endilll I managed to align my local errors with those in the CI and fix them by using actual files for the test instead... curious where the issue comes from, but I don't feel like looking into this deeper rn. |
4cc056c
to
b8a4f30
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AaronBallman do you have a clue why equality comparison for in-memory files works differently compared to on-disk files?
✅ With the latest revision this PR passed the C/C++ code formatter. |
As for investigation: |
Are they? I think you're supposed to use |
def test_file_eq_failing(self): | ||
index = Index.create() | ||
tu = index.parse( | ||
"t.c", | ||
unsaved_files=[ | ||
("t.c", "int a = 729;"), | ||
("s.c", "int a = 729;"), | ||
], | ||
) | ||
file1 = File.from_name(tu, "t.c") | ||
file2 = File.from_name(tu, "s.c") | ||
# FIXME: These files are not supposed to be equal | ||
self.assertEqual(file1, file2) | ||
|
||
def test_file_eq_failing_2(self): | ||
index = Index.create() | ||
tu = index.parse( | ||
"t.c", | ||
unsaved_files=[ | ||
("t.c", "int a = 729;"), | ||
("s.c", "int a = 728;"), | ||
], | ||
) | ||
file1 = File.from_name(tu, "t.c") | ||
file2 = File.from_name(tu, "s.c") | ||
# FIXME: These files are not supposed to be equal | ||
self.assertEqual(file1, file2) | ||
|
||
def test_file_eq_failing_3(self): | ||
index = Index.create() | ||
tu = index.parse( | ||
"t.c", | ||
unsaved_files=[ | ||
("t.c", '#include "a.c"\n#include "b.c";'), | ||
("a.c", "int a = 729;"), | ||
("b.c", "int b = 729;"), | ||
], | ||
) | ||
file1 = File.from_name(tu, "t.c") | ||
file2 = File.from_name(tu, "a.c") | ||
file3 = File.from_name(tu, "b.c") | ||
# FIXME: These files are not supposed to be equal | ||
self.assertEqual(file2, file3) | ||
self.assertEqual(file1, file2) | ||
self.assertEqual(file1, file3) | ||
|
||
def test_file_eq_failing_4(self): | ||
path = os.path.join(inputs_dir, "testfile.c") | ||
path_a = os.path.join(inputs_dir, "a.inc") | ||
path_b = os.path.join(inputs_dir, "b.inc") | ||
tu = TranslationUnit.from_source(path) | ||
print(tu.spelling, tu.cursor.spelling) | ||
file1 = File.from_name(tu, path) | ||
file2 = File.from_name(tu, path_a) | ||
file3 = File.from_name(tu, path_b) | ||
# FIXME: These files are not supposed to be equal | ||
self.assertEqual(file2, file3) | ||
self.assertEqual(file1, file2) | ||
self.assertEqual(file1, file3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AaronBallman take a look at the tests I wrote here. At least in the CI, only the last one is actually failing. From the first three, it looks like all in-memory files are considered equal, but test_file_eq_failing_4
which reads them from disk doesn't have that problem.
Even weirder, all four of these tests fail when I run them locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might be a bug here:
llvm-project/clang/tools/libclang/CIndex.cpp
Line 5173 in 1b07e86
return FEnt1.getUniqueID() == FEnt2.getUniqueID(); |
For starters, FileEntryRef
has an equality operator:
friend bool operator==(const FileEntryRef &LHS, const FileEntryRef &RHS) { |
But also, you can use FileManager::getNoncachedStatValue
to get a vfs::Status
object on which you can call equivalent()
to test for equivalency, so it's worth seeing if that gives the correct behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AaronBallman sorry for the delay and thanks a lot for the suggestions!
Changing the line you mentioned to use the equality operator instead indeed seems to result in the correct behavior! It seems like file equality doesn't have any tests in LibclangTest.cpp
either, so I'll add one for this and open a PR later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened a PR at #135773
Co-authored-by: Vlad Serebrennikov <[email protected]>
Co-authored-by: Vlad Serebrennikov <[email protected]>
f0951dd
to
bb4e33e
Compare
@Endilll having merged #135773 and rebased, the issues with file equality for in-memory files are resolved. |
…0383) This covers the `File` interface changes added by llvm#120590 --------- Co-authored-by: Mathias Stearn <[email protected]> Co-authored-by: Vlad Serebrennikov <[email protected]>
…0383) This covers the `File` interface changes added by llvm#120590 --------- Co-authored-by: Mathias Stearn <[email protected]> Co-authored-by: Vlad Serebrennikov <[email protected]>
…0383) This covers the `File` interface changes added by llvm#120590 --------- Co-authored-by: Mathias Stearn <[email protected]> Co-authored-by: Vlad Serebrennikov <[email protected]>
…0383) This covers the `File` interface changes added by llvm#120590 --------- Co-authored-by: Mathias Stearn <[email protected]> Co-authored-by: Vlad Serebrennikov <[email protected]>
This covers the
File
interface changes added by #120590