Repository: pydicom/pydicom

Issue:
"TypeError: 'NoneType' object is not subscriptable" when reading dcm file with empty string as Chartset and "use_none_as_empty_text_VR_value=True"
**Describe the bug**
Once thing I noticed is that `convert_encodings` in `charset.py` expects a list of encodings (according to the docstrings) from tag `0008,0005` but it can be just a value. 

The problem is when reading Dicom files in production environments I noticed that some devices that are capturing the DICOMs are not very DICOM Compliant and is sending empty string , which it should be allowed as `0008,0005` is a 1C type, which means that if present it should have a valid value. 

I enabled `use_none_as_empty_text_VR_value` to make sure other tags whose value should be float or int have None instead of empty string, but if `0008,0005` value is empty string is switched to None and `convert_encodings` fails with `TypeError: 'NoneType' object is not subscriptable`

**Expected behavior**
The expected behavior should be that if empty string or not present it should default to:
```
# default encoding if no encoding defined - corresponds to ISO IR 6 / ASCII
default_encoding = "iso8859"
```

**Steps To Reproduce**

out.dcm file if provided for testing with mock data but `Specific Character Set` set to empty string

If setting the `(0008, 0005) Specific Character Set` to empty string and setting `pydicom.config.use_none_as_empty_text_VR_value = True`

```
>>> import pydicom
>>> pydicom.config.datetime_conversion = True
>>> pydicom.config.allow_DS_float = True
>>> pydicom.config.use_none_as_empty_text_VR_value = True
>>> dataset = pydicom.dcmread("test.dcm")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/bernardo/.virtualenvs/backend-api/lib/python3.7/site-packages/pydicom/filereader.py", line 871, in dcmread
    force=force, specific_tags=specific_tags)
  File "/Users/bernardo/.virtualenvs/backend-api/lib/python3.7/site-packages/pydicom/filereader.py", line 744, in read_partial
    specific_tags=specific_tags)
  File "/Users/bernardo/.virtualenvs/backend-api/lib/python3.7/site-packages/pydicom/filereader.py", line 383, in read_dataset
    encoding = convert_encodings(char_set)
  File "/Users/bernardo/.virtualenvs/backend-api/lib/python3.7/site-packages/pydicom/charset.py", line 638, in convert_encodings
    encodings = encodings[:]
TypeError: 'NoneType' object is not subscriptable
>>> pydicom.config.use_none_as_empty_text_VR_value = False
>>> dataset = pydicom.dcmread("test.dcm")
```
`(0008, 0005) Specific Character Set              CS: ''`

**Your environment**

```bash
python -m pydicom.env_info
module       | version
------       | -------
platform     | Darwin-19.6.0-x86_64-i386-64bit
Python       | 3.7.6 (default, Dec 30 2019, 19:38:26)  [Clang 11.0.0 (clang-1100.0.33.16)]
pydicom      | 2.0.0
gdcm         | _module not found_
jpeg_ls      | _module not found_
numpy        | _module not found_
PIL          | 7.0.0
```


[out.dcm.zip](https://github.com/pydicom/pydicom/files/5248618/out.dcm.zip)


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=h1) Report
> Merging [#1192](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=desc) into [master](https://codecov.io/gh/pydicom/pydicom/commit/1f099ae0f75f0e2ed402a21702e584aac54a30ef?el=desc) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/pydicom/pydicom/pull/1192/graphs/tree.svg?width=650&height=150&src=pr&token=YciLV15Lwr)](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #1192   +/-   ##
=======================================
  Coverage   94.05%   94.05%           
=======================================
  Files          54       54           
  Lines        7968     7969    +1     
=======================================
+ Hits         7494     7495    +1     
  Misses        474      474           
```


| [Impacted Files](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pydicom/charset.py](https://codecov.io/gh/pydicom/pydicom/pull/1192/diff?src=pr&el=tree#diff-cHlkaWNvbS9jaGFyc2V0LnB5) | `94.09% <100.00%> (+0.02%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=footer). Last update [1f099ae...7156e30](https://codecov.io/gh/pydicom/pydicom/pull/1192?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/doc/release_notes/v2.1.0.rst b/doc/release_notes/v2.1.0.rst
index 1b7ac3039..bc593a6eb 100644
--- a/doc/release_notes/v2.1.0.rst
+++ b/doc/release_notes/v2.1.0.rst
@@ -61,3 +61,4 @@ Fixes
   a file-like (:issue:`1153`)
 * Raise ``TypeError`` if :func:`~pydicom.dcmread` or :func:`~pydicom.dcmwrite`
   is called with wrong argument
+* Gracefully handle empty Specific Character Set (:issue:`1190`)
diff --git a/pydicom/charset.py b/pydicom/charset.py
index 74be44e5f..689d11457 100644
--- a/pydicom/charset.py
+++ b/pydicom/charset.py
@@ -634,13 +634,16 @@ def convert_encodings(encodings):
         ``True``.
     """
 
-    # If a list if passed, we don't want to modify the list in place so copy it
-    encodings = encodings[:]
+    encodings = encodings or ['']
 
     if isinstance(encodings, str):
         encodings = [encodings]
-    elif not encodings[0]:
-        encodings[0] = 'ISO_IR 6'
+    else:
+        # If a list if passed, we don't want to modify the list
+        # in place so copy it
+        encodings = encodings[:]
+        if not encodings[0]:
+            encodings[0] = 'ISO_IR 6'
 
     py_encodings = []
     for encoding in encodings:


Test patch:
diff --git a/pydicom/tests/test_charset.py b/pydicom/tests/test_charset.py
index e66d69d5b..5e3a9f820 100644
--- a/pydicom/tests/test_charset.py
+++ b/pydicom/tests/test_charset.py
@@ -140,6 +140,15 @@ class TestCharset:
         pydicom.charset.decode_element(elem, [])
         assert 'iso8859' in elem.value.encodings
 
+    def test_empty_charset(self):
+        """Empty charset defaults to ISO IR 6"""
+        elem = DataElement(0x00100010, 'PN', 'CITIZEN')
+        pydicom.charset.decode_element(elem, [''])
+        assert ('iso8859',) == elem.value.encodings
+        elem = DataElement(0x00100010, 'PN', 'CITIZEN')
+        pydicom.charset.decode_element(elem, None)
+        assert ('iso8859',) == elem.value.encodings
+
     def test_bad_encoded_single_encoding(self, allow_invalid_values):
         """Test handling bad encoding for single encoding"""
         elem = DataElement(0x00100010, 'PN',
@@ -189,6 +198,15 @@ class TestCharset:
         encodings = ['iso_ir_126', 'iso_ir_144']
         assert encodings == pydicom.charset.convert_encodings(encodings)
 
+    def test_convert_empty_encoding(self):
+        """Test that empty encodings are handled as default encoding"""
+        encodings = ''
+        assert ['iso8859'] == pydicom.charset.convert_encodings(encodings)
+        encodings = ['']
+        assert ['iso8859'] == pydicom.charset.convert_encodings(encodings)
+        encodings = None
+        assert ['iso8859'] == pydicom.charset.convert_encodings(encodings)
+
     def test_bad_decoded_multi_byte_encoding(self, allow_invalid_values):
         """Test handling bad encoding for single encoding"""
         elem = DataElement(0x00100010, 'PN',