python-nss-ng 1.2.1__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. python_nss_ng-1.3.0/.aislop/config.yml +20 -0
  2. python_nss_ng-1.3.0/.git_archival.txt +4 -0
  3. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/PKG-INFO +1 -1
  4. python_nss_ng-1.3.0/_version.txt +1 -0
  5. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/pyproject.toml +0 -6
  6. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/__init__.py +2 -1
  7. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/nss_context.py +2 -0
  8. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nspr_error.h +2 -0
  9. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nspr_io.c +4 -0
  10. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nspr_io.h +3 -0
  11. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nss.c +4 -0
  12. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nss.h +2 -0
  13. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_ssl.c +4 -0
  14. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_ssl.h +2 -0
  15. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/secure_logging.py +1 -6
  16. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_documentation_accuracy.py +4 -12
  17. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_performance.py +21 -14
  18. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_platform_specific.py +3 -3
  19. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_type_hints.py +7 -5
  20. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/uv.lock +0 -4
  21. python_nss_ng-1.2.1/.git_archival.txt +0 -4
  22. python_nss_ng-1.2.1/_version.txt +0 -1
  23. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/.clangd +0 -0
  24. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/CONTRIBUTING.md +0 -0
  25. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/LICENSE +0 -0
  26. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/LICENSE.gpl +0 -0
  27. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/LICENSE.lgpl +0 -0
  28. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/LICENSE.mpl +0 -0
  29. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/LICENSES/Apache-2.0.txt +0 -0
  30. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/LICENSES/MPL-2.0.txt +0 -0
  31. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/MANIFEST.in +0 -0
  32. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/Makefile +0 -0
  33. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/QUICKSTART.md +0 -0
  34. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/README.md +0 -0
  35. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/REUSE.toml +0 -0
  36. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/SECURITY.md +0 -0
  37. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/ChangeLog +0 -0
  38. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/MAKEFILE_MIGRATION.md +0 -0
  39. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/MANYLINUX_CONFIG.md +0 -0
  40. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/MIGRATION.md +0 -0
  41. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/MUTATION_TESTING.md +0 -0
  42. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/TESTING.md +0 -0
  43. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/cert_dump.py +0 -0
  44. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/cert_trust.py +0 -0
  45. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/httplib_example.py +0 -0
  46. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/pbkdf2_example.py +0 -0
  47. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/ssl_cipher_info.py +0 -0
  48. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/ssl_example.py +0 -0
  49. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/ssl_version_range.py +0 -0
  50. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/verify_cert.py +0 -0
  51. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/examples/verify_server.py +0 -0
  52. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/doc/get_api +0 -0
  53. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/meson.build +0 -0
  54. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/pyrightconfig.json +0 -0
  55. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/scripts/README.md +0 -0
  56. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/scripts/meson-version.py +0 -0
  57. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/scripts/run-all-tests.sh +0 -0
  58. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/NSPRerrs.h +0 -0
  59. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/SECerrs.h +0 -0
  60. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/SSLerrs.h +0 -0
  61. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/deprecations.py +0 -0
  62. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/io.pyi +0 -0
  63. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/nss.pyi +0 -0
  64. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nspr_common.h +0 -0
  65. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_nspr_error.c +0 -0
  66. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_shared_doc.h +0 -0
  67. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/py_traceback.h +0 -0
  68. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/src/ssl.pyi +0 -0
  69. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/conftest.py +0 -0
  70. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/exceptions.py +0 -0
  71. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/run_tests +0 -0
  72. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/setup_certs.py +0 -0
  73. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_cert_components.py +0 -0
  74. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_cert_request.py +0 -0
  75. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_certificate_advanced.py +0 -0
  76. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_cipher.py +0 -0
  77. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_client_server.py +0 -0
  78. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_deprecations.py +0 -0
  79. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_digest.py +0 -0
  80. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_examples.py +0 -0
  81. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_misc.py +0 -0
  82. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_pkcs12.py +0 -0
  83. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_property_based.py +0 -0
  84. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_secure_logging.py +0 -0
  85. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_security.py +0 -0
  86. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_thread_safety.py +0 -0
  87. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_util.py +0 -0
  88. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_zzz_error_messages.py +0 -0
  89. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_zzz_integration.py +0 -0
  90. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_zzz_nonexistent_certs.py +0 -0
  91. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_zzz_nss_context.py +0 -0
  92. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/test_zzz_ocsp.py +0 -0
  93. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/test/util.py +0 -0
  94. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/typings/nss/__init__.pyi +0 -0
  95. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/typings/nss/error.pyi +0 -0
  96. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/typings/nss/io.pyi +0 -0
  97. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/typings/nss/nss.pyi +0 -0
  98. {python_nss_ng-1.2.1 → python_nss_ng-1.3.0}/typings/nss/ssl.pyi +0 -0
