diff --git a/third_party/2and3/attr/__init__.pyi b/third_party/2and3/attr/__init__.pyi
index fcb93b18e36f..38f16f06ba0c 100644
--- a/third_party/2and3/attr/__init__.pyi
+++ b/third_party/2and3/attr/__init__.pyi
@@ -20,12 +20,27 @@ from . import filters as filters
 from . import converters as converters
 from . import validators as validators
 
+from ._version_info import VersionInfo
+
+__version__: str
+__version_info__: VersionInfo
+__title__: str
+__description__: str
+__url__: str
+__uri__: str
+__author__: str
+__email__: str
+__license__: str
+__copyright__: str
+
 _T = TypeVar("_T")
 _C = TypeVar("_C", bound=type)
 
 _ValidatorType = Callable[[Any, Attribute[_T], _T], Any]
 _ConverterType = Callable[[Any], _T]
 _FilterType = Callable[[Attribute[_T], _T], bool]
+_ReprType = Callable[[Any], str]
+_ReprArgType = Union[bool, _ReprType]
 # FIXME: in reality, if multiple validators are passed they must be in a list or tuple,
 # but those are invariant and so would prevent subtypes of _ValidatorType from working
 # when passed in a list or tuple.
@@ -49,18 +64,16 @@ class Attribute(Generic[_T]):
     name: str
     default: Optional[_T]
     validator: Optional[_ValidatorType[_T]]
-    repr: bool
+    repr: _ReprArgType
     cmp: bool
+    eq: bool
+    order: bool
     hash: Optional[bool]
     init: bool
     converter: Optional[_ConverterType[_T]]
     metadata: Dict[Any, Any]
     type: Optional[Type[_T]]
     kw_only: bool
-    def __lt__(self, x: Attribute[_T]) -> bool: ...
-    def __le__(self, x: Attribute[_T]) -> bool: ...
-    def __gt__(self, x: Attribute[_T]) -> bool: ...
-    def __ge__(self, x: Attribute[_T]) -> bool: ...
 
 # NOTE: We had several choices for the annotation to use for type arg:
 # 1) Type[_T]
