Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-rope for openSUSE:Factory 
checked in at 2024-01-21 23:10:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-rope (Old)
 and      /work/SRC/openSUSE:Factory/.python-rope.new.16006 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-rope"

Sun Jan 21 23:10:11 2024 rev:33 rq:1140277 version:1.12.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-rope/python-rope.changes  2024-01-03 
12:24:10.937710947 +0100
+++ /work/SRC/openSUSE:Factory/.python-rope.new.16006/python-rope.changes       
2024-01-21 23:10:34.734366541 +0100
@@ -1,0 +2,13 @@
+Sun Jan 21 11:09:36 UTC 2024 - Dirk Müller <dmuel...@suse.com>
+
+- update to 1.12.0:
+  * #733 skip directories with perm error when building
+    autoimport index (@MrBago)
+  * #722, #723 Remove site-packages from packages search tree
+    (@tkrabel)
+  * #738 Implement os.PathLike on Resource (@lieryan)
+  * #739, #736 Ensure autoimport requests uses indexes (@lieryan)
+  * #734, #735 raise exception when extracting the start of a
+    block without the end
+
+-------------------------------------------------------------------

Old:
----
  rope-1.11.0.tar.gz

New:
----
  rope-1.12.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-rope.spec ++++++
--- /var/tmp/diff_new_pack.rZPFPe/_old  2024-01-21 23:10:35.358389287 +0100
+++ /var/tmp/diff_new_pack.rZPFPe/_new  2024-01-21 23:10:35.358389287 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-rope
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-rope
-Version:        1.11.0
+Version:        1.12.0
 Release:        0
 Summary:        A python refactoring library
 License:        LGPL-3.0-or-later

++++++ rope-1.11.0.tar.gz -> rope-1.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/CHANGELOG.md new/rope-1.12.0/CHANGELOG.md
--- old/rope-1.11.0/CHANGELOG.md        2023-11-05 16:10:32.000000000 +0100
+++ new/rope-1.12.0/CHANGELOG.md        2024-01-18 05:30:13.000000000 +0100
@@ -1,5 +1,15 @@
 # **Upcoming release**
 
+- ...
+
+# Release 1.12.0
+
+- #733 skip directories with perm error when building autoimport index 
(@MrBago)
+- #722, #723 Remove site-packages from packages search tree (@tkrabel)
+- #738 Implement os.PathLike on Resource (@lieryan)
+- #739, #736 Ensure autoimport requests uses indexes (@lieryan)
+- #734, #735 raise exception when extracting the start of a block without the 
end
+
 # Release 1.11.0
 
 - #710, #561 Implement `except*` syntax (@lieryan)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/PKG-INFO new/rope-1.12.0/PKG-INFO
--- old/rope-1.11.0/PKG-INFO    2023-11-05 16:12:09.193045400 +0100
+++ new/rope-1.12.0/PKG-INFO    2024-01-18 05:43:22.713984300 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: rope
-Version: 1.11.0
+Version: 1.12.0
 Summary: a python refactoring library...
 Author-email: Ali Gholami Rudi <aligr...@users.sourceforge.net>
 Maintainer-email: Lie Ryan <lieryan...@proton.me>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/docs/contributing.rst 
new/rope-1.12.0/docs/contributing.rst
--- old/rope-1.11.0/docs/contributing.rst       2023-11-05 16:08:39.000000000 
+0100
+++ new/rope-1.12.0/docs/contributing.rst       2024-01-18 05:15:50.000000000 
+0100
@@ -95,6 +95,13 @@
 Rope uses GitHub_. The repository exists at
 `python-rope/rope`_.
 
+Setting up for local development
+================================
+
+#. Clone repository: ``git clone https://github.com/python-rope/rope.git``
+#. Create a virtualenv: ``python -m venv rope-venv``
+#. Activate the virtualenv
+#. Install the project into the venv: ``pip install -e '.[doc,dev]'``
 
 Submitting pull requests
 ========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/docs/release-process.rst 