@@ -0,0 +1,20 @@
1
+ # SPDX-License-Identifier: MPL-2.0
2
+ # SPDX-FileCopyrightText: 2025 The Linux Foundation
3
+
4
+ # aislop quality gate configuration.
5
+ #
6
+ # The repository scans clean, so hold `aislop ci` at the strictest
7
+ # score the tool offers rather than the default 70.
8
+ #
9
+ # Note the limit of a score gate: aislop normalises the score by file
10
+ # count and rounds it, so a single low-weight finding (a stray
11
+ # python-formatting warning, say) still rounds to 100 and passes.
12
+ # Failing on any finding at all needs a step that gates on the
13
+ # diagnostic count in `aislop scan --json`, not on the score.
14
+ #
15
+ # The C sources under src/ come from upstream python-nss; they carry
16
+ # narrow, per-rule `aislop-ignore-file` directives in place of a blanket
17
+ # exclusion, so every other rule (including the security engine) still
18
+ # runs against them.
19
+ ci:
20
+ failBelow: 100
@@ -0,0 +1,4 @@
1
+ node: f3dfb2874779585519dc97dd4abd7cebd22b8814
2
+ node-date: 2026-08-18T15:12:11+01:00
3
+ describe-name: v1.3.0
4
+ ref-names: grafted, HEAD, tag: v1.3.0, origin/main, origin/HEAD
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-nss-ng
3
- Version: 1.2.1
3
+ Version: 1.3.0
4
4
  Summary: Python bindings for Network Security Services (NSS) and Netscape Portable Runtime (NSPR)
5
5
  Keywords: nss,nspr,cryptography,ssl,tls,pki,x509,security
6
6
  Author-Email: John Dennis <jdennis@redhat.com>, Matthew Watkins <mwatkins@linuxfoundation.org>
@@ -0,0 +1 @@
1
+ 1.3.0
@@ -319,9 +319,3 @@ before-all = "yum install -y nss-devel nspr-devel pkg-config || apt-get update &
319
319
 
320
320
  [tool.cibuildwheel.macos]
321
321
  before-all = "brew install nss nspr pkg-config"
322
-
323
- [tool.uv]
324
- # Supply-chain cooldown: do not resolve anything published in the last
325
- # 7 days (rolling window; uv records it as a relative span in uv.lock).
326
- # Requires uv >= 0.9.17 for the relative-duration ("7 days") form.
327
- exclude-newer = "7 days"
@@ -4,6 +4,8 @@
4
4
  # SPDX-License-Identifier: MPL-2.0
5
5
  # SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
 
7
+ # aislop-ignore-file ai-slop/unused-import -- "import" lines flagged here are RST code examples inside a documentation string, not real imports (ruff F401 validates the real ones)
8
+
7
9
  import sys
8
10
  from importlib.metadata import PackageNotFoundError
9
11
  from importlib.metadata import version as _pkg_version
@@ -154,7 +156,6 @@ Things All NSS programs must do
154
156
 
155
157
  - Import the NSS/NSPR modules::
156
158
 
157
- from nss.error import NSPRError
158
159
  import nss.io as io
159
160
  import nss.nss as nss
160
161
  import nss.ssl as ssl
@@ -29,6 +29,8 @@ import logging
29
29
  from collections.abc import Callable, Generator
30
30
  from typing import Any
31
31
 
