[PATCH] D56429: fix python3 compability issue

2019-01-15 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak marked an inline comment as done.
jstasiak added inline comments.



Comment at: bindings/python/clang/cindex.py:3001
+contents = b(contents)
+unsaved_files_array[i].name = b(fspath(name))
+unsaved_files_array[i].contents = contents

Nitpicking: the description only mentions changes related to file contents but 
this modification (`fspath(name)` -> `b(fspath(name))`) likely fixes a 
different issue, it may be worth mentioning this in the commit message. Unless 
this extra `b()` call is not strictly necessary here but added for consistency?



Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56429/new/

https://reviews.llvm.org/D56429



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56341: [python] Make the collections import future-proof

2019-01-05 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak added a comment.

Thanks. If you could commit this on my behalf I'd appreciate it (I don't have 
commit access).


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56341/new/

https://reviews.llvm.org/D56341



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56341: [python] Make the collections import future-proof

2019-01-04 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak created this revision.
jstasiak added reviewers: mgorny, michaelplatings, serge-sans-paille.
Herald added subscribers: cfe-commits, arphaman.

On Python 3.7 the old code raises a warning:

  

  DeprecationWarning: Using or importing the ABCs from 'collections' instead of 
from 'collections.abc' is deprecated, and in 3.8 it will stop working
  class ArgumentsIterator(collections.Sequence):

  

On Python 3.8 it wouldn't work anymore.


Repository:
  rC Clang

https://reviews.llvm.org/D56341

Files:
  bindings/python/clang/cindex.py


Index: bindings/python/clang/cindex.py
===
--- bindings/python/clang/cindex.py
+++ bindings/python/clang/cindex.py
@@ -64,7 +64,6 @@
 # o implement additional SourceLocation, SourceRange, and File methods.
 
 from ctypes import *
-import collections
 
 import clang.enumerations
 
@@ -123,6 +122,14 @@
 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.
@@ -2181,7 +2188,7 @@
 The returned object is iterable and indexable. Each item in the
 container is a Type instance.
 """
-class ArgumentsIterator(collections.Sequence):
+class ArgumentsIterator(collections_abc.Sequence):
 def __init__(self, parent):
 self.parent = parent
 self.length = None


Index: bindings/python/clang/cindex.py
===
--- bindings/python/clang/cindex.py
+++ bindings/python/clang/cindex.py
@@ -64,7 +64,6 @@
 # o implement additional SourceLocation, SourceRange, and File methods.
 
 from ctypes import *
-import collections
 
 import clang.enumerations
 
@@ -123,6 +122,14 @@
 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.
@@ -2181,7 +2188,7 @@
 The returned object is iterable and indexable. Each item in the
 container is a Type instance.
 """
-class ArgumentsIterator(collections.Sequence):
+class ArgumentsIterator(collections_abc.Sequence):
 def __init__(self, parent):
 self.parent = parent
 self.length = None
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54120: [python] Support PathLike filenames and directories

2018-11-10 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak updated this revision to Diff 173505.
jstasiak added a comment.

That's fair, changed string to just x, should be obvious from the context what 
x is.

Thank you for the review. As I don't have commit access I'd like to ask you to 
commit this on my behalf.


https://reviews.llvm.org/D54120

Files:
  bindings/python/clang/cindex.py
  bindings/python/tests/cindex/test_cdb.py
  bindings/python/tests/cindex/test_code_completion.py
  bindings/python/tests/cindex/test_translation_unit.py
  bindings/python/tests/cindex/util.py

Index: bindings/python/tests/cindex/util.py
===
--- bindings/python/tests/cindex/util.py
+++ bindings/python/tests/cindex/util.py
@@ -1,5 +1,15 @@
 # This file provides common utility functions for the test suite.
 
+import os
+HAS_FSPATH = hasattr(os, 'fspath')
+
+if HAS_FSPATH:
+from pathlib import Path as str_to_path
+else:
+str_to_path = None
+
+import unittest
+
 from clang.cindex import Cursor
 from clang.cindex import TranslationUnit
 
@@ -68,8 +78,13 @@
 return cursors
 
 
+skip_if_no_fspath = unittest.skipUnless(HAS_FSPATH,
+"Requires file system path protocol / Python 3.6+")
+
 __all__ = [
 'get_cursor',
 'get_cursors',
 'get_tu',
+'skip_if_no_fspath',
+'str_to_path',
 ]
Index: bindings/python/tests/cindex/test_translation_unit.py
===
--- bindings/python/tests/cindex/test_translation_unit.py
+++ bindings/python/tests/cindex/test_translation_unit.py
@@ -20,6 +20,8 @@
 from clang.cindex import TranslationUnit
 from .util import get_cursor
 from .util import get_tu