new/rope-1.12.0/docs/release-process.rst
--- old/rope-1.11.0/docs/release-process.rst    2023-10-15 08:08:40.000000000 
+0200
+++ new/rope-1.12.0/docs/release-process.rst    2024-01-18 05:39:22.000000000 
+0100
@@ -12,14 +12,15 @@
 
 1. Ensure tickets assigned to Milestones are up to date
 2. Update ``CHANGELOG.md``
-3. Increment version number in ``pyproject.toml``
-4. `git commit && git push`
-5. Tag the release with the tag annotation containing the release information,
+3. Close milestone
+4. Increment version number in ``pyproject.toml``
+5. `git commit && git push`
+6. Tag the release with the tag annotation containing the release information,
    ``python bin/tag-release.py``
-6. ``python3 -m build``
-7. ``twine upload -s dist/rope-$VERSION.{tar.gz,whl}``
-8. Publish to Discussions Announcement
-9. Close milestone
+7. ``python3 -m build``
+8. ``twine upload dist/rope-$VERSION.{tar.gz,whl}``
+9. Publish to Discussions Announcement
+10. Create Github Release
 
 
 Release Schedule
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/pyproject.toml 
new/rope-1.12.0/pyproject.toml
--- old/rope-1.11.0/pyproject.toml      2023-11-05 16:09:16.000000000 +0100
+++ new/rope-1.12.0/pyproject.toml      2024-01-18 05:42:05.000000000 +0100
@@ -21,7 +21,7 @@
     'Programming Language :: Python :: 3.12',
     'Topic :: Software Development',
 ]
-version = '1.11.0'
+version = '1.12.0'
 dependencies = ['pytoolconfig[global] >= 1.2.2']
 
 [[project.authors]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/rope/base/resources.py 
new/rope-1.12.0/rope/base/resources.py
--- old/rope-1.11.0/rope/base/resources.py      2023-10-15 08:07:50.000000000 
+0200
+++ new/rope-1.12.0/rope/base/resources.py      2024-01-18 05:15:50.000000000 
+0100
@@ -34,7 +34,7 @@
 from rope.base import change, exceptions, fscommands
 
 
-class Resource:
+class Resource(os.PathLike):
     """Represents files and folders in a project"""
 
     def __init__(self, project, path):
@@ -49,6 +49,10 @@
             hex(id(self)),
         )
 
