Getty fully qualified class name from class object
How can I programmatically get the fully qualified name of a class from its class object? (I'm referring to the name that is shown when str() or repr() is called on the class object.) Neither the __name__ or __qualname__ class attributes include the module. For example: >>> import logging >>> str(logging.Handler) "" >>> logging.Handler.__name__ 'Handler' >>> logging.Handler.__qualname__ 'Handler' How can I programmatically get 'logging.Handler' from the class object? -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Getty fully qualified class name from class object
On 8/22/23 11:13, Greg Ewing via Python-list wrote: Classes have a __module__ attribute: >>> logging.Handler.__module__ 'logging' Not sure why I didn't think to look for such a thing. Looks like it's as simple as f'{cls.__module__}.{cls.__qualname__}'. Thanks! -- Google Where SkyNet meets Idiocracy -- https://mail.python.org/mailman/listinfo/python-list
Re: Struggling to understand Callable type hinting
(Note: I have mail delivery disabled for this list and read it through GMane, so I am unable to respond with correct threading if I'm not cc'ed directly.) On 1/17/25 7:26 PM, dn via Python-list wrote: On 18/01/25 12:33, Ian Pilcher via Python-list wrote: I am making my first attempt to use type hinting in a new project, and I'm quickly hitting areas that I'm having trouble understanding. One of them is how to write type hints for a method decorator. Here is an example that illustrates my confusion. (Sorry for the length.) import collections.abc class BufferScanner(object): ... @staticmethod def _check_eof(method: collections.abc.Callable -> ( collections.abc.Callable ): ... I cannot figure out how to correctly specify the Callable argument and return type for _check_eof(). As indicated by the name, method should be a method (of the BufferScanner class), so its first positional argument should always be an instance of BufferScanner, but it could have any combination of positional and/or keyword arguments after that. Is it a typing problem? The def is not syntactically-correct (parentheses). Yes, but only when I re-typed it in my email client to avoid word- wrapping issues. What happens once corrected? Once the missing parenthesis is added, the version in my original post works just fine, but it's incomplete, because the Callables aren't parameterized. Based on what I've read, I would expect to be able to replace: @staticmethod def _check_eof(method: collections.abc.Callable) -> ( collections.abc.Callable ): ... with something like this: @staticmethod def _check_eof( method: collections.abc.Callable[[BufferScanner, ...], None] ) -> ( collections.abc.Callable[[BufferScanner, ...], bool] ): ... But Mypy gives me a bunch of errors when I do that. bs.py:19: error: Unexpected "..." [misc] bs.py:21: error: Unexpected "..." [misc] bs.py:32: error: Argument 1 to "_check_eof" of "BufferScanner" has incompatible type "Callable[[BufferScanner], None]"; expected "Callable[[BufferScanner, Any], None]" [arg-type] Found 3 errors in 1 file (checked 1 source file) (And even that wouldn't really be correct, if it worked, because it doesn't express the fact that the arguments of the two Callables are the same. I believe that ParamSpecs are supposed to address this, but there doesn't seem to be any way to use a ParamSpec when one or more of the parameter types is known. Also, which tool is 'complaining', and what does it have to say? Mypy 1.14.1. General comment: as far as type-hints go, rather than trying to learn how to deal with complex situations, it might be better to ease-in gradually - add the easy stuff now, and come back to deal with the rest later (otherwise the typing 'tail' is wagging the coding 'dog'!) Makes sense ... except that this decorator is what motivated me to use type hinting in this project in the first place. -- If your user interface is intuitive in retrospect ... it isn't intuitive -- https://mail.python.org/mailman/listinfo/python-list
[SOLVED] Struggling to understand Callable type hinting
(Note: I have mail delivery disabled for this list and read it through GMane, so I am unable to respond with correct threading if I'm not cc'ed directly.) On 1/18/25 8:52 AM, Ian Pilcher wrote: (And even that wouldn't really be correct, if it worked, because it doesn't express the fact that the arguments of the two Callables are the same. I believe that ParamSpecs are supposed to address this, but there doesn't seem to be any way to use a ParamSpec when one or more of the parameter types is known. I think that I figured it out. __P = typing.ParamSpec('__P') @staticmethod def _check_eof( method: collections.abc.Callable[ typing.Concatenate[BufferScanner, __P], None ] ) -> ( collections.abc.Callable[ typing.Concatenate[BufferScanner, __P], bool ] ): ... Mypy is happy, and it catches me if I try to use the decorator on some- thing that isn't a method of BufferScanner (or some other callable that takes an instance of BufferScanner as its first positional argument). -- If your user interface is intuitive in retrospect ... it isn't intuitive -- https://mail.python.org/mailman/listinfo/python-list
Struggling to understand Callable type hinting
I am making my first attempt to use type hinting in a new project, and I'm quickly hitting areas that I'm having trouble understanding. One of them is how to write type hints for a method decorator. Here is an example that illustrates my confusion. (Sorry for the length.) import collections.abc class BufferScanner(object): def __init__(self, buf: str) -> None: self._buffer = buf self._index = 0 self._eof = False self._line = 1 self._column = 1 @property def eof(self) -> bool: return self._eof @staticmethod def _check_eof(method: collections.abc.Callable -> ( collections.abc.Callable ): def wrapper(*args, **kwargs): self = args[0] if not self._eof: method(*args, **kwargs) if self._index >= len(self._buffer): self._eof = True return self._eof return wrapper @_check_eof def next_line(self) -> None: """Advance the scanner to the beginning of the next line.""" try: i = self._buffer.index('\n', self._index) except ValueError: self._index = len(self._buffer) # decorator will set _eof return self._index = i + 1 # move past the newline self._line += 1 self._column = 1 I cannot figure out how to correctly specify the Callable argument and return type for _check_eof(). As indicated by the name, method should be a method (of the BufferScanner class), so its first positional argument should always be an instance of BufferScanner, but it could have any combination of positional and/or keyword arguments after that. I've read the TypeVar and ParamSpec documentation, and me head is spinning, but neither one really seems to help with this situation. Any pointers to good resources or the correct way to do this are appreciated. Thanks! -- If your user interface is intuitive in retrospect ... it isn't intuitive -- https://mail.python.org/mailman/listinfo/python-list
Any way to "subclass" typing.Annotated?
(Note: I have mail delivery disabled for this list and read it through GMane. Please copy me on any responses, so that I can respond with proper threading.) From the things that I probably shouldn't spend my free time on department ... As background, I'm working on a project that is going to involve a bunch of abstract classes and dynamic types, and I've found that Python's existing abstract class implementation leaves a lot to be desired, particularly the inability to create abstract class variables and class methods. Having been seduced by the Siren song of Python's flexibility, I've been rolling my own implementation. Now to my question. I'm currently using annotations to create abstract class variables, for example: class Foo(object, metaclass=AbstractType): acv: Annotated[int, abstract] ('abstract' is simply a unique "flag" object.) This works just fine, but it's somewhat un-idiomatic. What I'd like to be able to do is create my own type, so that I could do something like this: class Foo(object, metaclass=AbstractType): acv: AbstractClassVariable[int] Essentially I'd like to create "subclass" of typing.Annotated that always sets the metadata to 'abstract'. Thus far, I haven't found a way to do this, as typing.Annotated can't be subclassed. Anyone have any ideas? -- If your user interface is intuitive in retrospect ... it isn't intuitive -- https://mail.python.org/mailman/listinfo/python-list