[issue44140] WeakKeyDictionary should support lookup by id instead of hash
New submission from conchylicultor : WeakKeyDictionary are great to "associate additional data with an object owned by other parts of an application", as quoted from the doc: https://docs.python.org/3/library/weakref.html#weakref.WeakKeyDictionary However, this currently only works for hashable types. Non-hashables are not supported: ``` @dataclass class A: pass a = A() d = weakref.WeakKeyDictionary() d[a] = 3 # TypeError: unhashable type: 'A' ``` With regular dict, this could be easilly solved by using `d[id(a)] = 3`, but WeakKeyDictionary don't accept `int` of course. I cannot wrap the object either as the weakref would not be attached to the original object, but the wrapper. It would be great to be able to force WeakKeyDictionary to perform lookup on `id` internally. Like `d = WeakKeyDictionary(use_id_lookup=True)` -- components: Library (Lib) messages: 393707 nosy: conchylicultor priority: normal severity: normal status: open title: WeakKeyDictionary should support lookup by id instead of hash type: enhancement versions: Python 3.10, Python 3.11, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue44140> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
conchylicultor added the comment: Yes, I know I can rename the closure, or wrap the annotation in 'quote'. I just wanted to point this out as it felt confusing to me. For instance, it feels inconsistent with: ``` def fn(datetime: datetime.Time): # Works as expected ``` Or: ``` @dataclass class A: datetime: datetime.Time = field(default_factory=datetime.Time.now) ``` The `datetime.Time.now` and the `datetime.Time` of the same statement refer to different objects. This might be the expected behavior, but this is confusing nonetheless. -- ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
conchylicultor added the comment: Sure, here is a minimal reproductible example demonstrating the issue: ``` import pathlib class C: pathlib: pathlib.Path = None ``` Which raises: ``` File "py", line 5, in C pathlib: pathlib.Path = None AttributeError: 'NoneType' object has no attribute 'Path' ``` -- ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
conchylicultor added the comment: The above example is a real world example I have currently have. Basically I have some dataclass based configuration like: in losses.py: ``` class LossesParams: ... ``` in dataset.py: ``` class DatasetParams: ... ``` in config.py: ``` @dataclasses.dataclass class Params: losses: losses.LossesParams = dataclasses.field() dataset: dataset.DatasetParams = dataclasses.field() ``` I want to use params as: ``` param = Params() param.datasets.batch_size = 123 ``` However the above code fail at `dataset: dataset.DatasetParams = dataclasses.field()` due to the closure issue. The example is simplified but this is a very concrete problem I encountered. -- ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
conchylicultor added the comment: > Do you have an actual use case for self-referential annotations? I'm not sure I understand the question. My use case is the following: ``` from ... import losses class A: losses: losses.Losses = losses.Losses() ``` Currently this is failing be cause this get resolved as: ``` class A: name: .Losses().Losses = .Losses() ``` Instead of what I want/expected: ``` class A: name: .Losses = .Losses() ``` I would expect that both "losses.Losses" on the left and right of the `=` refer to the outer module (`name: .Losses`), while currently it is resolved as `name: name.Losses` -- ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
conchylicultor added the comment: Interestingly mypy, pylint correctly resolve the closure. ``` class A: dataclasses: dataclasses.Field = dataclasses.field() A.dataclasses.other # mypy error: "Field[Any]" has no attribute "other" ``` So the current workaround is to use quotes: ``` class A: # Type correctly inferred and no closure runtime error losses: 'losses.Losses' = losses.Losses() ``` -- ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
Change by conchylicultor : -- components: +Library (Lib) -Interpreter Core ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
Change by conchylicultor : -- components: +Interpreter Core type: -> behavior versions: +Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9 ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue43746] Weird typing annotation closure behavior
New submission from conchylicultor : I observe some strange closure behavior for typing annotations when the name is defined ``` x: x = 1 # Works, __annotation__ == {'x': 1} ``` This creates issue, for example: ``` from ... import losses class A: # AttributeError: 'Losses' object has no attribute 'Losses' losses: losses.Losses = losses.Losses() ``` -- messages: 390304 nosy: conchylicultor priority: normal severity: normal status: open title: Weird typing annotation closure behavior ___ Python tracker <https://bugs.python.org/issue43746> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33129] Add kwarg-only option to dataclass
conchylicultor added the comment: For the API, I think we could add this feature with a single new `dataclass(kw_only: bool | str)` ``` @dataclasses.dataclass(kw_only=True) class A: a: int b: int c: int # A(*, a, b, c) @dataclasses.dataclass(kw_only='b') class A: a: int b: int c: int # A(a, *, b, c) ``` I think this would be flexible enough for all use cases, while avoiding the boilerplate from the above proposals. -- ___ Python tracker <https://bugs.python.org/issue33129> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39106] Add suggestions to argparse error message output for unrecognized arguments
conchylicultor added the comment: I don't think this should have been closed. [1] If the user is using sub_parser, the options are not even displayed. For example in our https://github.com/tensorflow/datasets project: ``` $ tfds build mnist --overwritte usage: tfds [-h] [--helpfull] [--version] {build,new} ... tfds: error: unrecognized arguments: --overwritte ``` [2] For some programs, there can be 20+ options and having to scroll through the list is not user friendly at all. [3] Other CLI, like Google absl.flags has this option too and it is very convenient. -- nosy: +conchylicultor ___ Python tracker <https://bugs.python.org/issue39106> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42512] Confusing that BinaryIO and IO[bytes] cannot be used interchangeably
Change by conchylicultor : -- components: +Library (Lib) type: -> behavior versions: +Python 3.10 ___ Python tracker <https://bugs.python.org/issue42512> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42512] Confusing that BinaryIO and IO[bytes] cannot be used interchangeably
New submission from conchylicultor : Currently, because `BinaryIO` is subclass of `IO[bytes]`, the 2 cannot be used interchangeably. Example with pytype: ``` def iter_zip(arch_f) -> List[typing.BinaryIO]]: with open(arch_f, 'rb') as fobj: z = zipfile.ZipFile(fobj) return [z.open(member) for member in z.infolist()] ``` Raise: ``` Expected: Tuple[str, BinaryIO] Actually returned: Tuple[Any, IO[bytes]] ``` Technically pytype is right as `ZipFile.open() -> IO[bytes]`: https://github.com/python/typeshed/blob/ca45cb21a8a0422cbb266cb25e08051fe481887c/stdlib/2and3/zipfile.pyi#L109 But this makes BinaryIO usage quite confusing. >From the implementation, it seems that the BinaryIO is slightly different >(https://github.com/python/cpython/blob/9f004634a2bf50c782e223e2eb386ffa769b901c/Lib/typing.py#L2094): But the documentation is unclear about the difference between the 2 https://docs.python.org/3/library/typing.html#typing.BinaryIO Additionally, `typing.IO` is implemented as Generic but shouldn't this be a Protocol instead ? -- messages: 382143 nosy: conchylicultor priority: normal severity: normal status: open title: Confusing that BinaryIO and IO[bytes] cannot be used interchangeably ___ Python tracker <https://bugs.python.org/issue42512> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue33129] Add kwarg-only option to dataclass
conchylicultor added the comment: Solving this would significantly improve @dataclass inheritance (https://bugs.python.org/issue39300). Any idea when this will land ? Currently, it is not possible to add required argument to a child dataclass (unless hacks like duplicating attributes): ``` import dataclasses @dataclasses.dataclass class A: x: int = 1 @dataclasses.dataclass class B(A): y: int # ERROR: non-default argument follows default argument ``` Keywords-only would solve this issue: ``` @dataclasses.dataclass class B(A): y: int = dataclasses.field(kw_only=True) B(123, y=456) ``` Note: Attrs already support this: https://www.attrs.org/en/stable/examples.html#keyword-only-attributes For the behavior, I think there are two options: ``` class A: a0: int a1: int = field(kw_only=True) a2: int class B(A): b0: int b1: int = field(kw_only=True) b2: int ``` Option 1: All attributes following `kw_only` are `kw_only` (kw_only indicates where to place '*') A(a0, *, a1, a2) B(a0, b0, *, a1, a2, b1, b2) Option 2: `kw_only` are individually moved to the end A(a0, a2, *, a1) B(a0, a2, b0, b2, *, a1, b1) I personally prefer Option 1, as it makes it easier to place the `*` with less boilerplate. ``` class Request: url: str timeout: int = field(default=-1, kw_only=True) verify: bool = False params: Optional[Dict[str, str]] = None cookies: Optional[Dict[str, str]] = None Request(url, *, timeout=-1, verify=False, params=None, cookies=None) ``` Which looks better than: ``` class Request: url: str timeout: int = field(default=-1, kw_only=True) verify: bool = field(default=False, kw_only=True) params: Optional[Dict[str, str]] = field(default=None, kw_only=True) cookies: Optional[Dict[str, str]] = field(default=None, kw_only=True) ``` -- nosy: +conchylicultor ___ Python tracker <https://bugs.python.org/issue33129> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42090] zipfile.Path.joinpath API inconsistent with pathlib.Path.joinpath
New submission from conchylicultor : The following code fail with zipfile.Path, but works with pathlib.Path: ``` path = path.joinpath().joinpath('other', 'other') ``` Zipfile: https://github.com/python/cpython/blob/95ad890a7b0341d8d2fde13f824bc24c65a8ece0/Lib/zipfile.py#L2363 ``` def joinpath(self, add): ``` Pathlib: https://github.com/python/cpython/blob/95ad890a7b0341d8d2fde13f824bc24c65a8ece0/Lib/pathlib.py#L955 ``` def joinpath(self, *args): ``` -- components: Library (Lib) messages: 379016 nosy: conchylicultor priority: normal severity: normal status: open title: zipfile.Path.joinpath API inconsistent with pathlib.Path.joinpath versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue42090> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42052] pathlib.Path should not call str() internally to allow inheritance
conchylicultor added the comment: Closing this as I realize that even if this was solved, it would still not fully resolve the issue. Basically I want to control how __fspath__ and __str__ behave externally (for users), but internal fspath and str should always call `super()` -- stage: -> resolved status: open -> closed ___ Python tracker <https://bugs.python.org/issue42052> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42052] pathlib.Path should not call str() internally to allow inheritance
New submission from conchylicultor : I'm writing a subclass of `pathlib.Path` with custom `__fspath__`. To prevent bad usages (users should use `os.fspath(path)` instead of `str(path)` to access the underlying path), I would like to overwrite `str`: ``` class MyPath(pathlib.PosixPath): def __fspath__(self) -> str: # Custom fspath def __str__(self) -> str: raise TypeError( f'Please do not use `str()` directly:' ' * For display: Use, f-string, `.format` or `repr`' ' * To access the path string: Use `os.fspath`, as per PEP 519' ) def __format__(self, format_spec) -> str: return format(super().__str__(), format_spec) ``` However, this is breaking pathlib internal, as `str(self)` is used at many places. It would be nice if all internal `str()` calls where replaced by some `self._str()`. I also think it would be more semantically correct if some of the `__str__` call where replaced by `__fspath__`, like: https://github.com/python/cpython/blob/b30934e9afb0af3f8e2e5f0992445be775b3c630/Lib/pathlib.py#L748 -- components: Library (Lib) messages: 378710 nosy: conchylicultor priority: normal severity: normal status: open title: pathlib.Path should not call str() internally to allow inheritance versions: Python 3.10 ___ Python tracker <https://bugs.python.org/issue42052> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com