Skip to content

Commit d8668b1

Browse files
authored
Merge pull request pwin#6 from pwin/v2.26
update fork from bitbucket repo
2 parents c460d3d + e3ed166 commit d8668b1

File tree

105 files changed

+30701
-747
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+30701
-747
lines changed

.gitignore

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# These are some examples of commonly ignored file patterns.
2+
# You should customize this list as applicable to your project.
3+
# Learn more about .gitignore:
4+
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
5+
6+
# Compiled Python bytecode
7+
*.py[cod]
8+
__pycache__
9+
10+
# Log files
11+
*.log
12+
13+
*.old
14+
*.save
15+
*.bug
16+
*.egg-info
17+
build
18+
doc/doctrees/
19+
doc/html/
20+
21+
# Generated by MacOS
22+
.DS_Store
23+
24+
# Generated by Windows
25+
Thumbs.db

MANIFEST.in

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ include ./README.rst
2020

2121
exclude .hg
2222
exclude .hg/*
23+
exclude .git
24+
exclude .git/*
25+
exclude .gitignore
2326

2427
exclude doc/examples/contraindications.py
2528

README.rst

+69-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ Owlready2
1010
:alt: download stats
1111

1212

13-
# The source of this fork is at https://bitbucket.org/jibalamy/owlready2/src/master/
14-
13+
1514
Owlready2 is a module for ontology-oriented programming in Python 3, including an optimized RDF quadstore.
1615

1716
Owlready2 can:
@@ -431,6 +430,7 @@ version 2 - 0.20
431430
version 2 - 0.21
432431
****************
433432

433+
* Use Pellet 2.3.1 (same version as Protégé) instead of 2.4 (which has a bug in SWRL for many builtin predicates including equals and matches)
434434
* Much faster mangement of annotations on relations
435435
* Bugfixes:
436436
- Fix bug on blank node in RDFlib/SPARQL support
@@ -439,11 +439,77 @@ version 2 - 0.21
439439
- Fix 'no query solution' error in search()
440440
- Fix literal support in RDF lists, causing "TypeError: '<' not supported between instances of 'NoneType' and 'int'" when saving ontologies
441441
- Fix DifferentFrom SWRL builtin
442+
- Fix string parsing in SWRL rules
443+
- Fix string and boolean literal representation (str/repr) in SWRL rules
444+
- Fix the inverse of subproperties having a symmetric superproperty
445+
446+
version 2 - 0.22
447+
****************
448+
449+
* Add support for disjoint unions (Class.disjoint_unions)
450+
* Add deepcopy support on class constructs, and automatically deep-copy constructs when needed (i.e. no more OwlReadySharedBlankNodeError)
451+
* Support the creation of blank nodes with RDFlib
452+
453+
version 2 - 0.23
454+
****************
455+
456+
* Add get_parents_of(), get_instances_of(), get_children_of() methods to ontology, for querying the hierarchical relations defined in a given ontology
457+
* Use Thing as default value for restrictions with number, instead of None
458+
* Add 'filter' parameter to save(), for filtering the entities saved (contributed by Javier de la Rosa)
459+
* Bugfixes:
460+
- Fix value restriction with the false value
461+
- Fix blank node loading from different ontologies
462+
- Fix constructs reused by several classes
463+
- Fix 'Class.is_a = []' was not turning the list into an Owlready list
464+
- Fix destroy_entity() - was not destroying the IRI of the entity
465+
- Improve setup.py: ignore Cython if Cython installation fails
466+
467+
version 2 - 0.24
468+
****************
469+
470+
* Support intersection of searches (e.g. World.search(...) & World.search(...))
471+
* Add owlready2.reasoning.JAVA_MEMORY
472+
* Move development repository to Git
473+
* Bugfixes:
474+
- Fix parsing of NTriples files that do not end with a new line
475+
- Fix KeyError with Prop.python_name when several properties share the same name
476+
- Fix get_ontology() calls in Python module imported by ontologies in a World that is not default_world
477+
- Fix use of PyMedTermino2 in a World that is not default_world
478+
- Fix World.as_rdflib_graph().get_context(onto) for ontology added after the creation of the RDFLIB graph
479+
- Fix destroying SWRL rules
480+
- Fix disjoint with non-atomic classes
481+
482+
version 2 - 0.25
483+
****************
484+
485+
* Allow the declaration of custom datatypes with declare_datatype()
486+
* Support the annotation of annotations (e.g. a comment on a comment)
487+
* search() now support the "subproperty_of" argument
488+
* search() now support the "bm25" argument (for full-text searches)
489+
* Bugfixes:
490+
- Fix Concept.descendant_concepts() in PymedTermino2
491+
- Update already loaded properties when new ontologies are loaded
492+
- Now accept %xx quoted characters in file:// URL
493+
- Improve error message on punned entities
494+
- Property.get_relations() now considers inverse properties
495+
- Fix "AttributeError: 'mappingproxy' object has no attribute 'pop'" error
496+
- Fix Thing.instances()
442497

498+
version 2 - 0.26
499+
****************
500+
501+
* Module owlready2.dl_render allows rendering entities to Description Logics (contributed by Simon Bin)
502+
* Bugfixes:
503+
- Adjustment in the comparison of strings from SameAs and DiferrentFrom, allowing equal comparison regardless of the case-sensitive (contributed by Thiago Feijó)
504+
- Fix transitive equivalent_to relations between classes and OWL constructs
505+
- Fix AnnotationProperty[entity] where entity is a predefined OWL entity (e.g. comment or Thing)
506+
- Fix entity.AnnotationProperty where entity is a predefined OWL entity (e.g. comment or Thing)
507+
508+
443509
Links
444510
-----
445511

446-
Owlready2 on BitBucket (development repository): https://bitbucket.org/jibalamy/owlready2
512+
Owlready2 on BitBucket (Git development repository): https://bitbucket.org/jibalamy/owlready2
447513

448514
Owlready2 on PyPI (Python Package Index, stable release): https://pypi.python.org/pypi/Owlready2
449515

TODO.rst

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Owlready2 TODO list
44
* Add support for property chain in entity.property.indirect()
55
* Add functions/methods for copying entities from an ontology to another
66
* Obtain individual property value inferred by HermiT
7-
* Add rule support
87

98
* Support additional file formats:
109
* OWL/XML write

__init__.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# You should have received a copy of the GNU Lesser General Public License
1818
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1919

20-
VERSION = "0.20"
20+
VERSION = "0.25"
2121

2222
JAVA_EXE = "java"
2323

@@ -61,7 +61,7 @@
6161
owlready2.namespace.IndividualValueList = IndividualValueList
6262
owlready2.entity.Thing = Thing
6363
owlready2.entity.Nothing = Nothing
64-
owlready2.entity.ClassConstruct = ClassConstruct
64+
owlready2.entity.Construct = Construct
6565
owlready2.entity.And = And
6666
owlready2.entity.Or = Or
6767
owlready2.entity.Not = Not
@@ -82,20 +82,20 @@
8282
owlready2.disjoint.Or = Or
8383
owlready2.prop.Restriction = Restriction
8484
owlready2.prop.ConstrainedDatatype = ConstrainedDatatype
85-
owlready2.prop.ClassConstruct = ClassConstruct
85+
owlready2.prop.Construct = Construct
8686
owlready2.prop.AnnotationProperty = AnnotationProperty
8787
owlready2.prop.Thing = Thing
88-
#owlready2.prop.ValueList = ValueList
88+
owlready2.prop.PropertyChain = PropertyChain
8989
owlready2.prop._check_superclasses = True
9090

9191
owlready2.prop.ThingClass = ThingClass
9292
owlready2.prop.And = And
9393
owlready2.prop.Or = Or
9494
owlready2.prop.OneOf = OneOf
95-
owlready2.annotation.ClassConstruct = ClassConstruct
95+
owlready2.annotation.Construct = Construct
9696

9797
owlready2.individual._keep_most_specific = _keep_most_specific
98-
owlready2.individual.ClassConstruct = ClassConstruct
98+
owlready2.individual.Construct = Construct
9999
owlready2.individual.TransitiveProperty = TransitiveProperty
100100
owlready2.individual.SymmetricProperty = SymmetricProperty
101101
owlready2.individual.ReflexiveProperty = ReflexiveProperty
@@ -104,6 +104,9 @@
104104
owlready2.class_construct.Thing = Thing
105105
owlready2.class_construct.ThingClass = ThingClass
106106
owlready2.class_construct.EntityClass = EntityClass
107+
108+
#owlready2.reasoning.Construct = Construct
109+
107110
del owlready2
108111

109112
from owlready2.rule import *

annotation.py

+44-26
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,34 @@
5252
# return bnode
5353

5454
class _AnnotList(CallbackListWithLanguage):
55-
__slots__ = ["_property", "_target", "_target_d", "_annot"]
56-
def __init__(self, l, source, property, target, target_d, annot):
55+
__slots__ = ["namespace", "_property", "_target", "_target_d", "_annot", "_od_2_bnode"]
56+
def __init__(self, l, source, property, target, target_d, annot, namespace, od_2_bnode):
5757
list.__init__(self, l)
58-
self._obj = source
59-
self._property = property
60-
self._target = target
61-
self._target_d = target_d
62-
self._annot = annot
58+
self.namespace = namespace
59+
self._obj = source
60+
self._property = property
61+
self._target = target
62+
self._target_d = target_d
63+
self._annot = annot
64+
self._od_2_bnode = od_2_bnode
6365

6466
def _callback(self, obj, old):
6567
old = set(old)
6668
new = set(self)
6769

70+
if isinstance(obj, _AnnotList): # Annotate an annotation
71+
storid = obj._od_2_bnode[self._target, self._target_d]
72+
else:
73+
storid = obj.storid
74+
6875
# Add before, in order to avoid destroying the axiom and then recreating, if all annotations are modified
6976
for added in new - old:
70-
x = obj.namespace.ontology._add_annotation_axiom(obj.storid, self._property, self._target, self._target_d, self._annot, *obj.namespace.ontology._to_rdf(added))
77+
o, d = obj.namespace.ontology._to_rdf(added)
78+
bnode = obj.namespace.ontology._add_annotation_axiom(storid, self._property, self._target, self._target_d, self._annot, o, d)
79+
self._od_2_bnode[o, d] = bnode
7180

7281
for removed in old - new:
73-
obj.namespace.ontology._del_annotation_axiom (obj.storid, self._property, self._target, self._target_d, self._annot, *obj.namespace.ontology._to_rdf(removed))
82+
obj.namespace.ontology._del_annotation_axiom(storid, self._property, self._target, self._target_d, self._annot, *obj.namespace.ontology._to_rdf(removed))
7483

7584

7685
class AnnotationPropertyClass(PropertyClass):
@@ -80,34 +89,43 @@ class AnnotationPropertyClass(PropertyClass):
8089
def __getitem__(Annot, entity):
8190
if isinstance(entity, tuple):
8291
source, property, target = entity
83-
if hasattr(source, "storid"):
84-
world = source.namespace.world # if Annot is in owl_world (e.g. comment), use the world of the source
85-
source_orig = source
86-
source = source.storid
92+
93+
if hasattr(source, "storid"):
94+
namespace = source.namespace # if Annot is in owl_world (e.g. comment), use the namespace of the source
95+
elif isinstance(source, _AnnotList):
96+
namespace = source._obj.namespace
8797
else:
88-
world = self.namespace.world
98+
namespace = Annot.namespace
99+
89100
if hasattr(property, "storid"): property = property.storid
90-
target, target_d = world._to_rdf(target)
101+
target, target_d = namespace.world._to_rdf(target)
102+
103+
if hasattr(source, "storid"):
104+
source_orig = source
105+
source = source.storid
106+
elif isinstance(source, _AnnotList):
107+
source_orig = source
108+
source = source._od_2_bnode[target, target_d]
109+
91110
l = []
92-
for bnode in world._get_annotation_axioms(source, property, target, target_d):
93-
for o, d in world._get_triples_sp_od(bnode, Annot.storid):
94-
l.append(world._to_python(o, d))
111+
112+
od_2_bnode = {}
113+
for bnode in namespace.world._get_annotation_axioms(source, property, target, target_d):
114+
for o, d in namespace.world._get_triples_sp_od(bnode, Annot.storid):
115+
l.append(namespace.world._to_python(o, d))
116+
od_2_bnode[o, d] = bnode
95117

96-
return _AnnotList(l, source_orig, property, target, target_d, Annot.storid)
118+
return _AnnotList(l, source_orig, property, target, target_d, Annot.storid, namespace, od_2_bnode)
97119

98120
else:
99-
if Annot is entity.namespace.world._props.get(Annot._python_name) and not isinstance(entity, ClassConstruct): # use cached value
121+
if Annot is entity.namespace.world._props.get(Annot._python_name) and not isinstance(entity, Construct): # use cached value
100122
r = getattr(entity, Annot._python_name)
101123
if isinstance(r, list): return r # May not be a list if hacked (e.g. Concept.terminology)
102124
return Annot._get_values_for_individual(entity)
103-
125+
104126
def __setitem__(Annot, index, values):
105127
if not isinstance(values, list): values = [values]
106-
107-
if isinstance(index, tuple):
108-
Annot[index].reinit(values)
109-
else:
110-
return setattr(index, Annot.python_name, values)
128+
Annot[index].reinit(values)
111129

112130
def __call__(Prop, type, c, *args):
113131
raise ValueError("Cannot create a property value restriction on an annotation property!")

base.py

+23-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def _universal_abbrev(iri):
114114
_universal_abbrev("http://www.w3.org/2002/07/owl#FunctionalProperty")
115115
_universal_abbrev("http://www.w3.org/2002/07/owl#InverseFunctionalProperty")
116116

117-
SPECIAL_ATTRS = { "namespace", "name", "_name", "iri", "_iri", "storid", "is_a", "equivalent_to", "_equivalent_to", "disjoint_with", "_disjoint_with", "defined_class", "__class__", "__qualname__", "__module__", "__doc__", "__bases__" }
117+
SPECIAL_ATTRS = { "namespace", "name", "_name", "iri", "_iri", "storid", "is_a", "equivalent_to", "_equivalent_to", "disjoint_with", "_disjoint_with", "defined_class", "_disjoint_unions", "__class__", "__qualname__", "__module__", "__doc__", "__bases__" }
118118
SPECIAL_PROP_ATTRS = { "namespace", "name", "_name", "python_name", "_python_name", "_domain", "_property_chain", "_inverse_property", "inverse_property", "inverse", "_range", "iri", "_iri", "storid", "is_a", "equivalent_to", "_equivalent_to", "disjoint_with", "_disjoint_with", "__class__", "__qualname__", "__module__", "__doc__", "__bases__" }
119119

120120

@@ -183,6 +183,21 @@ def set_datatype_iri(datatype, iri):
183183
_universal_datatype_2_abbrev [datatype] = _universal_iri_2_abbrev[iri]
184184
_universal_datatype_2_abbrev_unparser[datatype] = (_universal_iri_2_abbrev[iri], unparser)
185185

186+
187+
def declare_datatype(datatype, iri, parser, unparser):
188+
storid = _universal_abbrev(iri)
189+
from owlready2 import WORLDS
190+
for world in WORLDS:
191+
world.graph.execute("INSERT INTO resources VALUES (?,?)", (storid, iri))
192+
if world.graph._abbreviate_d:
193+
world.graph._abbreviate_d [iri] = storid
194+
world.graph._unabbreviate_d[storid] = iri
195+
196+
_universal_datatype_2_abbrev [datatype] = storid
197+
_universal_datatype_2_abbrev_unparser[datatype] = (storid, unparser)
198+
_universal_abbrev_2_datatype [storid] = datatype
199+
_universal_abbrev_2_datatype_parser [storid] = (datatype, parser)
200+
return storid
186201

187202
owl_alldisjointproperties = _universal_abbrev("http://www.w3.org/2002/07/owl#AllDisjointProperties")
188203
owl_equivalentproperty = _universal_abbrev("http://www.w3.org/2002/07/owl#equivalentProperty")
@@ -255,6 +270,13 @@ def set_datatype_iri(datatype, iri):
255270
owl_bottomobjectproperty = _universal_abbrev("http://www.w3.org/2002/07/owl#bottomObjectProperty")
256271
owl_bottomdataproperty = _universal_abbrev("http://www.w3.org/2002/07/owl#bottomDataProperty")
257272

273+
owl_disjointunion = _universal_abbrev("http://www.w3.org/2002/07/owl#disjointUnionOf")
274+
275+
#owlready_direct_is_a = _universal_abbrev("http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl#direct_is_a")
276+
#owlready_is_a_construct = _universal_abbrev("http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl#is_a_construct")
277+
#owlready_context_is_a = _universal_abbrev("http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl#context_is_a")
278+
owlready_concrete = _universal_abbrev("http://www.lesfleursdunormal.fr/static/_downloads/owlready_ontology.owl#concrete")
279+
258280
issubclass_python = issubclass
259281

260282

0 commit comments

Comments
 (0)