Skip to content

DatasetBag Class

THis module defines the DataSet class with is used to manipulate n

DatasetHistory

Bases: BaseModel

Class representing a dataset history.

Attributes:

Name Type Description
dataset_version DatasetVersion

A DatasetVersion object which captures the semantic versioning of the dataset.

dataset_rid RID

The RID of the dataset.

version_rid RID

The RID of the version record for the dataset in the Dataset_Version table.

minid str

The URL that represents the handle of the dataset bag. This will be None if a MINID has not been created yet.

snapshot str

Catalog snapshot ID of when the version record was created.

Source code in src/deriva_ml/dataset/aux_classes.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
class DatasetHistory(BaseModel):
    """
    Class representing a dataset history.

    Attributes:
        dataset_version (DatasetVersion): A DatasetVersion object which captures the semantic versioning of the dataset.
        dataset_rid (RID): The RID of the dataset.
        version_rid (RID): The RID of the version record for the dataset in the Dataset_Version table.
        minid (str): The URL that represents the handle of the dataset bag.  This will be None if a MINID has not
                     been created yet.
        snapshot (str): Catalog snapshot ID of when the version record was created.
    """

    dataset_version: DatasetVersion
    dataset_rid: RID
    version_rid: RID
    execution_rid: Optional[RID] = None
    description: str = ""
    minid: Optional[str] = None
    snapshot: Optional[str] = None

    model_config = ConfigDict(arbitrary_types_allowed=True)

DatasetMinid

Bases: BaseModel

Represent information about a MINID that refers to a dataset

Attributes:

Name Type Description
dataset_version DatasetVersion

A DatasetVersion object which captures the semantic versioning of the dataset.

metadata dict

A dictionary containing metadata from the MINID landing page.

minid str

The URL that represents the handle of the MINID associated with the dataset.

bag_url str

The URL to the dataset bag

identifier str

The identifier of the MINID in CURI form

landing_page str

The URL to the landing page of the MINID

version_rid str

RID of the dataset version.

checksum str

The checksum of the MINID in SHA256 form

Source code in src/deriva_ml/dataset/aux_classes.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
class DatasetMinid(BaseModel):
    """Represent information about a MINID that refers to a dataset

    Attributes:
        dataset_version (DatasetVersion): A DatasetVersion object which captures the semantic versioning of the dataset.
        metadata (dict): A dictionary containing metadata from the MINID landing page.
        minid (str): The URL that represents the handle of the MINID associated with the dataset.
        bag_url (str): The URL to the dataset bag
        identifier (str): The identifier of the MINID in CURI form
        landing_page (str): The URL to the landing page of the MINID
        version_rid (str): RID of the dataset version.
        checksum (str): The checksum of the MINID in SHA256 form

    """

    dataset_version: DatasetVersion
    metadata: dict[str, str | int] = {}
    minid: str = Field(alias="compact_uri", default=None)
    bag_url: str = Field(alias="location")
    identifier: Optional[str] = None
    landing_page: Optional[str] = None
    version_rid: RID = Field(alias="RID")
    checksum: str = Field(alias="checksums", default="")

    @computed_field
    @property
    def dataset_rid(self) -> str:
        rid_parts = self.version_rid.split("@")
        return rid_parts[0]

    @computed_field
    @property
    def dataset_snapshot(self) -> str:
        return self.version_rid.split("@")[1]

    @model_validator(mode="before")
    @classmethod
    def insert_metadata(cls, data: Any) -> Any:
        if isinstance(data, dict):
            if "metadata" in data:
                data = data | data["metadata"]
        return data

    @field_validator("bag_url", mode="before")
    @classmethod
    def convert_location_to_str(cls, value: list[str] | str) -> str:
        return value[0] if isinstance(value, list) else value

    @field_validator("checksum", mode="before")
    @classmethod
    def convert_checksum_to_value(cls, checksums: list[dict]) -> str:
        checksum_value = ""
        for checksum in checksums:
            if checksum.get("function") == "sha256":
                checksum_value = checksum.get("value")
                break
        return checksum_value

    model_config = ConfigDict(arbitrary_types_allowed=True)

