o
    iև                  	   @   s  d Z ddlZddlmZmZ ddlZddlmZ ddlZddl	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZ dd	lmZ dd
lmZmZ ddlmZ ddl m!Z! ddl"m#Z#m$Z$m%Z% ddl&m'Z' ddlm(Z( ddl)m*Z*m+Z+m,Z, ddl-Zddl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z7m8Z8 ej9rddl:Z:erddl;m<Z< 	d+de=dB de>de?e@e= B e=B dB e/B fddZAG dd dZBG dd deZCddddeCde=ee= B dB dd deBfd!d"ZD		d,d#eCde=ee= B dB d$d deBfd%d&ZEd'eEiZFd(e=de
fd)d*ZGdS )-zDefine the DataElement class.

A DataElement has a tag,
              a value representation (VR),
              a value multiplicity (VM)
              and a value.
    N)CallableMutableSequence)BufferedIOBase)AnyTYPE_CHECKING
NamedTuple)config)logger)dictionary_has_tagdictionary_descriptiondictionary_keyworddictionary_is_retiredprivate_dictionary_descriptiondictionary_VRrepeater_has_tag)hooks)JsonDataElementConverterBulkDataType)warn_and_log)
MultiValue)TagBaseTag_LUT_DESCRIPTOR_TAGS)UID)jsonrep)check_bufferbuffer_lengthbuffer_equality)
BUFFERABLE_VRS
PersonNameBYTES_VRAMBIGUOUS_VRSTR_VRALLOW_BACKSLASHDEFAULT_CHARSET_VRLONG_VALUE_VRVRvalidate_value)DatasetFr&   rawreturnc                 C   s^   | t jkr|r	dS g S tjrdS | t jkr|rdS tdS | tt jt jh v r-|r+dS dS dS )a  Return the value for an empty element for `VR`.

    The behavior of this property depends on the setting of
    :attr:`config.use_none_as_empty_value`. If that is set to ``True``,
    an empty value is represented by ``None`` (except for VR 'SQ'), otherwise
    it depends on `VR`. For text VRs (this includes 'AE', 'AS', 'CS', 'DA',
    'DT', 'LO', 'LT', 'PN', 'SH', 'ST', 'TM', 'UC', 'UI', 'UR' and 'UT') an
    empty string is used as empty value representation, for all other VRs
    except 'SQ', ``None``. For empty sequence values (VR 'SQ') an empty list
    is used in all cases.
    Note that this is used only if decoding the element - it is always
    possible to set the value to another empty value representation,
    which will be preserved during the element object lifetime.

    Parameters
    ----------
    VR : str or None
        The VR of the corresponding element.
    raw : bool, optional
        If ``True``, returns the value for a :class:`RawDataElement`,
        otherwise for a :class:`DataElement`

    Returns
    -------
    str or bytes or None or list
        The value a data element with `VR` is assigned on decoding
        if it is empty.
        N )	VR_SQr   use_none_as_empty_text_VR_valuePNr   r"   DSIS)r&   r)    r3   F/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/pydicom/dataelem.pyempty_value_for_VR9   s   

