Repository: wemake-services/wemake-python-styleguide

Issue:
False positive on WPS515
### What's wrong

WPS515 is that you can't use `open()` outside of a context manager (`with open() as x:`), but it does not detect an optional context manager, specifically when a file is being opened only as a condition (`with (open() if check else nullcontext()) as x:`)

### How it should be

It should detect the optional open in a context manager as valid (`with (open() if check else nullcontext()) as x:`)

### Flake8 version and plugins

contents of `flake8 --bug-report` is this:
```
{
  "dependencies": [],
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.8.3",
    "system": "Linux"
  },
  "plugins": [
    {
      "is_local": false,
      "plugin": "mccabe",
      "version": "0.6.1"
    },
    {
      "is_local": false,
      "plugin": "pycodestyle",
      "version": "2.6.0"
    },
    {
      "is_local": false,
      "plugin": "pyflakes",
      "version": "2.2.0"
    }
  ],
  "version": "3.8.3"
}
```
contents of flake8 config on pre-commit where this was run:
```
  - repo: https://github.com/asottile/yesqa
    rev: v1.2.3
    hooks:
      - id: yesqa
        additional_dependencies: &flake8-deps
          - flake8==4.0.1
          - flake8-formatter-abspath==1.0.1,<2
          - flake8-fixme==1.1.1
          - flake8-isort==4.1.0
          - flake8-unused-arguments==0.0.7
          - flake8-use-fstring==1.2
          - wemake-python-styleguide==0.17.0
          - bandit <1.7.3


  - repo: https://github.com/PyCQA/flake8
    rev: 4.0.1
    hooks:
      - id: flake8
        args:
          - --config=setup.cfg
        additional_dependencies: *flake8-deps
```

### pip information

pip version: `pip 22.3.1`
poetry version: `Poetry version 1.1.14`

pip freeze output:

