Repository: pydicom/pydicom

Issue:
"bytes" representation for AE fields not supported
#### Description
Fields with VR of AE in datasets, should support getting a `bytes` object. Perhaps, this should be even the default representation thereof, as they truly support only ASCII and not real strings.
Instead, when attempting to serialize a dataset with a `bytes` value, an error is raised.

#### Steps/Code to Reproduce
```
ds = Dataset()
ds.StationAETitle = b"abc"
ds.is_implicit_VR = True
ds.is_little_endian = True
write_file("/tmp/a.dcm", ds)
```

#### Versions
python 3.6.4
pydicom 1.0.1

Discussion:
pep8speaks: Hello @mrbean-bremen! Thanks for submitting the PR.

 - In the file [`pydicom/dataelem.py`](https://github.com/pydicom/pydicom/blob/716b8687b557d5bb165a8178dadd01201a39e55d/pydicom/dataelem.py), following are the PEP8 issues :

> [Line 203:17](https://github.com/pydicom/pydicom/blob/716b8687b557d5bb165a8178dadd01201a39e55d/pydicom/dataelem.py#L203): [E128](https://duckduckgo.com/?q=pep8%20E128) continuation line under-indented for visual indent
> [Line 242:80](https://github.com/pydicom/pydicom/blob/716b8687b557d5bb165a8178dadd01201a39e55d/pydicom/dataelem.py#L242): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (80 > 79 characters)

 - In the file [`pydicom/tests/test_filewriter.py`](https://github.com/pydicom/pydicom/blob/716b8687b557d5bb165a8178dadd01201a39e55d/pydicom/tests/test_filewriter.py), following are the PEP8 issues :

> [Line 367:80](https://github.com/pydicom/pydicom/blob/716b8687b557d5bb165a8178dadd01201a39e55d/pydicom/tests/test_filewriter.py#L367): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (84 > 79 characters)
> [Line 369:80](https://github.com/pydicom/pydicom/blob/716b8687b557d5bb165a8178dadd01201a39e55d/pydicom/tests/test_filewriter.py#L369): [E501](https://duckduckgo.com/?q=pep8%20E501) line too long (84 > 79 characters)



Patch:
diff --git a/doc/release-notes.rst b/doc/release-notes.rst
index 8d8889dc6..a9b32d0bb 100644
--- a/doc/release-notes.rst
+++ b/doc/release-notes.rst
@@ -4,6 +4,8 @@
 Release history
 ===============
 
+.. include:: whatsnew/v1.2.0.rst
+
 .. include:: whatsnew/v1.1.0.rst
 
 .. include:: whatsnew/v1.0.0.rst
diff --git a/doc/whatsnew/v1.2.0.rst b/doc/whatsnew/v1.2.0.rst
index 40f6b0a47..9ea652663 100644
--- a/doc/whatsnew/v1.2.0.rst
+++ b/doc/whatsnew/v1.2.0.rst
@@ -4,9 +4,17 @@ Version 1.2.0
 Changelog
 ---------
 
+
+Enhancements
+............
+
+* Added possibility to set byte strings as value for VRs that use only the
+  default character set (:issue:`624`)
+
 * ``DeferredDataElement`` class deprecated and will be removed in v1.3
   (:issue:`291`)
 
+
 Fixes
 .....
 
diff --git a/pydicom/dataelem.py b/pydicom/dataelem.py
index 1c4e8e4a9..c6b15e4b1 100644
--- a/pydicom/dataelem.py
+++ b/pydicom/dataelem.py
@@ -52,6 +52,11 @@ def isString(val):
     return isinstance(val, compat.string_types)
 
 
+def _is_bytes(val):
+    """Return True only in Python 3 if `val` is of type `bytes`."""
+    return False if in_py2 else isinstance(val, bytes)
+
+
 def isStringOrStringList(val):
     """Return True if `val` is a str or an iterable
        containing only strings."""
@@ -233,6 +238,14 @@ class DataElement(object):
 
     def _convert(self, val):
         """Convert `val` to an appropriate type for the element's VR."""
+
+        # If the value is a byte string and has a VR that can only be encoded
+        # using the default character repertoire, we convert it to a string
+        # here to allow for byte string input in these cases
+        if _is_bytes(val) and self.VR in (
+                'AE', 'AS', 'CS', 'DA', 'DS', 'DT', 'IS', 'TM', 'UI', 'UR'):
+            val = val.decode()
+
         if self.VR == 'IS':
             return pydicom.valuerep.IS(val)
         elif self.VR == 'DA' and config.datetime_conversion:


Test patch:
diff --git a/pydicom/tests/test_filewriter.py b/pydicom/tests/test_filewriter.py
index 4b943d651..6c0f11f82 100644
--- a/pydicom/tests/test_filewriter.py
+++ b/pydicom/tests/test_filewriter.py
@@ -316,7 +316,7 @@ class WriteDataElementTests(unittest.TestCase):
         self.check_data_element(data_elem, expected)
 
     def test_write_multi_DA(self):
-        data_elem = DataElement(0x0014407E, 'DA', ['20100101', '20101231'])
+        data_elem = DataElement(0x0014407E, 'DA', ['20100101', b'20101231'])
         expected = (b'\x14\x00\x7E\x40'  # tag
                     b'\x12\x00\x00\x00'  # length
                     b'20100101\\20101231 ')  # padded value
@@ -331,11 +331,13 @@ class WriteDataElementTests(unittest.TestCase):
                     b'\x06\x00\x00\x00'  # length
                     b'010203')  # padded value
         self.check_data_element(data_elem, expected)
+        data_elem = DataElement(0x00080030, 'TM', b'010203')
+        self.check_data_element(data_elem, expected)
         data_elem = DataElement(0x00080030, 'TM', time(1, 2, 3))
         self.check_data_element(data_elem, expected)
 
     def test_write_multi_TM(self):
-        data_elem = DataElement(0x0014407C, 'TM', ['082500', '092655'])
+        data_elem = DataElement(0x0014407C, 'TM', ['082500', b'092655'])
         expected = (b'\x14\x00\x7C\x40'  # tag
                     b'\x0E\x00\x00\x00'  # length
                     b'082500\\092655 ')  # padded value
@@ -350,21 +352,55 @@ class WriteDataElementTests(unittest.TestCase):
                     b'\x0E\x00\x00\x00'  # length
                     b'20170101120000')  # value
         self.check_data_element(data_elem, expected)
+        data_elem = DataElement(0x0008002A, 'DT', b'20170101120000')
+        self.check_data_element(data_elem, expected)
         data_elem = DataElement(0x0008002A, 'DT', datetime(2017, 1, 1, 12))
         self.check_data_element(data_elem, expected)
 
     def test_write_multi_DT(self):
         data_elem = DataElement(0x0040A13A, 'DT',
-                                ['20120820120804', '20130901111111'])
+                                ['20120820120804', b'20130901111111'])
         expected = (b'\x40\x00\x3A\xA1'  # tag
                     b'\x1E\x00\x00\x00'  # length
                     b'20120820120804\\20130901111111 ')  # padded value
         self.check_data_element(data_elem, expected)
+        data_elem = DataElement(
+            0x0040A13A, 'DT', u'20120820120804\\20130901111111')
+        self.check_data_element(data_elem, expected)
+        data_elem = DataElement(
+            0x0040A13A, 'DT', b'20120820120804\\20130901111111')
+        self.check_data_element(data_elem, expected)
+
         data_elem = DataElement(0x0040A13A, 'DT',
                                 [datetime(2012, 8, 20, 12, 8, 4),
                                  datetime(2013, 9, 1, 11, 11, 11)])
         self.check_data_element(data_elem, expected)
 
+    def test_write_ascii_vr_with_padding(self):
+        expected = (b'\x08\x00\x54\x00'  # tag
+                    b'\x0C\x00\x00\x00'  # length
+                    b'CONQUESTSRV ')  # padded value
+        data_elem = DataElement(0x00080054, 'AE', 'CONQUESTSRV')
+        self.check_data_element(data_elem, expected)
+        data_elem = DataElement(0x00080054, 'AE', b'CONQUESTSRV')
+        self.check_data_element(data_elem, expected)
+
+        expected = (b'\x08\x00\x62\x00'  # tag
+                    b'\x06\x00\x00\x00'  # length
+                    b'1.2.3\x00')  # padded value
+        data_elem = DataElement(0x00080062, 'UI', '1.2.3')
+        self.check_data_element(data_elem, expected)
+        data_elem = DataElement(0x00080062, 'UI', b'1.2.3')
+        self.check_data_element(data_elem, expected)
+
+        expected = (b'\x08\x00\x60\x00'  # tag
+                    b'\x04\x00\x00\x00'  # length
+                    b'REG ')
+        data_elem = DataElement(0x00080060, 'CS', 'REG')
+        self.check_data_element(data_elem, expected)
+        data_elem = DataElement(0x00080060, 'CS', b'REG')
+        self.check_data_element(data_elem, expected)
+
     def test_write_OD_implicit_little(self):
         """Test writing elements with VR of OD works correctly."""
         # VolumetricCurvePoints