microsoft / python-type-stubs

A set of type stubs for popular Python packages. These are works in progress from the Microsoft Python team and others, with the intent that they are contributed to typeshed or to the associated packages once sufficiently complete.
MIT License
251 stars 99 forks source link

Deprecated warning: center_of_mass and label have been moved from scipy.ndimage.measurements #303

Closed dtribose closed 10 months ago

dtribose commented 11 months ago

Using the stubs included here: In order to eliminate warning I see in my code editor ( VS Code ) for imports of scipy.ndimage.center_of_mass I need to import it as scipy.ndimage.measurements.center_of_mass, but this creates a runtime warning, "DeprecationWarning: Please use center_of_mass from the scipy.ndimage namespace, the scipy.ndimage.measurements namespace is deprecated". A similar issue happens for the function label (and possibly others).

debonte commented 10 months ago
dtribose commented 10 months ago

Thank you for replying.

When I run pyright on the command line I get the following warnings:

  c:\Users\myfirm\dev\tool_companion\reconstruction\myfirm_image_utils.py:255:27 - error: "Literal[1]" is not iterable
    "__iter__" method not defined (reportGeneralTypeIssues)
  c:\Users\myfirm\dev\tool_companion\reconstruction\myfirm_image_utils.py:255:27 - error: "Literal[0]" is not iterable
    "__iter__" method not defined (reportGeneralTypeIssues)
  c:\Users\myfirm\dev\tool_companion\reconstruction\myfirm_image_utils.py:257:33 - error: Argument of type "Unknown | Any | NDArray[float64] | tuple[Any, ...]" cannot be assigned to parameter "number" of type "_SupportsRound1[_T@round]" in function "round"
    Type "Unknown | Any | NDArray[float64] | tuple[Any, ...]" cannot be assigned to type "_SupportsRound1[_T@round]"
      "NDArray[float64]" is incompatible with protocol "_SupportsRound1[_T@round]"
        "__round__" is not present (reportGeneralTypeIssues)

Thanks, David

debonte commented 10 months ago

When I said, "What is the warning that you are seeing?," I meant the warning that you mentioned when you said the following:

warning I see in my code editor ( VS Code ) for imports of scipy.ndimage.center_of_mass I need to import it as scipy.ndimage.measurements.center_of_mass

I'm unable to repro that warning. Maybe it's being reported by some other extension, rather than Pylance?

Are you using the latest version of our scipy stubs? Either the latest from this repo or the ones bundled in Pylance (which should be equivalent)?

dtribose commented 10 months ago

What I see in VS Code is that the line in my code that calls the aforementioned code gets underlined in red, and the module name/tab is likewise colorized in red. I tested that the error was coming from Pylance by disabling it and restarting, then enabling it and restarting. And the files are the most up to date files.

I'm doing my imports like this: from scipy.ndimage import label as spi_label from scipy.ndimage import center_of_mass

When I add '.measurements' to scipy.ndimage - which is where the commands used to be located - the red-lined text goes away. Note: I checked and the same thing happens if I just import 'label' instead of renaming it as 'spi_label'.

In my pipenv .virtualenvs folder for this project under \Lib\site-packages\scipy\ndimage, I have the following files added: _ctest.pyi _cytest.pyi _nd_image.pyi _ni_label.pyi

The files were listed on github at 8 months old, and I downloaded them two weeks ago.

Thanks, David

debonte commented 10 months ago

What I see in VS Code is that the line in my code that calls the aforementioned code gets underlined in red, and the module name/tab is likewise colorized in red.

Ok, but what is the text of the warning? You can see it my either mousing over the red underlined text or opening the Problems pane (Ctrl+Shift+M).

dtribose commented 10 months ago

Here is the warning for label:

"Literal[1]" is not iterable
  "__iter__" method not definedPylance[reportGeneralTypeIssues](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportGeneralTypeIssues)
"Literal[0]" is not iterable
  "__iter__" method not definedPylance[reportGeneralTypeIssues](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportGeneralTypeIssues)