r5   c                   @   s  e Zd ZdZdZdZdZdZ				dNdee	B e
eef B de	d	ed
edB dedededB ddfddZd	eddfddZe	dOded  ded de	de	d	ede	dB dee	e	e	gef ee	gef B dB dd fddZded ge	f dB dedee	ef fddZ			dPdeded ge	f dB d eee	ef ge	f dB de	fd!d"Zedefd#d$Zejd%eddfd&d$Zedefd'd(Zedefd)d*Zedefd+d,Zedeee	 B dB e	B eB fd-d.Z dQd/d0Z!d%edefd1d2Z"d%edefd3d4Z#d5eeef dd fd6d7Z$d8edefd9d:Z%d8edefd;d<Z&de	fd=d>Z'ede	fd?d@Z(dAedefdBdCZ)ede	fdDdEZ*edefdFdGZ+edefdHdIZ,ede	fdJdKZ-de	fdLdMZ.dS )RDataElementa8  Contain and manipulate a DICOM Element.

    Examples
    --------

    While its possible to create a new :class:`DataElement` directly and add
    it to a :class:`~pydicom.dataset.Dataset`:

    >>> from pydicom import Dataset
    >>> elem = DataElement(0x00100010, 'PN', 'CITIZEN^Joan')
    >>> ds = Dataset()
    >>> ds.add(elem)

    Its far more convenient to use a :class:`~pydicom.dataset.Dataset`
    to add a new :class:`DataElement`, as the VR and tag are determined
    automatically from the DICOM dictionary:

    >>> ds = Dataset()
    >>> ds.PatientName = 'CITIZEN^Joan'

    Empty DataElement objects (e.g. with VM = 0) show an empty string as
    value for text VRs and `None` for non-text (binary) VRs:

    >>> ds = Dataset()
    >>> ds.PatientName = None
    >>> ds.PatientName
    ''

    >>> ds.BitsAllocated = None
    >>> ds.BitsAllocated

    >>> str(ds.BitsAllocated)
    'None'

    Attributes
    ----------
    descripWidth : int
        For string display, this is the maximum width of the description
        field (default ``35``).
    is_undefined_length : bool
        Indicates whether the length field for the element was ``0xFFFFFFFFL``
        (ie undefined).
    maxBytesToDisplay : int
        For string display, elements with values containing data which is
        longer than this value will display ``"array of # bytes"``
        (default ``16``).
    showVR : bool
        For string display, include the element's VR just before it's value
        (default ``True``).
    tag : pydicom.tag.BaseTag
        The element's tag.
    validation_mode : int
        The mode used to validate the element's value. See
        :attr:`Settings.writing_validation_mode
        <pydicom.config.Settings.writing_validation_mode>` for more information.
    VR : str
        The element's Value Representation.
    #      TFNtagr&   valuefile_value_tellis_undefined_lengthalready_convertedvalidation_moder*   c                 C   s   |du rt jj}t|tst|}|| _|tjkr;|j	s;t j
r;|s+|du s+t|dk r;zt|}W n	 ty:   Y nw || _|| _|rG|| _n|| _|| _|| _d| _dS )a  Create a new :class:`DataElement`.

        Parameters
        ----------
        tag : int | str | tuple[int, int]
            The DICOM (group, element) tag in any form accepted by
            :func:`~pydicom.tag.Tag` such as ``'PatientName'``,
            ``(0x10, 0x10)``, ``0x00100010``, etc.
        VR : str
            The 2 character DICOM value representation (see DICOM Standard,
            Part 5, :dcm:`Section 6.2<part05/sect_6.2.html>`).
        value : Any
            The value of the data element, the :doc:`allowed type depends on the VR
            </guides/element_value_types>` and includes:

            * a single :class:`str` value
            * an :class:`int` or :class:`int`
            * a :class:`list` or :class:`tuple` containing only a single type of item
              such as :class:`str`, :class:`int` or :class:`float`
            * a raw :class:`bytes` value
        file_value_tell : int, optional
            The byte offset to the start of the encoded element value.
        is_undefined_length : bool, optional
            Used internally to store whether the length field for this element
            was ``0xFFFFFFFF``, i.e. 'undefined length'. Default is ``False``.
        already_converted : bool, optional
            Used to determine whether or not the element's value requires
            conversion to a value with VM > 1. Default is ``False``.
        validation_mode : int, optional
            Defines if values are validated and how validation errors are
            handled.
        Ni  )r   settingsreading_validation_mode
isinstancer   r   r9   r-   UN
is_privatereplace_un_with_known_vrlenr   KeyErrorr&   r>   _valuer:   	file_tellr<   private_creator)selfr9   r&   r:   r;   r<   r=   r>   r3   r3   r4   __init__   s4   *


zDataElement.__init__c                 C   s   t | j|| j dS )zValidate the current value against the DICOM standard.
        See :func:`~pydicom.valuerep.validate_value` for details.
        N)r'   r&   r>   )rJ   r:   r3   r3   r4   validate   s   zDataElement.validateclsdataset_classr(   vr	value_keybulk_data_uri_handlerc              
   C   s   t ||||||}| }|tjkr-tjr-t|tr-tt	||t