32
+ # aislop-ignore-file ai-slop/hallucinated-import -- "nss" is this package's own compiled C-extension module (built from py_nss.c)
33
+
32
34
  logger = logging.getLogger(__name__)
33
35
 
34
36
 
@@ -5,6 +5,8 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+
8
10
  #ifndef NSS_ERROR_MODULE_H
9
11
  #define NSS_ERROR_MODULE_H
10
12
 
@@ -5,6 +5,10 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+ // aislop-ignore-file ai-slop/unreachable-code -- goto targets and the break after return in switch cases
10
+ // aislop-ignore-file complexity/file-too-large -- upstream extension module is a single translation unit
11
+
8
12
  // FIXME: add detail to each set_nspr_error()
9
13
  // FIXME: should nspr exception be derived from IOError? Note our detail is IOError's filename
10
14
  // FIXME: add factory functions for TCPSocket, UDPSocket
@@ -5,6 +5,9 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+ // aislop-ignore-file ai-slop/trivial-comment -- upstream decorative section banners
10
+
8
11
  #ifndef NSS_IO_MODULE_H
9
12
  #define NSS_IO_MODULE_H
10
13
 
@@ -5,6 +5,10 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+ // aislop-ignore-file ai-slop/unreachable-code -- goto targets and the break after return in switch cases
10
+ // aislop-ignore-file complexity/file-too-large -- upstream extension module is a single translation unit
11
+
8
12
  #if 0
9
13
 
10
14
  //Template for new classes
@@ -5,6 +5,8 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+
8
10
  // FIXME: some of these class types have items in them with arenas, but we can't hold a reference
9
11
  // to an arena, so check to make sure we copy the items out and don't store the
10
12
  // the item with the arena in it.
@@ -5,6 +5,10 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+ // aislop-ignore-file ai-slop/unreachable-code -- goto targets and the break after return in switch cases
10
+ // aislop-ignore-file complexity/file-too-large -- upstream extension module is a single translation unit
11
+
8
12
  // FIXME: sometimes in the API dist_name is used and sometimes ca_name, make consistent.
9
13
  // FIXME: PyIntObjects represent their value as a long, but in many places we declared their C representation as
10
14
  // as int, we should change it to long, and at the same time match the parameters used in the NSPR/NSS API
@@ -5,6 +5,8 @@
5
5
  * SPDX-FileCopyrightText: Copyright (c) 2010-2025 python-nss-ng contributors
6
6
  */
7
7
 
8
+ // aislop-ignore-file ai-slop/todo-stub -- maintainer notes carried from upstream python-nss
9
+
8
10
  #ifndef NSS_SSL_MODULE_H
9
11
  #define NSS_SSL_MODULE_H
10
12
 