+from .util import skip_if_no_fspath
+from .util import str_to_path
 
 
 kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
@@ -36,6 +38,17 @@
 yield t.name
 
 
+@contextmanager
+def save_tu_pathlike(tu):
+"""Convenience API to save a TranslationUnit to a file.
+
+Returns the filename it was saved to.
+"""
+with tempfile.NamedTemporaryFile() as t:
+tu.save(str_to_path(t.name))
+yield t.name
+
+
 class TestTranslationUnit(unittest.TestCase):
 def test_spelling(self):
 path = os.path.join(kInputsDir, 'hello.cpp')
@@ -89,6 +102,22 @@
 spellings = [c.spelling for c in tu.cursor.get_children()]
 self.assertEqual(spellings[-1], 'x')
 
+@skip_if_no_fspath
+def test_from_source_accepts_pathlike(self):
+tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-Iincludes'], unsaved_files = [
+(str_to_path('fake.c'), """
+#include "fake.h"
+int x;
+int SOME_DEFINE;
+"""),
+(str_to_path('includes/fake.h'), """
+#define SOME_DEFINE y
+""")
+])
+spellings = [c.spelling for c in tu.cursor.get_children()]
+self.assertEqual(spellings[-2], 'x')
+self.assertEqual(spellings[-1], 'y')
+
 def assert_normpaths_equal(self, path1, path2):
 """ Compares two paths for equality after normalizing them with
 os.path.normpath
@@ -135,6 +164,16 @@
 self.assertTrue(os.path.exists(path))
 self.assertGreater(os.path.getsize(path), 0)
 
+@skip_if_no_fspath
+def test_save_pathlike(self):
+"""Ensure TranslationUnit.save() works with PathLike filename."""
+
+tu = get_tu('int foo();')
+
+with save_tu_pathlike(tu) as path:
+self.assertTrue(os.path.exists(path))
+self.assertGreater(os.path.getsize(path), 0)
+
 def test_save_translation_errors(self):
 """Ensure that saving to an invalid directory raises."""
 
@@ -167,6 +206,22 @@
 # Just in case there is an open file descriptor somewhere.
 del tu2
 
+@skip_if_no_fspath
+def test_load_pathlike(self):
+"""Ensure TranslationUnits can be constructed from saved files -
+PathLike variant."""
+tu = get_tu('int foo();')
+self.assertEqual(len(tu.diagnostics), 0)
+with save_tu(tu) as path:
+tu2 = TranslationUnit.from_ast_file(filename=str_to_path(path))
+self.assertEqual(len(tu2.diagnostics), 0)
+
+foo = get_cursor(tu2, 'foo')
+self.assertIsNotNone(foo)
+
+# Just in case there is an open file descriptor somewhere.
+del tu2
+
 def test_index_parse(self):
 path = os.path.join(kInputsDir, 'hello.cpp')
 index = Index.create()
@@ -185,6 +240,19 @@
 with self.assertRaises(Exception):
 f = tu.get_file('foobar.cpp')
 
+@skip_if_no_fspath
+def test_get_file_pathlike(self):
+"""Ensure tu.get_file() works appropriately with PathLike filenames."""
+
+tu = get_tu('int foo();')
+
+f = tu.get_file(str_to_path('t.c'))
+self.assertIsInstance(f, File)
+self.assertEqual(f.name, 't.c')
+
+with 

[PATCH] D54120: [python] Support PathLike filenames and directories

2018-11-10 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak marked 2 inline comments as done.
jstasiak added a comment.

Thanks for the feedback, you're right those were things worth improving, I 
updated the code.


https://reviews.llvm.org/D54120



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54120: [python] Support PathLike filenames and directories

2018-11-10 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak updated this revision to Diff 173496.
jstasiak added a comment.

Tests are skipped using unittest skipping mechanism now and pathlib imported 
only when necessary.


https://reviews.llvm.org/D54120

Files:
  bindings/python/clang/cindex.py
  bindings/python/tests/cindex/test_cdb.py
  bindings/python/tests/cindex/test_code_completion.py
  bindings/python/tests/cindex/test_translation_unit.py
  bindings/python/tests/cindex/util.py

Index: bindings/python/tests/cindex/util.py
===
--- bindings/python/tests/cindex/util.py
+++ bindings/python/tests/cindex/util.py
@@ -1,5 +1,15 @@
 # This file provides common utility functions for the test suite.
 
+import os
+HAS_FSPATH = hasattr(os, 'fspath')
+
+if HAS_FSPATH:
+from pathlib import Path as str_to_path
+else:
+str_to_path = None
+
+import unittest
+
 from clang.cindex import Cursor
 from clang.cindex import TranslationUnit
 
@@ -68,8 +78,13 @@
 return cursors
 
 
+skip_if_no_fspath = unittest.skipUnless(HAS_FSPATH,
+"Requires file system path protocol / Python 3.6+")
+
 __all__ = [
 'get_cursor',
 'get_cursors',
 'get_tu',
+'skip_if_no_fspath',
+'str_to_path',
 ]
Index: bindings/python/tests/cindex/test_translation_unit.py
===
--- bindings/python/tests/cindex/test_translation_unit.py
+++ bindings/python/tests/cindex/test_translation_unit.py
@@ -20,6 +20,8 @@
 from clang.cindex import TranslationUnit
 from .util import get_cursor
 from .util import get_tu
+from .util import skip_if_no_fspath
+from .util import str_to_path
 
 
 kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
@@ -36,6 +38,17 @@
 yield t.name
 
 
+@contextmanager
+def save_tu_pathlike(tu):
+"""Convenience API to save a TranslationUnit to a file.
+
+Returns the filename it was saved to.
+"""
+with tempfile.NamedTemporaryFile() as t:
+tu.save(str_to_path(t.name))
+yield t.name
+
+
 class TestTranslationUnit(unittest.TestCase):
 def test_spelling(self):
 path = os.path.join(kInputsDir, 'hello.cpp')
@@ -89,6 +102,22 @@
 spellings = [c.spelling for c in tu.cursor.get_children()]
 self.assertEqual(spellings[-1], 'x')
 
+@skip_if_no_fspath
+def test_from_source_accepts_pathlike(self):
+tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-Iincludes'], unsaved_files = [
+(str_to_path('fake.c'), """
+#include "fake.h"
+int x;
+int SOME_DEFINE;
+"""),
+(str_to_path('includes/fake.h'), """
+#define SOME_DEFINE y
+""")
+])
+spellings = [c.spelling for c in tu.cursor.get_children()]
+self.assertEqual(spellings[-2], 'x')
+self.assertEqual(spellings[-1], 'y')
+
 def assert_normpaths_equal(self, path1, path2):
 """ Compares two paths for equality after normalizing them with
 os.path.normpath
@@ -135,6 +164,16 @@
 self.assertTrue(os.path.exists(path))
 self.assertGreater(os.path.getsize(path), 0)
 
+@skip_if_no_fspath
+def test_save_pathlike(self):
+"""Ensure TranslationUnit.save() works with PathLike filename."""
+
+tu = get_tu('int foo();')
+
+with save_tu_pathlike(tu) as path:
+self.assertTrue(os.path.exists(path))
+self.assertGreater(os.path.getsize(path), 0)
+
 def test_save_translation_errors(self):
 """Ensure that saving to an invalid directory raises."""
 
@@ -167,6 +206,22 @@
 # Just in case there is an open file descriptor somewhere.
 del tu2
 
+@skip_if_no_fspath
+def test_load_pathlike(self):
+"""Ensure TranslationUnits can be constructed from saved files -
+PathLike variant."""
+tu = get_tu('int foo();')
+self.assertEqual(len(tu.diagnostics), 0)
+with save_tu(tu) as path:
+tu2 = TranslationUnit.from_ast_file(filename=str_to_path(path))
+self.assertEqual(len(tu2.diagnostics), 0)
+
+foo = get_cursor(tu2, 'foo')
+self.assertIsNotNone(foo)
+
+# Just in case there is an open file descriptor somewhere.
+del tu2
+
 def test_index_parse(self):
 path = os.path.join(kInputsDir, 'hello.cpp')
 index = Index.create()
@@ -185,6 +240,19 @@
 with self.assertRaises(Exception):
 f = tu.get_file('foobar.cpp')
 
+@skip_if_no_fspath
+def test_get_file_pathlike(self):
+"""Ensure tu.get_file() works appropriately with PathLike filenames."""
+
+tu = get_tu('int foo();')
+
+f = tu.get_file(str_to_path('t.c'))
+self.assertIsInstance(f, File)
+self.assertEqual(f.name, 't.c')
+
+with self.assertRaises(Exception):
+f = tu.get_file(str_to_path('foobar.cpp'))
+
 def 

[PATCH] D54120: [python] Support PathLike filenames and directories

2018-11-05 Thread Jakub Stasiak via Phabricator via cfe-commits
jstasiak created this revision.
jstasiak added reviewers: mgorny, jbcoe.
Herald added a subscriber: arphaman.

Python 3.6 introduced a file system path protocol (PEP 519[1]). The standard 
library APIs accepting file system paths now accept path objects too. It could 
be useful to add this here as well for convenience.

  