```
arrow @ file:///home/stephen/.cache/pypoetry/artifacts/b0/ef/2b/7ad8aecfc5afdc6bf997876eed88636229b89fff4c954799a2bf813419/arrow-1.2.3-py3-none-any.whl
asgiref @ file:///home/stephen/.cache/pypoetry/artifacts/c0/2d/09/3112c2ecce571da12482f647b2ddc0887219a423764b1a16972950c51f/asgiref-3.6.0-py3-none-any.whl
asttokens==2.2.1
attrs @ file:///home/stephen/.cache/pypoetry/artifacts/15/e7/25/08e49da17b7a163cc79ad623f8562d6e5654e06ea4e64c85bf198f70eb/attrs-21.4.0-py2.py3-none-any.whl
backcall==0.2.0
black @ file:///home/stephen/.cache/pypoetry/artifacts/7b/15/09/29ddea29892a1fa7abde624d5fc0696f20a39ea0a9a29d5cb123b11e42/black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
bytecode @ file:///home/stephen/.cache/pypoetry/artifacts/ca/a0/79/7231aa0ec63f9990b01be65c3f462b111970af7cae6ba4dc88ede2bf05/bytecode-0.14.0-py3-none-any.whl
CacheControl==0.12.11
cachy==0.3.0
cattrs @ file:///home/stephen/.cache/pypoetry/artifacts/ed/db/43/c228fb5b0496b41a4bbceff097168d305c412db67fbde27ba80c77ac44/cattrs-1.10.0-py3-none-any.whl
certifi @ file:///home/stephen/.cache/pypoetry/artifacts/60/a1/33/c27c13b4132eadadd34d3bf21af7891feaf6d5a481d5fa9b22917f2d63/certifi-2022.12.7-py3-none-any.whl
cffi==1.15.1
charset-normalizer @ file:///home/stephen/.cache/pypoetry/artifacts/be/ac/6f/ec88b78e3c55f3b5e2d17fa3cc15b062a239fdeee13ba479587b7a0ad7/charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
cleo==0.8.1
click @ file:///home/stephen/.cache/pypoetry/artifacts/63/f3/4c/2270b95f4d37b9ea73cd401abe68b6e9ede30380533cd4e7118a8e3aa3/click-8.1.3-py3-none-any.whl
clikit==0.6.2
coverage @ file:///home/stephen/.cache/pypoetry/artifacts/3a/84/92/113c7a1de534a98bfa0016c01de9885e9c343779986d7a0799cb6188d4/coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
crashtest==0.3.1
cryptography==39.0.0
ddsketch @ file:///home/stephen/.cache/pypoetry/artifacts/ee/95/da/114850072238e4b7f4b1d02d636a459f75e772b65b9ed1e2941a44a91f/ddsketch-2.0.4-py3-none-any.whl
ddtrace @ file:///home/stephen/.cache/pypoetry/artifacts/8d/b3/63/76de0ee046f9fe5471548736dd718954084fb3a7ee1869cefb4846ba11/ddtrace-1.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
decorator==5.1.1
distlib==0.3.6
Django @ file:///home/stephen/.cache/pypoetry/artifacts/ec/6e/4f/f2c089f158c700f694119a36d19d9567838720dd33c4ddbf50c5bddf85/Django-3.2.16-py3-none-any.whl
djangorestframework @ file:///home/stephen/.cache/pypoetry/artifacts/7e/33/ce/04839a97e670c37b98bc510bb18a689354c825c7618e9c1910abbac7da/djangorestframework-3.14.0-py3-none-any.whl
envier @ file:///home/stephen/.cache/pypoetry/artifacts/e7/80/03/cfb04bdc9593acd8395c3907b27a866a78d4de9b7c2777357bbb57c74f/envier-0.4.0-py3-none-any.whl
environ-config @ file:///home/stephen/.cache/pypoetry/artifacts/e5/5e/9c/d4fb62c172cc314d83ebde6f2385a0f269e2f359d7161b9ba4ef93fd58/environ_config-21.2.0-py2.py3-none-any.whl
exceptiongroup @ file:///home/stephen/.cache/pypoetry/artifacts/e8/51/01/82a8e8653cf8bbb71a0adaa83ff3c9aabca85fe707f5c44e34e6bca8d0/exceptiongroup-1.1.0-py3-none-any.whl
executing==1.2.0
filelock==3.9.0
flmodels @ file:///home/stephen/.cache/pypoetry/artifacts/99/b4/8a/d287b3188095cd8485cba769dbe0ee59bda21c4bc123fd71f92c4151b9/flmodels-16.4.0-py3-none-any.whl
furl @ file:///home/stephen/.cache/pypoetry/artifacts/0d/1a/83/f5e9eb3ff92f3c2123c3653b684e67d98a05c75f786322acddc5ba0ef9/furl-2.1.3-py2.py3-none-any.whl
html5lib==1.1
hvac @ file:///home/stephen/.cache/pypoetry/artifacts/b8/1c/63/a2fcc1239abb064fb602308256496c2be92322e74e4787be4954d8230c/hvac-0.11.2-py2.py3-none-any.whl
idna @ file:///home/stephen/.cache/pypoetry/artifacts/6c/c4/9a/4a40812e61d669fffc474987128ff48aab9be33cdddc5e5038bd96f4ac/idna-3.4-py3-none-any.whl
importlib-metadata==6.0.0
iniconfig @ file:///home/stephen/.cache/pypoetry/artifacts/f1/96/71/372c50901dab084e8b6538dde5079505ed24e9307e169f611cad72bf7e/iniconfig-2.0.0-py3-none-any.whl
ipython==8.9.0
jaraco.classes==3.2.3
jedi==0.18.2
jeepney==0.8.0
jsonschema @ file:///home/stephen/.cache/pypoetry/artifacts/ef/e8/b0/de643fd12c134ba2b62ca897dc81e2d5611b9850b58f3679f807fdccf6/jsonschema-4.17.3-py3-none-any.whl
keyring==23.13.1
lazy-object-proxy @ file:///home/stephen/.cache/pypoetry/artifacts/2c/0d/a9/2b41ac754e33bc321389d11f8a260058c3d01a2aa469d7de41af21693e/lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
lockfile==0.12.2
matplotlib-inline==0.1.6
more-itertools @ file:///home/stephen/.cache/pypoetry/artifacts/20/5a/52/0319bb8278b9fcdd159534f98c19e7069057cce39414acfa9e738bb289/more_itertools-8.14.0-py3-none-any.whl
msgpack==1.0.4
mypy-extensions @ file:///home/stephen/.cache/pypoetry/artifacts/2f/c6/09/3e1afdcb75322c65b786e63cd7e879b6be3db36dea78ca376db5483ae4/mypy_extensions-0.4.3-py2.py3-none-any.whl
orderedmultidict @ file:///home/stephen/.cache/pypoetry/artifacts/27/cc/9d/5f327edbd70499997e8acd8158a3b6f292427915c878d06413b69b798f/orderedmultidict-1.0.1-py2.py3-none-any.whl
packaging @ file:///home/stephen/.cache/pypoetry/artifacts/1e/84/66/3c8b56af72554568e094f27240dddf5385442f1fc4c44609b4b3e48ee7/packaging-23.0-py3-none-any.whl
parso==0.8.3
pastel==0.2.1
pathspec @ file:///home/stephen/.cache/pypoetry/artifacts/91/ff/d6/9c8cbbd474eb7f2ccc438ac77e5d6e5b8bf100005da70b277205d4efd0/pathspec-0.10.3-py3-none-any.whl
pexpect==4.8.0
pickleshare==0.7.5
pkginfo==1.9.6
platformdirs @ file:///home/stephen/.cache/pypoetry/artifacts/20/72/b7/da4a168ccc7b08714fc0f286bf919abd605f3c40360cd411540c4eb562/platformdirs-2.6.2-py3-none-any.whl
pluggy @ file:///home/stephen/.cache/pypoetry/artifacts/49/3e/55/309ec3705ba3309d817d531002c0a02f643d06c5d5a889ce43236130d5/pluggy-1.0.0-py2.py3-none-any.whl
poetry==1.1.14
poetry-core==1.0.8
prometheus-client @ file:///home/stephen/.cache/pypoetry/artifacts/3e/ac/5d/0ca6105e39f961b125ff9db665955a7aa163d21b3f7da2f5094aaca7bc/prometheus_client-0.9.0-py2.py3-none-any.whl
prompt-toolkit==3.0.36
protobuf @ file:///home/stephen/.cache/pypoetry/artifacts/2e/a7/4d/faf0ce99e6847dcfd91ddcc13f9ce05172e95f49f9ad095985079f254c/protobuf-4.21.12-cp37-abi3-manylinux2014_x86_64.whl
psycopg2-binary @ file:///home/stephen/.cache/pypoetry/artifacts/8b/79/b1/0c5cdbf7dbad788a17740be37a8a8905558ca7f94c27254137857fa601/psycopg2-binary-2.9.5.tar.gz
ptyprocess==0.7.0
pure-eval==0.2.2
py @ file:///home/stephen/.cache/pypoetry/artifacts/71/fb/64/bfdc833c2055a893883f33deaac35ef2cbdd95d58031cfc69a630f32bf/py-1.11.0-py2.py3-none-any.whl
pycparser==2.21
pycryptodomex @ file:///home/stephen/.cache/pypoetry/artifacts/0c/1b/f4/0571ad8b55048bd2ec2eec9f97b54e417b60da87b095d8e57256b71030/pycryptodomex-3.16.0-cp35-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Pygments==2.14.0
pylev==1.4.0
pyparsing @ file:///home/stephen/.cache/pypoetry/artifacts/e1/09/c0/6a6df3ef412eb19fcda1b353ea54e3b48f9c518348fadd0967a962cbb6/pyparsing-3.0.9-py3-none-any.whl
pyrsistent @ file:///home/stephen/.cache/pypoetry/artifacts/4d/08/7c/e1d2ce275a47bf5f01f22259ece522318fd11061ff6b3ebedff180a1e5/pyrsistent-0.19.3-py3-none-any.whl
pytest @ file:///home/stephen/.cache/pypoetry/artifacts/5a/40/e0/b56e452f5ece4ecdc72b60e08481c37929a2222b3e256344f5f57e4c7c/pytest-7.2.1-py3-none-any.whl
pytest-cov @ file:///home/stephen/.cache/pypoetry/artifacts/a4/cf/e4/6928e34c02a0073e458ed27f54b6115bec390389f1c1b0953ae1a35898/pytest_cov-2.12.1-py2.py3-none-any.whl
python-dateutil @ file:///home/stephen/.cache/pypoetry/artifacts/39/9b/3b/576da7c854551d780528d75132c98882925e44de0aecf8a31a4bea379c/python_dateutil-2.8.2-py2.py3-none-any.whl
python-json-logger @ file:///home/stephen/.cache/pypoetry/artifacts/ff/08/00/e5c7c11bcd6024427831ee5fc9cf39297d12aebee7a733b84681d33c51/python_json_logger-2.0.4-py3-none-any.whl
pytz @ file:///home/stephen/.cache/pypoetry/artifacts/87/72/3b/8306d16cb9587ae7d35f1e377424ee0ac77af35f018f7c37783195763c/pytz-2022.7.1-py2.py3-none-any.whl
requests @ file:///home/stephen/.cache/pypoetry/artifacts/8e/ba/3e/c74e3b847d4ca1ab083b2c21df1ad2275db2891bf08d4a623d263e9662/requests-2.28.2-py3-none-any.whl
requests-toolbelt==0.9.1
SecretStorage==3.3.3
shellingham==1.5.0.post1
six @ file:///home/stephen/.cache/pypoetry/artifacts/89/b2/f8/fd92b6d5daa0f8889429b2fc67ec21eedc5cae5d531ee2853828ced6c7/six-1.16.0-py2.py3-none-any.whl
sqlparse @ file:///home/stephen/.cache/pypoetry/artifacts/a3/4e/dd/5068c76ef85bf54c4b208933a74bf760e5b3f50c67a98708b29c66a6f5/sqlparse-0.4.3-py3-none-any.whl
stack-data==0.6.2
tenacity @ file:///home/stephen/.cache/pypoetry/artifacts/72/b6/af/b87b523b7ec11c64f8667396d9335a921abf9c7b6afc064a9f5b00c363/tenacity-8.1.0-py3-none-any.whl
toml @ file:///home/stephen/.cache/pypoetry/artifacts/51/ac/24/674da558495229c57c3d2333cb23e24aac7aadf723ced29e2cc41a9e6e/toml-0.10.2-py2.py3-none-any.whl
tomli @ file:///home/stephen/.cache/pypoetry/artifacts/62/12/b6/6db9ebb9c8e1a6c5aa8a92ae73098d8119816b5e8507490916621bc305/tomli-2.0.1-py3-none-any.whl
tomlkit==0.11.6
traitlets==5.8.1
typing_extensions @ file:///home/stephen/.cache/pypoetry/artifacts/5a/62/d2/6e114f8e6602ecb5e40ed745c522ed05ef05b697e5432317e3de8b6bcd/typing_extensions-4.4.0-py3-none-any.whl
urllib3 @ file:///home/stephen/.cache/pypoetry/artifacts/e7/80/9c/00433a9d40d16b7901ec3ec22b0ace9c6c9b3117e3f7e77d1cf4b5c07b/urllib3-1.26.14-py2.py3-none-any.whl
virtualenv==20.17.1
wcwidth==0.2.6
webencodings==0.5.1
xmltodict @ file:///home/stephen/.cache/pypoetry/artifacts/73/be/c8/7db06d74fd309cfb86b6747350ac9144dc84ce29b0d191c8cb4c531b66/xmltodict-0.13.0-py2.py3-none-any.whl
zipp==3.11.0
```