DatasetSpec

Bases: BaseModel

Represent a dataset_table in an execution configuration dataset_table list

Attributes:

Name Type Description
rid RID

A dataset_table RID

materialize bool

If False do not materialize datasets, only download table data, no assets. Defaults to True

version DatasetVersion

The version of the dataset. Should follow semantic versioning.

Source code in src/deriva_ml/dataset/aux_classes.py
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
class DatasetSpec(BaseModel):
    """Represent a dataset_table in an execution configuration dataset_table list

    Attributes:
        rid (RID): A dataset_table RID
        materialize (bool): If False do not materialize datasets, only download table data, no assets.  Defaults to True
        version (DatasetVersion): The version of the dataset.  Should follow semantic versioning.
    """

    rid: RID
    materialize: bool = True
    version: DatasetVersion | conlist(item_type=int, min_length=3, max_length=3) | tuple[int, int, int] | str

    model_config = ConfigDict(arbitrary_types_allowed=True)

    @field_validator("version", mode="before")
    @classmethod
    def version_field_validator(cls, v: Any) -> Any:
        if isinstance(v, dict):
            return DatasetVersion(**v)
        elif isinstance(v, str):
            return DatasetVersion.parse(v)
        elif (isinstance(v, list) or isinstance(v, tuple)) and len(v) == 3:
            return DatasetVersion(int(v[0]), int(v[1]), int(v[2]))
        else:
            return v

    @model_validator(mode="before")
    @classmethod
    def _check_bare_rid(cls, data: Any) -> dict[str, str | bool]:
        # If you are just given a string, assume it's a rid and put into dict for further validation.
        return {"rid": data} if isinstance(data, str) else data

    @field_serializer("version")
    def serialize_version(self, version: DatasetVersion) -> dict[str, Any]:
        return version.to_dict()

DatasetVersion

Bases: Version

Represent the version associated with a dataset using semantic versioning.

Methods:

Name Description
replace

Replace the major and minor versions

Source code in src/deriva_ml/dataset/aux_classes.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class DatasetVersion(Version):
    """Represent the version associated with a dataset using semantic versioning.

    Methods:
        replace(major, minor, patch): Replace the major and minor versions
    """

    def __init__(self, major: SupportsInt, minor: SupportsInt = 0, patch: SupportsInt = 0):
        """Initialize a DatasetVersion object.

        Args:
            major: Major version number. Used to indicate schema changes.
            minor: Minor version number.  Used to indicate additional members added, or change in member values.
            patch: Patch number of the dataset.  Used to indicate minor clean-up and edits
        """
        super().__init__(major, minor, patch)

    def to_dict(self) -> dict[str, Any]:
        """

        Returns:
            dictionary of version information

        """
        return {"major": self.major, "minor": self.minor, "patch": self.patch}

    def to_tuple(self) -> tuple[int, int, int]:
        """

        Returns:
            tuple of version information

        """
        return self.major, self.minor, self.patch

    @classmethod
    def parse(cls, version: str, optional_minor_an_path=False) -> "DatasetVersion":
        v = Version.parse(version)
        return DatasetVersion(v.major, v.minor, v.patch)

    def increment_version(self, component: VersionPart) -> "DatasetVersion":
        match component:
            case VersionPart.major:
                return self.bump_major()
            case VersionPart.minor:
                return self.bump_minor()
            case VersionPart.patch:
                return self.bump_patch()
            case _:
                return self

build property writable

build: Optional[str]

The build part of a version (read-only).

major property writable

major: int

The major part of a version (read-only).

minor property writable

minor: int

The minor part of a version (read-only).

patch property writable

patch: int

The patch part of a version (read-only).

prerelease property writable

prerelease: Optional[str]

The prerelease part of a version (read-only).

__getitem__