+    def __fspath__(self) -> str:
+        """Return the file system path of this resource"""
+        return self.project._get_resource_path(self.path)
+
     def move(self, new_location):
         """Move resource to `new_location`"""
         self._perform_change(
@@ -60,14 +64,17 @@
         """Remove resource from the project"""
         self._perform_change(change.RemoveResource(self), "Removing <%s>" % 
self.path)
 
+    def is_dir(self):
+        """Alias for `is_folder()`"""
+
     def is_folder(self):
-        """Return true if the resource is a folder"""
+        """Return True if the resource is a Folder"""
 
     def create(self):
         """Create this resource"""
 
     def exists(self):
-        return os.path.exists(self.real_path)
+        return os.path.exists(self)
 
     @property
     def parent(self):
@@ -75,7 +82,7 @@
         return self.project.get_folder(parent)
 
     @property
-    def path(self):
+    def path(self) -> str:
         """Return the path of this resource relative to the project root
 
         The path is the list of parent directories separated by '/' followed
@@ -84,19 +91,18 @@
         return self._path
 
     @property
-    def name(self):
+    def name(self) -> str:
         """Return the name of this resource"""
         return self.path.split("/")[-1]
 
     @property
-    def real_path(self):
-        """Return the file system path of this resource"""
-        return self.project._get_resource_path(self.path)
+    def real_path(self) -> str:
+        return os.fspath(self)
 
     @property
-    def pathlib(self):
+    def pathlib(self) -> Path:
         """Return the file as a pathlib path."""
-        return Path(self.real_path)
+        return Path(self)
 
     def __eq__(self, obj):
         return self.__class__ == obj.__class__ and self.path == obj.path
@@ -135,7 +141,7 @@
                 DeprecationWarning,
                 stacklevel=2,
             )
-            with open(self.real_path, "rb") as handle:
+            with open(self, "rb") as handle:
                 return handle.read()
         return self.project.fscommands.read(self.real_path)
 
@@ -165,7 +171,7 @@
     def get_children(self):
         """Return the children of this folder"""
         try:
-            children = os.listdir(self.real_path)
+            children = os.listdir(self)
         except OSError:
             return []
         result = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/rope/contrib/autoimport/models.py 
new/rope-1.12.0/rope/contrib/autoimport/models.py
--- old/rope-1.11.0/rope/contrib/autoimport/models.py   2023-11-05 
16:08:39.000000000 +0100
+++ new/rope-1.12.0/rope/contrib/autoimport/models.py   2024-01-18 
05:15:50.000000000 +0100
@@ -9,6 +9,9 @@
     def __repr__(self):
         return f'{self.__class__.__name__}("{self._query}")'
 
+    def explain(self):
+        return FinalQuery("EXPLAIN QUERY PLAN " + self._query)
+
 
 class Query:
     def __init__(self, query: str, columns: List[str]):
@@ -100,9 +103,14 @@
     @classmethod
     def create_table(cls, connection):
         super().create_table(connection)
-        connection.execute("CREATE INDEX IF NOT EXISTS name ON names(name)")
-        connection.execute("CREATE INDEX IF NOT EXISTS module ON 
names(module)")
-        connection.execute("CREATE INDEX IF NOT EXISTS package ON 
names(package)")
+        # fmt: off
+        connection.execute("CREATE INDEX IF NOT EXISTS names_name ON 
names(name)")
+        connection.execute("CREATE INDEX IF NOT EXISTS names_module ON 
names(module)")
+        connection.execute("CREATE INDEX IF NOT EXISTS names_package ON 
names(package)")
+        connection.execute("CREATE INDEX IF NOT EXISTS names_name_nocase ON 
names(name COLLATE NOCASE)")
+        connection.execute("CREATE INDEX IF NOT EXISTS names_module_nocase ON 
names(module COLLATE NOCASE)")
+        connection.execute("CREATE INDEX IF NOT EXISTS names_package_nocase ON 
names(package COLLATE NOCASE)")
+        # fmt: on
 
     search_submodule_like = objects.where('module LIKE ("%." || ?)')
     search_module_like = objects.where("module LIKE (?)")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/rope/contrib/autoimport/sqlite.py 
new/rope-1.12.0/rope/contrib/autoimport/sqlite.py
--- old/rope-1.11.0/rope/contrib/autoimport/sqlite.py   2023-11-05 
16:08:39.000000000 +0100
+++ new/rope-1.12.0/rope/contrib/autoimport/sqlite.py   2024-01-18 
05:15:50.000000000 +0100
@@ -113,7 +113,7 @@
                 autoimport = AutoImport(..., memory=True)
         """
         self.project = project
-        project_package = get_package_tuple(Path(project.root.real_path), 
project)
+        project_package = get_package_tuple(project.root.pathlib, project)
         assert project_package is not None
         assert project_package.path is not None
         self.project_package = project_package
@@ -175,9 +175,7 @@
                 f"file:rope-{project_hash}:?mode=memory&cache=shared", uri=True
             )
         else:
-            return sqlite3.connect(
-                str(Path(project.ropefolder.real_path) / "autoimport.db")
-            )
+            return sqlite3.connect(project.ropefolder.pathlib / 
"autoimport.db")
 
     @property
     def connection(self):
@@ -542,17 +540,26 @@
             return folder.is_dir() and folder.as_posix() != "/usr/bin"
 
         folders = self.project.get_python_path_folders()
-        folder_paths = map(lambda folder: Path(folder.real_path), folders)
-        folder_paths = filter(filter_folders, folder_paths)  # type:ignore
+        folder_paths = filter(filter_folders, map(Path, folders))
         return list(OrderedDict.fromkeys(folder_paths))
 
+    def _safe_iterdir(self, folder: Path):
+        dirs = folder.iterdir()
+        while True:
+            try:
+                yield next(dirs)
+            except PermissionError:
+                pass
+            except StopIteration:
+                break
+
     def _get_available_packages(self) -> List[Package]:
         packages: List[Package] = [
             Package(module, Source.BUILTIN, None, PackageType.BUILTIN)
             for module in sys.builtin_module_names
         ]
         for folder in self._get_python_folders():
