Repository: pydicom/pydicom

Issue:
Revise the type annotation for pydicom.datadict.dictionary_has_tag()
**Describe the bug**

The documentation of [`pydicom.datadict.dictionary_has_tag()`](https://pydicom.github.io/pydicom/dev/reference/generated/pydicom.datadict.dictionary_has_tag.html#pydicom.datadict.dictionary_has_tag) suggests that a query using keywords (instead of a tag integer) would work:

```python
pydicom.datadict.dictionary_has_tag(tag: Union[int, str, Tuple[int, int], pydicom.tag.BaseTag]) -> bool
```

However, the function only accepts integer arguments.

```python
from pydicom.datadict import dictionary_has_tag, keyword_dict
dictionary_has_tag("PixelData")
# Returns False

dictionary_has_tag(keyword_dict["PixelData"])
# Returns True
```

(The problem may apply to other functions as well...)

**Expected behavior**
Following the docs, `dictionary_has_tag("PixelData")` should return True. 

It would be nice, if the flexible conversion of tags from names or hex-tuples (as the type annotation suggests) would also be possible for this function.

**Your environment**
```text
module       | version
------       | -------
platform     | macOS-10.14.6-x86_64-i386-64bit
Python       | 3.9.0 (v3.9.0:9cf6752276, Oct  5 2020, 11:29:23)  [Clang 6.0 (clang-600.0.57)]
pydicom      | 2.2.2
gdcm         | _module not found_
jpeg_ls      | _module not found_
numpy        | 1.20.1
PIL          | 8.0.1
pylibjpeg    | _module not found_
openjpeg     | _module not found_
libjpeg      | _module not found_
```



Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) Report
> Merging [#1562](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) (c05ddb7) into [master](https://codecov.io/gh/pydicom/pydicom/commit/1447dd5f91768cf28d29ee28f0b978678805c97b?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) (1447dd5) will **decrease** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/pydicom/pydicom/pull/1562/graphs/tree.svg?width=650&height=150&src=pr&token=YciLV15Lwr&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom)](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom)

```diff
@@            Coverage Diff             @@
##           master    #1562      +/-   ##
==========================================
- Coverage   97.42%   97.42%   -0.01%     
==========================================
  Files          66       66              
  Lines       10185    10183       -2     
==========================================
- Hits         9923     9921       -2     
  Misses        262      262              
```


| [Impacted Files](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) | Coverage Δ | |
|---|---|---|
| [pydicom/datadict.py](https://codecov.io/gh/pydicom/pydicom/pull/1562/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9kYXRhZGljdC5weQ==) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom). Last update [1447dd5...c05ddb7](https://codecov.io/gh/pydicom/pydicom/pull/1562?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom).

scaramallion: Yeah, I'll change it now
pep8speaks: Hello @scaramallion! Thanks for updating this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:

* In the file [`pydicom/datadict.py`](https://github.com/pydicom/pydicom/blob/3a5f1ddeeb6b92538c4106c6446858ecea974f06/pydicom/datadict.py):

> [Line 427:5](https://github.com/pydicom/pydicom/blob/3a5f1ddeeb6b92538c4106c6446858ecea974f06/pydicom/datadict.py#L427): [E722](https://duckduckgo.com/?q=pep8%20E722) do not use bare 'except'





Patch:
diff --git a/pydicom/datadict.py b/pydicom/datadict.py
index 99201be13..0457ed91a 100644
--- a/pydicom/datadict.py
+++ b/pydicom/datadict.py
@@ -249,9 +249,10 @@ def get_entry(tag: TagType) -> Tuple[str, str, str, str, str]:
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose entry is to be retrieved. Only entries
-        in the official DICOM dictionary will be checked, not entries in the
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose entry is to be retrieved, in any of the
+        forms accepted by :func:`~pydicom.tag.Tag`. Only entries in the
+        official DICOM dictionary will be checked, not entries in the
         private dictionary.
 
     Returns
@@ -292,8 +293,9 @@ def dictionary_is_retired(tag: TagType) -> bool:
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose retirement status is being checked.
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose retirement status is being checked, in
+        any of the forms accepted by :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -306,9 +308,7 @@ def dictionary_is_retired(tag: TagType) -> bool:
     KeyError
         If the tag is not present in the DICOM data dictionary.
     """
-    if 'retired' in get_entry(tag)[3].lower():
-        return True
-    return False
+    return 'retired' in get_entry(tag)[3].lower()
 
 
 def dictionary_VR(tag: TagType) -> str:
@@ -318,9 +318,9 @@ def dictionary_VR(tag: TagType) -> str:
 
     Parameters
     ----------
-    tag : int
+    tag : int or str or Tuple[int, int]
         The tag for the element whose value representation (VR) is being
-        retrieved.
+        retrieved, in any of the forms accepted by :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -342,9 +342,9 @@ def dictionary_VM(tag: TagType) -> str:
 
     Parameters
     ----------
-    tag : int
+    tag : int or str or Tuple[int, int]
         The tag for the element whose value multiplicity (VM) is being
-        retrieved.
+        retrieved, in any of the forms accepted by :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -366,8 +366,9 @@ def dictionary_description(tag: TagType) -> str:
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose description is being retrieved.
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose description is being retrieved, in any
+        of the forms accepted by :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -389,8 +390,9 @@ def dictionary_keyword(tag: TagType) -> str:
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose keyword is being retrieved.
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose keyword is being retrieved, in any of
+        the forms accepted by :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -410,8 +412,9 @@ def dictionary_has_tag(tag: TagType) -> bool:
 
     Parameters
     ----------
-    tag : int
-        The tag to check.
+    tag : int or str or Tuple[int, int]
+        The tag to check, in any of the forms accepted by
+        :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -419,7 +422,10 @@ def dictionary_has_tag(tag: TagType) -> bool:
         ``True`` if the tag corresponds to an element present in the official
         DICOM data dictionary, ``False`` otherwise.
     """
-    return (tag in DicomDictionary)
+    try:
+        return Tag(tag) in DicomDictionary
+    except Exception:
+        return False
 
 
 def keyword_for_tag(tag: TagType) -> str:
@@ -427,8 +433,9 @@ def keyword_for_tag(tag: TagType) -> str:
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose keyword is being retrieved.
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose keyword is being retrieved, in any of
+        the forms accepted by :func:`~pydicom.tag.Tag`.
 
     Returns
     -------
@@ -514,9 +521,10 @@ def get_private_entry(
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose entry is to be retrieved. Only entries
-        in the private dictionary will be checked.
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose entry is to be retrieved, in any of the
+        forms accepted by :func:`~pydicom.tag.Tag`. Only entries in the
+        private dictionary will be checked.
     private_creator : str
         The name of the private creator.
 
@@ -574,9 +582,9 @@ def private_dictionary_VR(tag: TagType, private_creator: str) -> str:
 
     Parameters
     ----------
-    tag : int
+    tag : int or str or Tuple[int, int]
         The tag for the element whose value representation (VR) is being
-        retrieved.
+        retrieved, in any of the forms accepted by :func:`~pydicom.tag.Tag`.
     private_creator : str
         The name of the private creator.
 
@@ -598,9 +606,9 @@ def private_dictionary_VM(tag: TagType, private_creator: str) -> str:
 
     Parameters
     ----------
-    tag : int
+    tag : int or str or Tuple[int, int]
         The tag for the element whose value multiplicity (VM) is being
-        retrieved.
+        retrieved, in any of the forms accepted by :func:`~pydicom.tag.Tag`.
     private_creator : str
         The name of the private creator.
 
@@ -622,8 +630,9 @@ def private_dictionary_description(tag: TagType, private_creator: str) -> str:
 
     Parameters
     ----------
-    tag : int
-        The tag for the element whose description is being retrieved.
+    tag : int or str or Tuple[int, int]
+        The tag for the element whose description is being retrieved, in any
+        of the forms accepted by :func:`~pydicom.tag.Tag`.
     private_creator : str
         The name of the private createor.
 


Test patch:
diff --git a/pydicom/tests/test_dictionary.py b/pydicom/tests/test_dictionary.py
index 30af2de7e..77b6bb36b 100644
--- a/pydicom/tests/test_dictionary.py
+++ b/pydicom/tests/test_dictionary.py
@@ -30,6 +30,8 @@ class TestDict:
         """Test dictionary_has_tag"""
         assert dictionary_has_tag(0x00100010)
         assert not dictionary_has_tag(0x11110010)
+        assert dictionary_has_tag("PatientName")
+        assert not dictionary_has_tag("PatientMane")
 
     def test_repeater_has_tag(self):
         """Test repeater_has_tag"""