### OS information

Ubuntu 18.04
False positive on WPS515
### What's wrong

WPS515 is that you can't use `open()` outside of a context manager (`with open() as x:`), but it does not detect an optional context manager, specifically when a file is being opened only as a condition (`with (open() if check else nullcontext()) as x:`)

### How it should be

It should detect the optional open in a context manager as valid (`with (open() if check else nullcontext()) as x:`)

### Flake8 version and plugins

contents of `flake8 --bug-report` is this:
```
{
  "dependencies": [],
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.8.3",
    "system": "Linux"
  },
  "plugins": [
    {
      "is_local": false,
      "plugin": "mccabe",
      "version": "0.6.1"
    },
    {
      "is_local": false,
      "plugin": "pycodestyle",
      "version": "2.6.0"
    },
    {
      "is_local": false,
      "plugin": "pyflakes",
      "version": "2.2.0"
    }
  ],
  "version": "3.8.3"
}
```
contents of flake8 config on pre-commit where this was run:
```
  - repo: https://github.com/asottile/yesqa
    rev: v1.2.3
    hooks:
      - id: yesqa
        additional_dependencies: &flake8-deps
          - flake8==4.0.1
          - flake8-formatter-abspath==1.0.1,<2
          - flake8-fixme==1.1.1
          - flake8-isort==4.1.0
          - flake8-unused-arguments==0.0.7
          - flake8-use-fstring==1.2
          - wemake-python-styleguide==0.17.0
          - bandit <1.7.3


  - repo: https://github.com/PyCQA/flake8
    rev: 4.0.1
    hooks:
      - id: flake8
        args:
          - --config=setup.cfg
        additional_dependencies: *flake8-deps
```