-            for package in folder.iterdir():
+            for package in self._safe_iterdir(folder):
                 package_tuple = get_package_tuple(package, self.project)
                 if package_tuple is None:
                     continue
@@ -602,7 +609,7 @@
         if target_name in sys.builtin_module_names:
             return Package(target_name, Source.BUILTIN, None, 
PackageType.BUILTIN)
         for folder in self._get_python_folders():
-            for package in folder.iterdir():
+            for package in self._safe_iterdir(folder):
                 package_tuple = get_package_tuple(package, self.project)
                 if package_tuple is None:
                     continue
@@ -617,7 +624,7 @@
     ) -> ModuleFile:
         assert self.project_package.path
         underlined = underlined if underlined else self.underlined
-        resource_path: Path = Path(resource.real_path)
+        resource_path: Path = resource.pathlib
         # The project doesn't need its name added to the path,
         # since the standard python file layout accounts for that
         # so we set add_package_name to False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/rope/contrib/autoimport/utils.py 
new/rope-1.12.0/rope/contrib/autoimport/utils.py
--- old/rope-1.11.0/rope/contrib/autoimport/utils.py    2023-10-15 
08:08:40.000000000 +0200
+++ new/rope-1.12.0/rope/contrib/autoimport/utils.py    2024-01-18 
05:15:50.000000000 +0100
@@ -20,7 +20,7 @@
     """
     package_name = package_path.name
     package_type: PackageType
-    if package_name.startswith(".") or package_name == "__pycache__":
+    if package_name.startswith(".") or package_name in ["__pycache__", 
"site-packages"]:
         return None
     if package_name.endswith((".egg-info", ".dist-info")):
         return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/rope/refactor/extract.py 
new/rope-1.12.0/rope/refactor/extract.py
--- old/rope-1.11.0/rope/refactor/extract.py    2023-10-15 08:08:40.000000000 
+0200
+++ new/rope-1.12.0/rope/refactor/extract.py    2024-01-18 05:15:50.000000000 
+0100
@@ -444,8 +444,10 @@
     def base_conditions(self, info):
         if info.region[1] > info.scope_region[1]:
             raise RefactoringError("Bad region selected for extract method")
+
         end_line = info.region_lines[1]
         end_scope = info.global_scope.get_inner_scope_for_line(end_line)
+
         if end_scope != info.scope and end_scope.get_end() != end_line:
             raise RefactoringError("Bad region selected for extract method")
         try:
@@ -497,6 +499,14 @@
             raise RefactoringError(
                 "Extracted piece should contain complete statements."
             )
+        unbalanced_region_finder = _UnbalancedRegionFinder(
+            info.region_lines[0], info.region_lines[1]
+        )
+        unbalanced_region_finder.visit(info.pymodule.ast_node)
+        if unbalanced_region_finder.error:
+            raise RefactoringError(
+                "Extracted piece cannot contain the start of a block without 
the end."
+            )
 
     def _is_region_on_a_word(self, info):
         if (
@@ -1093,6 +1103,34 @@
         pass
 
 
+class _UnbalancedRegionFinder(_BaseErrorFinder):
+    """
+    Flag an error if we are including the start of a block without the end.
+    We detect this by ensuring there is no AST node that starts inside the
+    selected range but ends outside of it.
+    """
+
+    def __init__(self, line_start: int, line_end: int):
+        self.error = False
+        self.line_start = line_start
+        self.line_end = line_end
+
+    def generic_visit(self, node: ast.AST):
+        if not hasattr(node, "end_lineno"):
+            super().generic_visit(node)  # Visit children
+            return
+        ends_before_range_starts = node.end_lineno < self.line_start
+        starts_after_range_ends = node.lineno > self.line_end
+        if ends_before_range_starts or starts_after_range_ends:
+            return  # Don't visit children
+        starts_on_or_after_range_start = node.lineno >= self.line_start
+        ends_after_range_ends = node.end_lineno > self.line_end
+        if starts_on_or_after_range_start and ends_after_range_ends:
+            self.error = True
+            return  # Don't visit children
+        super().generic_visit(node)  # Visit children
+
+
 class _GlobalFinder(ast.RopeNodeVisitor):
     def __init__(self):
         self.globals_ = OrderedSet()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/rope.egg-info/PKG-INFO 
new/rope-1.12.0/rope.egg-info/PKG-INFO
--- old/rope-1.11.0/rope.egg-info/PKG-INFO      2023-11-05 16:12:09.000000000 
+0100
+++ new/rope-1.12.0/rope.egg-info/PKG-INFO      2024-01-18 05:43:22.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: rope
-Version: 1.11.0
+Version: 1.12.0
 Summary: a python refactoring library...
 Author-email: Ali Gholami Rudi <aligr...@users.sourceforge.net>
 Maintainer-email: Lie Ryan <lieryan...@proton.me>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/rope-1.11.0/ropetest/contrib/autoimport/autoimporttest.py 
new/rope-1.12.0/ropetest/contrib/autoimport/autoimporttest.py
--- old/rope-1.11.0/ropetest/contrib/autoimport/autoimporttest.py       
2023-11-05 16:08:39.000000000 +0100
+++ new/rope-1.12.0/ropetest/contrib/autoimport/autoimporttest.py       
2024-01-18 05:15:50.000000000 +0100
@@ -186,3 +186,39 @@
     with assert_database_is_preserved(conn), \
             patch("rope.base.versioning.calculate_version_hash", 
return_value="up-to-date-value"):
         autoimport._setup_db()
+
+
+class TestQueryUsesIndexes:
+    def explain(self, autoimport, query):
+        explanation = list(autoimport._execute(query.explain(), 
("abc",)))[0][-1]
+        # the explanation text varies, on some sqlite version
+        explanation = explanation.replace("TABLE ", "")
+        return explanation
+
+    def test_search_by_name_uses_index(self, autoimport):
+        query = models.Name.search_by_name.select_star()
+        assert (
+            self.explain(autoimport, query)
+            == "SEARCH names USING INDEX names_name (name=?)"
+        )
+
+    def test_search_by_name_like_uses_index(self, autoimport):
+        query = models.Name.search_by_name_like.select_star()
+        assert (
+            self.explain(autoimport, query)
+            == "SEARCH names USING INDEX names_name_nocase (name>? AND name<?)"
+        )
+
+    def test_search_module_like_uses_index(self, autoimport):
+        query = models.Name.search_module_like.select_star()
+        assert (
+            self.explain(autoimport, query)
+            == "SEARCH names USING INDEX names_module_nocase (module>? AND 
module<?)"
+        )
+
+    def test_search_submodule_like_uses_index(self, autoimport):
+        query = models.Name.search_submodule_like.select_star()
+        assert (
+            self.explain(autoimport, query)
+            == "SCAN names" # FIXME: avoid full table scan
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/ropetest/contrib/autoimporttest.py 
new/rope-1.12.0/ropetest/contrib/autoimporttest.py
--- old/rope-1.11.0/ropetest/contrib/autoimporttest.py  2023-10-15 
08:07:50.000000000 +0200
+++ new/rope-1.12.0/ropetest/contrib/autoimporttest.py  2024-01-18 
05:15:50.000000000 +0100
@@ -134,13 +134,28 @@
         self.assertIn(import_statement, self.importer.search("D"))
 
     def test_generate_full_cache(self):
-        """The single thread test takes much longer than the multithread test 
but is easier to debug"""
+        # The single thread test takes much longer than the multithread test 
but is easier to debug
         single_thread = False
         self.importer.generate_modules_cache(single_thread=single_thread)
         self.assertIn(("from typing import Dict", "Dict"), 
self.importer.search("Dict"))
-        self.assertTrue(len(self.importer._dump_all()) > 0)
+        self.assertGreater(len(self.importer._dump_all()), 0)
         for table in self.importer._dump_all():
-            self.assertTrue(len(table) > 0)
+            self.assertGreater(len(table), 0)
+
+    def 
test_skipping_directories_not_accessible_because_of_permission_error(self):
+        # The single thread test takes much longer than the multithread test 
but is easier to debug
+        single_thread = False
+        self.importer.generate_modules_cache(single_thread=single_thread)
+        
+        # Create a temporary directory and set permissions to 000
+        import tempfile, sys
+        with tempfile.TemporaryDirectory() as dir:
+            import os
+            os.chmod(dir, 0o000)
+            self.importer.project.prefs.python_path = [dir]
+            self.importer.generate_modules_cache(single_thread=single_thread)
+        self.assertIn(("from typing import Dict", "Dict"), 
self.importer.search("Dict"))
+        self.assertGreater(len(self.importer._dump_all()), 0)
 
 
 class AutoImportObservingTest(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/ropetest/projecttest.py 
new/rope-1.12.0/ropetest/projecttest.py
--- old/rope-1.11.0/ropetest/projecttest.py     2023-10-15 08:07:50.000000000 
+0200
+++ new/rope-1.12.0/ropetest/projecttest.py     2024-01-18 05:15:50.000000000 
+0100
@@ -9,6 +9,7 @@
 from rope.base.libutils import path_to_resource
 from rope.base.project import NoProject, Project, _realpath
 from rope.base.resourceobserver import FilteredResourceObserver
+from rope.base.resources import File, Folder
 from ropetest import testutils
 
 
@@ -610,6 +611,18 @@
         self.assertEqual(2, len(source_folders))
         self.assertTrue(self.project.root in source_folders and src in 
source_folders)
 
+    def test_folder_is_pathlike(self):
+        resource = self.project.root.create_folder("src")
+        self.assertIsInstance(resource, Folder)
+
+        self.assertIsInstance(os.fspath(resource), str)
+
+    def test_file_is_pathlike(self):
+        resource = self.project.root.create_file("mod.py")
+        self.assertIsInstance(resource, File)
+
+        self.assertIsInstance(os.fspath(resource), str)
+
 
 class ResourceObserverTest(unittest.TestCase):
     def setUp(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rope-1.11.0/ropetest/refactor/extracttest.py 
new/rope-1.12.0/ropetest/refactor/extracttest.py
--- old/rope-1.11.0/ropetest/refactor/extracttest.py    2023-11-05 
16:08:39.000000000 +0100
+++ new/rope-1.12.0/ropetest/refactor/extracttest.py    2024-01-18 
05:15:50.000000000 +0100
@@ -1149,6 +1149,64 @@
         end = code.rindex(")") + 1
         with self.assertRaises(rope.base.exceptions.RefactoringError):
             self.do_extract_method(code, start, end, "new_func")
+    
+    def test_raising_exception_on_incomplete_block(self):
+        code = dedent("""\
+            if True:
+                a = 1
+                b = 2
+        """)
+        start = code.index("if")
+        end = code.index("1") + 1
+        with self.assertRaises(rope.base.exceptions.RefactoringError):
+            self.do_extract_method(code, start, end, "new_func")
+
+    def test_raising_exception_on_incomplete_block_2(self):
+        code = dedent("""\
+            if True:
+                a = 1
+            #
+                b = 2
+        """)
+        start = code.index("if")
+        end = code.index("1") + 1
+        with self.assertRaises(rope.base.exceptions.RefactoringError):
+            self.do_extract_method(code, start, end, "new_func")
+
+    def test_raising_exception_on_incomplete_block_3(self):
+        code = dedent("""\
+            if True:
+                a = 1
+            
+                b = 2
+        """)
+        start = code.index("if")
+        end = code.index("1") + 1
+        with self.assertRaises(rope.base.exceptions.RefactoringError):
+            self.do_extract_method(code, start, end, "new_func")
+
+    def test_raising_exception_on_incomplete_block_4(self):
+        code = dedent("""\
+                #
+            if True:
+                a = 1
+                b = 2
+        """)
+        start = code.index("#")
+        end = code.index("1") + 1
+        with self.assertRaises(rope.base.exceptions.RefactoringError):
+            self.do_extract_method(code, start, end, "new_func")
+
+    def test_raising_exception_on_incomplete_block_5(self):
+        code = dedent("""\
+            if True:
+                if 0:
+                    a = 1
+        """)
+        start = code.index("if")
+        end = code.index("0:") + 2
+        with self.assertRaises(rope.base.exceptions.RefactoringError):
+            self.do_extract_method(code, start, end, "new_func")
 
     def test_extract_method_and_extra_blank_lines(self):
         code = dedent("""\

Reply via email to