From 0c9aed91697c5bc1eb16c2254406149e2395fdae Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 8 Jul 2017 21:50:01 -0400 Subject: Fixed #3747 -- cache extensions on x.509 objects (#3769) * Fixed #3747 -- cache extensions on x.509 objects * be kind to cpython, save a dict lookup * flake8 * changelog --- src/cryptography/hazmat/backends/openssl/x509.py | 8 ++++---- src/cryptography/utils.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index a04d6d53..5bf0438e 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -126,7 +126,7 @@ class _Certificate(object): oid = _obj2txt(self._backend, alg[0].algorithm) return x509.ObjectIdentifier(oid) - @property + @utils.cached_property def extensions(self): if self._backend._lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER: return _CERTIFICATE_EXTENSION_PARSER.parse( @@ -200,7 +200,7 @@ class _RevokedCertificate(object): ) ) - @property + @utils.cached_property def extensions(self): return _REVOKED_CERTIFICATE_EXTENSION_PARSER.parse( self._backend, self._x509_revoked @@ -334,7 +334,7 @@ class _CertificateRevocationList(object): else: return self._backend._lib.sk_X509_REVOKED_num(revoked) - @property + @utils.cached_property def extensions(self): return _CRL_EXTENSION_PARSER.parse(self._backend, self._x509_crl) @@ -391,7 +391,7 @@ class _CertificateSigningRequest(object): oid = _obj2txt(self._backend, alg[0].algorithm) return x509.ObjectIdentifier(oid) - @property + @utils.cached_property def extensions(self): x509_exts = self._backend._lib.X509_REQ_get_extensions(self._x509_req) return _CSR_EXTENSION_PARSER.parse(self._backend, x509_exts) diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index d28dc71d..efb12e21 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -145,3 +145,17 @@ def deprecated(value, module_name, message, warning_class): if not isinstance(module, _ModuleWithDeprecations): sys.modules[module_name] = _ModuleWithDeprecations(module) return _DeprecatedValue(value, message, warning_class) + + +def cached_property(func): + cached_name = "_cached_{0}".format(func) + sentinel = object() + + def inner(instance): + cache = getattr(instance, cached_name, sentinel) + if cache is not sentinel: + return cache + result = func(instance) + setattr(instance, cached_name, result) + return result + return property(inner) -- cgit v1.2.3