### pip information

pip version: `pip 22.3.1`
poetry version: `Poetry version 1.1.14`

pip freeze output:

```
arrow @ file:///home/stephen/.cache/pypoetry/artifacts/b0/ef/2b/7ad8aecfc5afdc6bf997876eed88636229b89fff4c954799a2bf813419/arrow-1.2.3-py3-none-any.whl
asgiref @ file:///home/stephen/.cache/pypoetry/artifacts/c0/2d/09/3112c2ecce571da12482f647b2ddc0887219a423764b1a16972950c51f/asgiref-3.6.0-py3-none-any.whl
asttokens==2.2.1
attrs @ file:///home/stephen/.cache/pypoetry/artifacts/15/e7/25/08e49da17b7a163cc79ad623f8562d6e5654e06ea4e64c85bf198f70eb/attrs-21.4.0-py2.py3-none-any.whl
backcall==0.2.0
black @ file:///home/stephen/.cache/pypoetry/artifacts/7b/15/09/29ddea29892a1fa7abde624d5fc0696f20a39ea0a9a29d5cb123b11e42/black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
bytecode @ file:///home/stephen/.cache/pypoetry/artifacts/ca/a0/79/7231aa0ec63f9990b01be65c3f462b111970af7cae6ba4dc88ede2bf05/bytecode-0.14.0-py3-none-any.whl
CacheControl==0.12.11
cachy==0.3.0
cattrs @ file:///home/stephen/.cache/pypoetry/artifacts/ed/db/43/c228fb5b0496b41a4bbceff097168d305c412db67fbde27ba80c77ac44/cattrs-1.10.0-py3-none-any.whl
certifi @ file:///home/stephen/.cache/pypoetry/artifacts/60/a1/33/c27c13b4132eadadd34d3bf21af7891feaf6d5a481d5fa9b22917f2d63/certifi-2022.12.7-py3-none-any.whl
cffi==1.15.1
charset-normalizer @ file:///home/stephen/.cache/pypoetry/artifacts/be/ac/6f/ec88b78e3c55f3b5e2d17fa3cc15b062a239fdeee13ba479587b7a0ad7/charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
cleo==0.8.1
click @ file:///home/stephen/.cache/pypoetry/artifacts/63/f3/4c/2270b95f4d37b9ea73cd401abe68b6e9ede30380533cd4e7118a8e3aa3/click-8.1.3-py3-none-any.whl
clikit==0.6.2
coverage @ file:///home/stephen/.cache/pypoetry/artifacts/3a/84/92/113c7a1de534a98bfa0016c01de9885e9c343779986d7a0799cb6188d4/coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
crashtest==0.3.1
cryptography==39.0.0
ddsketch @ file:///home/stephen/.cache/pypoetry/artifacts/ee/95/da/114850072238e4b7f4b1d02d636a459f75e772b65b9ed1e2941a44a91f/ddsketch-2.0.4-py3-none-any.whl
ddtrace @ file:///home/stephen/.cache/pypoetry/artifacts/8d/b3/63/76de0ee046f9fe5471548736dd718954084fb3a7ee1869cefb4846ba11/ddtrace-1.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
decorator==5.1.1
distlib==0.3.6
Django @ file:///home/stephen/.cache/pypoetry/artifacts/ec/6e/4f/f2c089f158c700f694119a36d19d9567838720dd33c4ddbf50c5bddf85/Django-3.2.16-py3-none-any.whl
djangorestframework @ file:///home/stephen/.cache/pypoetry/artifacts/7e/33/ce/04839a97e670c37b98bc510bb18a689354c825c7618e9c1910abbac7da/djangorestframework-3.14.0-py3-none-any.whl
envier @ file:///home/stephen/.cache/pypoetry/artifacts/e7/80/03/cfb04bdc9593acd8395c3907b27a866a78d4de9b7c2777357bbb57c74f/envier-0.4.0-py3-none-any.whl
environ-config @ file:///home/stephen/.cache/pypoetry/artifacts/e5/5e/9c/d4fb62c172cc314d83ebde6f2385a0f269e2f359d7161b9ba4ef93fd58/environ_config-21.2.0-py2.py3-none-any.whl
exceptiongroup @ file:///home/stephen/.cache/pypoetry/artifacts/e8/51/01/82a8e8653cf8bbb71a0adaa83ff3c9aabca85fe707f5c44e34e6bca8d0/exceptiongroup-1.1.0-py3-none-any.whl
executing==1.2.0
filelock==3.9.0
flmodels @ file:///home/stephen/.cache/pypoetry/artifacts/99/b4/8a/d287b3188095cd8485cba769dbe0ee59bda21c4bc123fd71f92c4151b9/flmodels-16.4.0-py3-none-any.whl
furl @ file:///home/stephen/.cache/pypoetry/artifacts/0d/1a/83/f5e9eb3ff92f3c2123c3653b684e67d98a05c75f786322acddc5ba0ef9/furl-2.1.3-py2.py3-none-any.whl
html5lib==1.1
hvac @ file:///home/stephen/.cache/pypoetry/artifacts/b8/1c/63/a2fcc1239abb064fb602308256496c2be92322e74e4787be4954d8230c/hvac-0.11.2-py2.py3-none-any.whl
idna @ file:///home/stephen/.cache/pypoetry/artifacts/6c/c4/9a/4a40812e61d669fffc474987128ff48aab9be33cdddc5e5038bd96f4ac/idna-3.4-py3-none-any.whl
importlib-metadata==6.0.0
iniconfig @ file:///home/stephen/.cache/pypoetry/artifacts/f1/96/71/372c50901dab084e8b6538dde5079505ed24e9307e169f611cad72bf7e/iniconfig-2.0.0-py3-none-any.whl
ipython==8.9.0
jaraco.classes==3.2.3
jedi==0.18.2
jeepney==0.8.0
jsonschema @ file:///home/stephen/.cache/pypoetry/artifacts/ef/e8/b0/de643fd12c134ba2b62ca897dc81e2d5611b9850b58f3679f807fdccf6/jsonschema-4.17.3-py3-none-any.whl
keyring==23.13.1
lazy-object-proxy @ file:///home/stephen/.cache/pypoetry/artifacts/2c/0d/a9/2b41ac754e33bc321389d11f8a260058c3d01a2aa469d7de41af21693e/lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
lockfile==0.12.2
matplotlib-inline==0.1.6
more-itertools @ file:///home/stephen/.cache/pypoetry/artifacts/20/5a/52/0319bb8278b9fcdd159534f98c19e7069057cce39414acfa9e738bb289/more_itertools-8.14.0-py3-none-any.whl
msgpack==1.0.4
mypy-extensions @ file:///home/stephen/.cache/pypoetry/artifacts/2f/c6/09/3e1afdcb75322c65b786e63cd7e879b6be3db36dea78ca376db5483ae4/mypy_extensions-0.4.3-py2.py3-none-any.whl
orderedmultidict @ file:///home/stephen/.cache/pypoetry/artifacts/27/cc/9d/5f327edbd70499997e8acd8158a3b6f292427915c878d06413b69b798f/orderedmultidict-1.0.1-py2.py3-none-any.whl
packaging @ file:///home/stephen/.cache/pypoetry/artifacts/1e/84/66/3c8b56af72554568e094f27240dddf5385442f1fc4c44609b4b3e48ee7/packaging-23.0-py3-none-any.whl
parso==0.8.3
pastel==0.2.1
pathspec @ file:///home/stephen/.cache/pypoetry/artifacts/91/ff/d6/9c8cbbd474eb7f2ccc438ac77e5d6e5b8bf100005da70b277205d4efd0/pathspec-0.10.3-py3-none-any.whl
pexpect==4.8.0
pickleshare==0.7.5
pkginfo==1.9.6
platformdirs @ file:///home/stephen/.cache/pypoetry/artifacts/20/72/b7/da4a168ccc7b08714fc0f286bf919abd605f3c40360cd411540c4eb562/platformdirs-2.6.2-py3-none-any.whl
pluggy @ file:///home/stephen/.cache/pypoetry/artifacts/49/3e/55/309ec3705ba3309d817d531002c0a02f643d06c5d5a889ce43236130d5/pluggy-1.0.0-py2.py3-none-any.whl
poetry==1.1.14
poetry-core==1.0.8
prometheus-client @ file:///home/stephen/.cache/pypoetry/artifacts/3e/ac/5d/0ca6105e39f961b125ff9db665955a7aa163d21b3f7da2f5094aaca7bc/prometheus_client-0.9.0-py2.py3-none-any.whl
prompt-toolkit==3.0.36
protobuf @ file:///home/stephen/.cache/pypoetry/artifacts/2e/a7/4d/faf0ce99e6847dcfd91ddcc13f9ce05172e95f49f9ad095985079f254c/protobuf-4.21.12-cp37-abi3-manylinux2014_x86_64.whl
psycopg2-binary @ file:///home/stephen/.cache/pypoetry/artifacts/8b/79/b1/0c5cdbf7dbad788a17740be37a8a8905558ca7f94c27254137857fa601/psycopg2-binary-2.9.5.tar.gz
ptyprocess==0.7.0
pure-eval==0.2.2
py @ file:///home/stephen/.cache/pypoetry/artifacts/71/fb/64/bfdc833c2055a893883f33deaac35ef2cbdd95d58031cfc69a630f32bf/py-1.11.0-py2.py3-none-any.whl
pycparser==2.21
pycryptodomex @ file:///home/stephen/.cache/pypoetry/artifacts/0c/1b/f4/0571ad8b55048bd2ec2eec9f97b54e417b60da87b095d8e57256b71030/pycryptodomex-3.16.0-cp35-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl
Pygments==2.14.0
pylev==1.4.0
pyparsing @ file:///home/stephen/.cache/pypoetry/artifacts/e1/09/c0/6a6df3ef412eb19fcda1b353ea54e3b48f9c518348fadd0967a962cbb6/pyparsing-3.0.9-py3-none-any.whl
pyrsistent @ file:///home/stephen/.cache/pypoetry/artifacts/4d/08/7c/e1d2ce275a47bf5f01f22259ece522318fd11061ff6b3ebedff180a1e5/pyrsistent-0.19.3-py3-none-any.whl
pytest @ file:///home/stephen/.cache/pypoetry/artifacts/5a/40/e0/b56e452f5ece4ecdc72b60e08481c37929a2222b3e256344f5f57e4c7c/pytest-7.2.1-py3-none-any.whl
pytest-cov @ file:///home/stephen/.cache/pypoetry/artifacts/a4/cf/e4/6928e34c02a0073e458ed27f54b6115bec390389f1c1b0953ae1a35898/pytest_cov-2.12.1-py2.py3-none-any.whl
python-dateutil @ file:///home/stephen/.cache/pypoetry/artifacts/39/9b/3b/576da7c854551d780528d75132c98882925e44de0aecf8a31a4bea379c/python_dateutil-2.8.2-py2.py3-none-any.whl
python-json-logger @ file:///home/stephen/.cache/pypoetry/artifacts/ff/08/00/e5c7c11bcd6024427831ee5fc9cf39297d12aebee7a733b84681d33c51/python_json_logger-2.0.4-py3-none-any.whl
pytz @ file:///home/stephen/.cache/pypoetry/artifacts/87/72/3b/8306d16cb9587ae7d35f1e377424ee0ac77af35f018f7c37783195763c/pytz-2022.7.1-py2.py3-none-any.whl
requests @ file:///home/stephen/.cache/pypoetry/artifacts/8e/ba/3e/c74e3b847d4ca1ab083b2c21df1ad2275db2891bf08d4a623d263e9662/requests-2.28.2-py3-none-any.whl
requests-toolbelt==0.9.1
SecretStorage==3.3.3
shellingham==1.5.0.post1
six @ file:///home/stephen/.cache/pypoetry/artifacts/89/b2/f8/fd92b6d5daa0f8889429b2fc67ec21eedc5cae5d531ee2853828ced6c7/six-1.16.0-py2.py3-none-any.whl
sqlparse @ file:///home/stephen/.cache/pypoetry/artifacts/a3/4e/dd/5068c76ef85bf54c4b208933a74bf760e5b3f50c67a98708b29c66a6f5/sqlparse-0.4.3-py3-none-any.whl
stack-data==0.6.2
tenacity @ file:///home/stephen/.cache/pypoetry/artifacts/72/b6/af/b87b523b7ec11c64f8667396d9335a921abf9c7b6afc064a9f5b00c363/tenacity-8.1.0-py3-none-any.whl
toml @ file:///home/stephen/.cache/pypoetry/artifacts/51/ac/24/674da558495229c57c3d2333cb23e24aac7aadf723ced29e2cc41a9e6e/toml-0.10.2-py2.py3-none-any.whl
tomli @ file:///home/stephen/.cache/pypoetry/artifacts/62/12/b6/6db9ebb9c8e1a6c5aa8a92ae73098d8119816b5e8507490916621bc305/tomli-2.0.1-py3-none-any.whl
tomlkit==0.11.6
traitlets==5.8.1
typing_extensions @ file:///home/stephen/.cache/pypoetry/artifacts/5a/62/d2/6e114f8e6602ecb5e40ed745c522ed05ef05b697e5432317e3de8b6bcd/typing_extensions-4.4.0-py3-none-any.whl
urllib3 @ file:///home/stephen/.cache/pypoetry/artifacts/e7/80/9c/00433a9d40d16b7901ec3ec22b0ace9c6c9b3117e3f7e77d1cf4b5c07b/urllib3-1.26.14-py2.py3-none-any.whl
virtualenv==20.17.1
wcwidth==0.2.6
webencodings==0.5.1
xmltodict @ file:///home/stephen/.cache/pypoetry/artifacts/73/be/c8/7db06d74fd309cfb86b6747350ac9144dc84ce29b0d191c8cb4c531b66/xmltodict-0.13.0-py2.py3-none-any.whl
zipp==3.11.0
```