||ddd}	t|	j}z| |||dW S  tyL }
 ztd| d| |
d}
~
ww )as  Return a :class:`DataElement` from a DICOM JSON Model attribute
        object.

        Parameters
        ----------
        dataset_class : dataset.Dataset derived class
            The class object to use for **SQ** element items.
        tag : str
            The data element's tag as uppercase hex.
        vr : str
            The data element's value representation (VR).
        value : str or list[None | str | int | float | bytes | dict]
            The data element's value(s).
        value_key : str or None
            The attribute name for `value`, should be one of:
            ``{"Value", "InlineBinary", "BulkDataURI"}``. If the element's VM
            is ``0`` and none of the keys are used then will be ``None``.
        bulk_data_uri_handler: callable or None
            Callable function that accepts either the `tag`, `vr` and
            "BulkDataURI" `value` or just the "BulkDataURI" `value` of the JSON
            representation of a data element and returns the actual value of
            that data element (retrieved via DICOMweb WADO-RS). If no
            `bulk_data_uri_handler` is specified (default) then the
            corresponding element will have an "empty" value such as
            ``""``, ``b""`` or ``None`` depending on the `vr` (i.e. the
            Value Multiplicity will be 0).

        Returns
        -------
        DataElement
        r   T)r9   r:   r&   zData element 'z!' could not be loaded from JSON: N)r   get_element_valuesr-   rB   r   rD   rA   bytesRawDataElementr   rE   convert_raw_data_elementr:   	Exception
ValueError)rM   rN   r9   rO   r:   rP   rQ   	converter
elem_valuer)   excr3   r3   r4   	from_json   s.   .

zDataElement.from_jsonbulk_data_element_handlerbulk_data_thresholdc           
         s  d| j i}| j ttB tjh v rB| jsA| j} dur+t|d d kr+ | |d< nt	|
d}td| j d ||d	< n| j tjkrX fd
d| jD }||d< n| j tjkr| jsg }| jdkrl| j}n| jg}|D ]*}d|jd i}	t|jdkr|jd |	d< t|jdkr|jd |	d< ||	 qr||d< n7| j tjkr| js| j}| jdkr|g}dd |D |d< n| js| jdkr| j}n| jg}dd |D |d< d|v rt|d | j |d< |S )a  Return a dictionary representation of the :class:`DataElement`
        conforming to the DICOM JSON Model as described in the DICOM
        Standard, Part 18, :dcm:`Annex F<part18/chaptr_F.html>`.

        Parameters
        ----------
        bulk_data_element_handler : callable or None
            Callable that accepts a bulk :class`data element
            <pydicom.dataelem.DataElement>` and returns the
            "BulkDataURI" as a :class:`str` for retrieving the value of the
            data element via DICOMweb WADO-RS.
        bulk_data_threshold : int
            Size of base64 encoded data element above which a value will be
            provided in form of a "BulkDataURI" rather than "InlineBinary".
            Ignored if no `bulk_data_element_handler` is given.

        Returns
        -------
        dict
            Mapping representing a JSON encoded data element as ``{str: Any}``.
        rO   N      BulkDataURIzutf-8zencode bulk data element 'z' inlineInlineBinaryc                    s    g | ]}|j  d d dqS )c                 S      | S Nr3   dr3   r3   r4   <lambda>l  s    z5DataElement.to_json_dict.<locals>.<listcomp>.<lambda>)r\   r]   dump_handler)to_json).0dsr\   r]   r3   r4   
<listcomp>h  s    z,DataElement.to_json_dict.<locals>.<listcomp>Value   
Alphabeticr   Ideographic   Phoneticc                 S   s   g | ]}t |d qS )08X)formatri   vr3   r3   r4   rl     s    c                 S   s   g | ]}|qS r3   r3   ru   r3   r3   r4   rl     s    )r&   r    r!   r-   US_SSis_emptyr:   rE   base64	b64encodedecoder	   infonamer.   r0   VM
componentsappendATr   convert_to_python_number)
rJ   r\   r]   json_elementbinary_valueencoded_valuer:   rY   rv   compsr3   rk   r4   to_json_dict>  sb   






