Skip to content

Version

version

The module implements version management following semantic versioning principles with custom adaptations for Arista EOS and CloudVision Portal (CVP) software versioning schemes.

Classes:

Name Description
SemVer:

Base class implementing semantic versioning with comparison and matching capabilities.

EosVersion:

Specialized version handling for Arista EOS software releases.

CvpVersion:

Specialized version handling for CloudVision Portal releases.

Attributes:

Name Type Description
major int

Major version number.

minor int

Minor version number.

patch int

Patch version number.

rtype Optional[str]

Release type (e.g., ‘M’ for maintenance, ‘F’ for feature).

other Any

Additional version information.

regex_version ClassVar[Pattern[str]]

Regular expression to extract version information.

regex_branch ClassVar[Pattern[str]]

Regular expression to extract branch information.

description str

A basic description of this class.

Examples:

# Basic SemVer usage:
>>> version = SemVer(major=4, minor=23, patch=3)
'4.23.3'

# EOS version handling:
>>> eos = EosVersion.from_str('4.23.3M')
>>> eos.branch
'4.23'

# CVP version handling:
>>> cvp = CvpVersion.from_str('2024.1.0')
>>> str(cvp)

The module enforces version format validation through regular expressions and provides comprehensive comparison operations (==, !=, <, <=, >, >=) between versions.

Note:
  • EOS versions follow the format: ..[M|F]
  • CVP versions follow the format: ..

CvpVersion

Bases: SemVer

A CloudVision Portal Version class that inherits from SemVer.

This class implements version management for CloudVision Portal (CVP) versions following a modified semantic versioning pattern where: - major version represents the year (e.g. 2024) - minor version represents feature releases - patch version represents bug fixes

Examples:

>>> version = CvpVersion(2024, 1, 0)
>>> str(version)
'2024.1.0'

Attributes:

Name Type Description
major int

The year component of the version (e.g. 2024).

minor int

The minor version number.

patch int

The patch version number.

rtype Optional[str]

Release type if any.

other Any

Additional version information if any.

regex_version ClassVar[Pattern[str]]

Regular expression to parse version strings.

regex_branch ClassVar[Pattern[str]]

Regular expression to parse branch version strings.

description str

Brief description of the class purpose.

EosVersion

Bases: SemVer

EosVersion object to play with version management in code.

Since EOS is not using strictly semver approach, this class mimics some functions from the semver library for Arista EOS versions. It is based on Pydantic and provides helpers for comparison.

Examples:

>>> version = EosVersion(major=4, minor=21, patch=1, rtype="M")
>>> print(version)
EosVersion(major=4, minor=21, patch=1, rtype='M', other=None)
>>> version = EosVersion.from_str('4.32.1F')
>>> print(version)
EosVersion(major=4, minor=32, patch=1, rtype='F', other=None)

Attributes:

Name Type Description
major int

Major version number, default is 4.

minor int

Minor version number, default is 0.

patch int

Patch version number, default is 0.

rtype Optional[str]

Release type, default is “F”.

other Any

Any other version information.

regex_version ClassVar[Pattern[str]]

Regular expression to extract version information.

regex_branch ClassVar[Pattern[str]]

Regular expression to extract branch information.

description str

A basic description of this class, default is “A Generic SemVer implementation”.

SemVer

Bases: BaseModel

A class to represent a Semantic Version (SemVer) based on pydanntic.

This class provides methods to parse, compare, and manipulate semantic versions. It supports standard semantic versioning with optional release type and additional version information.

Examples:

>>> version = SemVer(major=4, minor=23, patch=3, rtype="M")
>>> str(version)
'4.23.3M'
>>> version2 = SemVer.from_str('4.24.1F')
>>> version2.branch
'4.24'
>>> version < version2
True
>>> version.match("<=4.24.0")
True
>>> version.is_in_branch("4.23")
True

Attributes:

Name Type Description
major int

Major version number.

minor int

Minor version number.

patch int

Patch version number.

rtype Optional[str]

Release type (e.g., ‘M’ for maintenance, ‘F’ for feature).

other Any

Additional version information.

regex_version ClassVar[Pattern[str]]

Regular expression to extract version information.

regex_branch ClassVar[Pattern[str]]

Regular expression to extract branch information.

description str

A basic description of this class.

branch property

branch: str

Extract branch of version.

Returns:

Type Description
str

Branch from version.

__eq__

__eq__(other)

Implement eq function (==)

Source code in eos_downloader/models/version.py
257
258
259
260
@typing.no_type_check
def __eq__(self, other):
    """Implement __eq__ function (==)"""
    return self._compare(other) == 0

__ge__

__ge__(other)

Implement ge function (>=)

Source code in eos_downloader/models/version.py
286
287
288
289
290
@typing.no_type_check
def __ge__(self, other):
    # type: ignore
    """Implement __ge__ function (>=)"""
    return self._compare(other) >= 0

__gt__

__gt__(other)

Implement gt function (>)

Source code in eos_downloader/models/version.py
280
281
282
283
284
@typing.no_type_check
def __gt__(self, other):
    # type: ignore
    """Implement __gt__ function (>)"""
    return self._compare(other) > 0

__le__

__le__(other)

Implement le function (<=)

Source code in eos_downloader/models/version.py
274
275
276
277
278
@typing.no_type_check
def __le__(self, other):
    # type: ignore
    """Implement __le__ function (<=)"""
    return self._compare(other) <= 0

__lt__

__lt__(other)

Implement lt function (<)

Source code in eos_downloader/models/version.py
268
269
270
271
272
@typing.no_type_check
def __lt__(self, other):
    # type: ignore
    """Implement __lt__ function (<)"""
    return self._compare(other) < 0

__ne__

__ne__(other)

Implement nw function (!=)

Source code in eos_downloader/models/version.py
262
263
264
265
266
@typing.no_type_check
def __ne__(self, other):
    # type: ignore
    """Implement __nw__ function (!=)"""
    return self._compare(other) != 0

__str__

__str__() -> str

Standard str representation.

Return string for EOS version like 4.23.3M.

Returns:

Type Description
str

A standard EOS version string representing ...

Source code in eos_downloader/models/version.py
190
191
192
193
194
195
196
197
198
199
200
201
def __str__(self) -> str:
    """
    Standard str representation.

    Return string for EOS version like 4.23.3M.

    Returns
    -------
    str
        A standard EOS version string representing <MAJOR>.<MINOR>.<PATCH><RTYPE>.
    """
    return f"{self.major}.{self.minor}.{self.patch}{self.other if self.other is not None else ''}{self.rtype if self.rtype is not None else ''}"

from_str classmethod

from_str(semver: str) -> SemVer

Parse a string into a SemVer object.

This method parses a semantic version string or branch name into a SemVer object. It supports both standard semver format (x.y.z) and branch format.

Parameters:

Name Type Description Default
semver str

The version string to parse. Can be either a semantic version string (e.g., “1.2.3”) or a branch format.

required

Returns:

Type Description
SemVer

A SemVer object representing the parsed version. Returns an empty SemVer object if parsing fails.

Examples:

>>> SemVer.from_str("1.2.3")
SemVer(major=1, minor=2, patch=3)
>>> SemVer.from_str("branch-1.2.3")
SemVer(major=1, minor=2, patch=3)
Source code in eos_downloader/models/version.py
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
173
174
175
176
@classmethod
def from_str(cls, semver: str) -> SemVer:
    """Parse a string into a SemVer object.

    This method parses a semantic version string or branch name into a SemVer object.
    It supports both standard semver format (x.y.z) and branch format.

    Parameters
    ----------
    semver : str
        The version string to parse. Can be either a semantic version
        string (e.g., "1.2.3") or a branch format.

    Returns
    -------
    SemVer
        A SemVer object representing the parsed version.
        Returns an empty SemVer object if parsing fails.

    Examples
    --------
    >>> SemVer.from_str("1.2.3")
    SemVer(major=1, minor=2, patch=3)
    >>> SemVer.from_str("branch-1.2.3")
    SemVer(major=1, minor=2, patch=3)
    """

    logging.debug(f"Creating SemVer object from string: {semver}")

    if cls.regex_version.match(semver):
        matches = cls.regex_version.match(semver)
        # assert matches is not None
        assert matches is not None
        logging.debug(f"Matches version: {matches}")
        return cls(**matches.groupdict())
    if cls.regex_branch.match(semver):
        matches = cls.regex_branch.match(semver)
        # assert matches is not None
        assert matches is not None
        logging.debug(f"Matches branch: {matches}")
        return cls(**matches.groupdict())
    logging.error(f"Error occured with {semver}")
    return SemVer()

is_in_branch

is_in_branch(branch_str: str) -> bool

Check if current version is part of a branch version.

Comparison is done across MAJOR and MINOR.

Parameters:

Name Type Description Default
branch_str str

A string for EOS branch. It supports following formats 4.23 or 4.23.0.

required

Returns:

Type Description
bool

True if current version is in provided branch, otherwise False.

Source code in eos_downloader/models/version.py
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
def is_in_branch(self, branch_str: str) -> bool:
    """
    Check if current version is part of a branch version.

    Comparison is done across MAJOR and MINOR.

    Parameters
    ----------
    branch_str : str
        A string for EOS branch. It supports following formats 4.23 or 4.23.0.

    Returns
    -------
    bool
        True if current version is in provided branch, otherwise False.
    """
    logging.info(f"Checking if {self} is in branch {branch_str}")
    try:
        branch = SemVer.from_str(branch_str)
    except Exception as error:  # pylint: disable = broad-exception-caught
        logger.error(exc_to_str(error))
    else:
        return self.major == branch.major and self.minor == branch.minor
    return False

match

match(match_expr: str) -> bool

Compare self to match a match expression.

Parameters:

Name Type Description Default
match_expr str

Optional operator and version; valid operators are: < smaller than > greater than >= greater or equal than <= smaller or equal than == equal != not equal.

required

Raises:

Type Description
ValueError

If input has no match_expr nor match_ver.

Returns:

Type Description
bool

True if the expression matches the version, otherwise False.

Examples:

>>> eos_version.match("<=4.23.3M")
True
>>> eos_version.match("==4.23.3M")
False
Source code in eos_downloader/models/version.py
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
def match(self, match_expr: str) -> bool:
    """
    Compare self to match a match expression.

    Parameters
    ----------
    match_expr : str
        Optional operator and version; valid operators are:
          ``<``   smaller than
          ``>``   greater than
          ``>=``  greater or equal than
          ``<=``  smaller or equal than
          ``==``  equal
          ``!=``  not equal.

    Raises
    ------
    ValueError
        If input has no match_expr nor match_ver.

    Returns
    -------
    bool
        True if the expression matches the version, otherwise False.

    Examples
    --------
    >>> eos_version.match("<=4.23.3M")
    True
    >>> eos_version.match("==4.23.3M")
    False
    """
    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 "
            "['<', '>', '==', '<=', '>=', '!=']. "
            f"You provided: {match_expr}"
        )
    possibilities_dict = {
        ">": (1,),
        "<": (-1,),
        "==": (0,),
        "!=": (-1, 1),
        ">=": (0, 1),
        "<=": (-1, 0),
    }
    possibilities = possibilities_dict[prefix]
    cmp_res = self._compare(SemVer.from_str(match_version))

    return cmp_res in possibilities