(function) def spi_label(
    input: Unknown,
    structure: Unknown | None = None,
    output: Unknown | None = None
) -> (tuple[ndarray[Unknown, Unknown] | NDArray[int32] | NDArray[float64], Literal[1, 0]] | Unknown | tuple[ndarray[Unknown, Unknown] | NDArray[int32] | NDArray[float64], Unknown] | Literal[1, 0])

And here is the warning for center_of_mass:

Argument of type "Unknown | NDArray[float64] | tuple[Any, ...]" cannot be assigned to parameter "number" of type "_SupportsRound1[_T@round]" in function "round"
  Type "Unknown | NDArray[float64] | tuple[Any, ...]" cannot be assigned to type "_SupportsRound1[_T@round]"
    "NDArray[float64]" is incompatible with protocol "_SupportsRound1[_T@round]"
      "__round__" is not presentPylance[reportGeneralTypeIssues](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportGeneralTypeIssues)
(variable) center_of_mass_: tuple[Unknown | NDArray[float64], ...] | list[tuple[Any, ...]]

Best, David

debonte commented 10 months ago

@dtribose, I'm asking about the warning that you claim told you to switch from scipy.ndimage.center_of_mass to scipy.ndimage.measurements.center_of_mass.

dtribose commented 10 months ago

Got it. Here you go:

C:\Path_to_code\s_image_utils.py:12: DeprecationWarning: Please use label from the scipy.ndimage namespace, the scipy.ndimage.measurements namespace is deprecated. from scipy.ndimage.measurements import label as spi_label C:\Path_to_code\s_image_utils.py:13: DeprecationWarning: Please use center_of_mass from the scipy.ndimage namespace, the scipy.ndimage.measurements namespace is deprecated. from scipy.ndimage.measurements import center_of_mass

Best, David

debonte commented 10 months ago

Not the runtime warning that told you not to use scipy.ndimage.measurements, the warning that VS Code showed you that told you that you should use scipy.ndimage.measurements.

dtribose commented 10 months ago

My earlier messages are the only warning I received about the deprecated code - and VS code never suggested I use scipy.ndimage.measurements.

However, the red underline in my code, and the associated text window that pops up when you omit the '.measurements' are indications (i.e. 'Suggests') that there is a disconnect between Pylance, the Scipy .pyi headers, and VS code and I have no idea where the problem lies.

However, it looks to me like the .pyi files needs to be updated so they are consistent using scipy.ndimage - without the '.measurements' addition - such that we no longer get the deprecated warnings and we no longer get the red marked lines of code in the editor while using Pylance.

Best, David

debonte commented 10 months ago

However, the red underline in my code, and the associated text window that pops up when you omit the '.measurements' are indications (i.e. 'Suggests') that there is a disconnect between Pylance, the Scipy .pyi headers, and VS code and I have no idea where the problem lies.

Any red squiggly underlines that you see in VS Code's editor should be associated with diagnostics (warnings/errors/etc) in the Problems pane. If you can reproduce that red underline "when you omit the '.measurements'", it's the text of that diagnostic that I want to see.

And you also mentioned that an "associated text window" pops up. Can you provide the contents of that or a screenshot?

However, it looks to me like the .pyi files needs to be updated so they are consistent using scipy.ndimage

I don't see any file or directory names within our stubs that contain the word measurements, not do I see any stub files that contain the word measurements beyond spatial\transform\rotation.pyi where it is contained in a docstring.

Can you point me to specific stub files that you are concerned about?

dtribose commented 10 months ago

The messages in the dictionary elements in the problem pane are very similar to what I already shared with you, but here it:

