
    01ib5                     N    S r SSKJr  SSKJr  SSKJrJrJr  S/r	 " S S5      r
g)a   
The [`Resource`][rdflib.resource.Resource] class wraps a
[`Graph`][rdflib.graph.Graph]
and a resource reference (i.e. a [`URIRef`][rdflib.term.URIRef] or
[`BNode`][rdflib.term.BNode]) to support a resource-oriented way of
working with a graph.

It contains methods directly corresponding to those methods of the Graph
interface that relate to reading and writing data. The difference is that a
Resource also binds a resource identifier, making it possible to work without
tracking both the graph and a current subject. This makes for a "resource
oriented" style, as compared to the triple orientation of the Graph API.

Resulting generators are also wrapped so that any resource reference values
([`URIRef`][rdflib.term.URIRef] and [`BNode`][rdflib.term.BNode]) are in turn
wrapped as Resources. (Note that this behaviour differs from the corresponding
methods in [`Graph`][rdflib.graph.Graph], where no such conversion takes place.)


## Basic Usage Scenario

Start by importing things we need and define some namespaces:

```python
>>> from rdflib import *
>>> FOAF = Namespace("http://xmlns.com/foaf/0.1/")
>>> CV = Namespace("http://purl.org/captsolo/resume-rdf/0.2/cv#")

```

Load some RDF data:

```python
>>> graph = Graph().parse(format='n3', data='''
... @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
... @prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
... @prefix foaf: <http://xmlns.com/foaf/0.1/> .
... @prefix cv: <http://purl.org/captsolo/resume-rdf/0.2/cv#> .
...
... @base <http://example.org/> .
...
... </person/some1#self> a foaf:Person;
...     rdfs:comment "Just a Python & RDF hacker."@en;
...     foaf:depiction </images/person/some1.jpg>;
...     foaf:homepage <http://example.net/>;
...     foaf:name "Some Body" .
...
... </images/person/some1.jpg> a foaf:Image;
...     rdfs:label "some 1"@en;
...     rdfs:comment "Just an image"@en;
...     foaf:thumbnail </images/person/some1-thumb.jpg> .
...
... </images/person/some1-thumb.jpg> a foaf:Image .
...
... [] a cv:CV;
...     cv:aboutPerson </person/some1#self>;
...     cv:hasWorkHistory [ cv:employedIn </#company>;
...             cv:startDate "2009-09-04"^^xsd:date ] .
... ''')

```

Create a Resource:

```python
>>> person = Resource(
...     graph, URIRef("http://example.org/person/some1#self"))

```

Retrieve some basic facts:

```python
>>> person.identifier
rdflib.term.URIRef('http://example.org/person/some1#self')

>>> person.value(FOAF.name)
rdflib.term.Literal('Some Body')

>>> person.value(RDFS.comment)
rdflib.term.Literal('Just a Python & RDF hacker.', lang='en')

```

Resources can be sliced (like graphs, but the subject is fixed):

```python
>>> for name in person[FOAF.name]:
...     print(name)
Some Body
>>> person[FOAF.name : Literal("Some Body")]
True

```

Resources as unicode are represented by their identifiers as unicode:

```python
>>> %(unicode)s(person)  #doctest: +SKIP
'Resource(http://example.org/person/some1#self'

```

Resource references are also Resources, so you can easily get e.g. a qname
for the type of a resource, like:

```python
>>> person.value(RDF.type).qname()
'foaf:Person'

```

Or for the predicates of a resource:

```python
>>> sorted(
...     p.qname() for p in person.predicates()
... )  #doctest: +NORMALIZE_WHITESPACE +SKIP
['foaf:depiction', 'foaf:homepage',
 'foaf:name', 'rdf:type', 'rdfs:comment']

```

Follow relations and get more data from their Resources as well:

```python
>>> for pic in person.objects(FOAF.depiction):
...     print(pic.identifier)
...     print(pic.value(RDF.type).qname())
...     print(pic.value(FOAF.thumbnail).identifier)
http://example.org/images/person/some1.jpg
foaf:Image
http://example.org/images/person/some1-thumb.jpg

```

```python
>>> for cv in person.subjects(CV.aboutPerson):
...     work = list(cv.objects(CV.hasWorkHistory))[0]
...     print(work.value(CV.employedIn).identifier)
...     print(work.value(CV.startDate))
http://example.org/#company
2009-09-04

```

It's just as easy to work with the predicates of a resource:

```python
>>> for s, p in person.subject_predicates():
...     print(s.value(RDF.type).qname())
...     print(p.qname())
...     for s, o in p.subject_objects():
...         print(s.value(RDF.type).qname())
...         print(o.value(RDF.type).qname())
cv:CV
cv:aboutPerson
cv:CV
foaf:Person

```

This is useful for e.g. inspection:

```python
>>> thumb_ref = URIRef("http://example.org/images/person/some1-thumb.jpg")
>>> thumb = Resource(graph, thumb_ref)
>>> for p, o in thumb.predicate_objects():
...     print(p.qname())
...     print(o.qname())
rdf:type
foaf:Image

```

## Schema Example

With this artificial schema data:

```python
>>> graph = Graph().parse(format='n3', data='''
... @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
... @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
... @prefix owl: <http://www.w3.org/2002/07/owl#> .
... @prefix v: <http://example.org/def/v#> .
...
... v:Artifact a owl:Class .
...
... v:Document a owl:Class;
...     rdfs:subClassOf v:Artifact .
...
... v:Paper a owl:Class;
...     rdfs:subClassOf v:Document .
...
... v:Choice owl:oneOf (v:One v:Other) .
...
... v:Stuff a rdf:Seq; rdf:_1 v:One; rdf:_2 v:Other .
...
... ''')

```

From this class:

```python
>>> artifact = Resource(graph, URIRef("http://example.org/def/v#Artifact"))

```

we can get at subclasses:

```python
>>> subclasses = list(artifact.transitive_subjects(RDFS.subClassOf))
>>> [c.qname() for c in subclasses]
['v:Artifact', 'v:Document', 'v:Paper']

```

and superclasses from the last subclass:

```python
>>> [c.qname() for c in subclasses[-1].transitive_objects(RDFS.subClassOf)]
['v:Paper', 'v:Document', 'v:Artifact']

```

Get items from the Choice:

```python
>>> choice = Resource(graph, URIRef("http://example.org/def/v#Choice"))
>>> [it.qname() for it in choice.value(OWL.oneOf).items()]
['v:One', 'v:Other']

```

On add, other resources are auto-unboxed:

```python
>>> paper = Resource(graph, URIRef("http://example.org/def/v#Paper"))
>>> paper.add(RDFS.subClassOf, artifact)
>>> artifact in paper.objects(RDFS.subClassOf) # checks Resource instance
True
>>> (paper._identifier, RDFS.subClassOf, artifact._identifier) in graph
True

```

## Technical Details

Comparison is based on graph and identifier:

```python
>>> g1 = Graph()
>>> t1 = Resource(g1, URIRef("http://example.org/thing"))
>>> t2 = Resource(g1, URIRef("http://example.org/thing"))
>>> t3 = Resource(g1, URIRef("http://example.org/other"))
>>> t4 = Resource(Graph(), URIRef("http://example.org/other"))

>>> t1 is t2
False

>>> t1 == t2
True
>>> t1 != t2
False

>>> t1 == t3
False
>>> t1 != t3
True

>>> t3 != t4
True

>>> t3 < t1 and t1 > t3
True
>>> t1 >= t1 and t1 >= t3
True
>>> t1 <= t1 and t3 <= t1
True

>>> t1 < t1 or t1 < t3 or t3 > t1 or t3 > t3
False

```

Hash is computed from graph and identifier:

```python
>>> g1 = Graph()
>>> t1 = Resource(g1, URIRef("http://example.org/thing"))

>>> hash(t1) == hash(Resource(g1, URIRef("http://example.org/thing")))
True

>>> hash(t1) == hash(Resource(Graph(), t1.identifier))
False
>>> hash(t1) == hash(Resource(Graph(), URIRef("http://example.org/thing")))
False

```

The Resource class is suitable as a base class for mapper toolkits. For
example, consider this utility for accessing RDF properties via qname-like
attributes:

```python
>>> class Item(Resource):
...
...     def __getattr__(self, p):
...         return list(self.objects(self._to_ref(*p.split('_', 1))))
...
...     def _to_ref(self, pfx, name):
...         return URIRef(self._graph.store.namespace(pfx) + name)

```

It works as follows:

```python
>>> graph = Graph().parse(format='n3', data='''
... @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
... @prefix foaf: <http://xmlns.com/foaf/0.1/> .
...
... @base <http://example.org/> .
... </person/some1#self>
...     foaf:name "Some Body";
...     foaf:depiction </images/person/some1.jpg> .
... </images/person/some1.jpg> rdfs:comment "Just an image"@en .
... ''')

>>> person = Item(graph, URIRef("http://example.org/person/some1#self"))

>>> print(person.foaf_name[0])
Some Body

```

The mechanism for wrapping references as resources cooperates with subclasses.
Therefore, accessing referenced resources automatically creates new `Item`
objects:

```python
>>> isinstance(person.foaf_depiction[0], Item)
True

>>> print(person.foaf_depiction[0].rdfs_comment[0])
Just an image

```
    )RDF)Path)BNodeNodeURIRefResourcec                   6   \ rS rSrSrS r\S 5       r\S 5       rS r	S r
S rS	 rS
 rS rS rS rS rS)S jrS rS)S jrS)S jrS)S jrS rS rS r\R6                  SSS4S jrS rS)S jrS)S jrS rS r S r!S  r"S! r#S" r$S# r%S$ r&S% r'S& r(S' r)S(r*g)*r   ih  z>A Resource is a wrapper for a graph and a resource identifier.c                     Xl         X l        g N_graph_identifier)selfgraphsubjects      I/home/james-whalen/.local/lib/python3.13/site-packages/rdflib/resource.py__init__Resource.__init__k  s    "    c                     U R                   $ r   )r   r   s    r   r   Resource.grapho  s    {{r   c                     U R                   $ r   r   r   s    r   
