diff --git a/ldapserver/server.py b/ldapserver/server.py
index e59ef2c7e7369875291fbc60ab46df52edaf52b3..ffef3c7b3d73a49fe619e609cb8174d2766bc6dc 100644
--- a/ldapserver/server.py
+++ b/ldapserver/server.py
@@ -1,6 +1,7 @@
 import traceback
 import ssl
 import socketserver
+import typing
 
 from . import asn1, exceptions, ldap, schema, directory
 
@@ -42,7 +43,7 @@ class BaseLDAPRequestHandler(socketserver.BaseRequestHandler):
 		self.on_disconnect()
 		self.request.close()
 
-	def handle_message(self, shallowmsg):
+	def handle_message(self, shallowmsg: ldap.ShallowLDAPMessage) -> typing.Iterable[ldap.ProtocolOp]:
 		'''Handle an LDAP request
 
 		:param shallowmsg: Half-decoded LDAP message to handle
@@ -105,42 +106,42 @@ class BaseLDAPRequestHandler(socketserver.BaseRequestHandler):
 	def on_exception(self, e):
 		traceback.print_exc()
 
-	def handle_bind(self, op, controls=None):
+	def handle_bind(self, op: ldap.BindRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPAuthMethodNotSupported()
 
-	def handle_unbind(self, op, controls=None):
+	def handle_unbind(self, op: ldap.UnbindRequest, controls=None) -> typing.NoReturn:
 		reject_critical_controls(controls)
 		self.keep_running = False
 
-	def handle_search(self, op, controls=None):
+	def handle_search(self, op: ldap.SearchRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		yield ldap.SearchResultDone(ldap.LDAPResultCode.success)
 
-	def handle_modify(self, op, controls=None):
+	def handle_modify(self, op: ldap.ModifyRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPInsufficientAccessRights()
 
-	def handle_add(self, op, controls=None):
+	def handle_add(self, op: ldap.AddRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPInsufficientAccessRights()
 
-	def handle_delete(self, op, controls=None):
+	def handle_delete(self, op: ldap.DelRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPInsufficientAccessRights()
 
-	def handle_modifydn(self, op, controls=None):
+	def handle_modifydn(self, op: ldap.ModifyDNRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPInsufficientAccessRights()
 
-	def handle_compare(self, op, controls=None):
+	def handle_compare(self, op: ldap.CompareRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPInsufficientAccessRights()
 
-	def handle_abandon(self, op, controls=None):
+	def handle_abandon(self, op: ldap.AbandonRequest, controls=None) -> typing.NoReturn:
 		reject_critical_controls(controls)
 
-	def handle_extended(self, op, controls=None):
+	def handle_extended(self, op: ldap.ExtendedRequest, controls=None) -> typing.Iterable[ldap.ProtocolOp]:
 		reject_critical_controls(controls)
 		raise exceptions.LDAPProtocolError()
 
@@ -476,6 +477,7 @@ class SimpleLDAPRequestHandler(BaseLDAPRequestHandler):
 				newpw = self.do_password_modify()
 			else:
 				decoded, _ = ldap.PasswdModifyRequestValue.from_ber(op.requestValue)
+				# pylint: disable=no-member
 				newpw = self.do_password_modify(decoded.userIdentity, decoded.oldPasswd, decoded.newPasswd)
 			if newpw is None:
 				yield ldap.ExtendedResponse(ldap.LDAPResultCode.success)