
    01iFG              
      2   S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	J
r
JrJr  SSKJrJrJrJrJrJrJrJrJrJrJrJrJrJr  SSKJrJrJr  SSKr SSK!r SSK"r SS	K#J$r$  \(       a  SS
KJ%r%  / SQr&\" S\S9r'\" S5      r(0 SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_S S_SS_r)S!/S"/S#/S$/S%/S&S'/S(/S)/S*/S+.	r*S,/S-/S./S//S0.r+SJS1 jr,SKS2 jr-SLSMS3 jjr.SNS4 jr/ SO     SPS5 jjr0   SQ         SRS6 jjr1SSS7 jr2STS8 jr3SOSUS9 jjr4SVSWS: jjr5 SO       SXS; jjr6S< SSS=4               SYS> jjr7\SZS? j5       r8\S@SA.     S[SB jj5       r8SSA.     S[SC jjr8SDr9 SE\9-   SF-   r: \:SG-   r; \9SE-   r< \:SH-   r= S\SI jr>g)]z
Some utility functions.

Miscellaneous utilities

* list2set
* first
* uniq
* more_than

Term characterisation and generation

* to_term
* from_n3

Date/time utilities

* date_time
* parse_date_time

    )annotations)timegm)splitext)altzonegmtime	localtimetimetimezone)TYPE_CHECKINGAnyCallableDictHashableIterableIteratorListOptionalSetTupleTypeVarUnionoverload)quoteurlsplit
urlunsplitN)sign)Graph)list2setfirstuniq	more_thanto_termfrom_n3	date_timeparse_date_timeguess_format
find_rootsget_tree	_coalesce_iri2uri
_HashableT)bound_AnyTxmlrdfowln3ttlturtlenttrixxhtmlrdfahtmlsvgnqnquadstrigjsonjson-ldjsonldzapplication/rdf+xmlztext/n3ztext/turtlezapplication/n-tripleszapplication/trixz	text/htmlzapplication/xhtml+xmlzapplication/n-quadszapplication/trigzapplication/ld+json)	r.   r1   r3   r4   r5   r7   r;   r<   r>   zapplication/sparql-results+xmlzapplication/sparql-results+jsonztext/csvztext/tab-separated-values)r.   r=   csvtsvc                    [        5       nU  Vs/ s H$  o"U;  d  M
  UR                  U5      (       a  M"  UPM&     sn$ s  snf )zL
Return a new list without duplicates.
Preserves the order, unlike set(seq)
)setadd)seqseenxs      E/home/james-whalen/.local/lib/python3.13/site-packages/rdflib/util.pyr   r   v   s3    
 5D@s!tmADHHQKAs@@@s   	===c                    U  H  nUs  $    g)zS
