Enable to work with Python projects containing lots of packages, of which you only want to develop some.
Reason this release was yanked:
brown bag
Project description
Mixed development source packages on top of stable constraints using pip
mxdev [mɪks dɛv] is a utility that makes it easy to work with Python projects containing lots of packages, of which you only want to develop some.
It builds on top of the idea to have stable version constraints and then develop from a VCS on top of it.
As part of the above use-case sometimes versions of the stable constraints need an override with a different (i.e. newer) version. Other software follow the same idea are mr.developer for Python's zc.buildout or mrs-developer for NPM packages.
Overview
mxdev procedure is:
- Configuration is read,
- Requirements and constraints (given in the configuration) are read.
- Sources from VCS are fetched into a target directory,
- Modified constraints (handled packages commented, overridden versions replaced) and requirements (handled packages as editable from sources) are written.
mxdev will not run pip for you!
Installation
pip install mxdev
mxdev >=4.0 needs pip version 23 at minimum to work properly
Quick Start
- Create
mx.iniconfiguration file:
[settings]
requirements-in = requirements.txt
requirements-out = requirements-mxdev.txt
constraints-out = constraints-mxdev.txt
# Custom variables for reuse
github = git+ssh://git@github.com/
[mypackage]
url = ${settings:github}myorg/mypackage.git
branch = main
extras = test
- Run mxdev to fetch sources and generate files:
mxdev
- Install with pip using the generated files:
pip install -r requirements-mxdev.txt
For more examples see the example/ directory.
Configuration
Configuration is done in an INI file (default: mx.ini) using configparser.ExtendedInterpolation syntax.
Settings Section [settings]
The main section must be called [settings], even if kept empty.
I/O Settings
| Option | Description | Default |
|---|---|---|
requirements-in |
Input requirements file (can be URL). Empty value = generate from INI only | requirements.txt |
requirements-out |
Output requirements with development sources as -e entries |
requirements-mxdev.txt |
constraints-out |
Output constraints (developed packages commented out) | constraints-mxdev.txt |
Behavior Settings
| Option | Description | Default |
|---|---|---|
default-target |
Target directory for VCS checkouts | ./sources |
threads |
Number of parallel threads for fetching sources | 4 |
offline |
Skip all VCS fetch operations (handy for offline work) | False |
default-install-mode |
Default install-mode for packages: direct or skip |
direct |
default-update |
Default update behavior: yes or no |
yes |
default-use |
Default use behavior (when false, sources not checked out) | True |
Package Overrides
version-overrides
Override package versions which are already defined in a dependent constraints file.
I.e. an upstream constraints.txt contains already somefancypackage==2.0.3.
Given that, for some reason (like with my further developed sources), we need version 3.0.0 of the above package.
Then in this section, this can be defined as:
[settings]
version-overrides =
somefancypackage==3.0.0
otherpackage==33.12.1
It is possible to add as many overrides as needed. When writing the constraints-out, the new version will be taken into account. If there is a source section defined for the same package, the source will be used and entries here are ignored.
Note: When using uv pip install the version overrides here are not needed, since it supports overrides natively.
With uv it is recommended to create an overrides.txt file with the version overrides and use uv pip install --override overrides.txt [..] to install the packages.
ignores
Ignore packages that are already defined in a dependent constraints file.
No new version will be provided.
This is specifically handy if a package is going to be installed editable from local file system (like -e .), but was already pinned in an upstream constraints file.
This can be defined as:
[settings]
ignores =
somefancypackage
otherpackage
main-package
mxdev can handle one Python package as main package directly via ini config. If defined, it will be added as last entry in the resulting requirements out file.
This can be defined as:
[settings]
main-package = -e .[test]
If the main package is defined in a dependent constraint file, its name must be added to ignores.
Advanced Settings
include
Include one or more other INI files.
The included file is read before the main file, so the main file overrides included settings. Included files may include other files. Innermost inclusions are read first.
If an included file is an HTTP-URL, it is loaded from there.
If the included file is a relative path, it is loaded relative to the parent's directory or URL.
Default: empty
directory
mxdev provides a default setting containing the current working directory which can be used inside package or custom sections:
[sectionname]
param = ${settings:directory}/some/path
Custom Variables
Additionally, custom variables can be defined as key = value pair.
Those can be referenced in other values as ${settings:key} and will be expanded there.
[settings]
github = git+ssh://git@github.com/
gitlab = git+ssh://git@gitlab.com/
Package Source Sections
Sections other than [settings] can define:
- Package sources:
[PACKAGENAME]- VCS sources to checkout and develop - Hook configuration:
[hookname-section]- Settings for mxdev extensions (see EXTENDING.md)
For package sources, the section name is the package name: [PACKAGENAME]
Basic Package Options
| Option | Type | Description | Default |
|---|---|---|---|
url |
required | VCS checkout URL | — |
vcs |
optional | Version control system: git, fs, svn, gitsvn, hg, bzr, darcs |
git |
branch |
optional | Branch name or tag to checkout | main |
extras |
optional | Comma-separated package extras (e.g., test,dev) |
empty |
subdirectory |
optional | Path to Python package when not in repository root | empty |
target |
optional | Custom target directory (overrides default-target) |
default-target |
pushurl |
optional | Writable URL for pushes (not applied after initial checkout) | — |
VCS Support Status:
git(stable, tested)fs(stable, tested) - local directory pseudo-VCSsvn,gitsvn,hg,bzr,darcs(unstable, tests need rewrite)
Installation Options
| Option | Description | Default |
|---|---|---|
install-mode |
direct: Install with pip -e PACKAGEPATHskip: Only clone, don't install |
default-install-mode |
use |
When false, source is not checked out and version not overridden |
default-use |
Git-Specific Options
| Option | Description | Default |
|---|---|---|
depth |
Git clone depth (shallow clone). Set GIT_CLONE_DEPTH=1 env var for global default |
full clone |
submodules |
Submodule handling: always, checkout, recursive (see below) |
always |
Git Submodule Modes
always(default): Git submodules will always be checked out, updated if already presentcheckout: Submodules only fetched during checkout, existing submodules stay untouchedrecursive: Fetches submodules recursively, results ingit clone --recurse-submoduleson checkout andsubmodule update --init --recursiveon update
Usage
Run mxdev (for more options run mxdev --help).
Mxdev will
- read the configuration from
mx.ini, - fetch the packages defined in the config file and
- write a requirements and constraints file.
Now, use the generated requirements and constraints files with i.e. pip install -r requirements-mxdev.txt.
Example Configuration
Example mx.ini
This looks like so:
[settings]
requirements-in = requirements.txt
requirements-out = requirements-mxdev.txt
constraints-out = constraints-mxdev.txt
version-overrides =
baz.baaz==1.9.32
ignores =
my.ignoredpackage
# custom variables
github = git+ssh://git@github.com/
mygit = git+ssh://git@git.kup.tirol/
[foo.bar]
url = ${settings:github}orga/foo.bar.git
branch = fix99
extras = test,baz
[kup.fancyproject]
url = ${settings:mygit}customers/fancycorp/kup.fancyproject.git
branch = fix99
extras = test,baz
More Examples
For comprehensive examples demonstrating all features, see the example/ directory.
Real-World Examples
Extending
The functionality of mxdev can be extended by hooks. This is useful to generate additional scripts or files or automate any other setup steps related to mxdev's domain.
See EXTENDING.md for complete documentation on creating mxdev extensions.
Rationale
Problem
There is a constraint file like -c constraints.txt with a package foo.bar with a version pin.
Then it is not possible to install this package in a requirements file editable like -r requirements.txt with -e git+ssh://git@github.com/orga/foo.bar.git@fix-99.
Neither it is possible to override inherited version constraints with custom ones.
Idea
A pre-processor fetches (as this can be an URL) and expands all -c SOMEOTHER_FILE_OR_URL and -r SOMEOTHER_FILE_OR_URL files into one, filtering out all packages given in a configuration file.
For each of those packages, a -e ... entry is generated instead and written to a new TARGET.txt.
Same is true for version overrides: a new entry is written to the resulting constraints file while the original version is disabled.
The configuration is read from a file mx.ini in ExtendedInterpolation INI syntax (YAML would be nice, but the package must have as less dependencies as possible to other packages).
Trivia
Mx (generally pronounced like mix [mɪks], or [məks] in the UK) is meant to be a gender-neutral alternative to the titles Mr. and Ms. but also associates with the word "mix".
Misc
The VCS-related code is taken from mr.developer.
Thanks to Florian Schulze and Contributors.
Contributing
If you want to help with the development (improvement, update, bug-fixing, ...) of mxdev this is a great idea!
The code is located in the GitHub MXStack Organization / mxdev.
You can fork it, work on the project and create a pull request.
Maintainers are Jens Klein and the BlueDynamics Alliance developer team.
We appreciate any contribution! If you have an idea, found a bug, want to drop us a question, or a release is needed, please just file an issue at the mxdev issue tracker.
Changes
4.1.1 (2025-10-20)
- Modernize release method with hatchling. See RELEASE.md [jensens]
- Modernize tox setup. [jensens]
- Modernize Github workflows. [jensens]
- Enhance test coverage [jensens]
- Fix Makefile. [jensens]
4.1.0 (2025-06-03)
-
Support environment variable
GIT_CLONE_DEPTHfor setting a default git depth for all checkouts. Useful for CI. [maurits] -
Fix #47: Do not add packages with capital names uncommented at the bottom ignore list when checked out. [petschki]
4.0.3 (2024-05-17)
- Fix #45: Packages with capital names do not get ignored when checked out. [jensens]
4.0.2 (2024-03-13)
- Fix #42: deprecated use of
pkg_resouresto load entry points and parse requirements. This enables mxdev to work on Python 3.12, wherepkg_resourcesis no longer installed by default in virtual_envs. [jensens]
4.0.1 (2024-03-01)
- Fix specifying out a revision (#40) [pbauer]
4.0.0 (2024-02-28)
-
Breaking: Remove
--preon sources from generatedrequirements-mxdev.txt. Usually it is not needed any longer, at least withy pip 23.x. This is a breaking change if you rely on the--preoption being present in the generated file. Now the--preoption should be added topip installwhen the generated file is used. This change enables the use of the generated file with the alternative pip replacementuv. [jensens] -
Breaking: Drop official support for Python 3.7 (it is end of life). [jensens]
-
Document
mx.inisectionsvcssetting. [jensens]
3.1.0 (2023-12-10)
- Feature: Provide
directorydefault setting [rnix] - Feature: Include other INI config files [jensens]
3.0.0 (2023-05-08)
- Removed leftover print [jensens]
3.0.0b3 (2023-04-23)
-
Fix usage of
--install-option='pre'and use--preoption in requirements files instead. The install options are deprecated in pip 23 which Plone switched to recently. More info: https://github.com/pypa/pip/issues/11358 https://discuss.python.org/t/passing-command-line-arguments-to-pip-install-after-install-options-deprecation/22981/6 [thet, fredvd] -
Fix reading sections from the config parser without defaults if the section contains a setting that also exists as default. [rnix]
-
Do not write constraints out to the file if no constraints are defined. [rnix]
-
Add the
main-packageoption to the settings. [rnix]
3.0.0b2 (2023-02-07)
-
In this package, use
pyproject.tomland markdown for README et al. [jensens] -
Add
useoption to sources, anddefault-useto the settings.default-useis true by default. When false, the source is not checked out, and the version for this package is not overridden. [maurits]
3.0.0b1 (2022-11-21)
-
Do not use
libvcs, but recycled and updated (type hints, tests)mr.developerVCS code. Code for GIT is tested well, code for SVN, Mercurial, Bazaar and DARCS needs contributors with knowledge in this area. Additional options, likepushurl, ... (see README) were added.pipstyle VCS URLs are not supported any longer. [jensens, rnix, zworkb] -
Config parser options are now considered case-sensitive. [rnix]
-
Do not fail
mxdevrun ifrequirements.txtis missing. [rnix] -
Add flag to only fetch repositories and skip generating files. [rnix]
-
Add flag to skip fetching of repositories. [rnix]
-
Add support for custom hooks. [rnix]
-
Rename
sources.initomx.iniin the documentation. [rnix] -
Introduce state object and pass it to read/fetch/write. State object contains all required runtime data. [rnix]
2.0.0 (2022-01-31)
-
Depend on pip 22, where interdependency mode is no longer needed. Remove all interdependency-related code. [jensens]
-
Better error message if the requirements-in file does not exist. [jensens]
-
Better last message with the full pip command. [jensens]
-
Allow empty
requirements-inconfiguration. [jensens]
1.1.0 (2021-12-29)
- Feature: Ignore existing constraints.
New setting
ignoreswith a list of packages (one per line) to ignore constraints without providing a version. [jensens]
1.0.1 (2021-12-21)
- Fix: If a developed package depends on another developed package the dependent package was ignored sometimes (!?).
Instead, the last release was taken.
Solution: Install it with the
--preoption in order to allow the other non-final/in-development release. [jensens]
1.0.0 (2021-12-12)
- Defaults for "outfiles" are
*-mxdev.txtnow. [jensens]
1.0.0b4 (2021-12-07)
- Fix interdependency mode. [jensens]
1.0.0b3 (2021-12-07)
- Fix: Do not apply override disabling on requirements. [jensens]
1.0.0b2 (2021-12-07)
- Add feature: version overrides. [jensens]
1.0.0b1 (2021-12-04)
-
Add
-sor--silentoption. [jensens] -
Beautified output. [jensens]
-
Fixed missing CR if
*.txtdoes not end with a newline. [jensens]
1.0.0a9 (2021-12-01)
- Added auto correction for pip URLs, so that GitHub or GitLab URLs can be used as copied in
sources.ini. [zworkb]
1.0.0a8 (2021-11-30)
-
Added interdependency handling to avoid manual dependency order resolution. [jensens, gogobd]
-
Added skip mode to exclude packages from installation (clone/update only). [jensens, gogobd]
-
Removed position feature. [jensens, gogobd]
1.0.0a7 (2021-11-30)
- Removed Workaround for libvcs and depend on libvcs>=0.10.1. [jensens]
1.0.0a6 (2021-11-30)
- Workaround for libvcs bug https://github.com/vcs-python/libvcs/issues/295 [jensens, gogobd]
1.0.0a5 (2021-11-30)
- Workaround for libvcs bug https://github.com/vcs-python/libvcs/issues/293 [jensens, gogobd]
1.0.0a4 (2021-11-29)
- Fix: editable can be configured to be processed before or after initial requirements. [jensens]
1.0.0a3 (2021-11-23)
- Fix #1: Re-run of pip vanishes committed changes [jensens]
1.0.0a2 (2021-11-21)
-
Fix/simplify packaging. [jensens]
-
Implement subdirectory editable install [jensens]
-
Implement package extras [jensens]
1.0.0a1 (2021-11-21)
- Initial work. [jensens]
License
Copyright (c) 2022-2025, mxstack Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mxdev-4.1.1.tar.gz.
File metadata
- Download URL: mxdev-4.1.1.tar.gz
- Upload date:
- Size: 57.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a1db1ec7f92b8ac416647fe448e399f6ef8c136032f5a640dcae493976cf0fa
|
|
| MD5 |
cab1581346444026949d4c5fd0e03122
|
|
| BLAKE2b-256 |
b27b459d16c3881c5f2d43a8f64e59e028bc9359c5ffb14052d1646cdf62c144
|
Provenance
The following attestation bundles were made for mxdev-4.1.1.tar.gz:
Publisher:
release.yaml on mxstack/mxdev
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxdev-4.1.1.tar.gz -
Subject digest:
8a1db1ec7f92b8ac416647fe448e399f6ef8c136032f5a640dcae493976cf0fa - Sigstore transparency entry: 623116533
- Sigstore integration time:
-
Permalink:
mxstack/mxdev@42f4178d7e213c0d4593619cee18e7f75e2cac0a -
Branch / Tag:
refs/tags/v4.1.1 - Owner: https://github.com/mxstack
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@42f4178d7e213c0d4593619cee18e7f75e2cac0a -
Trigger Event:
release
-
Statement type:
File details
Details for the file mxdev-4.1.1-py3-none-any.whl.
File metadata
- Download URL: mxdev-4.1.1-py3-none-any.whl
- Upload date:
- Size: 34.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
951526c7679a6dd10b295f1e40b026369a2ad6e6272d8b6c4ed88fbb3cc991c6
|
|
| MD5 |
864e16398764b199f3562f565a0db39f
|
|
| BLAKE2b-256 |
db0b24d41ed20c52e21f38f025ec1ced0cf20c83442f20149e56b38fa23a93c0
|
Provenance
The following attestation bundles were made for mxdev-4.1.1-py3-none-any.whl:
Publisher:
release.yaml on mxstack/mxdev
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mxdev-4.1.1-py3-none-any.whl -
Subject digest:
951526c7679a6dd10b295f1e40b026369a2ad6e6272d8b6c4ed88fbb3cc991c6 - Sigstore transparency entry: 623116537
- Sigstore integration time:
-
Permalink:
mxstack/mxdev@42f4178d7e213c0d4593619cee18e7f75e2cac0a -
Branch / Tag:
refs/tags/v4.1.1 - Owner: https://github.com/mxstack
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@42f4178d7e213c0d4593619cee18e7f75e2cac0a -
Trigger Event:
release
-
Statement type: