pylance-release icon indicating copy to clipboard operation
pylance-release copied to clipboard

`#region` nesting doesn't recognise last `#endregion` if there's no code after it at the end of the file on a non-"root" indent level

Open jvacek opened this issue 3 years ago • 5 comments

Sorry for the monster title, just check the video and you'll see what I mean Type: Bug

Behaviour

Expected vs. Actual

  • Have a #region block that ends at the end of the file that is on a second level of indenting
  • There should be no code on that level after it
  • Expected: it works and folds right
  • Actual: it does not get recognised and does not fold

https://user-images.githubusercontent.com/1302278/188624489-64185c21-0dcb-4364-909e-d395916da126.mov

video above: after deleting the second _, the region on line 540 unfolds because it doesn't think it is a region anymore

Steps to reproduce:

  1. Open VSCode with a Python editor
  2. Write some code like described
  3. Make a #region block that ends at the end of the file, with no code following it
  4. try to fold the block

Diagnostic data

  • Python version (& distribution if applicable, e.g. Anaconda): 3.9.13
  • Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): Venv
  • Value of the python.languageServer setting: Default
Output for Python in the Output panel (ViewOutput, change the drop-down the upper-right of the Output panel to Python)

XXX
User Settings


venvPath: "<placeholder>"

languageServer: "Pylance"

linting
• flake8Args: "<placeholder>"
• flake8Enabled: true
• mypyEnabled: true

sortImports
• args: "<placeholder>"

formatting
• provider: "black"

testing
• pytestArgs: "<placeholder>"
• pytestEnabled: true
• unittestEnabled: true

Extension version: 2022.14.0 VS Code version: Code 1.71.0 (Universal) (784b0177c56c607789f9638da7b6bf3230d47a8c, 2022-09-01T07:25:38.437Z) OS version: Darwin arm64 22.1.0 Modes: Sandboxed: No

System Info
Item Value
CPUs Apple M1 (8 x 24)
GPU Status 2d_canvas: enabled
canvas_oop_rasterization: disabled_off
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
metal: disabled_off
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_renderer: enabled_on
video_decode: enabled
video_encode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled
webgpu: disabled_off
Load (avg) 3, 4, 4
Memory (System) 16.00GB (0.05GB free)
Process Argv --crash-reporter-id cf9a22bc-bfd6-4435-a340-7efeb83080bd
Screen Reader no
VM 0%
A/B Experiments
vsliv368:30146709
vsreu685:30147344
python383:30185418
vspor879:30202332
vspor708:30202333
vspor363:30204092
vstes627:30244334
vslsvsres303:30308271
pythonvspyl392:30443607
vserr242:30382549
pythontb:30283811
vsjup518:30340749
pythonptprofiler:30281270
vshan820:30294714
vstes263cf:30335440
vscoreces:30445986
pythondataviewer:30285071
vscod805:30301674
binariesv615:30325510
bridge0708:30335490
bridge0723:30353136
cmake_vspar411:30557514
vsaa593cf:30376535
pythonvs932:30410667
cppdebug:30492333
pylanb8912:30545647
vsclangdf:30486550
c4g48928:30535728
hb751961:30553087
dsvsc012cf:30540253
azure-dev_surveyone:30548225
i497e931:30553904

jvacek avatar Sep 06 '22 11:09 jvacek

Can you provide a code sample that reproduces this issue? I was only able to reproduce similar behavior when my code had more #region comments than #endregion comments.

Is that the issue on your side also? We should probably emit a warning for unmatched #region/#endregion comments.

debonte avatar Sep 08 '22 06:09 debonte

If this is at the bottom of the file, it won't fold right

class tree:
    # region B
    def flower(self):
        return "random words"

    # endregion

But this will work

class tree:
    # region B
    def flower(self):
        return "random words"

    # endregion

    hello = "world" # ←---

jvacek avatar Sep 08 '22 09:09 jvacek

@jvacek, thanks for the code sample. I'm able to repro this issue now.

I noticed that the indentation of the hello = "world" line is important and has some unexpected effects:

When that line is fully dedented, only the class and def are foldable:

class tree:
    # region B
    def flower(self):
        return "random words"

    # endregion

hello = "world" # ←---

When it is indented one level, the #region is also foldable:

class tree:
    # region B
    def flower(self):
        return "random words"

    # endregion

    hello = "world" # ←---

And when it is indented one more level (to the body of the function), only the class and #region are foldable (not the def):

class tree:
    # region B
    def flower(self):
        return "random words"

    # endregion

        hello = "world" # ←---

debonte avatar Sep 08 '22 17:09 debonte

FYI, I also opened an issue to consider warning about unmatched #region/#endregion comments: https://github.com/microsoft/pylance-release/issues/3308

debonte avatar Sep 08 '22 17:09 debonte

The issue is that VS Code does not allow folding ranges to overlap only partially. One needs to completely surround the other, or else they need to be completely separate.

For example, the following is allowed. [Note that indentation is for readability, but has no effect on folding behavior]:

# Range 1 start
  # Range 2 start
  # Range 2 end
# Range 2 end

But this is invalid:

# Range 1 start
  # Range 2 start
# Range 1 end
  # Range 2 end

Ranges that overlap partially like this are considered invalid and are filtered out by VS Code during FoldingModel.update().

Going back to the earlier examples...

In this example, we currently do not include the #endregion comment in the class folding range, so we end up with partially overlapping ranges:

class tree:                    # Range 1 start
    # region B                 # Range 2 start
    def flower(self):
        return "random words"  # Range 1 end

    # endregion                # Range 2 end

hello = "world" # ←---

Whereas, in this case the region's range is fully contained within the class range:

class tree:                    # Range 1 start
    # region B                 # Range 2 start
    def flower(self):
        return "random words"

    # endregion                # Range 2 end

    hello = "world"            # Range 1 end

debonte avatar Sep 10 '22 07:09 debonte

This issue has been fixed in prerelease version 2023.2.11, which we've just released. You can find the changelog here: CHANGELOG.md

bschnurr avatar Feb 02 '23 05:02 bschnurr