Writing Your Own Methods

Changed in version 1.0.0: User parameters, previously passed as keyword arguments, are now passed as a single params argument.

If you need to customize how a versioningit step is carried out, you can write a custom function in a Python module in your project directory and point versioningit to that function as described under “Specifying the Method”.

When a custom function is called, it will be passed a step-specific set of arguments, as documented below, plus all of the parameters specified in the step’s subtable in pyproject.toml. (The arguments are passed as keyword arguments, so custom methods need to give them the same names as documented here.) For example, given the below configuration:

[tool.versioningit.vcs]
method = { module = "ving_methods", value = "my_vcs", module-dir = "tools" }
tag-dir = "tags"
annotated-only = true

versioningit will carry out the vcs step by calling my_vcs() in ving_methods.py in the tools/ directory with the arguments project_dir (set to the directory in which the pyproject.toml file is located) and params={"tag-dir": "tags", "annotated-only": True}.

If a user-supplied parameter to a method is invalid, the method should raise a versioningit.errors.ConfigError. If a method is passed a parameter that it does not recognize, it should ignore it (though it may log a warning).

If you choose to store your custom methods in your setup.py, be sure to place the call to setup() under an if __name__ == "__main__": guard so that the module can be imported without executing setup().

If you store your custom methods in a module other than setup.py that is not part of the project’s Python package (e.g., if the module is stored in a tools/ directory), you need to ensure that the module is included in your project’s sdists but not in wheels.

If your custom method depends on any third-party libraries, they must be listed in your project’s build-system.requires.

vcs

A custom vcs method is a callable with the following synopsis:

funcname(*, project_dir: str | pathlib.Path, params: dict[str, Any]) versioningit.VCSDescription
Parameters:
  • project_dir (path) – the path to a project directory

  • params (dict) – a collection of user-supplied parameters

Returns:

a description of the state of the version control repository at the directory

Return type:

versioningit.VCSDescription

Raises:

tag2version

A custom tag2version method is a callable with the following synopsis:

funcname(*, tag: str, params: dict[str, Any]) str
Parameters:
  • tag (str) – a tag retrieved from version control

  • params (dict) – a collection of user-supplied parameters

Returns:

a version string extracted from tag

Return type:

str

Raises:

versioningit.errors.InvalidTagError – if the tag cannot be parsed

next-version

A custom next-version method is a callable with the following synopsis:

funcname(*, version: str, branch: str | None, params: dict[str, Any]) str
Parameters:
  • version (str) – a project version (as extracted from a VCS tag)

  • branch (Optional[str]) – the name of the VCS repository’s current branch (if any)

  • params (dict) – a collection of user-supplied parameters

Returns:

a version string for use as the {next_version} field in [tool.versioningit.format] format templates.

Return type:

str

Raises:

versioningit.errors.InvalidVersionError – if version cannot be parsed

format

A custom format method is a callable with the following synopsis:

funcname(*, description: versioningit.VCSDescription, base_version: str, next_version: str, params: dict[str, Any]) str
Parameters:
  • description – a versioningit.VCSDescription returned by a vcs method

  • base_version (str) – a version string extracted from the VCS tag

  • next_version (str) – a “next version” calculated by the next-version step

  • params (dict) – a collection of user-supplied parameters

Returns:

the project’s final version string

Return type:

str

Changed in version 2.0.0: The version argument was renamed to base_version.

Note that the format method is not called if description.state is "exact", in which case the version returned by the tag2version step is used as the final version.

template-fields

A custom template-fields method is a callable with the following synopsis:

funcname(*, version: str, description: VCSDescription | None, base_version: str | None, next_version: str | None, params: dict[str, Any]) dict[str, Any]
Parameters:
  • version (str) – the project’s final version

  • description (Optional[VCSDescription]) – a versioningit.VCSDescription returned by a vcs method; None if the vcs method failed

  • base_version (Optional[str]) – a version string extracted from the VCS tag; None if the tag2version step or a previous step failed

  • next_version (Optional[str]) – a “next version” calculated by the next-version step; None if the step or a previous one failed

  • params (dict) – a collection of user-supplied parameters

Return type:

dict[str, Any]

write

A custom write method is a callable with the following synopsis:

funcname(*, project_dir: str | pathlib.Path, template_fields: dict[str, Any], params: dict[str, Any]) None
Parameters:
  • project_dir (path) – the path to a project directory

  • template_fields (dict) – a collection of variables to use in filling out templates, as calculated by the template-fields step

  • params (dict) – a collection of user-supplied parameters

Changed in version 2.0.0: version argument replaced with template_fields

onbuild

Added in version 1.1.0.

A custom onbuild method is a callable with the following synopsis:

funcname(*, file_provider: OnbuildFileProvider, is_source: bool, template_fields: dict[str, Any], params: dict[str, Any]) None

Modifies the files about to be included in an sdist or wheel

Parameters:
  • file_provider – an object for accessing files being built into an sdist or wheel

  • is_source (bool) – true if an sdist or other artifact that preserves source paths is being built, false if a wheel or other artifact that uses installation paths is being built

  • template_fields (dict) – a collection of variables to use in filling out templates, as calculated by the template-fields step

  • params (dict) – a collection of user-supplied parameters

Changed in version 2.0.0: version argument replaced with template_fields

Changed in version 3.0.0: build_dir argument replaced with file_provider

onbuild methods are provided with instances of the following abstract base classes for operating on:

class versioningit.OnbuildFileProvider[source]

Added in version 3.0.0.

An abstract base class for accessing files that are about to be included in an sdist or wheel currently being built

abstract get_file(source_path: str | PurePath, install_path: str | PurePath, is_source: bool) OnbuildFile[source]

Get an object for reading & writing a file in the project being built.

Parameters:
  • source_path – the path to the file relative to the root of the project’s source

  • install_path – the path to the same file when it’s in a wheel, relative to the root of the wheel (or, equivalently, the path to the file when it’s installed in a site-packages directory, relative to that directory)

  • is_sourceTrue if building an sdist or other artifact that preserves source paths, False if building a wheel or other artifact that uses install paths

class versioningit.OnbuildFile[source]

Added in version 3.0.0.

An abstract base class for opening a file in a project currently being built

abstract open(mode: TextMode = 'r', encoding: str | None = None, errors: str | None = None, newline: str | None = None) TextIO[source]
abstract open(mode: BinaryMode, encoding: None = None, errors: None = None, newline: None = None) IO[bytes]

Open the associated file. mode must be "r", "w", "a", "rb", "br", "wb", "bw", "ab", or "ba".

When opening a file for writing or appending, if the file does not already exist, any parent directories are created automatically.

Distributing Your Methods in an Extension Package

If you want to make your custom versioningit methods available for others to use, you can package them in a Python package and distribute it on PyPI. Simply create a Python package as normal that contains the method function, and specify the method function as an entry point of the project. The name of the entry point group is versioningit.STEP (though, for next-version and template-fields, the group is spelled with an underscore instead of a hyphen). For example, if you have a custom vcs method implemented as a foobar_vcs() function in mypackage/vcs.py, you would declare it as follows:

[options.entry_points]
versioningit.vcs =
    foobar = mypackage.vcs:foobar_vcs
[project.entry-points."versioningit.vcs"]
foobar = "mypackage.vcs:foobar_vcs"

Once your package is on PyPI, package developers can use it by including it in their build-system.requires and specifying the name of the entry point (For the entry point above, this would be foobar) as the method name in the appropriate subtable. For example, a user of the foobar method for the vcs step would specify it as:

[tool.versioningit.vcs]
method = "foobar"
# Parameters go here