__getitem__(
    index: Union[int, slice],
) -> Union[
    int,
    Optional[str],
    Tuple[Union[int, str], ...],
]

self.getitem(index) <==> self[index] Implement getitem.

If the part requested is undefined, or a part of the range requested is undefined, it will throw an index error. Negative indices are not supported.

:param index: a positive integer indicating the offset or a :func:slice object :raises IndexError: if index is beyond the range or a part is None :return: the requested part of the version at position index

ver = semver.Version.parse("3.4.5") ver[0], ver[1], ver[2] (3, 4, 5)

Source code in semver/version.py
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
def __getitem__(
    self, index: Union[int, slice]
) -> Union[int, Optional[str], Tuple[Union[int, str], ...]]:
    """
    self.__getitem__(index) <==> self[index] Implement getitem.

    If the part  requested is undefined, or a part of the range requested
    is undefined, it will throw an index error.
    Negative indices are not supported.

    :param index: a positive integer indicating the
           offset or a :func:`slice` object
    :raises IndexError: if index is beyond the range or a part is None
    :return: the requested part of the version at position index

    >>> ver = semver.Version.parse("3.4.5")
    >>> ver[0], ver[1], ver[2]
    (3, 4, 5)
    """
    if isinstance(index, int):
        index = slice(index, index + 1)
    index = cast(slice, index)

    if (
        isinstance(index, slice)
        and (index.start is not None and index.start < 0)
        or (index.stop is not None and index.stop < 0)
    ):
        raise IndexError("Version index cannot be negative")

    part = tuple(
        filter(lambda p: p is not None, cast(Iterable, self.to_tuple()[index]))
    )

    if len(part) == 1:
        return part[0]
    elif not part:
        raise IndexError("Version part undefined")
    return part

__init__

__init__(
    major: SupportsInt,
    minor: SupportsInt = 0,
    patch: SupportsInt = 0,
)

Initialize a DatasetVersion object.

Parameters:

Name Type Description Default
major SupportsInt

Major version number. Used to indicate schema changes.

required
minor SupportsInt

Minor version number. Used to indicate additional members added, or change in member values.

0
patch SupportsInt

Patch number of the dataset. Used to indicate minor clean-up and edits

0
Source code in src/deriva_ml/dataset/aux_classes.py
45
46
47
48
49
50
51
52
53
def __init__(self, major: SupportsInt, minor: SupportsInt = 0, patch: SupportsInt = 0):
    """Initialize a DatasetVersion object.

    Args:
        major: Major version number. Used to indicate schema changes.
        minor: Minor version number.  Used to indicate additional members added, or change in member values.
        patch: Patch number of the dataset.  Used to indicate minor clean-up and edits
    """
    super().__init__(major, minor, patch)

__iter__

__iter__() -> VersionIterator

Return iter(self).

Source code in semver/version.py
244
245
246
def __iter__(self) -> VersionIterator:
    """Return iter(self)."""
    yield from self.to_tuple()

bump_build

bump_build(
    token: Optional[str] = "build",
) -> Version

Raise the build part of the version, return a new object but leave self untouched.

:param token: defaults to 'build' :return: new :class:Version object with the raised build part. The original object is not modified.

ver = semver.parse("3.4.5-rc.1+build.9") ver.bump_build() Version(major=3, minor=4, patch=5, prerelease='rc.1', build='build.10')

Source code in semver/version.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
    def bump_build(self, token: Optional[str] = "build") -> "Version":
        """
        Raise the build part of the version, return a new object but leave self
        untouched.

        :param token: defaults to ``'build'``
        :return: new :class:`Version` object with the raised build part.
            The original object is not modified.

        >>> ver = semver.parse("3.4.5-rc.1+build.9")
        >>> ver.bump_build()
        Version(major=3, minor=4, patch=5, prerelease='rc.1', \
build='build.10')
        """
        cls = type(self)
        if self._build is not None:
            build = self._build
        elif token == "":
            build = "0"
        elif token is None:
            build = "build.0"
        else:
            build = str(token) + ".0"

        # self._build or (token or "build") + ".0"
        build = cls._increment_string(build)
        if self._build is not None:
            build = self._build
        elif token == "":
            build = "0"
        elif token is None:
            build = "build.0"
        else:
            build = str(token) + ".0"

        # self._build or (token or "build") + ".0"
        build = cls._increment_string(build)
        return cls(self._major, self._minor, self._patch, self._prerelease, build)

bump_major

bump_major() -> Version

Raise the major part of the version, return a new object but leave self untouched.

:return: new object with the raised major part

ver = semver.parse("3.4.5") ver.bump_major() Version(major=4, minor=0, patch=0, prerelease=None, build=None)

Source code in semver/version.py
266
267
268
269
270
271
272
273
274
275
276
277
278
def bump_major(self) -> "Version":
    """
    Raise the major part of the version, return a new object but leave self
    untouched.

    :return: new object with the raised major part

    >>> ver = semver.parse("3.4.5")
    >>> ver.bump_major()
    Version(major=4, minor=0, patch=0, prerelease=None, build=None)
    """
    cls = type(self)
    return cls(self._major + 1)

bump_minor

bump_minor() -> Version

Raise the minor part of the version, return a new object but leave self untouched.

:return: new object with the raised minor part

ver = semver.parse("3.4.5") ver.bump_minor() Version(major=3, minor=5, patch=0, prerelease=None, build=None)

Source code in semver/version.py
280
281
282
283
284
285
286
287
288
289
290
291
292
def bump_minor(self) -> "Version":
    """
    Raise the minor part of the version, return a new object but leave self
    untouched.

    :return: new object with the raised minor part

    >>> ver = semver.parse("3.4.5")
    >>> ver.bump_minor()
    Version(major=3, minor=5, patch=0, prerelease=None, build=None)
    """
    cls = type(self)
    return cls(self._major, self._minor + 1)

bump_patch

bump_patch() -> Version

Raise the patch part of the version, return a new object but leave self untouched.

:return: new object with the raised patch part

ver = semver.parse("3.4.5") ver.bump_patch() Version(major=3, minor=4, patch=6, prerelease=None, build=None)

Source code in semver/version.py
294
295
296
297
298
299
300
301
302
303
304
305
306
def bump_patch(self) -> "Version":
    """
    Raise the patch part of the version, return a new object but leave self
    untouched.

    :return: new object with the raised patch part

    >>> ver = semver.parse("3.4.5")
    >>> ver.bump_patch()
    Version(major=3, minor=4, patch=6, prerelease=None, build=None)
    """
    cls = type(self)
    return cls(self._major, self._minor, self._patch + 1)

bump_prerelease

bump_prerelease(
    token: Optional[str] = "rc",
) -> Version

Raise the prerelease part of the version, return a new object but leave self untouched.

:param token: defaults to 'rc' :return: new :class:Version object with the raised prerelease part. The original object is not modified.

ver = semver.parse("3.4.5") ver.bump_prerelease().prerelease 'rc.2' ver.bump_prerelease('').prerelease '1' ver.bump_prerelease(None).prerelease 'rc.1'

Source code in semver/version.py
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
def bump_prerelease(self, token: Optional[str] = "rc") -> "Version":
    """
    Raise the prerelease part of the version, return a new object but leave
    self untouched.

    :param token: defaults to ``'rc'``
    :return: new :class:`Version` object with the raised prerelease part.
        The original object is not modified.

    >>> ver = semver.parse("3.4.5")
    >>> ver.bump_prerelease().prerelease
    'rc.2'
    >>> ver.bump_prerelease('').prerelease
    '1'
    >>> ver.bump_prerelease(None).prerelease
    'rc.1'
    """
    cls = type(self)
    if self._prerelease is not None:
        prerelease = self._prerelease
    elif token == "":
        prerelease = "0"
    elif token is None:
        prerelease = "rc.0"
    else:
        prerelease = str(token) + ".0"

    prerelease = cls._increment_string(prerelease)
    return cls(self._major, self._minor, self._patch, prerelease)

compare

compare(other: Comparable) -> int

Compare self with other.

:param other: the second version :return: The return value is negative if ver1 < ver2, zero if ver1 == ver2 and strictly positive if ver1 > ver2

Version.parse("1.0.0").compare("2.0.0") -1 Version.parse("2.0.0").compare("1.0.0") 1 Version.parse("2.0.0").compare("2.0.0") 0

Source code in semver/version.py
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
def compare(self, other: Comparable) -> int:
    """
    Compare self with other.

    :param other: the second version
    :return: The return value is negative if ver1 < ver2,
         zero if ver1 == ver2 and strictly positive if ver1 > ver2

    >>> Version.parse("1.0.0").compare("2.0.0")
    -1
    >>> Version.parse("2.0.0").compare("1.0.0")
    1
    >>> Version.parse("2.0.0").compare("2.0.0")
    0
    """
    cls = type(self)
    if isinstance(other, String.__args__):  # type: ignore
        other = cls.parse(other)
    elif isinstance(other, dict):
        other = cls(**other)
    elif isinstance(other, (tuple, list)):
        other = cls(*other)
    elif not isinstance(other, cls):
        raise TypeError(
            f"Expected str, bytes, dict, tuple, list, or {cls.__name__} instance, "
            f"but got {type(other)}"
        )

    v1 = self.to_tuple()[:3]
    v2 = other.to_tuple()[:3]
    x = _cmp(v1, v2)
    if x:
        return x

    rc1, rc2 = self.prerelease, other.prerelease
    rccmp = self._nat_cmp(rc1, rc2)

    if not rccmp:
        return 0
    if not rc1:
        return 1
    elif not rc2:
        return -1

    return rccmp

finalize_version

finalize_version() -> Version

Remove any prerelease and build metadata from the version.

:return: a new instance with the finalized version string

str(semver.Version.parse('1.2.3-rc.5').finalize_version()) '1.2.3'

Source code in semver/version.py
544
545
546
547
548
549
550
551
552
553
554
def finalize_version(self) -> "Version":
    """
    Remove any prerelease and build metadata from the version.

    :return: a new instance with the finalized version string

    >>> str(semver.Version.parse('1.2.3-rc.5').finalize_version())
    '1.2.3'
    """
    cls = type(self)
    return cls(self.major, self.minor, self.patch)

is_compatible

is_compatible(other: Version) -> bool

Check if current version is compatible with other version.

The result is True, if either of the following is true:

  • both versions are equal, or
  • both majors are equal and higher than 0. Same for both minors. Both pre-releases are equal, or
  • both majors are equal and higher than 0. The minor of b's minor version is higher then a's. Both pre-releases are equal.

The algorithm does not check patches.

.. versionadded:: 3.0.0

:param other: the version to check for compatibility :return: True, if other is compatible with the old version, otherwise False

Version(1, 1, 0).is_compatible(Version(1, 0, 0)) False Version(1, 0, 0).is_compatible(Version(1, 1, 0)) True

Source code in semver/version.py
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
def is_compatible(self, other: "Version") -> bool:
    """
    Check if current version is compatible with other version.

    The result is True, if either of the following is true:

    * both versions are equal, or
    * both majors are equal and higher than 0. Same for both minors.
      Both pre-releases are equal, or
    * both majors are equal and higher than 0. The minor of b's
      minor version is higher then a's. Both pre-releases are equal.

    The algorithm does *not* check patches.

    .. versionadded:: 3.0.0

    :param other: the version to check for compatibility
    :return: True, if ``other`` is compatible with the old version,
             otherwise False

    >>> Version(1, 1, 0).is_compatible(Version(1, 0, 0))
    False
    >>> Version(1, 0, 0).is_compatible(Version(1, 1, 0))
    True
    """
    if not isinstance(other, Version):
        raise TypeError(f"Expected a Version type but got {type(other)}")

    # All major-0 versions should be incompatible with anything but itself
    if (0 == self.major == other.major) and (self[:4] != other[:4]):
        return False

    return (
        (self.major == other.major)
        and (other.minor >= self.minor)
        and (self.prerelease == other.prerelease)
    )

is_valid classmethod

is_valid(version: str) -> bool

Check if the string is a valid semver version.

.. versionadded:: 2.9.1

.. versionchanged:: 3.0.0 Renamed from :meth:~semver.version.Version.isvalid

:param version: the version string to check :return: True if the version string is a valid semver version, False otherwise.

Source code in semver/version.py
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
@classmethod
def is_valid(cls, version: str) -> bool:
    """
    Check if the string is a valid semver version.

    .. versionadded:: 2.9.1

    .. versionchanged:: 3.0.0
       Renamed from :meth:`~semver.version.Version.isvalid`

    :param version: the version string to check
    :return: True if the version string is a valid semver version, False
             otherwise.
    """
    try:
        cls.parse(version)
        return True
    except ValueError:
        return False

match

match(match_expr: str) -> bool

Compare self to match a match expression.

:param match_expr: optional operator and version; valid operators are < smaller than > greater than >= greator or equal than <= smaller or equal than == equal != not equal :return: True if the expression matches the version, otherwise False

semver.Version.parse("2.0.0").match(">=1.0.0") True semver.Version.parse("1.0.0").match(">1.0.0") False semver.Version.parse("4.0.4").match("4.0.4") True

Source code in semver/version.py
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
def match(self, match_expr: str) -> bool:
    """
    Compare self to match a match expression.

    :param match_expr: optional operator and version; valid operators are
          ``<``   smaller than
          ``>``   greater than
          ``>=``  greator or equal than
          ``<=``  smaller or equal than
          ``==``  equal
          ``!=``  not equal
    :return: True if the expression matches the version, otherwise False

    >>> semver.Version.parse("2.0.0").match(">=1.0.0")
    True
    >>> semver.Version.parse("1.0.0").match(">1.0.0")
    False
    >>> semver.Version.parse("4.0.4").match("4.0.4")
    True
    """
    prefix = match_expr[:2]
    if prefix in (">=", "<=", "==", "!="):
        match_version = match_expr[2:]
    elif prefix and prefix[0] in (">", "<"):
        prefix = prefix[0]
        match_version = match_expr[1:]
    elif match_expr and match_expr[0] in "0123456789":
        prefix = "=="
        match_version = match_expr
    else:
        raise ValueError(
            "match_expr parameter should be in format <op><ver>, "
            "where <op> is one of "
            "['<', '>', '==', '<=', '>=', '!=']. "
            "You provided: %r" % match_expr
        )

    possibilities_dict = {
        ">": (1,),
        "<": (-1,),
        "==": (0,),
        "!=": (-1, 1),
        ">=": (0, 1),
        "<=": (-1, 0),
    }

    possibilities = possibilities_dict[prefix]
    cmp_res = self.compare(match_version)

    return cmp_res in possibilities

next_version

next_version(
    part: str,
    prerelease_token: str = "rc",
) -> Version

Determines next version, preserving natural order.

.. versionadded:: 2.10.0

This function is taking prereleases into account. The "major", "minor", and "patch" raises the respective parts like the bump_* functions. The real difference is using the "prerelease" part. It gives you the next patch version of the prerelease, for example:

str(semver.parse("0.1.4").next_version("prerelease")) '0.1.5-rc.1'

:param part: One of "major", "minor", "patch", or "prerelease" :param prerelease_token: prefix string of prerelease, defaults to 'rc' :return: new object with the appropriate part raised

Source code in semver/version.py
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
def next_version(self, part: str, prerelease_token: str = "rc") -> "Version":
    """
    Determines next version, preserving natural order.

    .. versionadded:: 2.10.0

    This function is taking prereleases into account.
    The "major", "minor", and "patch" raises the respective parts like
    the ``bump_*`` functions. The real difference is using the
    "prerelease" part. It gives you the next patch version of the
    prerelease, for example:

    >>> str(semver.parse("0.1.4").next_version("prerelease"))
    '0.1.5-rc.1'

    :param part: One of "major", "minor", "patch", or "prerelease"
    :param prerelease_token: prefix string of prerelease, defaults to 'rc'
    :return: new object with the appropriate part raised
    """
    cls = type(self)
    # "build" is currently not used, that's why we use [:-1]
    validparts = cls.NAMES[:-1]
    if part not in validparts:
        raise ValueError(
            f"Invalid part. Expected one of {validparts}, but got {part!r}"
        )
    version = self
    if (version.prerelease or version.build) and (
        part == "patch"
        or (part == "minor" and version.patch == 0)
        or (part == "major" and version.minor == version.patch == 0)
    ):
        return version.replace(prerelease=None, build=None)

    # Only check the main parts:
    if part in cls.NAMES[:3]:
        return getattr(version, "bump_" + part)()

    if not version.prerelease:
        version = version.bump_patch()
    return version.bump_prerelease(prerelease_token)

replace

replace(
    **parts: Union[int, Optional[str]],
) -> Version

Replace one or more parts of a version and return a new :class:Version object, but leave self untouched.

.. versionadded:: 2.9.0 Added :func:Version.replace

:param parts: the parts to be updated. Valid keys are: major, minor, patch, prerelease, or build :return: the new :class:~semver.version.Version object with the changed parts :raises TypeError: if parts contain invalid keys

Source code in semver/version.py
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
def replace(self, **parts: Union[int, Optional[str]]) -> "Version":
    """
    Replace one or more parts of a version and return a new :class:`Version`
    object, but leave self untouched.

    .. versionadded:: 2.9.0
       Added :func:`Version.replace`

    :param parts: the parts to be updated. Valid keys are:
      ``major``, ``minor``, ``patch``, ``prerelease``, or ``build``
    :return: the new :class:`~semver.version.Version` object with
      the changed parts
    :raises TypeError: if ``parts`` contain invalid keys
    """
    version = self.to_dict()
    version.update(parts)
    try:
        return type(self)(**version)  # type: ignore
    except TypeError:
        unknownkeys = set(parts) - set(self.to_dict())
        error = "replace() got %d unexpected keyword argument(s): %s" % (
            len(unknownkeys),
            ", ".join(unknownkeys),
        )
        raise TypeError(error)

to_dict

to_dict() -> dict[str, Any]

Returns:

Type Description
dict[str, Any]

dictionary of version information

Source code in src/deriva_ml/dataset/aux_classes.py
55
56
57
58
59
60
61
62
def to_dict(self) -> dict[str, Any]:
    """

    Returns:
        dictionary of version information

    """
    return {"major": self.major, "minor": self.minor, "patch": self.patch}

to_tuple

to_tuple() -> tuple[int, int, int]

Returns:

Type Description
tuple[int, int, int]

tuple of version information

Source code in src/deriva_ml/dataset/aux_classes.py
64
65
66
67
68
69
70
71
def to_tuple(self) -> tuple[int, int, int]:
    """

    Returns:
        tuple of version information

    """
    return self.major, self.minor, self.patch

VersionPart

Bases: Enum

Simple enumeration for semantic versioning.

Attributes:

Name Type Description
major int

Major version number

minor int

Minor version number

patch int

Patch version number

Source code in src/deriva_ml/dataset/aux_classes.py
23
24
25
26
27
28
29
30
31
32
33
34
35
class VersionPart(Enum):
    """Simple enumeration for semantic versioning.

    Attributes:
        major (int): Major version number
        minor (int): Minor version number
        patch (int): Patch version number

    """

    major = "major"
    minor = "minor"
    patch = "patch"