{
 "action": "Not for automatic application — applied word for word, the patch does not parse: SyntaxError: closing parenthesis ']' does not match opening parenthesis '(' on line 17 (line 23). Show this correction to the user as a lead. Replace the old line with the new one; the rest of the code can stay.",
 "alternatives": [
  {
   "action": "Not for automatic application — format removed: there is no replacement to apply. Show this correction to the user as a lead. add_extensions is not available in pyopenssl 26.4.0; remove or replace this use. The same code works on pyopenssl 26.0.0: pin a version before 26.4.0 if you cannot change the code. Release notes: builder = builder.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)",
   "applicability": {
    "method": "literal_patch",
    "reason": "format removed: there is no replacement to apply",
    "run_on": "26.4.0",
    "status": "not_applicable"
   },
   "by_notes": true,
   "changelog_ref": {
    "quote": "Removed deprecated ``OpenSSL.crypto.X509Extension``, ``OpenSSL.crypto.X509Req.add_extension``, ``OpenSSL.crypto.X509Req.get_extensions``, ``OpenSSL.crypto.X509.add_extension``, ``OpenSSL.crypto.X509.get_extensions``. ``cryptography.x509`` should be used instead.",
    "url": "https://github.com/pyca/pyopenssl/blob/HEAD/CHANGELOG.rst"
   },
   "confirmations": 1,
   "detect": [
    "cert.add_extensions"
   ],
   "equivalence": "not_comparable",
   "format": "removed",
   "kind": "removed",
   "right": "",
   "script_right": "import datetime\n\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.x509.oid import NameOID\nfrom OpenSSL import crypto\n\n\ndef main():\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n    crypto_key = key.to_cryptography_key()\n\n    name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, \"test.local\")])\n    now = datetime.datetime.now(datetime.timezone.utc)\n\n    builder = (\n        x509.CertificateBuilder()  # X.509 version 3 by default\n        .serial_number(1)\n        .subject_name(name)\n        .issuer_name(name)\n        .public_key(crypto_key.public_key())\n        .not_valid_before(now)\n        .not_valid_after(now + datetime.timedelta(seconds=365 * 24 * 60 * 60))\n        .add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)\n    )\n    cert = crypto.X509.from_cryptography(builder.sign(crypto_key, hashes.SHA256()))\n\n    print(f\"Subject CN: {cert.get_subject().CN}\")\n    for extension in cert.to_cryptography().extensions:\n        name = extension.oid._name\n        print(f\"{name}: {extension.value}\")\n\n\nif __name__ == \"__main__\":\n    main()",
   "script_wrong": "from OpenSSL import crypto\n\n\ndef main():\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n\n    cert = crypto.X509()\n    cert.set_version(2)  # X.509 version 3\n    cert.set_serial_number(1)\n    cert.get_subject().CN = \"test.local\"\n    cert.set_issuer(cert.get_subject())\n    cert.set_pubkey(key)\n    cert.gmtime_adj_notBefore(0)\n    cert.gmtime_adj_notAfter(365 * 24 * 60 * 60)\n\n    cert.add_extensions([\n        crypto.X509Extension(b\"basicConstraints\", True, b\"CA:FALSE\")\n    ])\n    cert.sign(key, \"sha256\")\n\n    print(f\"Subject CN: {cert.get_subject().CN}\")\n    for index in range(cert.get_extension_count()):\n        extension = cert.get_extension(index)\n        name = extension.get_short_name().decode(\"ascii\")\n        print(f\"{name}: {extension}\")\n\n\nif __name__ == \"__main__\":\n    main()",
   "seen_in_models": [
    "gpt-6.1-sol"
   ],
   "wrong": "cert.add_extensions(["
  }
 ],
 "applicability": {
  "line": 17,
  "method": "literal_patch",
  "occurrences": 1,
  "patched_sha": "6ee5f82e14f6",
  "reason": "applied word for word, the patch does not parse: SyntaxError: closing parenthesis ']' does not match opening parenthesis '(' on line 17 (line 23)",
  "run_on": "26.4.0",
  "status": "syntax_error"
 },
 "by_notes": true,
 "changelog_ref": {
  "quote": "Removed deprecated ``OpenSSL.crypto.X509Extension``, ``OpenSSL.crypto.X509Req.add_extension``, ``OpenSSL.crypto.X509Req.get_extensions``, ``OpenSSL.crypto.X509.add_extension``, ``OpenSSL.crypto.X509.get_extensions``. ``cryptography.x509`` should be used instead.",
  "url": "https://github.com/pyca/pyopenssl/blob/HEAD/CHANGELOG.rst"
 },
 "confirmations": {
  "failed": 0,
  "worked": 2
 },
 "detect": [
  "certificate.add_extensions"
 ],
 "ecosystem": "pypi",
 "equivalence": "same",
 "error_kind": "missing_attr",
 "error_signature": {
  "message": "'X509' object has no attribute 'add_extensions'",
  "norm": "missing_attr:add_extensions",
  "type": "AttributeError"
 },
 "first_seen": "2026-10-23T05:42:51+00:00",
 "format": "replace",
 "format_version": 2,
 "id": "pypi/pyopenssl/26.4.0/0003",
 "kind": "removed",
 "license": "https://creativecommons.org/licenses/by/4.0/",
 "package": "pyopenssl",
 "proof": {
  "applicability": {
   "line": 17,
   "method": "literal_patch",
   "occurrences": 1,
   "patched_sha": "6ee5f82e14f6",
   "reason": "applied word for word, the patch does not parse: SyntaxError: closing parenthesis ']' does not match opening parenthesis '(' on line 17 (line 23)",
   "run_on": "26.4.0",
   "status": "syntax_error"
  },
  "auto_apply": false,
  "auto_apply_reason": "the patch gives syntax_error when applied word for word",
  "auto_apply_rule": "Automatic application is allowed only when proof.equivalent is true and proof.applicability.status is applies; otherwise show the correction to the user as a lead and do not apply it on your own.",
  "equivalence": "same",
  "equivalent": true,
  "fails_on": "26.4.0",
  "fixed_on": "26.4.0",
  "level": "differential",
  "method": {
   "fix_on": "26.4.0",
   "name": "stdout_match",
   "normalization": "lines stripped, blank lines dropped, runs of whitespace collapsed; memory addresses, timestamps and temporary paths masked",
   "original_on": "26.0.0",
   "scope": "the observable stdout of one example script; return values, files, other inputs and exception types are not compared, so a match is not a proof of equivalent behaviour"
  },
  "script_right": "from datetime import datetime, timedelta, timezone\n\nfrom cryptography import x509\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.x509.oid import NameOID\nfrom OpenSSL import crypto\n\n\ndef format_extension_value(value):\n    if isinstance(value, x509.BasicConstraints):\n        text = \"CA:TRUE\" if value.ca else \"CA:FALSE\"\n        if value.path_length is not None:\n            text += f\", pathlen:{value.path_length}\"\n        return text\n    return str(value)\n\n\ndef main():\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n    private_key = key.to_cryptography_key()\n\n    subject = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, \"test.local\")])\n    now = datetime.now(timezone.utc)\n\n    builder = (\n        x509.CertificateBuilder()  # X.509 v3 by default\n        .serial_number(1)\n        .subject_name(subject)\n        .issuer_name(subject)\n        .public_key(private_key.public_key())\n        .not_valid_before(now)\n        .not_valid_after(now + timedelta(seconds=365 * 24 * 60 * 60))\n        .add_extension(\n            x509.BasicConstraints(ca=False, path_length=None),\n            critical=True,\n        )\n    )\n    signed = builder.sign(private_key, hashes.SHA256())\n    certificate = crypto.X509.from_cryptography(signed)\n\n    print(f\"Subject CN: {certificate.get_subject().CN}\")\n    for extension in signed.extensions:\n        name = extension.oid._name\n        print(f\"{name}: {format_extension_value(extension.value)}\")\n\n\nif __name__ == \"__main__\":\n    main()",
  "script_wrong": "from OpenSSL import crypto\n\n\ndef main():\n    key = crypto.PKey()\n    key.generate_key(crypto.TYPE_RSA, 2048)\n\n    certificate = crypto.X509()\n    certificate.set_version(2)  # X.509 v3\n    certificate.set_serial_number(1)\n    certificate.get_subject().CN = \"test.local\"\n    certificate.set_issuer(certificate.get_subject())\n    certificate.set_pubkey(key)\n    certificate.gmtime_adj_notBefore(0)\n    certificate.gmtime_adj_notAfter(365 * 24 * 60 * 60)\n\n    certificate.add_extensions([\n        crypto.X509Extension(\n            b\"basicConstraints\",\n            critical=True,\n            value=b\"CA:FALSE\",\n        )\n    ])\n    certificate.sign(key, \"sha256\")\n\n    print(f\"Subject CN: {certificate.get_subject().CN}\")\n    for index in range(certificate.get_extension_count()):\n        extension = certificate.get_extension(index)\n        name = extension.get_short_name().decode(\"ascii\")\n        print(f\"{name}: {extension}\")\n\n\nif __name__ == \"__main__\":\n    main()",
  "works_on": "26.0.0"
 },
 "right": ".add_extension(",
 "seen_in_models": [
  "gpt-6.1-sol"
 ],
 "seq": 3,
 "slug": "openssl-crypto-x509extension",
 "source": "pipeline",
 "symbol": "add_extensions",
 "updated": "2026-10-27T17:20:00+00:00",
 "url": "https://formachines.ai/errata/pypi/pyopenssl/0003-openssl-crypto-x509extension/",
 "variant_confirmations": 1,
 "variant_models": [
  "gpt-6.1-sol"
 ],
 "verified": "sandbox",
 "versions": {
  "changed_in": ">26.0.0,<=26.4.0",
  "fails_on": "26.4.0",
  "works_on": "26.0.0"
 },
 "wrong": "certificate.add_extensions(["
}