zDataElement.to_json_dict   rg   c                 C   s:   dt ttf dtfdd}|du r|n|}|| ||S )a(  Return a JSON representation of the :class:`DataElement`.

        Parameters
        ----------
        bulk_data_threshold : int, optional
            Size of base64 encoded data element above which a value will be
            provided in form of a "BulkDataURI" rather than "InlineBinary".
            Ignored if no `bulk_data_element_handler` is given.
        bulk_data_element_handler : callable, optional
            Callable that accepts a bulk :class`data element
            <pydicom.dataelem.DataElement>` and returns the
            "BulkDataURI" as a :class:`str` for retrieving the value of the
            data element via DICOMweb WADO-RS.
        dump_handler : callable, optional
            Callable function that accepts a :class:`dict` of ``{str: Any}``
            and returns the serialized (dumped) JSON :class:`str` (by default
            uses :func:`json.dumps`).

        Returns
        -------
        str
            Mapping representing a JSON encoded data element

        See also
        --------
        Dataset.to_json
        re   r*   c                 S   s   t j| ddS )NT)	sort_keys)jsondumpsrd   r3   r3   r4   	json_dump  s   z&DataElement.to_json.<locals>.json_dumpN)dictstrr   r   )rJ   r]   r\   rg   r   r3   r3   r4   rh     s
   "
zDataElement.to_jsonc                 C   s   | j S )a  Get or set the element's value.

        Parameters
        ----------
        val : Any
            The value to use to set the element's value, should be an :doc:`appropriate
            type for the VR</guides/element_value_types>`. The value will be validated
            in accordance with the element's :attr:`~DataElement.validation_mode`.

        Returns
        -------
        Any
            The element's value.
        )rG   rJ   r3   r3   r4   r:     s   zDataElement.valuevalc              
   C   s   t |trJ| jtvr!tdd tD }td| j dd| zt| W n tyD } zt	|d| j
 d| j d| d }~ww || _d S | jtvrpt |tr`d	|v r]|d	n|}nt |trpd
|v rn|d
n|}| || _d S )Nc                 s   s     | ]}d |vrt |V  qdS )orNr   )ri   rO   r3   r3   r4   	<genexpr>  s    z$DataElement.value.<locals>.<genexpr>zElements with a VR of 'z:' cannot be used with buffered values, supported VRs are: z, Invalid buffer for  '': \   \)rA   r   r&   r   sortedrW   joinr   rV   typer9   r}   rG   r#   r   splitrS   _convert_value)rJ   r   	supportedrZ   r3   r3   r4   r:     s,   


"


c              
   C   s   | j tjkrdS | jdu rdS t| jttB tB r | jrdS dS t| jtrOzt	| jr/dW S dW S  t