[1] https://www.python.org/dev/peps/pep-0519


Repository:
  rC Clang

https://reviews.llvm.org/D54120

Files:
  bindings/python/clang/cindex.py
  bindings/python/tests/cindex/test_cdb.py
  bindings/python/tests/cindex/test_code_completion.py
  bindings/python/tests/cindex/test_translation_unit.py
  bindings/python/tests/cindex/util.py

Index: bindings/python/tests/cindex/util.py
===
--- bindings/python/tests/cindex/util.py
+++ bindings/python/tests/cindex/util.py
@@ -1,5 +1,15 @@
 # This file provides common utility functions for the test suite.
 
+import os
+HAS_FSPATH = hasattr(os, 'fspath')
+
+try:
+import pathlib
+except ImportError:
+str_to_path = None
+else:
+str_to_path = pathlib.Path
+
 from clang.cindex import Cursor
 from clang.cindex import TranslationUnit
 
@@ -72,4 +82,6 @@
 'get_cursor',
 'get_cursors',
 'get_tu',
+'HAS_FSPATH',
+'str_to_path',
 ]
Index: bindings/python/tests/cindex/test_translation_unit.py
===
--- bindings/python/tests/cindex/test_translation_unit.py
+++ bindings/python/tests/cindex/test_translation_unit.py
@@ -20,6 +20,8 @@
 from clang.cindex import TranslationUnit
 from .util import get_cursor
 from .util import get_tu
+from .util import HAS_FSPATH
+from .util import str_to_path
 
 
 kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
@@ -36,6 +38,17 @@
 yield t.name
 
 
+@contextmanager
+def save_tu_pathlike(tu):
+"""Convenience API to save a TranslationUnit to a file.
+
+Returns the filename it was saved to.
+"""
+with tempfile.NamedTemporaryFile() as t:
+tu.save(str_to_path(t.name))
+yield t.name
+
+
 class TestTranslationUnit(unittest.TestCase):
 def test_spelling(self):
 path = os.path.join(kInputsDir, 'hello.cpp')
@@ -89,6 +102,22 @@
 spellings = [c.spelling for c in tu.cursor.get_children()]
 self.assertEqual(spellings[-1], 'x')
 
+if HAS_FSPATH:
+def test_from_source_accepts_pathlike(self):
+tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-Iincludes'], unsaved_files = [
+(str_to_path('fake.c'), """
+#include "fake.h"
+int x;
+int SOME_DEFINE;
+"""),
+(str_to_path('includes/fake.h'), """
+#define SOME_DEFINE y
+""")
+])
+spellings = [c.spelling for c in tu.cursor.get_children()]
+self.assertEqual(spellings[-2], 'x')
+self.assertEqual(spellings[-1], 'y')
+
 def assert_normpaths_equal(self, path1, path2):
 """ Compares two paths for equality after normalizing them with
 os.path.normpath
@@ -135,6 +164,16 @@
 self.assertTrue(os.path.exists(path))
 self.assertGreater(os.path.getsize(path), 0)
 
+if HAS_FSPATH:
+def test_save_pathlike(self):
+"""Ensure TranslationUnit.save() works with PathLike filename."""
+
+tu = get_tu('int foo();')
+
+with save_tu_pathlike(tu) as path:
+self.assertTrue(os.path.exists(path))
+self.assertGreater(os.path.getsize(path), 0)
+
 def test_save_translation_errors(self):
 """Ensure that saving to an invalid directory raises."""
 
@@ -167,6 +206,17 @@
 # Just in case there is an open file descriptor somewhere.
 del tu2
 
+# We can also pass the filename as Path-like object
+if HAS_FSPATH:
+tu2 = TranslationUnit.from_ast_file(filename=str_to_path(path))
+self.assertEqual(len(tu2.diagnostics), 0)
+
+foo = get_cursor(tu2, 'foo')
+self.assertIsNotNone(foo)
+
+# Just in case there is an open file descriptor somewhere.
+del tu2
+
 def test_index_parse(self):
 path = os.path.join(kInputsDir, 'hello.cpp')
 index = Index.create()
@@ -185,6 +235,19 @@
 with self.assertRaises(Exception):
 f = tu.get_file('foobar.cpp')
 
+if HAS_FSPATH:
+def test_get_file_pathlike(self):
+"""Ensure tu.get_file() works appropriately with PathLike filenames."""
+
+tu = get_tu('int foo();')
+
+f = tu.get_file(str_to_path('t.c'))
+self.assertIsInstance(f, File)
+self.assertEqual(f.name, 't.c')
+
+with self.assertRaises(Exception):
+f = tu.get_file(str_to_path('foobar.cpp'))
+
 def test_get_source_location(self):
 """Ensure