- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 720
Description
Similar to #394, but deeper.
In current pyjwt, PyJWT.encode's type annotation is:
https://github.com/jpadilla/pyjwt/blob/master/jwt/api_jwt.py#L48
    def encode(self,
               payload,  # type: Union[Dict, bytes]
               key,  # type: str
               algorithm='HS256',  # type: str
               headers=None,  # type: Optional[Dict]
               json_encoder=None  # type: Optional[Callable]
               ):
        # Check that we get a mapping
        if not isinstance(payload, Mapping):
            raise TypeError('Expecting a mapping object, as JWT only supports '
                            'JSON objects as payloads.')payload is Union[Dict, bytes], but actually it should be Mapping[str, Any].
And current PyJWS.encode's type annotation also is Union[Dict, bytes].
https://github.com/jpadilla/pyjwt/blob/master/jwt/api_jws.py#L77
    def encode(self,
               payload,  # type: Union[Dict, bytes]
               key,  # type: str
               algorithm='HS256',  # type: str
               headers=None,  # type: Optional[Dict]
               json_encoder=None  # type: Optional[Callable]
               ):
        segments = []
        if algorithm is None:
            algorithm = 'none'
        if algorithm not in self._valid_algs:
            pass
        # Header
        header = {'typ': self.header_typ, 'alg': algorithm}
        if headers:
            self._validate_headers(headers)
            header.update(headers)
        json_header = force_bytes(
            json.dumps(
                header,
                separators=(',', ':'),
                cls=json_encoder
            )
        )
        segments.append(base64url_encode(json_header))
        segments.append(base64url_encode(payload))But it calls base64url_encode and pass the payload.
base64url_encode is defined in utils.py
def base64url_encode(input):
    return base64.urlsafe_b64encode(input).replace(b'=', b'')
From the doc, we can know that it rejects a dict as argument.
base64.urlsafe_b64encode
Encode bytes-like object s using the URL- and filesystem-safe alphabet, which substitutes - instead of + and _ instead of / in the standard Base64 alphabet, and return the encoded bytes. The result can still contain =.
So the type of payload in PyJWS.encode should be bytes.
PyJWT is the subclass of PyJWS, and encode should be compatable with supertype annotation, because of  Liskov substitution principle.