yN } zt|d| j d| j d| d}~ww zt| j W n
 ty`   Y dS w t| jS )zReturn the value multiplicity of the element as :class:`int`.

        .. versionchanged:: 3.0

            **SQ** elements now always return a VM of ``1``.
        rn   Nr   r   r   r   )r&   r-   r.   r:   rA   r   rS   r   r   r   rV   r   r9   r}   iter	TypeErrorrE   )rJ   rZ   r3   r3   r4   r~     s&   
"
zDataElement.VMc                 C   s   t | jtS )zvReturn ``True`` if the element's value is a :class:`io.BufferedIOBase`
        instance, ``False`` otherwise.
        )rA   rG   r   r   r3   r3   r4   is_buffered     zDataElement.is_bufferedc                 C   s"   | j tjkrt| j S | jdkS )z,Return ``True`` if the element has no value.r   )r&   r-   r.   boolr:   r~   r   r3   r3   r4   rx     s   
zDataElement.is_emptyc                 C   s
   t | jS )zReturn the value for an empty element.

        See :func:`empty_value_for_VR` for more information.

        Returns
        -------
        str or None
            The value this data element is assigned on decoding if it is empty.
        )r5   r&   r   r3   r3   r4   empty_value   s   
zDataElement.empty_valuec                 C   s   | j | _dS )zoClears the value, e.g. sets it to the configured empty value.

        See :func:`empty_value_for_VR`.
        N)r   rG   r   r3   r3   r4   clear-  r   zDataElement.clearc                 C   s   | j dkrtjrt|tjrtd| jtj	kr)ddl
m} t||r%|S ||S t|ds3| |S t|dkr@| |d S | j tv rp|rpdtdtfd	d
}ttj|d | j |dd D ]
}t| j|| j q`t||S t| j|S )zConvert `val` to an appropriate type and return the result.

        Uses the element's VR in order to determine the conversion method and
        resulting type.
        i zThe value for (7FE0,0010) 'Pixel Data' should be set using 'bytes' not 'numpy.ndarray'. See the Dataset.set_pixel_data() method for an alternative that supports ndarrays.r   )Sequencer   rn   r   r*   c                 S   rb   rc   r3   )r   r3   r3   r4   _skip_conversionY  s   z4DataElement._convert_value.<locals>._skip_conversionN)r9   r   
have_numpyrA   numpyndarrayr   r&   r-   r.   pydicom.sequencer   hasattr_convertrE   r   r   r'   USr>   r   )rJ   r   r   r   r:   r3   r3   r4   r   4  s0   





zDataElement._convert_valuec                 C   s<  | j tv rt|tr| }| j tjkrtj|| j	S | j tj
kr.tjr.tjj
|| j	dS | j tjkr=tj|d| j	S | j tjkrOtjrOtjj|| j	dS | j tjkratjratjj|| j	dS | j tjkrs|durqt|| j	S dS | j tjkrt|| j	dS | j tjkr|dks|rt|tr|S t|S | | |S )z:Convert `val` to an appropriate type for the element's VR.)r>   FNr   )r&   r$   rA   rS   r{   r-   r2   pydicomvaluerepr>   DAr   datetime_conversionr1   DTTMUIr   r0   r   r   r   r   rL   )rJ   r   r3   r3   r4   r   d  s(   
zDataElement._convertmemoc                 C   s   | j }||}||t| < | j D ]?\}}| jrH|dkrHzt||t|| W q t	yG } zt
|d| j d| j d| d}~ww t||t|| q|S )z"Implementation of copy.deepcopy().rG   z'Error deepcopying the buffered element r   r   N)	__class____new__id__dict__itemsr   setattrcopydeepcopyrV   r   r9   r}   )rJ   r   rM   resultkrv   rZ   r3   r3   r4   __deepcopy__  s&   

zDataElement.__deepcopy__otherc              
   C   s   || u rdS t || jrs| j|jks| j|jkrdS tjr6t | jtjr6t	| jt	|jko5t
| j|jS | jsB|jsB| j|jkS z| jrNt| j|jW S t|j| jW S  tyr } zt|d| j d| j d| d}~ww tS )ae  Compare `self` and `other` for equality.

        Returns
        -------
        bool
            The result if `self` and `other` are the same class
        NotImplemented
            If `other` is not the same class as `self` then returning
            :class:`NotImplemented` delegates the result to
            ``superclass.__eq__(subclass)``.
        TFr   r   r   N)rA   r   r9   r&   r   r   r:   r   r   rE   allcloser   r   rV   r   r}   NotImplemented)rJ   r   rZ   r3   r3   r4   __eq__  s(   "zDataElement.__eq__c                 C   s
   | |k S )z*Compare `self` and `other` for inequality.r3   )rJ   r   r3   r3   r4   __ne__  s   