@@ -127,7 +127,6 @@ def check_message_safety(message: str) -> LogSensitivity:
127
127
  """
128
128
  message_lower = message.lower()
129
129
 
130
- # Check for forbidden patterns
131
130
  for pattern in FORBIDDEN_LOG_PATTERNS:
132
131
  if pattern in message_lower:
133
132
  return LogSensitivity.SENSITIVE
@@ -272,7 +271,6 @@ def log_exception_safely(
272
271
  # Log only the exception type and context
273
272
  msg = f"{context}: {exc_type} occurred (details redacted for security)"
274
273
  elif sensitivity == LogSensitivity.REDACTED:
275
- # Log with redaction
276
274
  msg = f"{context}: {exc_type}: {redact_message(exc_message)}"
277
275
  else:
278
276
  # Safe to log
@@ -329,23 +327,20 @@ class SecureExceptionHandler:
329
327
 
330
328
  def __exit__(self, exc_type, exc_val, exc_tb):
331
329
  if exc_type is not None:
332
- # Log the exception securely
330
+
333
331
  def logger_fn(msg: str) -> None:
334
332
  self.logger.log(self.log_level, msg)
335
333
 
336
334
  log_exception_safely(logger_fn, exc_val, self.context)
337
335
 
338
- # Return False to re-raise, True to suppress
339
336
  return not self.reraise
340
337
  return None
341
338
 
342
339
 
343
340
  # Example usage patterns
344
341
  if __name__ == "__main__":
345
- # Configure logging
346
342
  logging.basicConfig(level=logging.DEBUG)
347
343
 
348
- # Create secure logger
349
344
  logger = get_secure_logger(__name__)
350
345
 
351
346
  # Safe logging
@@ -335,19 +335,11 @@ class TestDocumentationCompleteness:
335
335
  if not doc_dir.exists():
336
336
  pytest.skip("doc directory not found")
337
337
 
338
- # Look for testing-related docs
339
- md_files = list(doc_dir.glob("*.md"))
340
- filenames = [f.name.lower() for f in md_files]
341
-
342
- # Should have some testing documentation
343
- has_test_docs = any("test" in name for name in filenames)
338
+ filenames = sorted(path.name.lower() for path in doc_dir.glob("*.md"))
344
339
 
345
- # This is a soft requirement
346
- if has_test_docs:
347
- assert True
348
- else:
349
- # Just document that test docs are recommended
350
- pass
340
+ assert any("test" in name for name in filenames), (
341
+ f"doc/ should document the test suite, found: {filenames}"
342
+ )
351
343
 
352
344
  def test_api_reference_or_stubs_exist(self):
353
345
  """Test that API reference or type stubs exist."""
@@ -180,6 +180,7 @@ class TestMemoryUsage:
180
180
 
181
181
  # Force garbage collection
182
182
  gc.collect()
183
+ baseline_blocks = sys.getallocatedblocks()
183
184
 
184
185
  # Perform many digest operations
185
186
  for _ in range(iterations):
@@ -189,8 +190,11 @@ class TestMemoryUsage:
189
190
  # Force garbage collection
190
191
  gc.collect()
191
192
 
192
- # Memory should be stable (hard to test directly, but shouldn't crash)
193
- assert True
193
+ # sha256_digest returns bytes, which the cyclic GC does not track, so
194
+ # count CPython allocator blocks instead: a retained result costs one
195
+ # block per iteration. Native NSS allocations stay invisible here.
196
+ growth = sys.getallocatedblocks() - baseline_blocks
197
+ assert growth < iterations // 10, f"Digest operations leaked {growth} blocks"
194
198
 
195
199
  @pytest.mark.slow
196
200
  def test_certificate_reference_memory(self, nss_db_context):
@@ -199,6 +203,7 @@ class TestMemoryUsage:
199
203
 
200
204
  # Force garbage collection
201
205
  gc.collect()
206
+ baseline_blocks = sys.getallocatedblocks()
202
207
 
203
208
  for _ in range(iterations):
204
209
  try:
@@ -213,8 +218,10 @@ class TestMemoryUsage:
213
218
  # Force garbage collection
214
219
  gc.collect()
215
220
 
216
- # Should not crash or leak
217
- assert True
221
+ # CertificateType carries no Py_TPFLAGS_HAVE_GC, so a retained wrapper
222
+ # never reaches gc.get_objects(); it does cost an allocator block.
223
+ growth = sys.getallocatedblocks() - baseline_blocks
224
+ assert growth < iterations // 10, f"Certificate lookups leaked {growth} blocks"
218
225
 
219
226
  @pytest.mark.slow
220
227
  def test_digest_context_memory(self, nss_db_context):
@@ -223,6 +230,7 @@ class TestMemoryUsage:
223
230
 
224
231
  # Force garbage collection
225
232
  gc.collect()
233
+ baseline_blocks = sys.getallocatedblocks()
226
234
 
227
235
  for _ in range(iterations):
228
236
  context = nss.create_digest_context(nss.SEC_OID_SHA256)
@@ -235,8 +243,10 @@ class TestMemoryUsage:
235
243
  # Force garbage collection
236
244
  gc.collect()
237
245
 
238
- # Should not leak
239
- assert True
246
+ # PK11ContextType is likewise untracked by the cyclic GC; the allocator
247
+ # block count still rises by one per retained context.
248
+ growth = sys.getallocatedblocks() - baseline_blocks
249
+ assert growth < iterations // 10, f"Digest contexts leaked {growth} blocks"
240
250
 
241
251
 
242
252
  class TestStressConditions:
@@ -268,18 +278,17 @@ class TestStressConditions:
268
278
  def test_rapid_context_creation_destruction(self, nss_db_context):
269
279
  """Test rapid creation and destruction of contexts."""
270
280
  iterations = 500
281
+ expected = nss.sha256_digest(b"test")
271
282
 
272
283
  for _ in range(iterations):
273
284
  context = nss.create_digest_context(nss.SEC_OID_SHA256)
274
285
  context.digest_begin()
275
286
  context.digest_op(b"test")
276
287
  digest = context.digest_final()
277
- assert digest is not None
288
+ # Rapid churn must not carry state between contexts
289
+ assert digest == expected
278
290
  # Context destroyed immediately
279
291
 
280
- # Should handle rapid churn
281
- assert True
282
-
283
292
  @pytest.mark.slow
284
293
  def test_large_data_chunks(self, nss_db_context):
285
294
  """Test processing very large data."""
@@ -296,13 +305,11 @@ class TestStressConditions:
296
305
  """Test many small operations in sequence."""
297
306
  iterations = 5000
298
307
  test_data = b"small"
308
+ expected = nss.sha256_digest(test_data)
299
309
 
300
310
  for _ in range(iterations):
301
311
  digest = nss.sha256_digest(test_data)
302
- assert digest is not None
303
-
304
- # Should handle many small operations
305
- assert True
312
+ assert digest == expected
306
313
 
307
314
 
308
315
  class TestConcurrentPerformance:
@@ -12,6 +12,7 @@ import os
12
12
  import platform
13
13
  import subprocess
14
14
  import sys
15
+ import sysconfig
15
16
  import tempfile
16
17
 
17
18
  import pytest
@@ -439,9 +440,8 @@ class TestCrossPlatformCompatibility:
439
440
  # Windows: .exe
440
441
  if sys.platform.startswith("win"):
441
442
  pytest.skip("Windows not supported")
442
- else:
443
- # Unix systems don't require extension
444
- assert True
443
+
444
+ assert sysconfig.get_config_var("EXE") == ""
445
445
 
446
446
 
447
447
  if __name__ == "__main__":
@@ -52,12 +52,13 @@ class TestTypeHints:
52
52
  def test_mypy_available(self):
53
53
  """Test if mypy is available for type checking."""
54
54
  try:
55
- import mypy
56
-
57
- assert True # mypy is available
55
+ import mypy.api
58
56
  except ImportError:
59
57
  pytest.skip("mypy not installed - install with: pip install mypy")
60
58
 
59
+ # The stub validation below drives mypy through this entry point
60
+ assert callable(mypy.api.run)
61
+
61
62
  @pytest.mark.skipif(sys.version_info < (3, 8), reason="Type hints require Python 3.8+")
62
63
  def test_mypy_validates_stubs(self, stub_files):
63
64
  """Test that mypy validates stub files without errors."""
@@ -156,11 +157,12 @@ class TestPythonModuleHints:
156
157
 
157
158
  try:
158
159
  import nss_context
159
-
160
- assert True
161
160
  except ImportError:
162
161
  pytest.fail("nss_context module not found")
163
162
 
163
+ assert hasattr(nss_context, "NSSContext")
164
+ assert hasattr(nss_context, "nss_context")
165
+
164
166
  def test_deprecations_has_hints(self):
165
167
  """Test that deprecations.py has type hints."""
166
168
  sys.path.insert(0, "src")
@@ -9,10 +9,6 @@ resolution-markers = [
9
9
  "python_full_version < '3.12'",
10
10
  ]
11
11
 
12
- [options]
13
- exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
14
- exclude-newer-span = "P7D"
15
-
16
12
  [[package]]
17
13
  name = "ast-serialize"
18
14
  version = "0.3.0"
@@ -1,4 +0,0 @@
1
- node: 0dedcdfba5bdf88fee5c42918949cb6403738886
2
- node-date: 2026-06-30T09:23:01-06:00
3
- describe-name: v1.2.1
4
- ref-names: grafted, HEAD, tag: v1.2.1, origin/main, origin/HEAD
@@ -1 +0,0 @@
1
- 1.2.1
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes