Installation¶
From packages¶
Easiest way is to install uv, then use it to run mdedup ad-hoc with the uvx command:
$ uvx --from mail-deduplicate mdedup
To install mdedup system-wide, use the uv tool command:
$ uv tool install mail-deduplicate
Then you can run mdedup directly:
$ mdedup --version
pipx is a great way to install Python applications globally:
$ pipx install mail-deduplicate
You can install the latest stable release and its dependencies with a simple pip call:
$ python -m pip install mail-deduplicate
Other variations includes:
$ pip install mail-deduplicate
$ pip3 install mail-deduplicate
If you have difficulties to use pip, see
pip’s own installation instructions.
Binaries¶
Binaries are compiled at each release, so you can skip the installation process above and download the standalone executables directly.
This is the preferred way of testing mdedup without polluting your machine. They also offer the possibility of running the CLI on older systems not supporting the minimal Python version required by mdedup.
Platform |
|
|
|---|---|---|
Linux |
||
macOS |
||
Windows |
All links above points to the latest released version of mdedup.
See also
Older releases If you need to test previous versions for regression, compatibility or general troubleshooting, you’ll find the old binaries attached as assets to past releases on GitHub.
Caution
Development builds
Each commit to the development branch triggers the compilation of binaries. This way you can easily test the bleeding edge version of mdedup and report any issue.
Look at the list of latest binary builds. Then select the latest Build & release/release.yaml workflow run and download the binary artifact corresponding to your platform and architecture.
Note
ABI targets
$ file ./mdedup*
./mdedup-linux-arm64.bin: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=520bfc6f2bb21f48ad568e46752888236552b26a, for GNU/Linux 3.7.0, stripped
./mdedup-linux-x64.bin: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=56ba24bccfa917e6ce9009223e4e83924f616d46, for GNU/Linux 3.2.0, stripped
./mdedup-macos-arm64.bin: Mach-O 64-bit executable arm64
./mdedup-macos-x64.bin: Mach-O 64-bit executable x86_64
./mdedup-windows-arm64.exe: PE32+ executable (console) Aarch64, for MS Windows
./mdedup-windows-x64.exe: PE32+ executable (console) x86-64, for MS Windows
Run mdedup¶
Mail Deduplicate should now be available system-wide:
$ mdedup --version
mdedup, version 7.0.0
(...)
If not, you can directly execute the module from Python:
$ python -m mail_deduplicate --version
mdedup, version 7.0.0
(...)
Shell completion¶
Completion for popular shell rely on Click feature.
Add this to ~/.bashrc:
eval "$(_MDEDUP_COMPLETE=bash_source mdedup)"
Add this to ~/.zshrc:
eval "$(_MDEDUP_COMPLETE=zsh_source mdedup)"
Add this to ~/.config/fish/completions/mdedup.fish:
eval (env _MDEDUP_COMPLETE=fish_source mdedup)
Alternatively, export the generated completion code as a static script to be executed:
$ _MDEDUP_COMPLETE=bash_source mdedup > ~/.mdedup-complete.bash
Then source it from ~/.bashrc:
. ~/.mdedup-complete.bash
$ _MDEDUP_COMPLETE=zsh_source mdedup > ~/.mdedup-complete.zsh
Then source it from ~/.zshrc:
. ~/.mdedup.zsh
_MDEDUP_COMPLETE=fish_source mdedup > ~/.config/fish/completions/mdedup.fish
Python dependencies¶
FYI, here is a graph of Python package dependencies:
flowchart TD
classDef missing stroke-dasharray: 5
arrow["arrow\n1.3.0"]
boltons["boltons\n25.0.0"]
bracex["bracex\n2.5.post1"]
certifi["certifi\n2025.1.31"]
charset-normalizer["charset-normalizer\n3.4.1"]
click-extra["click-extra\n4.15.0"]
click_0["click\n8.1.8"]
cloup["cloup\n3.0.7"]
distro["distro\n1.9.0"]
extra-platforms["extra-platforms\n2.1.0"]
idna["idna\n3.10"]
mail-deduplicate["mail-deduplicate\n7.6.2"]
mergedeep["mergedeep\n1.3.4"]
python-dateutil["python-dateutil\n2.9.0.post0"]
pyyaml["PyYAML\n6.0.2"]
requests["requests\n2.32.3"]
six["six\n1.17.0"]
tabulate["tabulate\n0.9.0"]
types-python-dateutil["types-python-dateutil\n2.9.0.20241206"]
urllib3["urllib3\n2.4.0"]
wcmatch["wcmatch\n10.0"]
xmltodict["xmltodict\n0.14.2"]
arrow -- ">=2.7.0" --> python-dateutil
arrow -- ">=2.8.10" --> types-python-dateutil
click-extra -- ">=2.0.0" --> extra-platforms
click-extra -- "~=0.14.2" --> xmltodict
click-extra -- "~=0.9" --> tabulate
click-extra -- "~=1.3.4" --> mergedeep
click-extra -- "~=10.0" --> wcmatch
click-extra -- "~=2.32.3" --> requests
click-extra -- "~=25.0.0" --> boltons
click-extra -- "~=3.0.5" --> cloup
click-extra -- "~=6.0.0" --> pyyaml
click-extra -- "~=8.1.8" --> click_0
cloup -- ">=8.0,<9.0" --> click_0
extra-platforms -- "~=1.9.0" --> distro
extra-platforms -- "~=25.0.0" --> boltons
mail-deduplicate -- "~=0.9" --> tabulate
mail-deduplicate -- "~=1.3.0" --> arrow
mail-deduplicate -- "~=25.0.0" --> boltons
mail-deduplicate -- "~=4.15.0" --> click-extra
python-dateutil -- ">=1.5" --> six
requests -- ">=1.21.1,<3" --> urllib3
requests -- ">=2,<4" --> charset-normalizer
requests -- ">=2.5,<4" --> idna
requests -- ">=2017.4.17" --> certifi
wcmatch -- ">=2.1.1" --> bracex