6767
6868
6969@contextlib .contextmanager
70- def _wrap_encryption_errors_ctx ():
70+ def _wrap_encryption_errors ():
7171 """Context manager to wrap encryption related errors."""
7272 try :
7373 yield
@@ -79,19 +79,6 @@ def _wrap_encryption_errors_ctx():
7979 raise EncryptionError (exc )
8080
8181
82- def _wrap_encryption_errors (encryption_func = None ):
83- """Decorator or context manager to wrap encryption related errors."""
84- if encryption_func :
85- @functools .wraps (encryption_func )
86- def wrap_encryption_errors (* args , ** kwargs ):
87- with _wrap_encryption_errors_ctx ():
88- return encryption_func (* args , ** kwargs )
89-
90- return wrap_encryption_errors
91- else :
92- return _wrap_encryption_errors_ctx ()
93-
94-
9582class _EncryptionIO (MongoCryptCallback ):
9683 def __init__ (self , client , key_vault_coll , mongocryptd_client , opts ):
9784 """Internal class to perform I/O on behalf of pymongocrypt."""
@@ -260,8 +247,8 @@ def __init__(self, io_callbacks, opts):
260247 self ._auto_encrypter = AutoEncrypter (io_callbacks , MongoCryptOptions (
261248 opts ._kms_providers , schema_map ))
262249 self ._bypass_auto_encryption = opts ._bypass_auto_encryption
250+ self ._closed = False
263251
264- @_wrap_encryption_errors
265252 def encrypt (self , database , cmd , check_keys , codec_options ):
266253 """Encrypt a MongoDB command.
267254
@@ -274,17 +261,20 @@ def encrypt(self, database, cmd, check_keys, codec_options):
274261 :Returns:
275262 The encrypted command to execute.
276263 """
277- # Workaround for $clusterTime which is incompatible with check_keys.
278- cluster_time = check_keys and cmd .pop ('$clusterTime' , None )
279- encoded_cmd = _dict_to_bson (cmd , check_keys , codec_options )
280- encrypted_cmd = self ._auto_encrypter .encrypt (database , encoded_cmd )
281- # TODO: PYTHON-1922 avoid decoding the encrypted_cmd.
282- encrypt_cmd = _inflate_bson (encrypted_cmd , DEFAULT_RAW_BSON_OPTIONS )
283- if cluster_time :
284- encrypt_cmd ['$clusterTime' ] = cluster_time
285- return encrypt_cmd
286-
287- @_wrap_encryption_errors
264+ self ._check_closed ()
265+ with _wrap_encryption_errors ():
266+ # Workaround for $clusterTime which is incompatible with
267+ # check_keys.
268+ cluster_time = check_keys and cmd .pop ('$clusterTime' , None )
269+ encoded_cmd = _dict_to_bson (cmd , check_keys , codec_options )
270+ encrypted_cmd = self ._auto_encrypter .encrypt (database , encoded_cmd )
271+ # TODO: PYTHON-1922 avoid decoding the encrypted_cmd.
272+ encrypt_cmd = _inflate_bson (
273+ encrypted_cmd , DEFAULT_RAW_BSON_OPTIONS )
274+ if cluster_time :
275+ encrypt_cmd ['$clusterTime' ] = cluster_time
276+ return encrypt_cmd
277+
288278 def decrypt (self , response ):
289279 """Decrypt a MongoDB command response.
290280
@@ -294,10 +284,17 @@ def decrypt(self, response):
294284 :Returns:
295285 The decrypted command response.
296286 """
297- return self ._auto_encrypter .decrypt (response )
287+ self ._check_closed ()
288+ with _wrap_encryption_errors ():
289+ return self ._auto_encrypter .decrypt (response )
290+
291+ def _check_closed (self ):
292+ if self ._closed :
293+ raise InvalidOperation ("Cannot use MongoClient after close" )
298294
299295 def close (self ):
300296 """Cleanup resources."""
297+ self ._closed = True
301298 self ._auto_encrypter .close ()
302299
303300 @staticmethod
@@ -430,7 +427,7 @@ def create_data_key(self, kms_provider, master_key=None,
430427 The ``_id`` of the created data key document.
431428 """
432429 self ._check_closed ()
433- with _wrap_encryption_errors_ctx ():
430+ with _wrap_encryption_errors ():
434431 return self ._encryption .create_data_key (
435432 kms_provider , master_key = master_key ,
436433 key_alt_names = key_alt_names )
@@ -461,7 +458,7 @@ def encrypt(self, value, algorithm, key_id=None, key_alt_name=None):
461458 'key_id must be a bson.binary.Binary with subtype 4' )
462459
463460 doc = encode ({'v' : value }, codec_options = self ._codec_options )
464- with _wrap_encryption_errors_ctx ():
461+ with _wrap_encryption_errors ():
465462 encrypted_doc = self ._encryption .encrypt (
466463 doc , algorithm , key_id = key_id , key_alt_name = key_alt_name )
467464 return decode (encrypted_doc )['v' ]
@@ -481,7 +478,7 @@ def decrypt(self, value):
481478 raise TypeError (
482479 'value to decrypt must be a bson.binary.Binary with subtype 6' )
483480
484- with _wrap_encryption_errors_ctx ():
481+ with _wrap_encryption_errors ():
485482 doc = encode ({'v' : value })
486483 decrypted_doc = self ._encryption .decrypt (doc )
487484 return decode (decrypted_doc ,
0 commit comments