Repository: python/mypy

Issue:
Refactor overloads away in 'random' stubs
It seems that all the `@overload` decorators in `stubs/3.2/random.py` could be represented without overloading, such as by using union types.



Discussion:
Yeah, e.g. shuffle() seems to just be taking an optional second parameter named random of type  Function[[], float].

`randrange(start = 1, stop = 10, step = None)`
This call causes TypeError in Python3.4, but can pass mypy type check.

Looks like the stdlib default for step is 1, not None.


Resolving patch:
diff --git a/stubs/3.2/random.py b/stubs/3.2/random.py
--- a/stubs/3.2/random.py
+++ b/stubs/3.2/random.py
@@ -8,7 +8,7 @@
 
 import _random
 from typing import (
-    Any, overload, typevar, Sequence, List, Function, AbstractSet
+    Any, typevar, Sequence, List, Function, AbstractSet, Union
 )
 
 t = typevar('t')
@@ -19,25 +19,11 @@ def seed(self, a: Any = None, version: int = 2) -> None: pass
     def getstate(self) -> tuple: pass
     def setstate(self, state: tuple) -> None: pass
     def getrandbits(self, k: int) -> int: pass
-
-    @overload
-    def randrange(self, stop: int) -> int: pass
-    @overload
-    def randrange(self, start: int, stop: int, step: int = 1) -> int: pass
-
+    def randrange(self, start: int, stop: Union[int, None] = None, step: int = 1) -> int: pass
     def randint(self, a: int, b: int) -> int: pass
     def choice(self, seq: Sequence[t]) -> t: pass
-
-    @overload
-    def shuffle(self, x: List[Any]) -> None: pass
-    @overload
-    def shuffle(self, x: List[Any], random: Function[[], float]) -> None: pass
-
-    @overload
-    def sample(self, population: Sequence[t], k: int) -> List[t]: pass
-    @overload
-    def sample(self, population: AbstractSet[t], k: int) -> List[t]: pass
-
+    def shuffle(self, x: List[Any], random: Union[Function[[], float], None] = None) -> None: pass
+    def sample(self, population: Union[Sequence[t], AbstractSet[t]], k: int) -> List[t]: pass
     def random(self) -> float: pass
     def uniform(self, a: float, b: float) -> float: pass
     def triangular(self, low: float = 0.0, high: float = 1.0,
@@ -64,25 +50,11 @@ def seed(a: Any = None, version: int = 2) -> None: pass
 def getstate() -> object: pass
 def setstate(state: object) -> None: pass
 def getrandbits(k: int) -> int: pass
-
-@overload
-def randrange(stop: int) -> int: pass
-@overload
-def randrange(start: int, stop: int, step: int = 1) -> int: pass
-
+def randrange(start: int, stop: Union[None, int] = None, step: int = 1) -> int: pass
 def randint(a: int, b: int) -> int: pass
 def choice(seq: Sequence[t]) -> t: pass
-
-@overload
-def shuffle(x: List[Any]) -> None: pass
-@overload
-def shuffle(x: List[Any], random: Function[[], float]) -> None: pass
-
-@overload
-def sample(population: Sequence[t], k: int) -> List[t]: pass
-@overload
-def sample(population: AbstractSet[t], k: int) -> List[t]: pass
-
+def shuffle(x: List[Any], random: Union[Function[[], float], None] = None) -> None: pass
+def sample(population: Union[Sequence[t], AbstractSet[t]], k: int) -> List[t]: pass
 def random() -> float: pass
 def uniform(a: float, b: float) -> float: pass
 def triangular(low: float = 0.0, high: float = 1.0,


Test patch: