[issue44140] WeakKeyDictionary should support lookup by id instead of hash

2021-05-15 Thread conchylicultor


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

2021-04-09 Thread conchylicultor


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

2021-04-09 Thread conchylicultor


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

2021-04-08 Thread conchylicultor


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

2021-04-08 Thread conchylicultor


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

2021-04-06 Thread conchylicultor


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

2021-04-06 Thread conchylicultor


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

2021-04-06 Thread conchylicultor


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

2021-04-06 Thread conchylicultor


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

2020-12-16 Thread conchylicultor


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

2020-12-11 Thread conchylicultor


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

2020-11-30 Thread conchylicultor


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

2020-11-30 Thread conchylicultor


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

2020-11-11 Thread conchylicultor


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

2020-10-19 Thread conchylicultor


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

2020-10-16 Thread conchylicultor


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

2020-10-16 Thread conchylicultor


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