From 7b2557461070abc6a446cc0a86fd579b56e138e1 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Sun, 6 Aug 2017 14:59:30 -0400 Subject: [PATCH 1/6] Make configparser.RawConfigParser.__getitem__ return a SectionProxy This reflects the code in the cpython tree and makes the following (valid) code type-check correctly: ``` from configparser import ConfigParser config = ConfigParser() config.read_dict({'section': {'key': 'false'}}) assert config['section'].getboolean('key') is False ``` --- stdlib/3/configparser.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/3/configparser.pyi b/stdlib/3/configparser.pyi index c481852b54eb..203edc7f4f0a 100644 --- a/stdlib/3/configparser.pyi +++ b/stdlib/3/configparser.pyi @@ -70,7 +70,7 @@ class RawConfigParser(_parser): def __len__(self) -> int: ... - def __getitem__(self, section: str) -> _section: ... + def __getitem__(self, section: str) -> SectionProxy: ... def __setitem__(self, section: str, options: _section) -> None: ... From 93a27f56f6a02f050f38d9e198c545d09c983819 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Sun, 6 Aug 2017 20:45:23 -0400 Subject: [PATCH 2/6] RawConfigParser.items() returns SectionProxys not mappings Because .items() uses __getitem__ to produce second item in each tuple. --- stdlib/3/configparser.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/3/configparser.pyi b/stdlib/3/configparser.pyi index 203edc7f4f0a..96598258dcc3 100644 --- a/stdlib/3/configparser.pyi +++ b/stdlib/3/configparser.pyi @@ -113,7 +113,7 @@ class RawConfigParser(_parser): ... # This is incompatible with Mapping so we ignore the type. - def items(self, section: str = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, _section]]: ... # type: ignore + def items(self, section: str = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, SectionProxy]]: ... # type: ignore def set(self, section: str, option: str, value: str) -> None: ... From 60d5f92db4167a079337ad7399d0a32f5beb6ad2 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Sun, 6 Aug 2017 22:30:44 -0400 Subject: [PATCH 3/6] section argument to RawConfigParser.items is Optional --- stdlib/3/configparser.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/3/configparser.pyi b/stdlib/3/configparser.pyi index 96598258dcc3..f3306ba458c7 100644 --- a/stdlib/3/configparser.pyi +++ b/stdlib/3/configparser.pyi @@ -113,7 +113,7 @@ class RawConfigParser(_parser): ... # This is incompatible with Mapping so we ignore the type. - def items(self, section: str = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, SectionProxy]]: ... # type: ignore + def items(self, section: Optional[str] = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, SectionProxy]]: ... # type: ignore def set(self, section: str, option: str, value: str) -> None: ... From 7c80d55faf009747e66d73eb6a5ebac8c055ab7b Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Sun, 6 Aug 2017 22:31:50 -0400 Subject: [PATCH 4/6] Add comment explaining the status of RawConfigParser.items TL;DR, we're hitting https://github.com/python/mypy/issues/3805 when implemented correctly as an override, and https://github.com/python/mypy/issues/1855 when we try to work around that with a union. --- stdlib/3/configparser.pyi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stdlib/3/configparser.pyi b/stdlib/3/configparser.pyi index f3306ba458c7..c52c94dbb234 100644 --- a/stdlib/3/configparser.pyi +++ b/stdlib/3/configparser.pyi @@ -113,6 +113,11 @@ class RawConfigParser(_parser): ... # This is incompatible with Mapping so we ignore the type. + # This should really be an override with the following line added. See + # https://github.com/python/mypy/issues/3805 for why it isn't. + # def items(self, section: str = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, str]]: ... + # (It could be a union of the two in the meantime, to improve matters + # slightly, but then we hit https://github.com/python/mypy/issues/1855.) def items(self, section: Optional[str] = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, SectionProxy]]: ... # type: ignore def set(self, section: str, option: str, value: str) -> None: ... From b4d88386c5bae2fcd4c541a8682dd1c63de387d9 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Mon, 7 Aug 2017 01:49:04 -0400 Subject: [PATCH 5/6] Correctly implement RawConfigParser.items overloading --- stdlib/3/configparser.pyi | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/stdlib/3/configparser.pyi b/stdlib/3/configparser.pyi index c52c94dbb234..e1096478d6ed 100644 --- a/stdlib/3/configparser.pyi +++ b/stdlib/3/configparser.pyi @@ -2,9 +2,9 @@ # reading configparser.py. import sys -from typing import (MutableMapping, Mapping, Dict, Sequence, List, Union, - Iterable, Iterator, Callable, Any, IO, overload, Optional, - Pattern, TypeVar) +from typing import (AbstractSet, MutableMapping, Mapping, Dict, Sequence, List, + Union, Iterable, Iterator, Callable, Any, IO, overload, + Optional, Pattern, TypeVar) # Types only used in type comments only from typing import Optional, Tuple # noqa @@ -112,13 +112,11 @@ class RawConfigParser(_parser): def get(self, section: str, option: str, *, raw: bool = ..., vars: _section = ..., fallback: str = ...) -> str: # type: ignore ... - # This is incompatible with Mapping so we ignore the type. - # This should really be an override with the following line added. See - # https://github.com/python/mypy/issues/3805 for why it isn't. - # def items(self, section: str = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, str]]: ... - # (It could be a union of the two in the meantime, to improve matters - # slightly, but then we hit https://github.com/python/mypy/issues/1855.) - def items(self, section: Optional[str] = ..., raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, SectionProxy]]: ... # type: ignore + @overload + def items(self, *, raw: bool = ..., vars: _section = ...) -> AbstractSet[Tuple[str, SectionProxy]]: ... + + @overload + def items(self, section: str, raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, str]]: ... def set(self, section: str, option: str, value: str) -> None: ... From d648a75dc1d0805cebb6d7de94493b12cf31046f Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Wed, 9 Aug 2017 10:29:44 -0400 Subject: [PATCH 6/6] RawConfigParser.items(str) returns a List not an Iterable --- stdlib/3/configparser.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/3/configparser.pyi b/stdlib/3/configparser.pyi index e1096478d6ed..b6ff0dcde258 100644 --- a/stdlib/3/configparser.pyi +++ b/stdlib/3/configparser.pyi @@ -116,7 +116,7 @@ class RawConfigParser(_parser): def items(self, *, raw: bool = ..., vars: _section = ...) -> AbstractSet[Tuple[str, SectionProxy]]: ... @overload - def items(self, section: str, raw: bool = ..., vars: _section = ...) -> Iterable[Tuple[str, str]]: ... + def items(self, section: str, raw: bool = ..., vars: _section = ...) -> List[Tuple[str, str]]: ... def set(self, section: str, option: str, value: str) -> None: ...