@@ -89,16 +102,17 @@ class Attribute(Generic[_T]):
 def attrib(
     default: None = ...,
     validator: None = ...,
-    repr: bool = ...,
-    cmp: bool = ...,
+    repr: _ReprArgType = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
-    convert: None = ...,
     metadata: Optional[Mapping[Any, Any]] = ...,
     type: None = ...,
     converter: None = ...,
     factory: None = ...,
     kw_only: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> Any: ...
 
 # This form catches an explicit None or no default and infers the type from the other arguments.
@@ -106,16 +120,17 @@ def attrib(
 def attrib(
     default: None = ...,
     validator: Optional[_ValidatorArgType[_T]] = ...,
-    repr: bool = ...,
-    cmp: bool = ...,
+    repr: _ReprArgType = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
-    convert: Optional[_ConverterType[_T]] = ...,
     metadata: Optional[Mapping[Any, Any]] = ...,
     type: Optional[Type[_T]] = ...,
     converter: Optional[_ConverterType[_T]] = ...,
     factory: Optional[Callable[[], _T]] = ...,
     kw_only: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> _T: ...
 
 # This form catches an explicit default argument.
@@ -123,16 +138,17 @@ def attrib(
 def attrib(
     default: _T,
     validator: Optional[_ValidatorArgType[_T]] = ...,
-    repr: bool = ...,
-    cmp: bool = ...,
+    repr: _ReprArgType = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
-    convert: Optional[_ConverterType[_T]] = ...,
     metadata: Optional[Mapping[Any, Any]] = ...,
     type: Optional[Type[_T]] = ...,
     converter: Optional[_ConverterType[_T]] = ...,
     factory: Optional[Callable[[], _T]] = ...,
     kw_only: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> _T: ...
 
 # This form covers type=non-Type: e.g. forward references (str), Any
@@ -140,16 +156,17 @@ def attrib(
 def attrib(
     default: Optional[_T] = ...,
     validator: Optional[_ValidatorArgType[_T]] = ...,
-    repr: bool = ...,
-    cmp: bool = ...,
+    repr: _ReprArgType = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
-    convert: Optional[_ConverterType[_T]] = ...,
     metadata: Optional[Mapping[Any, Any]] = ...,
     type: object = ...,
     converter: Optional[_ConverterType[_T]] = ...,
     factory: Optional[Callable[[], _T]] = ...,
     kw_only: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> Any: ...
 @overload
 def attrs(
@@ -157,7 +174,7 @@ def attrs(
     these: Optional[Dict[str, Any]] = ...,
     repr_ns: Optional[str] = ...,
     repr: bool = ...,
-    cmp: bool = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
     slots: bool = ...,
@@ -168,6 +185,8 @@ def attrs(
     kw_only: bool = ...,
     cache_hash: bool = ...,
     auto_exc: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> _C: ...
 @overload
 def attrs(
@@ -175,7 +194,7 @@ def attrs(
     these: Optional[Dict[str, Any]] = ...,
     repr_ns: Optional[str] = ...,
     repr: bool = ...,
-    cmp: bool = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
     slots: bool = ...,
@@ -186,6 +205,8 @@ def attrs(
     kw_only: bool = ...,
     cache_hash: bool = ...,
     auto_exc: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> Callable[[_C], _C]: ...
 
 # TODO: add support for returning NamedTuple from the mypy plugin
@@ -204,7 +225,7 @@ def make_class(
     bases: Tuple[type, ...] = ...,
     repr_ns: Optional[str] = ...,
     repr: bool = ...,
-    cmp: bool = ...,
+    cmp: Optional[bool] = ...,
     hash: Optional[bool] = ...,
     init: bool = ...,
     slots: bool = ...,
@@ -215,6 +236,8 @@ def make_class(
     kw_only: bool = ...,
     cache_hash: bool = ...,
     auto_exc: bool = ...,
+    eq: Optional[bool] = ...,
+    order: Optional[bool] = ...,
 ) -> type: ...
 
 # _funcs --
diff --git a/third_party/2and3/attr/_version_info.pyi b/third_party/2and3/attr/_version_info.pyi
new file mode 100644
index 000000000000..45ced0863377
--- /dev/null
+++ b/third_party/2and3/attr/_version_info.pyi
@@ -0,0 +1,9 @@
+class VersionInfo:
+    @property
+    def year(self) -> int: ...
+    @property
+    def minor(self) -> int: ...
+    @property
+    def micro(self) -> int: ...
+    @property
+    def releaselevel(self) -> str: ...
diff --git a/third_party/2and3/attr/exceptions.pyi b/third_party/2and3/attr/exceptions.pyi
index 48fffcc1e2df..736fde2e1d20 100644
--- a/third_party/2and3/attr/exceptions.pyi
+++ b/third_party/2and3/attr/exceptions.pyi
@@ -1,3 +1,5 @@
+from typing import Any
+
 class FrozenInstanceError(AttributeError):
     msg: str = ...
 
@@ -5,3 +7,9 @@ class AttrsAttributeNotFoundError(ValueError): ...
 class NotAnAttrsClassError(ValueError): ...
 class DefaultAlreadySetError(RuntimeError): ...
 class UnannotatedAttributeError(RuntimeError): ...
+class PythonTooOldError(RuntimeError): ...
+
+class NotCallableError(TypeError):
+    msg: str = ...
+    value: Any = ...
+    def __init__(self, msg: str, value: Any) -> None: ...
diff --git a/third_party/2and3/attr/validators.pyi b/third_party/2and3/attr/validators.pyi
index 01af06845ec3..9a22abb197d7 100644
--- a/third_party/2and3/attr/validators.pyi
+++ b/third_party/2and3/attr/validators.pyi
@@ -1,24 +1,66 @@
-from typing import Container, List, Union, TypeVar, Type, Any, Optional, Tuple
+from typing import (
+    Container,
+    List,
+    Union,
+    TypeVar,
+    Type,
+    Any,
+    Optional,
+    Tuple,
+    Iterable,
+    Mapping,
+    Callable,
+    Match,
+    AnyStr,
+    overload,
+)
 from . import _ValidatorType
 
 _T = TypeVar("_T")
+_T1 = TypeVar("_T1")
+_T2 = TypeVar("_T2")
+_T3 = TypeVar("_T3")
+_I = TypeVar("_I", bound=Iterable)
+_K = TypeVar("_K")
+_V = TypeVar("_V")
+_M = TypeVar("_M", bound=Mapping)
 
+# To be more precise on instance_of use some overloads.
+# If there are more than 3 items in the tuple then we fall back to Any
+@overload
+def instance_of(type: Type[_T]) -> _ValidatorType[_T]: ...
+@overload
+def instance_of(type: Tuple[Type[_T]]) -> _ValidatorType[_T]: ...
+@overload
 def instance_of(
-    type: Union[Tuple[Type[_T], ...], Type[_T]]
-) -> _ValidatorType[_T]: ...
+    type: Tuple[Type[_T1], Type[_T2]]
+) -> _ValidatorType[Union[_T1, _T2]]: ...
+@overload
+def instance_of(
+    type: Tuple[Type[_T1], Type[_T2], Type[_T3]]
+) -> _ValidatorType[Union[_T1, _T2, _T3]]: ...
+@overload
+def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ...
 def provides(interface: Any) -> _ValidatorType[Any]: ...
 def optional(
     validator: Union[_ValidatorType[_T], List[_ValidatorType[_T]]]
 ) -> _ValidatorType[Optional[_T]]: ...
 def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
 def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
+def matches_re(
+    regex: AnyStr,
+    flags: int = ...,
+    func: Optional[
+        Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]]
+    ] = ...,
+) -> _ValidatorType[AnyStr]: ...
 def deep_iterable(
     member_validator: _ValidatorType[_T],
-    iterable_validator: Optional[_ValidatorType[_T]],
-) -> _ValidatorType[_T]: ...
+    iterable_validator: Optional[_ValidatorType[_I]] = ...,
+) -> _ValidatorType[_I]: ...
 def deep_mapping(
-    key_validator: _ValidatorType[_T],
-    value_validator: _ValidatorType[_T],
-    mapping_validator: Optional[_ValidatorType[_T]],
-) -> _ValidatorType[_T]: ...
+    key_validator: _ValidatorType[_K],
+    value_validator: _ValidatorType[_V],
+    mapping_validator: Optional[_ValidatorType[_M]] = ...,
+) -> _ValidatorType[_M]: ...
 def is_callable() -> _ValidatorType[_T]: ...