return the first element in a python sequence
for graphs, use graph.value instead
N )rE   results     rH   r   r      s    
      c                J    U(       a  [        S U  5       5      $ [        U 5      $ )z,removes duplicate strings from the sequence.c              3  @   #    U  H  oR                  5       v   M     g 7fN)strip).0ss     rH   	<genexpr>uniq.<locals>.<genexpr>   s     /h7799hs   )rC   )sequencerP   s     rH   r    r       s     /h///8}rL   c                2    SnU  H  nUS-  nX!:  d  M    g   g)z>Returns 1 if sequence has more items than number and 0 if not.r      rJ   )rU   numberiitems       rH   r!   r!      s'    	A	Q:  rL   c                   U (       d  U$ U R                  S5      (       a8  U R                  S5      (       a"  [        R                  R	                  U SS 5      $ U R                  S5      (       a8  U R                  S5      (       a"  [        R                  R                  U SS 5      $ U R                  S5      (       a  [        R                  R                  U 5      $ SU -  n[        U5      e)a]  
Creates and returns an Identifier of type corresponding
to the pattern of the given positional argument string `s`:

'' returns the `default` keyword argument value or `None`

'<s>' returns `URIRef(s)` (i.e. without angle brackets)

'"s"' returns `Literal(s)` (i.e. without doublequotes)

'_s' returns `BNode(s)` (i.e. without leading underscore)

<>rW   "_zUnrecognised term syntax: '%s')
startswithendswithrdflibtermURIRefLiteralBNode	Exception)rR   defaultmsgs      rH   r"   r"      s      	
c		qzz#{{!!!Ab'**	
c		qzz#{{""1Qr7++	
c		{{  ##.2nrL   c                   U (       d  U$ U R                  S5      (       a@  [        R                  R                  U SS R	                  S5      R                  S5      5      $ U R                  S5      (       a  U R                  S5      (       a  SnOSnU R                  US5      u  pVU[        U5      S nSnSnUR                  S	5      n	U	S
:  a  [        XiS-   S XU5      nOUR                  S5      (       a  USS nUR                  SS5      nUR                  SS5      nUR	                  S5      R                  S5      n[        R                  R                  XXU5      $ U S:X  d  U S:X  a"  [        R                  R                  U S:H  5      $ U R                  5       R                  SSS5      R                  SSS5      R                  SSS5      R                  5       (       a  SU R                  5       ;   a@  [        R                  R                  U [        R                  R                  R                   S9$ SU ;   aI  [        R                  R                  [#        U 5      [        R                  R                  R$                  S9$ [        R                  R                  ['        U 5      [        R                  R                  R(                  S9$ U R                  S5      (       a-  [        U SS 5      n
[        R*                  R-                  X*5      $ U R                  S5      (       a-  [        U SS 5      n
[        R*                  R/                  X*5      $ U R                  S5      (       a"  [        R                  R1                  U SS 5      $ SU ;   a  Uc;  [        R                  R3                  [        R*                  R/                  5       5      nU R5                  SS5      u  p[7        UR9                  5       5      U   n[        R                  R;                  U5      U   $ [        R                  R1                  U 5      $ )aE  Creates the Identifier corresponding to the given n3 string.

```python
>>> from rdflib.term import URIRef, Literal
>>> from rdflib.namespace import NamespaceManager
>>> from_n3('<http://ex.com/foo>') == URIRef('http://ex.com/foo')
True
>>> from_n3('"foo"@de') == Literal('foo', lang='de')
True
>>> from_n3('"""multi\nline\nstring"""@en') == Literal(
...     'multi\nline\nstring', lang='en')
True
>>> from_n3('42') == Literal(42)
True
>>> from_n3(Literal(42).n3()) == Literal(42)
True
>>> from_n3('"42"^^xsd:integer') == Literal(42)
True
>>> from rdflib import RDFS
>>> from_n3('rdfs:label') == RDFS['label']
True
>>> nsm = NamespaceManager(rdflib.graph.Graph())
>>> nsm.bind('dbpedia', 'http://dbpedia.org/resource/')
>>> berlin = URIRef('http://dbpedia.org/resource/Berlin')
>>> from_n3('dbpedia:Berlin', nsm=nsm) == berlin
True

```
r\   rW   r^   zraw-unicode-escapezunicode-escaper_   z"""Nz^^r      @z\"z\xz\\xtruefalse. -e)datatype{[z_::)ra   rc   rd   re   encodedecodersplitlenrfindr#   replacerf   lower	isnumeric	namespaceXSDdoublefloatdecimalintintegergraphQuotedGraphr   rg   NamespaceManagersplitdict
namespaces	Namespace)rR   ri   backendnsmquotesvaluerestrt   languagedtoffset
identifierprefix	last_partnss                 rH   r#   r#      sp   F ||C {{!!aGNN/0778HI
 	
 
c		<<FFhhvq)c&km$ ::d#q=
 tqLN3WsKHs##8eS) eV, 1299:JK{{""5H==	
fW{{""1;//			b!		b!		b!				 !'');;&&q63C3C3G3G3N3N&OO!8;;&&uQx&:J:J:N:N:V:V&WW{{""3q6F4D4D4H4H4P4P"QQ	
c		QqW%
 ||''<<	
c		QqW%
 ||!!'66	
d		{{  12''	;""33FLL4F4F4HICGGCO#.."#F+))"-i88{{  ##rL   c           	         U c
  [        5       n U(       a6  [        U 5      nUS   (       a
  [        S-  nO	[        S-  nSUS-  US-  4-  nO[	        U 5      nSnUu	  pVpxppnSXVXxXU4-  nU$ )aO  http://www.w3.org/TR/NOTE-datetime ex: 1997-07-16T19:20:30Z

```python
>>> date_time(1126482850)
'2005-09-11T23:54:10Z'

@@ this will change depending on where it is run
#>>> date_time(1126482850, local_time_zone=True)
#'2005-09-11T19:54:10-04:00'

>>> date_time(1)
'1970-01-01T00:00:01Z'

>>> date_time(0)
'1970-01-01T00:00:00Z'

```
   <   z
-%02d:%02dZz!%0004d-%02d-%02dT%02d:%02d:%02d%s)r	   r   r   r
   r   )tlocal_time_zone
time_tupletz_minstzdyearmonthdayhhmmsswdyzrR   s                  rH   r$   r$   )  s    & 	yFq\
a=mG"nGgmWr\::AY
-7*D""+tCRS.QQAHrL   c                   SU ;  a  U S-  n U R                  S5      u  pUSS USS pCU(       a  US:X  a  USS nSnO6[        USS 5      n[        US	S
 5      n[        U5      U-  US-  -   S-  nU* nUR                  S5      u  pnUR                  S5      u  pn[        [        U	5      [        U
5      [        U5      [        U5      [        U5      [        U5      SSS4	5      nX-   nU$ )a  always returns seconds in UTC

```python
# tests are written like this to make any errors easier to understand
>>> parse_date_time('2005-09-11T23:54:10Z') - 1126482850.0
0.0

>>> parse_date_time('2005-09-11T16:54:10-07:00') - 1126482850.0
0.0

>>> parse_date_time('1970-01-01T00:00:01Z') - 1.0
0.0

>>> parse_date_time('1970-01-01T00:00:00Z') - 0.0
0.0
>>> parse_date_time("2005-09-05T10:42:00") - 1125916920.0
0.0

```
Tz
T00:00:00Zr   r   Nr   r^            r   rr   rw   )r   r   r   r   )valymdr	   hmstz_str	tz_offset
signed_hrsminssecsr   r   r   hourminutesecondr   s                   rH   r%   r%   O  s    , #~|		#ICq)T!"XVs]CRy	_
6!A;Z 4'*r/9R?E	yy~D99S>D&	TCJC#d)S[#f+qRSUVW	A 	
AHrL   c                    U=(       d    [         nUR                  [        U 5      5      =(       d    UR                  U R                  5       5      $ )a  
Guess RDF serialization based on file suffix. Uses
`SUFFIX_FORMAT_MAP` unless `fmap` is provided.

Example:
    ```python
    >>> guess_format('path/to/file.rdf')
    'xml'
    >>> guess_format('path/to/file.owl')
    'xml'
    >>> guess_format('path/to/file.ttl')
    'turtle'
    >>> guess_format('path/to/file.json')
    'json-ld'
    >>> guess_format('path/to/file.xhtml')
    'rdfa'
    >>> guess_format('path/to/file.svg')
    'rdfa'
    >>> guess_format('path/to/file.xhtml', {'xhtml': 'grddl'})
    'grddl'

    ```

    This also works with just the suffixes, with or without leading dot, and
    regardless of letter case:

    ```python
    >>> guess_format('.rdf')
    'xml'
    >>> guess_format('rdf')
    'xml'
    >>> guess_format('RDF')
    'xml'

    ```
)SUFFIX_FORMAT_MAPget_get_extr~   )fpathfmaps     rH   r&   r&   ~  s7    J $$D88HUO$?(??rL   c                    [        U 5      S   nUS:X  a  U R                  S5      (       a  U nU(       a  UR                  5       nUR                  S5      (       a  USS nU$ )a  
Gets the file extension from a file(path); stripped of leading '.' and in
lower case.

Example:
    ```python
    >>> _get_ext("path/to/file.txt")
    'txt'
    >>> _get_ext("OTHER.PDF")
    'pdf'
    >>> _get_ext("noext")
    ''
    >>> _get_ext(".rdf")
    'rdf'

    ```
r^   rq   rp   rW   N)r   ra   r~   )r   r~   exts      rH   r   r     s[    $ 5/"
C
byU%%c**iik
~~c!"gJrL   c                    [        5       nUc
  [        5       nU R                  U5       HD  u  pEUR                  U5        XB;   a  UR                  U5        XS;  d  M3  UR                  U5        MF     U$ )a  Find the roots in some sort of transitive hierarchy.

find_roots(graph, rdflib.RDFS.subClassOf)
will return a set of all roots of the sub-class hierarchy

Assumes triple of the form (child, prop, parent), i.e. the direction of
`RDFS.subClassOf` or `SKOS.broader`
)rC   subject_objectsrD   remove)r   proproots	non_rootsrG   r   s         rH   r'   r'     sb     (+uI}%%d+a:LLOIIaL , LrL   c                    U $ rO   rJ   )rG   s    rH   <lambda>r     s    qrL   downc           
     $   Uc
  [        5       nX;   a  gUR                  U5        / nUS:X  a  U R                  X!5      nOU R                  X5      nU H+  n	[	        X	X#XEU5      n
U
(       d  M  UR                  U
5        M-     U" U5      [        XtS94$ )a  
Return a nested list/tuple structure representing the tree
built by the transitive property given, starting from the root given

i.e.

```python
get_tree(
    graph,
    rdflib.URIRef("http://xmlns.com/foaf/0.1/Person"),
    rdflib.RDFS.subClassOf,
)
```

will return the structure for the subClassTree below person.

dir='down' assumes triple of the form (child, prop, parent),
i.e. the direction of RDFS.subClassOf or SKOS.broader
Any other dir traverses in the other direction
Nr   )key)rC   rD   subjectsobjectsr(   appendsorted)r   rootr   mappersortkeydonedirtreebranchesbranchr   s              rH   r(   r(     s    < |u|HHTND f}>>$-==,UD'E1KKN 
 4L&344rL   c                    g rO   rJ   ri   argss     rH   r)   r)     s    @CrL   .)ri   c                    g rO   rJ   r   s     rH   r)   r)     s     rL   c                &    U H
  nUc  M  Us  $    U $ )a  
This is a null coalescing function, it will return the first non-`None`
argument passed to it, otherwise it will return `default` which is `None`
by default.

For more info regarding the rationale of this function see deferred
[PEP 505](https://peps.python.org/pep-0505/).

Args:
    *args: Values to consider as candidates to return, the first arg that
        is not `None` will be returned. If no argument is passed this function
        will return None.
    default: The default value to return if none of the args are not `None`.

Returns:
    The first `args` that is not `None`, otherwise the value of
        `default` if there are no `args` or if all `args` are `None`.
rJ   )ri   r   args      rH   r)   r)     s    * ?J  NrL   z!$&'()*+,;=%z:@z/?/c                   [        U 5      nUu  p#pEnUS;  a  U $ [        U[        S9n[        U[        S9n[        U[        S9nUR                  (       a+  UR                  R                  S5      R                  S5      nOSnSU;   a  SU S3nUR                  (       a  U SUR                   3nUR                  (       aO  [        UR                  [        S9nUR                  (       a  [        UR                  [        S9nU SU 3nU S	U 3n[        X#XEU45      n	U R                  S
5      (       a  U	R                  S
5      (       d  U	S
-  n	U	$ )u  
Prior art:

- [iri_to_uri from Werkzeug](https://github.com/pallets/werkzeug/blob/92c6380248c7272ee668e1f8bbd80447027ccce2/src/werkzeug/urls.py#L926-L931)

```python
>>> _iri2uri("https://dbpedia.org/resource/Almería")
'https://dbpedia.org/resource/Almer%C3%ADa'

```
)httphttps)safeidnaasciirq   rw   rv   ]rm   #)r   r   _PATH_SAFE_CHARS_QUERY_SAFE_CHARShostnamerx   ry   portusername_USERNAME_SAFE_CHARSpasswordr   rb   )
iripartsschemenetlocpathqueryfragmentauthpass_quoteduris
             rH   r*   r*   a  s6    SME.3+VT( &&
,-D%/0EX$56H~~&&v.55g>
f}VHAzz81UZZL)~~U^^*>?>>5IJKV1[M*D66(#
fd8<
=C
||Cc!2!2s
JrL   )rE   zIterable[_HashableT]returnzList[_HashableT])rE   zIterable[_AnyT]r   Optional[_AnyT])r   )rU   zIterable[str]rP   r   r   zSet[str])rU   zIterable[Any]rX   r   r   r   rO   )rR   Optional[str]ri    Optional[rdflib.term.Identifier]r   r   )NNN)
rR   strri   r   r   r   r   z+Optional[rdflib.namespace.NamespaceManager]r   z&Optional[Union[rdflib.term.Node, str]])NF)r   r   r   r   )r   r   r   zOptional[Dict[str, str]]r   r   )T)r   r   r~   boolr   r   )r   r   r   rdflib.term.URIRefr   Optional[Set[rdflib.term.Node]]r   zSet[rdflib.term.Node])r   r   r   zrdflib.term.Noder   r  r   z.Callable[[rdflib.term.Node], rdflib.term.Node]r   zOptional[Callable[[Any], Any]]r   r  r   r   r   z,Optional[Tuple[rdflib.term.Node, List[Any]]])r   r   ri   r-   r   r-   )r   r   ri   r   r   r   )r   r   r   r   )?__doc__
__future__r   calendarr   os.pathr   r	   r   r   r   r
   typingr   r   r   r   r   r   r   r   r   r   r   r   r   r   urllib.parser   r   r   rdflib.graphrc   rdflib.namespacerdflib.termrdflib.compatr   r   __all__r+   r-   r   FORMAT_MIMETYPE_MAP"RESPONSE_TABLE_FORMAT_MIMETYPE_MAPr   r   r    r!   r"   r#   r$   r%   r&   r   r'   r(   r)   _RFC3986_SUBDELIMS_RFC3986_PCHAR_NUr   r   r   r*   rJ   rL   rH   <module>r     sv  , #   < ;     5 4    "  \2
	5	5 
5 	$	
 
8 	$ F V F 
6 	( h F I i  y! * ""+o"
# 12$% %&
  --./<'(	& "A CG?%> "!7;	m$
m$m$ m$ 
5	m$
 ,m$`#L,^&@R> .2
 + 	< >I.2,01515
15 15 ;	15
 ,15 *15 
15 215h 
 C 
 C 
7:%4 
 8<%46 # 
 ,,t3  &,  *C/ 
 %s* 2rL   