### OS information

Ubuntu 18.04


Discussion:

Resolving patch:
diff --git a/wemake_python_styleguide/visitors/ast/functions.py b/wemake_python_styleguide/visitors/ast/functions.py
--- a/wemake_python_styleguide/visitors/ast/functions.py
+++ b/wemake_python_styleguide/visitors/ast/functions.py
@@ -211,10 +211,20 @@ def _check_open_call_context(self, node: ast.Call) -> None:
         if not function_name:
             return
 
-        if isinstance(nodes.get_parent(node), ast.withitem):
+        parent_node = nodes.get_parent(node)
+
+        if isinstance(parent_node, ast.withitem):
             # We do not care about `with` or `async with` - both are fine.
             return
 
+        if_exp_inside_with = (
+            isinstance(parent_node, ast.IfExp) and
+            isinstance(nodes.get_parent(parent_node), ast.withitem)
+        )
+
+        if if_exp_inside_with:
+            return
+
         self.add_violation(OpenWithoutContextManagerViolation(node))
 
     def _check_type_compare(self, node: ast.Call) -> None:


Test patch:
diff --git a/tests/test_formatter/snapshots/snap_test_formatter_output.py b/tests/test_formatter/snapshots/snap_test_formatter_output.py
--- a/tests/test_formatter/snapshots/snap_test_formatter_output.py
+++ b/tests/test_formatter/snapshots/snap_test_formatter_output.py
@@ -70,37 +70,37 @@
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter1.py\x1b[0m\x1b[0m
 
   1:1      WPS111 Found too short name: s < 2
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:7      WPS110 Found wrong variable name: handle
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
         ^
 
   2:21     WPS432 Found magic number: 200
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
   2:21     WPS303 Found underscored number: 2_00
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter2.py\x1b[0m\x1b[0m
 
   1:1      WPS110 Found wrong variable name: data
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:10     WPS110 Found wrong variable name: param
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
            ^
 
   2:12     WPS437 Found protected attribute usage: _protected
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
          ^
 
   2:31     WPS303 Found underscored number: 10_00
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                             ^
 
 Full list of violations and explanations:
@@ -136,37 +136,37 @@
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter1.py\x1b[0m\x1b[0m
 
   1:1      WPS111 Found too short name: s < 2
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:7      WPS110 Found wrong variable name: handle
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
         ^
 
   2:21     WPS432 Found magic number: 200
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
   2:21     WPS303 Found underscored number: 2_00
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter2.py\x1b[0m\x1b[0m
 
   1:1      WPS110 Found wrong variable name: data
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:10     WPS110 Found wrong variable name: param
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
            ^
 
   2:12     WPS437 Found protected attribute usage: _protected
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
          ^
 
   2:31     WPS303 Found underscored number: 10_00
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                             ^
 
 \x1b[1mWPS110\x1b[0m: Found wrong variable name: handle
@@ -203,44 +203,44 @@
 
   1:1      WPS111 Found too short name: s < 2
            -> https://pyflak.es/WPS111
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:7      WPS110 Found wrong variable name: handle
            -> https://pyflak.es/WPS110
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
         ^
 
   2:21     WPS432 Found magic number: 200
            -> https://pyflak.es/WPS432
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
   2:21     WPS303 Found underscored number: 2_00
            -> https://pyflak.es/WPS303
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter2.py\x1b[0m\x1b[0m
 
   1:1      WPS110 Found wrong variable name: data
            -> https://pyflak.es/WPS110
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:10     WPS110 Found wrong variable name: param
            -> https://pyflak.es/WPS110
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
            ^
 
   2:12     WPS437 Found protected attribute usage: _protected
            -> https://pyflak.es/WPS437
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
          ^
 
   2:31     WPS303 Found underscored number: 10_00
            -> https://pyflak.es/WPS303
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                             ^
 
 Full list of violations and explanations:
@@ -251,37 +251,37 @@
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter1.py\x1b[0m\x1b[0m
 
   1:1      WPS111 Found too short name: s < 2
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:7      WPS110 Found wrong variable name: handle
-  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32ms\x1b[39;49;00m(handle: \x1b[36mint\x1b[39;49;00m) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
         ^
 
   2:21     WPS432 Found magic number: 200
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
   2:21     WPS303 Found underscored number: 2_00
-  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m handle + \x1b[34m2_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                   ^
 
 \x1b[4m\x1b[1m./tests/fixtures/formatter/formatter2.py\x1b[0m\x1b[0m
 
   1:1      WPS110 Found wrong variable name: data
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
   ^
 
   1:10     WPS110 Found wrong variable name: param
-  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:
+  \x1b[34mdef\x1b[39;49;00m \x1b[32mdata\x1b[39;49;00m(param) -> \x1b[36mint\x1b[39;49;00m:\x1b[37m\x1b[39;49;00m
            ^
 
   2:12     WPS437 Found protected attribute usage: _protected
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
          ^
 
   2:31     WPS303 Found underscored number: 10_00
-  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m
+  \x1b[34mreturn\x1b[39;49;00m param._protected + \x1b[34m10_00\x1b[39;49;00m\x1b[37m\x1b[39;49;00m
                             ^
 
 \x1b[1mWPS110\x1b[0m: Found wrong variable name: handle
diff --git a/tests/test_visitors/test_ast/test_functions/test_call_context/test_open_with.py b/tests/test_visitors/test_ast/test_functions/test_call_context/test_open_with.py
--- a/tests/test_visitors/test_ast/test_functions/test_call_context/test_open_with.py
+++ b/tests/test_visitors/test_ast/test_functions/test_call_context/test_open_with.py
@@ -33,6 +33,13 @@ def wrapper():
         ...
 """
 
+context_manager5 = """
+def wrapper():
+    with ({0} if check else nullcontext()) as x:
+        ...
+"""
+
+
 # Wrong:
 
 expression = '{0}'
@@ -51,6 +58,7 @@ def wrapper():
     context_manager2,
     context_manager3,
     context_manager4,
+    context_manager5,
 ])
 @pytest.mark.parametrize('call', [
     'open()',