identifierResource.identifiers  s    r   c                 x    [        [        5      [        U R                  5      -  [        U R                  5      -  $ r   )hashr   r   r   r   s    r   __hash__Resource.__hash__w  s*    H~T[[ 11D9I9I4JJJr   c                     [        U[        5      =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r   )
isinstancer   r   r   r   others     r   __eq__Resource.__eq__z  s?    uh' 6u||+6  E$5$55	
r   c                     X:X  + $ r    r#   s     r   __ne__Resource.__ne__  s      r   c                 `    [        U[        5      (       a  U R                  UR                  :  $ g)NF)r"   r   r   r#   s     r   __lt__Resource.__lt__  s)    eX&&##e&7&777r   c                 *    X:  =(       d    X:H  (       + $ r   r(   r#   s     r   __gt__Resource.__gt__  s    L1DM22r   c                      X:  =(       d    X:H  $ r   r(   r#   s     r   __le__Resource.__le__  s    |,t},r   c                     X:  + $ r   r(   r#   s     r   __ge__Resource.__ge__  s    r   c                 ,    [        U R                  5      $ r   )strr   r   s    r   __unicode__Resource.__unicode__  s    4##$$r   c                     [        U[        5      (       a  UR                  nU R                  R	                  U R                  X45        g r   )r"   r   r   r   addr   pos      r   r<   Resource.add  3    a""A))101r   Nc                     [        U[        5      (       a  UR                  nU R                  R	                  U R                  X45        g r   )r"   r   r   r   remover=   s      r   rC   Resource.remove  s5    a""AD,,a34r   c                     [        U[        5      (       a  UR                  nU R                  R	                  U R                  X45        g r   )r"   r   r   r   setr=   s      r   rF   Resource.set  rA   r   c                 j    U R                  U R                  R                  XR                  5      5      $ r   )
_resourcesr   subjectsr   r   	predicates     r   rJ   Resource.subjects  s&    t{{33I?O?OPQQr   c                     [        U[        5      (       a  UR                  nU R                  U R                  R                  U R                  U5      5      $ r   )r"   r   r   rI   r   
predicates)r   r?   s     r   rO   Resource.predicates  s>    a""At{{55d6F6FJKKr   c                 l    U R                  U R                  R                  U R                  U5      5      $ r   )rI   r   objectsr   rK   s     r   rR   Resource.objects  s(    t{{2243C3CYOPPr   c                 j    U R                  U R                  R                  U R                  5      5      $ r   )_resource_pairsr   subject_predicatesr   r   s    r   rV   Resource.subject_predicates  s(    ##DKK$B$B4CSCS$TUUr   c                 j    U R                  U R                  R                  U R                  5      5      $ r   )rU   r   subject_objectsr   r   s    r   rY   Resource.subject_objects  s(    ##DKK$?$?@P@P$QRRr   c                 j    U R                  U R                  R                  U R                  5      5      $ r   )rU   r   predicate_objectsr   r   s    r   r\   Resource.predicate_objects  s(    ##DKK$A$A$BRBR$STTr   Tc           	          [        U[        5      (       a  UR                  nU R                  U R                  R                  U R                  XX45      5      $ r   )r"   r   r   _castr   value)r   r>   r?   defaultanys        r   r`   Resource.value  s@    a""Azz$++++D,<,<aGQRRr   c                 j    U R                  U R                  R                  U R                  5      5      $ r   )rI   r   itemsr   r   s    r   re   Resource.items  s&    t{{001A1ABCCr   c                 l    U R                  U R                  R                  U R                  X5      5      $ r   )rI   r   transitive_objectsr   r   rL   remembers      r   rh   Resource.transitive_objects  s-    KK**4+;+;YQ
 	
r   c                 l    U R                  U R                  R                  XR                  U5      5      $ r   )rI   r   transitive_subjectsr   ri   s      r   rm   Resource.transitive_subjects  s-    KK++I7G7GR
 	
r   c                 L    U R                   R                  U R                  5      $ r   )r   qnamer   r   s    r   rp   Resource.qname  s    {{  !1!122r   c              #   j   #    U H)  u  p#U R                  U5      U R                  U5      4v   M+     g 7fr   r_   )r   pairss1s2s       r   rU   Resource._resource_pairs  s,     FB**R.$**R.00 s   13c              #      #    U H:  u  p#nU R                  U5      U R                  U5      U R                  U5      4v   M<     g 7fr   rs   )r   triplessr>   r?   s        r   _resource_triplesResource._resource_triples  s8     GA!**Q-A

1== s   AAc              #   D   #    U H  nU R                  U5      v   M     g 7fr   rs   )r   nodesnodes      r   rI   Resource._resources  s     D**T"" s    c                 ^    [        U[        [        45      (       a  U R                  U5      $ U$ r   )r"   r   r   _new)r   r   s     r   r_   Resource._cast  s&    dUFO,,99T?"Kr   c                 p    U R                  U R                  R                  U R                  S S 45      5      $ r   )r{   r   ry   r   r   s    r   __iter__Resource.__iter__  s2    %%KK$ =>
 	
r   c                 Z   [        U[        5      (       a  UR                  (       a  [        S5      eUR                  UR
                  p2[        U[        5      (       a  UR                  n[        U[        5      (       a  UR                  nUc  Uc  U R                  5       $ Uc  U R                  U5      $ Uc  U R                  U5      $ U R                  X#4U R                  ;   $ [        U[        [        45      (       a  U R                  U5      $ [        SU< S[        U5      < S35      e)NzSResources fix the subject for slicing, and can only be sliced by predicate/object. zTYou can only index a resource by a single rdflib term, a slice of rdflib terms, not z ())r"   slicestep	TypeErrorstartstopr   r   r\   rO   rR   r   r   r   r   type)r   itemr>   r?   s       r   __getitem__Resource.__getitem__  s    dE""yyi  ::tyyq!X&&MM!X&&MMyQY--//q))||A&.$++==tTl++<<%%d% r   c                 &    U R                  X5        g r   )rF   )r   r   r`   s      r   __setitem__Resource.__setitem__  s    r   c                 :    [        U 5      " U R                  U5      $ r   )r   r   )r   r   s     r   r   Resource._new  s    Dz$++w//r   c                      SU R                   -  $ )NzResource(%s)r   r   s    r   __str__Resource.__str__  s     0 000r   c                 @    SU R                   < SU R                  < S3$ )Nz	Resource(,r   r   r   s    r   __repr__Resource.__repr__  s    $(KK1A1ABBr   r   r   )+__name__
__module____qualname____firstlineno____doc__r   propertyr   r   r   r%   r)   r,   r/   r2   r5   r9   r<   rC   rF   rJ   rO   rR   rV   rY   r\   r   r`   re   rh   rm   rp   rU   r{   rI   r_   r   r   r   r   r   r   __static_attributes__r(   r   r   r   r   h  s    H#      K
!3- %252RLQVSU ii44 SD



31>#

601Cr   N)r   rdflib.namespacer   rdflib.pathsr   rdflib.termr   r   r   __all__r   r(   r   r   <module>r      s/   ^@ !  + +,gC gCr   