Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to use function objects as singletons #668

Open
Jackenmen opened this issue Aug 21, 2019 · 6 comments
Open

Allow to use function objects as singletons #668

Jackenmen opened this issue Aug 21, 2019 · 6 comments
Labels
topic: feature Discussions about new features for Python's type annotations

Comments

@Jackenmen
Copy link
Contributor

Jackenmen commented Aug 21, 2019

I was trying to create some stubs for lxml library, but I encountered a function that depending on a function object it gets (as in specific function object - checked with identity check) only finds objects of specific type.

Here's a very simplified mock-up of it so that you can get some idea on what I mean (the typing for arg argument in the find function is incorrect and that's what I want to be able to type hint in some way):

from typing import Union

class _Element: ...

def Element() -> _Element: ...

class _Comment: ...

def Comment() -> _Comment: ...

def find(arg: Union[Element, Comment]) -> Union[_Element, _Comment]:
    if arg is Element:
        # only find _Element objects
    elif arg is Element:
        # only find _Comment objects

# this function should only accept `Element` and `Comment` function object 
find(arg=Element)

So basically those functions serve as a singletons. Unfortunately typing.Union only allows Enums to work as singletons.

I am not entirely sure if this should be supported, usually the code could just be adjusted to use Enums, but in this case it will be used for type stubs so the code can't be edited. And to be honest, I am not sure if the code really needs editing in that case as if I didn't need typing for that library, I would say it's actually quite intuitive to use these factory functions as arguments in this case.

@gvanrossum
Copy link
Member

I recommend that you try the work-around you suggested yourself and use it for a while, then tell us how bad (or not) that was. Implementing this in mypy would probably be a significant project, which means it won't happen soon.

@Jackenmen
Copy link
Contributor Author

Thanks for quick answer. If you mean the Enum workaround then unfortunately like I said, I created this issue with type stubs in mind - I am not lxml developer and I just wanted to help create proper type stubs for lxml (JelleZijlstra/lxml-stubs)
I know very well that this wouldn't happen any time soon, I just wanted to know if such addition may happen some day or if it's rather something that you would rather want to not implement.

@gvanrossum
Copy link
Member

Honestly I think it's rather an odd corner case -- why function objects and not class objects? Perhaps the best way to think about this is PEP 586 (Literal types) -- are there other objects that we could support inside the brackets of Literal[...]? @Michael0x2a

@Jackenmen
Copy link
Contributor Author

In case this would actually be class object, I don't think there's a way to type a class object without including subclass objects? (which would be required if it were supposed to be used in code that uses simple identity check)

@JelleZijlstra
Copy link
Member

Well, if we're in the realm of hypothetical type system features, we could say that Literal[SomeClass] means exactly that class object, while Type[SomeClass] means that class object or a subclass.

@Jackenmen
Copy link
Contributor Author

Before I fully read PEP 586, I even thought that such use is going to be possible with Literal types.

@srittau srittau added the topic: feature Discussions about new features for Python's type annotations label Nov 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: feature Discussions about new features for Python's type annotations
Projects
None yet
Development

No branches or pull requests

4 participants