deriva 1.7.9__py3-none-any.whl → 1.7.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
deriva/core/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.7.9"
1
+ __version__ = "1.7.10"
2
2
 
3
3
  from deriva.core.utils.core_utils import *
4
4
  from deriva.core.base_cli import BaseCLI, KeyValuePairArgs
deriva/core/datapath.py CHANGED
@@ -11,7 +11,8 @@ from requests import HTTPError
11
11
  import warnings
12
12
  from . import DEFAULT_HEADERS, ermrest_model as _erm
13
13
 
14
- __all__ = ['DataPathException', 'Min', 'Max', 'Sum', 'Avg', 'Cnt', 'CntD', 'Array', 'ArrayD', 'Bin']
14
+ __all__ = ['DataPathException', 'Min', 'Max', 'Sum', 'Avg', 'Cnt', 'CntD', 'Array', 'ArrayD', 'Bin', 'All', 'Any',
15
+ 'simple_denormalization', 'simple_denormalization_with_whole_entities']
15
16
 
16
17
  logger = logging.getLogger(__name__)
17
18
  """Logger for this module"""
@@ -1265,6 +1266,19 @@ class _ColumnWrapper (object):
1265
1266
 
1266
1267
  __eq__ = eq
1267
1268
 
1269
+ def ne(self, other):
1270
+ """Returns a 'not equal' comparison predicate.
1271
+
1272
+ :param other: `None` or any other literal value.
1273
+ :return: a filter predicate object
1274
+ """
1275
+ if other is None:
1276
+ return _ComparisonPredicate(self, "::null::", '').negate()
1277
+ else:
1278
+ return _ComparisonPredicate(self, "=", other).negate()
1279
+
1280
+ __ne__ = ne
1281
+
1268
1282
  def lt(self, other):
1269
1283
  """Returns a 'less than' comparison predicate.
1270
1284
 
@@ -1311,8 +1325,6 @@ class _ColumnWrapper (object):
1311
1325
  :param other: a _string_ literal value.
1312
1326
  :return: a filter predicate object
1313
1327
  """
1314
- if not isinstance(other, str):
1315
- logger.warning("'regexp' method comparison only supports string literals.")
1316
1328
  return _ComparisonPredicate(self, "::regexp::", other)
1317
1329
 
1318
1330
  def ciregexp(self, other):
@@ -1321,8 +1333,6 @@ class _ColumnWrapper (object):
1321
1333
  :param other: a _string_ literal value.
1322
1334
  :return: a filter predicate object
1323
1335
  """
1324
- if not isinstance(other, str):
1325
- logger.warning("'ciregexp' method comparison only supports string literals.")
1326
1336
  return _ComparisonPredicate(self, "::ciregexp::", other)
1327
1337
 
1328
1338
  def ts(self, other):
@@ -1331,8 +1341,6 @@ class _ColumnWrapper (object):
1331
1341
  :param other: a _string_ literal value.
1332
1342
  :return: a filter predicate object
1333
1343
  """
1334
- if not isinstance(other, str):
1335
- logger.warning("'ts' method comparison only supports string literals.")
1336
1344
  return _ComparisonPredicate(self, "::ts::", other)
1337
1345
 
1338
1346
  def alias(self, name):
@@ -1395,6 +1403,16 @@ class _ColumnAlias (object):
1395
1403
 
1396
1404
  __eq__ = eq
1397
1405
 
1406
+ def ne(self, other):
1407
+ """Returns a 'not equal' comparison predicate.
1408
+
1409
+ :param other: `None` or any other literal value.
1410
+ :return: a filter predicate object
1411
+ """
1412
+ return self._base_column.ne(other)
1413
+
1414
+ __ne__ = ne
1415
+
1398
1416
  def lt(self, other):
1399
1417
  """Returns a 'less than' comparison predicate.
1400
1418
 
@@ -1713,7 +1731,7 @@ class _ComparisonPredicate (_Predicate):
1713
1731
  assert isinstance(lop, _ColumnWrapper)
1714
1732
  assert isinstance(rop, _ColumnWrapper) or isinstance(rop, int) or \
1715
1733
  isinstance(rop, float) or isinstance(rop, str) or \
1716
- isinstance(rop, date)
1734
+ isinstance(rop, date) or isinstance(rop, _Quantifier)
1717
1735
  assert isinstance(op, str)
1718
1736
  self._lop = lop
1719
1737
  self._op = op
@@ -1739,6 +1757,9 @@ class _ComparisonPredicate (_Predicate):
1739
1757
  if isinstance(self._rop, _ColumnWrapper):
1740
1758
  # The only valid circumstance for a _ColumnWrapper rop is in a link 'on' predicate for simple key/fkey joins
1741
1759
  return "(%s)=(%s)" % (self._lop._instancename, self._rop._fqname)
1760
+ elif isinstance(self._rop, _Quantifier):
1761
+ # Quantifiers can be trusted to properly urlquote their literals
1762
+ return "%s%s%s" % (self._lop._instancename, self._op, str(self._rop))
1742
1763
  else:
1743
1764
  # All other comparisons are serialized per the usual form
1744
1765
  return "%s%s%s" % (self._lop._instancename, self._op, urlquote(str(self._rop)))
@@ -1810,6 +1831,34 @@ class _NegationPredicate (_Predicate):
1810
1831
  return "!(%s)" % self._child
1811
1832
 
1812
1833
 
1834
+ class _Quantifier (object):
1835
+ """Base class of quantifiers."""
1836
+ def __init__(self, quantifier_name, *args):
1837
+ """Initializes the quantifier object.
1838
+
1839
+ :param quantifier_name: name of the quantifier per ERMrest specification.
1840
+ :param args: arguments of the quantifier per ERMrest specification.
1841
+ """
1842
+ super(_Quantifier, self).__init__()
1843
+ self._quantifier_name = quantifier_name
1844
+ self._args = args
1845
+
1846
+ def __str__(self):
1847
+ return "%s(%s)" % (self._quantifier_name, ','.join([urlquote(str(arg)) for arg in self._args]))
1848
+
1849
+
1850
+ class All (_Quantifier):
1851
+ """Universal quantifier."""
1852
+ def __init__(self, *args):
1853
+ super(All, self).__init__('all', *args)
1854
+
1855
+
1856
+ class Any (_Quantifier):
1857
+ """Existential quantifier."""
1858
+ def __init__(self, *args):
1859
+ super(Any, self).__init__('any', *args)
1860
+
1861
+
1813
1862
  class AggregateFunction (object):
1814
1863
  """Base class of all aggregate functions."""
1815
1864
  def __init__(self, fn_name, arg):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deriva
3
- Version: 1.7.9
3
+ Version: 1.7.10
4
4
  Summary: Python APIs and CLIs (Command-Line Interfaces) for the DERIVA platform.
5
5
  Home-page: https://github.com/informatics-isi-edu/deriva-py
6
6
  Author: USC Information Sciences Institute, Informatics Systems Research Division
@@ -8,11 +8,11 @@ deriva/config/dump_catalog_annotations.py,sha256=QzaWDLfWIAQ0eWVV11zeceWgwDBOYIe
8
8
  deriva/config/rollback_annotation.py,sha256=vqrIcen-KZX8LDpu2OVNivzIHpQoQgWkZAChZJctvtk,3015
9
9
  deriva/config/examples/group_owner_policy.json,sha256=8v3GWM1F_BWnYD9x_f6Eo4kBDvyy8g7mRqujfoEKLNc,2408
10
10
  deriva/config/examples/self_serve_policy.json,sha256=pW-cqWz4rJNNXwY4eVZFkQ8gKCHclC9yDa22ylfcDqY,1676
11
- deriva/core/__init__.py,sha256=NKiBln9VluAuOX25MSfa-xDpYY86NwJY1civQ_Kg5QY,4975
11
+ deriva/core/__init__.py,sha256=2YJow_azmav6XbSDKH_fIO7or9_VyHdN1Od8_H-T964,4976
12
12
  deriva/core/annotation.py,sha256=PkAkPkxX1brQsb8_drR1Qj5QjQA5mjkpXhkq9NuZ1g8,13432
13
13
  deriva/core/base_cli.py,sha256=78Ilf3_f2xREQb3IIj6q0jwWAiXSObZszG0JURs36lA,2902
14
14
  deriva/core/catalog_cli.py,sha256=CwfTf7C81SpU1J_aPsWiIbPOBAyekkIh384KUivq5H8,23550
15
- deriva/core/datapath.py,sha256=w8LvPAd_DuknKxHc_YS6NUHhTY6XpCSkfa0m_xQUdZE,89068
15
+ deriva/core/datapath.py,sha256=h9WzLipAYctppoiZehyDNJdFpCnbU9-z-AWVD80z2Pk,90525
16
16
  deriva/core/deriva_binding.py,sha256=6yGXIbnayDtb9LU-JVK43zk02-aQwshrKiaLi1pru-8,13086
17
17
  deriva/core/deriva_server.py,sha256=nsW3gwg1sIaHl3BTf-nL41AkSj3dEpcEBlatvjvN8CQ,200
18
18
  deriva/core/ermrest_catalog.py,sha256=2mShQgo35DIQ-0UOEqu2VgCDTE3sUrQSWVDm1jW_tQ8,55547
@@ -97,10 +97,10 @@ deriva/transfer/upload/processors/metadata_update_processor.py,sha256=Hgu5huZf7Z
97
97
  deriva/transfer/upload/processors/rename_processor.py,sha256=UQ-JQuQgyYCGT-fU9kHA53kPdQ20kt-2Bb486od7B14,2423
98
98
  deriva/transfer/upload/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
99
  deriva/utils/__init__.py,sha256=jv2YF__bseklT3OWEzlqJ5qE24c4aWd5F4r0TTjOrWQ,65
100
- deriva-1.7.9.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
100
+ deriva-1.7.10.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
101
101
  tests/deriva/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
102
  tests/deriva/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
- tests/deriva/core/test_datapath.py,sha256=0vUlQ48KYkDW5L7hzwyGAETa_40y0JmZDalk0W0fCq4,38722
103
+ tests/deriva/core/test_datapath.py,sha256=ft7qDp9peomnhtREry5et4QDO4RyfCCBSE6YnNDNYe8,40225
104
104
  tests/deriva/core/test_ermrest_model.py,sha256=tmWmAgXTcLBueY4iUS14uq-b1SjgKMaFGt2lw9mYvbg,34330
105
105
  tests/deriva/core/mmo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
106
  tests/deriva/core/mmo/base.py,sha256=3iLqUDNdiJaERB-8-G-5NEvkJr9fz0YUMvPxl5hMINE,9356
@@ -109,8 +109,8 @@ tests/deriva/core/mmo/test_mmo_find.py,sha256=PcUN76sik68B3XKg0G3wHVpKcPEld_6Rtb
109
109
  tests/deriva/core/mmo/test_mmo_prune.py,sha256=4pYtYL8g1BgadlewNPVpVA5lT_gV6SPTDYf04ZKzBTA,6851
110
110
  tests/deriva/core/mmo/test_mmo_rename.py,sha256=4oSR1G3Od701Ss3AnolI1Z7CbMxKuQF2uSr2_IcoR6s,8512
111
111
  tests/deriva/core/mmo/test_mmo_replace.py,sha256=w-66LWyiQ_ajC7Ipmhc4kAKwIloPdQELeUPsvelTdX8,8439
112
- deriva-1.7.9.dist-info/METADATA,sha256=QXs8Ca5GdL-Sw7SY41j0tYR5maXv16epbvoIoH6SnNU,1890
113
- deriva-1.7.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
114
- deriva-1.7.9.dist-info/entry_points.txt,sha256=HmYCHlgbjYQ_aZX_j4_4tApH4tDTbYtS66jKlfytbn8,850
115
- deriva-1.7.9.dist-info/top_level.txt,sha256=_LHDie5-O53wFlexfrxjewpVkf04oydf3CqX5h75DXE,13
116
- deriva-1.7.9.dist-info/RECORD,,
112
+ deriva-1.7.10.dist-info/METADATA,sha256=OrMw19lEt6tH9VyJq5a8wL4WpeIu-Wr1a8rjrJLKNdk,1891
113
+ deriva-1.7.10.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
114
+ deriva-1.7.10.dist-info/entry_points.txt,sha256=HmYCHlgbjYQ_aZX_j4_4tApH4tDTbYtS66jKlfytbn8,850
115
+ deriva-1.7.10.dist-info/top_level.txt,sha256=_LHDie5-O53wFlexfrxjewpVkf04oydf3CqX5h75DXE,13
116
+ deriva-1.7.10.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -10,10 +10,8 @@ import logging
10
10
  from operator import itemgetter
11
11
  import os
12
12
  import unittest
13
- import sys
14
13
  from deriva.core import DerivaServer, get_credential, ermrest_model as _em, __version__
15
- from deriva.core.datapath import DataPathException, Min, Max, Sum, Avg, Cnt, CntD, Array, ArrayD, Bin, \
16
- simple_denormalization_with_whole_entities
14
+ from deriva.core.datapath import *
17
15
 
18
16
  try:
19
17
  from pandas import DataFrame
@@ -575,10 +573,28 @@ class DatapathTests (unittest.TestCase):
575
573
  self.assertEqual(expected_results_len, len(results))
576
574
 
577
575
  def test_filter_equality(self):
576
+ # test with value
578
577
  results = self.experiment.filter(
579
578
  self.experiment.column_definitions['Name'] == TEST_EXP_NAME_FORMAT.format(1)
580
579
  ).entities()
581
580
  self.assertEqual(len(results), 1)
581
+ # test again with null
582
+ results = self.experiment.filter(
583
+ self.experiment.column_definitions['Name'] == None
584
+ ).entities()
585
+ self.assertEqual(len(results), 0)
586
+
587
+ def test_filter_notequal(self):
588
+ # test with value
589
+ results = self.experiment.filter(
590
+ self.experiment.column_definitions['Amount'] != 0
591
+ ).entities()
592
+ self.assertEqual(len(results), TEST_EXP_MAX-1)
593
+ # test again with null
594
+ results = self.experiment.filter(
595
+ self.experiment.column_definitions['Amount'] != None
596
+ ).entities()
597
+ self.assertEqual(len(results), TEST_EXP_MAX)
582
598
 
583
599
  def test_filter_inequality(self):
584
600
  results = self.experiment.filter(
@@ -592,6 +608,24 @@ class DatapathTests (unittest.TestCase):
592
608
  ).entities()
593
609
  self.assertEqual(len(results), 1)
594
610
 
611
+ @unittest.skipUnless(TEST_EXP_MAX >= 3, "this test was designed for at least 3 elements in the test set")
612
+ def test_fitler_w_quantifier(self):
613
+ int_args = [0, int(TEST_EXP_MAX/2), TEST_EXP_MAX-1, TEST_EXP_MAX*2]
614
+ str_args = [TEST_EXP_NAME_FORMAT.format(i) for i in int_args]
615
+ for name, cname, Q, args, expectation in [
616
+ ('any_3_ints', 'Amount', Any, int_args, 3),
617
+ ('all_1_int', 'Amount', All, [int_args[0]], 1),
618
+ ('all_3_ints', 'Amount', All, int_args, 0),
619
+ ('any_3_strs', 'Name', Any, str_args, 3),
620
+ ('all_1_str', 'Name', All, [str_args[0]], 1),
621
+ ('all_3_strs', 'Name', All, str_args, 0)
622
+ ]:
623
+ with self.subTest(name=name):
624
+ results = self.experiment.filter(
625
+ self.experiment.column_definitions[cname] == Q(*args)
626
+ ).entities()
627
+ self.assertEqual(len(results), expectation)
628
+
595
629
  def test_filter_negation(self):
596
630
  results = self.experiment.filter(
597
631
  ~ (self.experiment.column_definitions['Name'].ciregexp(TEST_EXP_NAME_FORMAT.format(0)[10:]))