How do you know a user doesn’t have the wrong version of when running your application?
– Simple, you bundle with your application. Here’s a short write-up on how you could go about doing just that.

What’s “vendoring”?

Bundling a third-party application with your own application is sometimes referred to as “vendoring”. By vendoring, you explicitly control which version of a dependency is being used with your application. Since there are numerous versions of you want to make sure your application is used with the version of you had in mind when designing your application.


It’s important to mention you cannot bundle any application with your own application. You must look into what you’re actually legally allowed to do. In the case with, it’s developed under the MIT license, which means you can do anything you like with it. You can even modify, sell your software with it bundled and keep it all closed source. However, speaking as a collaborator on the project, we’re always super happy to hear about what you’re doing with :)

Curious on different types of licensing?
– Check this out:

With that out of the way, let’s move on…

Python package folder structure

In this example, I’ll just create a simple folder structure where we’ll put the script in a “vendor” folder and our main app ( at the top level. The files makes it possible for Python to import the contents of the folders as modules.


The files can (and should most often) be left empty. Any contents in these files will be executed upon import, which is not in general cases desired. Instead the action will happen inside of

In short, this is how you load your vendored version of from within

from .vendor import Qt
from .vendor.Qt import QtWidgets

# and so on...

For a complete and working example, please see this git repo I set up:

Installation instructions

You now have a couple of options of where to tell your users to put your package, so that it can be run in Python. In essence, you need to put the package on a path where Python will search for it. You could use an existing path, already known to your Python interpreter, where it will already search automatically. To find out which paths are available, run the following from the Python interpreter:

>>> import site
>>> print(site.getsitepackages())
>>> print(site.getusersitepackages())

If you would rather specify a custom path where you’ll have the package sitting, you can tell Python to look for the package in a specific path:

>>> import site
>>> site.addsitedir(YOUR_PATH_HERE)  # add path containing myPackage to PYTHONPATH

For more info on the site package, see here.

For this example, I’m cloning the example git repository down onto my local macOS disk drive:

cd ~/code/repos
git clone

Running your application

Make sure the interpreter you’re using has either PySide, PyQt4, PySide2 or PyQt5 installed. Then import myapp from mypackage and, finally, run the function. I’m doing it like this:

>>> import site
>>> site.addsitedir('/Users/fredrik/code/repos/')
>>> import mypackage
>>> from mypackage import myapp

Pro tip #1: Semantic versioning

By using semantic versioning (aka “semver”) you can check the versions against e.g. a required minimum version which your application requires. One way of doing this is to utilize setuptool’s packaging.version.parse function:

>>> from packaging import version
>>> version.parse("1.0.0b1") < version.parse("1.0.1")

Pro tip #2: Making your package available on PyPi

If you wish to go even further and let users download your package from PyPi (via pip), you’ll need to add a file (and optionally a setup.cfg file if you e.g. wish to generate a universal wheel) and configure it accordingly. Then I’d recommend you create a wheel and finally upload that to PyPi. Read more about this over at the setuptools documentation.

Here’s the in the project as an example.


I previously covered vendoring in my Installing (advanced methods) blog post. Check it out for additional info.

How are you distributing

I’m curious on how you make available to users. Let me know in the comments below!