zDataElement.__ne__c                 C   s`   | j pd}| jd| j d| j }| jr%| j d| d| j d| S | j d| d| S )z2Return :class:`str` representation of the element.r,   N< z: )repvalr}   descripWidthshowVRr9   r&   )rJ   r:   r}   r3   r3   r4   __str__  s
   
zDataElement.__str__c                 C   s   | j rt| jS | jtv r)zt| j}W n	 ty   Y nw || jkr)d| dS | j| jkr6d| j dS t	| jt
r@| jjS t| jS )z<Return a :class:`str` representation of the element's value.z	Array of z	 elements)r   reprr:   r&   r%   rE   r   maxBytesToDisplayr~   rA   r   r}   )rJ   lengthr3   r3   r4   r     s   



zDataElement.repvalkeyc                 C   s$   z| j | W S  ty   tdw )z=Return the item at `key` if the element's value is indexable.z2DataElement value is unscriptable (not a Sequence))r:   r   )rJ   r   r3   r3   r4   __getitem__  s
   zDataElement.__getitem__c                 C   s   | j jr,| jr zt| j | j}d| dW S  ty   Y dS w | j jd? dkr*dS dS t| j s6t| j r;t| j S | j jdkrCdS dS )	a&  Return the DICOM dictionary name for the element as :class:`str`.

        Returns
        -------
        str
            * For officially registered DICOM Data Elements this will be the
              *Name* as given in
              :dcm:`Table 6-1<part06/chapter_6.html#table_6-1>`.
            * For private elements known to *pydicom* this will be the *Name*
              in the format ``'[name]'``.
            * For unknown private elements this will be ``'Private tag data'``.
            * Otherwise returns an empty string ``''``.
        []   r   zPrivate CreatorzPrivate tag datazGroup Lengthr,   )	r9   rC   rI   r   rF   elementr
   r   r   )rJ   r}   r3   r3   r4   r}     s&   
zDataElement.namec                 C   s   | j jS )zXReturn ``True`` if the element's tag is private.

        .. versionadded:: 2.1
        )r9   rC   r   r3   r3   r4   rC     s   zDataElement.is_privatec                 C      t | jr
t| jS dS )a\  Return the element's retired status as :class:`bool`.

        For officially registered DICOM Data Elements this will be ``True`` if
        the retired status as given in the DICOM Standard, Part 6,
        :dcm:`Table 6-1<part06/chapter_6.html#table_6-1>` is 'RET'. For private
        or unknown elements this will always be ``False``.
        F)r
   r9   r   r   r3   r3   r4   
is_retired#     
	
zDataElement.is_retiredc                 C   r   )a3  Return the element's keyword (if known) as :class:`str`.

        For officially registered DICOM Data Elements this will be the
        *Keyword* as given in
        :dcm:`Table 6-1<part06/chapter_6.html#table_6-1>`. For private or
        unknown elements this will return an empty string ``''``.
        r,   )r
   r9   r   r   r3   r3   r4   keyword1  r   zDataElement.keywordc                 C   s   t | S )z)Return the representation of the element.r   r   r3   r3   r4   __repr__?  s   zDataElement.__repr__)NFFNrc   )r   NN)r*   N)/__name__
__module____qualname____doc__r   r   r   is_rawintr   tupler   r   rK   rL   classmethodr   r   r   r[   r   r   rh   propertyr:   setterr~   r   rx   rS   listr   r   r   r   r   r   r   r   r   r   r   r}   rC   r   r   r   r3   r3   r3   r4   r6   h   s    ;	
KC

W
+"$
0")
(r6   c                   @   sj   e Zd ZU dZeed< edB ed< eed< edB ed< eed< e	ed< e	ed	< d
Z
e	ed< dZe	ed< dS )rT   z=Container for the data from a raw (mostly) undecoded element.r9   Nr&   r   r:   
value_tellis_implicit_VRis_little_endianTr   Fr   )r   r   r   r   r   __annotations__r   r   rS   r   r   r   r3   r3   r3   r4   rT   D  s   
 rT   encodingrj   r   rj   zDataset | Nonec                C   s   i }t jrt j| fi t j} tjr/tj| |f||dtj tj| |f||dtj ntj| |||d tj| |||d t| j|d |d | j	| j
dkddS )a  Return a :class:`DataElement` created from `raw`.

    .. versionadded:: 3.0

    **Customization Hooks**

    All callback functions for :func:`convert_raw_data_element`
    use the function signature::

        def func(
            raw: RawDataElement,
            data: dict[str, Any],
            *,
            encoding: str | MutableSequence[str] | None = None,
            ds: pydicom.dataset.Dataset | None = None,
            **kwargs: dict[str, Any],
        ) -> None:
            ...

    Where `raw`, `encoding` and `ds` are the objects passed to this function,
    `data` is a :class:`dict` that's persistent for each raw element and is used
    to store the results of the corresponding callback functions, and `kwargs`
    are keyword arguments passed by setting the ``"raw_element_kwargs"`` hook
    via :meth:`~pydicom.hooks.Hooks.register_kwargs`.

    Available :class:`hooks<pydicom.hooks.Hooks>` are (in order of execution):

    * ``"raw_element_vr"``: a function to perform the VR lookup for the raw element,
      required to add ``{"VR": str}`` to `data`.
    * ``"raw_element_value"``: a function to perform the conversion of the raw element
      :class:`bytes` value to an appropriate type (such as :class:`int` for VR
      **US**), required to add ``{"value": Any}`` to `data`.

    :meth:`~pydicom.hooks.Hooks.register_callback` is used to set the callback
    function for a given hook, and only one callback can be set per hook.

    Parameters
    ----------
    raw : pydicom.dataelem.RawDataElement
        The raw data to convert to a :class:`DataElement`.
    encoding : str | MutableSequence[str] | None
        The character set encodings for the raw data element.
    ds : pydicom.dataset.Dataset | None
        The parent dataset of `raw`.

    Returns
    -------
    pydicom.dataelem.DataElement
        A :class:`~pydicom.dataelem.DataElement` instance created from `raw`.
    r   r&   r:   l    T)r=   )r   data_element_callbackdata_element_callback_kwargsr   raw_element_kwargsraw_element_vrraw_element_valuer6   r9   r   r   )r)   r   rj   datar3   r3   r4   rU   R  s8   8rU   raw_data_elementdatasetc                 C   s   d}t |t t| ||dS )a.  Return a :class:`DataElement` created from `raw_data_element`.

    .. deprecated:: 3.0

        ``DataElement_from_raw`` will be removed in v4.0, use
        :func:`~pydicom.dataelem.convert_raw_data_element` instead.

    Call the configured data_element_callbacks to do relevant
    pre/post-processing and convert values from raw to native types

    Parameters
    ----------
    raw_data_element : pydicom.dataelem.RawDataElement
        The raw data to convert to a :class:`DataElement`.
    encoding : str | list[str] | None
        The character encoding of the raw data.
    dataset : pydicom.dataset.Dataset | None
        If given, used to resolve the VR for known private tags.

    Returns
    -------
    DataElement
        A :class:`~pydicom.dataelem.DataElement` instance created from `raw`.
    z'pydicom.dataelem.DataElement_from_raw' is deprecated and will be removed in v4.0, please use 'pydicom.dataelem.convert_raw_data_element' instead)r)   r   rj   )r   DeprecationWarningrU   )r   r   r   msgr3   r3   r4   _DataElement_from_raw  s   
r   DataElement_from_rawr}   c                 C   s*   | t v rtjst |  S tdtd| )Nzmodule z has no attribute )_DEPRECATEDr   _use_futureAttributeErrorr   )r}   r3   r3   r4   __getattr__  s   r   )F)NN)Hr   ry   collections.abcr   r   r   ior   r   typingr   r   r   r   r   pydicom.configr	   pydicom.datadictr
   r   r   r   r   r   r   pydicom.hooksr   pydicom.jsonrepr   r   pydicom.miscr   pydicom.multivalr   pydicom.tagr   r   r   pydicom.uidr   r   pydicom.fileutilr   r   r   pydicom.valuerepr   r   r    r!   r"   r#   r$   r%   r&   r-   r'   r   r   pydicom.datasetr(   r   r   rS   r   r5   r6   rT   rU   r   r   r   r3   r3   r3   r4   <module>   s   $	0
/     a
T
+