[{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "Argument of type \"Unknown | NDArray[float64] | tuple[Any, ...]\" cannot be assigned to parameter \"number\" of type \"_SupportsRound1[_T@round]\" in function \"round\"\n  Type \"Unknown | NDArray[float64] | tuple[Any, ...]\" cannot be assigned to type \"_SupportsRound1[_T@round]\"\n    \"NDArray[float64]\" is incompatible with protocol \"_SupportsRound1[_T@round]\"\n      \"__round__\" is not present",
    "source": "Pylance",
    "startLineNumber": 249,
    "startColumn": 33,
    "endLineNumber": 249,
    "endColumn": 51
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[0]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 247,
    "startColumn": 27,
    "endLineNumber": 247,
    "endColumn": 42
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[1]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 247,
    "startColumn": 27,
    "endLineNumber": 247,
    "endColumn": 42
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[0]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 232,
    "startColumn": 30,
    "endLineNumber": 232,
    "endColumn": 46
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[1]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 232,
    "startColumn": 30,
    "endLineNumber": 232,
    "endColumn": 46
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[0]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 203,
    "startColumn": 23,
    "endLineNumber": 203,
    "endColumn": 38
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[1]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 203,
    "startColumn": 23,
    "endLineNumber": 203,
    "endColumn": 38
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[0]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 112,
    "startColumn": 23,
    "endLineNumber": 112,
    "endColumn": 38
},{
    "resource": "/c:/Users/sigray/dev/xrm_companion/reconstruction/sigray_image_utils.py",
    "owner": "_generated_diagnostic_collection_name_#0",
    "code": {
        "value": "reportGeneralTypeIssues",
        "target": {
            "$mid": 1,
            "path": "/microsoft/pyright/blob/main/docs/configuration.md",
            "scheme": "https",
            "authority": "github.com",
            "fragment": "reportGeneralTypeIssues"
        }
    },
    "severity": 8,
    "message": "\"Literal[1]\" is not iterable\n  \"__iter__\" method not defined",
    "source": "Pylance",
    "startLineNumber": 112,
    "startColumn": 23,
    "endLineNumber": 112,
    "endColumn": 38
}]

Regarding the 'associated text window' - that is just the pop up one sees when you hover over the red squiggly underlined text and the verbiage was given in a previous comment, and those details are more or less repeated above in the text from the PROBLEMS tab.

I'm using the scipy.ndimage stub files: _ctest.pyi _cytest.pyi _nd_image.pyi _ni_label.pyi

The adding of '.measurements' was proposed by a coworker, since these modules used to be in this subpackage. Perhaps just adding an unknown path or subpackage name causes is to be ignored in Pyright/Pylance.

The issue with center_of_mass(...) is slightly different than what I originally thought and not really related to the function signature but the return type. It appears to be related to the fact the function has two return types - a single tuple, or a list of tuples - and I was using the one where it is a single tuple. If I change my code to force it to return (and use) a list of tuples, even if it has only one element in the list, then my code is no longer underlined, although that should not be necessary.

image

Thanks, David

debonte commented 10 months ago

Perhaps just adding an unknown path or subpackage name causes is to be ignored in Pyright/Pylance.

When you import center_of_mass from scipy.ndimage.measurements we fail to find the definition of center_of_mass so it's type is Any. You can see this by mousing over the import.

image

All operations are valid on an object of type Any, which is why the diagnostic on your center_of_mass call disappears when you make this change. It's the same if you import label from scipy.ndimage.measurements.

This could be fixed by scipy in their measurements.py file by adding the following:

from ._measurements import center_of_mass as center_of_mass

With this change in scipy, your file shows the same error on the center_of_mass call regardless of which namespace you import center_of_mass from. However, given that importing from scipy.ndimage.measurements is deprecated I doubt that scipy would want to invest effort in improving the experience.

It appears to be related to the fact the function has two return types

Yes, in both your label and center_of_mass calls, the core problem is that Pylance doesn't have enough information to predict what the return value's type will be. For Pylance to know that a single tuple will be returned in some scenarios and not others, the stubs would need to include @overloads to define a mapping between types of parameters and corresponding types of return values.

To be honest, our stubs don't describe this section of the scipy API very well. I saw that scipy has accepted a number of PRs to add better static typing support. If you're interested in improving scipy behavior in static type checkers, consider contributing to that effort.