U
    H4f                     @   s   d dl Zd dlZd dlmZmZmZ d dlmZ d dl	m
Z
mZmZmZ d dlmZmZmZ d dlmZ G dd de
Zded	d
dZdejejef dddZdejdddZdd Zdd Zdd ZdS )    N)urljoinurlparse
urlunparse)etree)Resolver	XMLParserXMLSyntaxError
fromstring)DTDForbiddenEntitiesForbiddenr   )Settingsc                   @   s    e Zd ZdZdd Zdd ZdS )ImportResolverz/Custom lxml resolve to use the transport objectc                 C   s
   || _ d S )N)	transport)selfr    r   //tmp/pip-unpacked-wheel-04z2hmy8/zeep/loader.py__init__   s    zImportResolver.__init__c                 C   s*   t |jdkr&| j|}| ||S d S )N)httphttps)r   schemer   loadZresolve_string)r   urlZpubidcontextcontentr   r   r   resolve   s    zImportResolver.resolveN)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s   r   r   c              
   C   s   |pt  }|j }tdd||jd}|jt| zzt| ||d}| j	}|j
rl|jrlt|j
|j|j|jr|j|jfD ]*}|dkrq~| D ]}	t|	j|	jqq~|W S  tjk
r }
 ztd|
j | dW 5 d}
~
X Y nX dS )a  Parse an XML string and return the root Element.

    :param content: The XML string
    :type content: str
    :param transport: The transport instance to load imported documents
    :type transport: zeep.transports.Transport
    :param base_url: The base url of the document, used to make relative
      lookups absolute.
    :type base_url: str
    :param settings: A zeep.settings.Settings object containing parse settings.
    :type settings: zeep.settings.Settings
    :returns: The document root
    :rtype: lxml.etree._Element

    TF)Zremove_commentsresolve_entitiesrecoverZ	huge_tree)parserbase_urlNz!Invalid XML content received (%s)r   )r   strictr   Zxml_huge_treeZ	resolversaddr   r	   ZgetroottreedocinfodoctypeZ
forbid_dtdr
   Z
system_url	public_idZforbid_entitiesZinternalDTDZexternalDTDZiterentitiesr   namer   r   r   msg)r   r   r#   settingsr!   r"   Zelementtreer&   Zdtdentityexcr   r   r   	parse_xml   s>    

   r.   )r   c                 C   sF   |pt  }t| dr|  }n|r,t| |} || }t||||dS )Load an external XML document.

    :param url:
    :param transport:
    :param base_url:
    :param settings: A zeep.settings.Settings object containing parse settings.
    :type settings: zeep.settings.Settings

    readr+   r   hasattrr0   absolute_locationr   r.   r   r   r#   r+   r   r   r   r   load_externalG   s    




r6   c                    sL   |pt  }t| dr|  }n|r,t| |} || I dH }t||||dS )r/   r0   Nr1   r2   r5   r   r   r   load_external_async]   s    




r7   c                 C   sX   |rt ||}|rT| jrTt|}t|}|j|jkrT|j|jkrTtd|dd  }|S )zReturn a 'normalized' url for the given url.

    This will make the url absolute and force it to https when that setting is
    enabled.

    )r      N)r4   Zforce_httpsr   netlocr   r   )r+   r   r#   Zbase_url_partsZ	url_partsr   r   r   normalize_locationq   s    



r:   c                 C   sp   | |kr| S t | jdkr| S |r:t |jdkr:t|| S tj| rJ| S |rltjtjtj|| S | S )zMake an url absolute (if it is optional) via the passed base url.

    :param location: The (relative) url
    :type location: str
    :param base: The base location
    :type base: str
    :returns: An absolute URL
    :rtype: str

    r   r   file)	r   r   r   ospathisabsrealpathjoindirname)locationbaser   r   r   r4      s    
r4   c                 C   s    t | jdkrdS tj|  S )zCheck if the given value is a relative path

    :param value: The value
    :type value: str
    :returns: Boolean indicating if the url is relative. If it is absolute then
      False is returned.
    :rtype: boolean

    r;   F)r   r   r=   r>   r?   )valuer   r   r   is_relative_path   s    
rF   )NN)NN)NN)os.pathr=   typingurllib.parser   r   r   lxmlr   Z
lxml.etreer   r   r   r	   Zzeep.exceptionsr
   r   Zzeep.settingsr   r   strr.   UnionIOr6   r7   r:   r4   rF   r   r   r   r   <module>   s"   0   