python-varname icon indicating copy to clipboard operation
python-varname copied to clipboard

overload type returns for nameof

Open lucasteles opened this issue 3 years ago • 5 comments

the nameof always return an union, it makes it hard to use in places where we just want a string

    foo = "..."
    x1: str = nameof(foo) #Expression of type "str | Tuple[str, ...]" cannot be assigned to declared type "Tuple[str, ...]"
    x2: Tuple[str, ...] = nameof(foo) # Expression of type "str | Tuple[str, ...]" cannot be assigned to declared type "Tuple[str, ...]"
    x3: Tuple[str, ...] | str = nameof(foo) # ok

would be great to have an overload to only return Tuple when more names are passed,

or maybe a new deterministic one var function?

lucasteles avatar Jun 16 '22 18:06 lucasteles

Are you using python 3.11?

All the cases worked with python3.10:

bpython version 0.22.1 on top of Python 3.10.0 /path/to/python
>>> from varname import nameof
>>> from typing import Tuple
>>> foo = "..."
>>> x1: str = nameof(foo)
>>> x2: Tuple[str, ...] = nameof(foo)
>>> x3: Tuple[str, ...] | str = nameof(foo)
>>> x1
'foo'
>>> x2
'foo'
>>> x3
'foo'

Python 3.11 is not fully supported yet. See also: https://github.com/alexmojaki/executing/pull/31

pwwang avatar Jun 16 '22 19:06 pwwang

@pwwang yes I am using the 3.10

It work, but the pylance/pyright type check gives the error

lucasteles avatar Jun 16 '22 21:06 lucasteles

@overload requires the function to have the same definition. For the case of nameof, we'd need to call nameof([var1, var2]) for multiple names, which is not what I wanted it to be.

Maybe we can consider separating it into nameof (for single var) and nameof_multi (for multiple vars), but adding one more function adds complexity to the API. This issue exists with other varname core functions as well.

You can temporarily disable the type check on that line with # pyright: reportGeneralTypeIssues=false if you want for now.

pwwang avatar Jun 16 '22 21:06 pwwang

~~Probably https://github.com/wesselb/plum is a good idea?~~

pwwang avatar Aug 31 '22 04:08 pwwang

After some experiments, the following works:

@overload
def nameof(
    var: Any,
    more_var: Any,
    /,    # <-------
    *more_vars: Any,
) -> Tuple[str, ...]:
    ...


@overload
def nameof(
    var: Any,
) -> str:
    ...


def nameof(
    var: Any,
    *more_vars: Any,
) -> str | Tuple[str, ...]:
    ...

However, / was introduced in python3.8. Without it, mypy reports an error.

pwwang avatar Sep 19 '22 18:09 pwwang

Link commit 1a4c450ee4d8b92ee6677c3ba9fc836a1a7d2d68

pwwang avatar Dec 06 '22 02:12 pwwang