Qt donne accès au presse-papier via QApplication.clipboard(). Dans l'absolu, ce code fonctionnera :

>>> from PyQt5.QtWidgets import QApplication
>>> QApplication.clipboard().setText("azerty")

En pratique, cela ne fonctionne pas terrible (reproduit sur GNU/Linux et macOS, PyQt 5.11 et 5.13) :

>>> from PyQt5.QtWidgets import QApplication
>>> QApplication([]).clipboard().setText("azerty")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QClipboard has been deleted

>>> cb = QApplication([]).clipboard()
>>> cb
<PyQt5.QtGui.QClipboard object at 0x7f514d298708>
>>> cb.setText("azerty")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QClipboard has been deleted

>>> # PyQt 5.13+, avec un context manager
>>> from PyQt5.QtCore import QCoreApplication
>>> with QCoreApplication([]) as app:
...    print(QApplication.clipboard().text())
[1]    7604 segmentation fault  python

Si Qt n'est pas chaud, on peut tenter notre chance avec d'autres solutions spécifiques à chaque OS.
Nous allons créer 2 fonctions, simples d'utilisation :

# Store some text in the clipboard
copy("some text")

# Get clipboard data
paste()

GNU/Linux : xclip

Je pars sur xclip (mais xsel aurait pu faire l'affaire aussi).

from subprocess import PIPE, Popen, check_output

def copy(text: str) -> None:
    """Copy some *text* into the clipboard. The xclip tool needs to be installed.
    Emulate: echo "blablabla" | xclip -selection c
    """
    with Popen(["xclip", "-selection", "c"], stdin=PIPE) as p:
        p.stdin.write(text.encode("utf-8"))
        p.stdin.close()
        p.wait()

def paste() -> str:
    """Get the text data from the clipboard. The xclip tool needs to be installed.
    Emulate: xclip -selection c -o
    """
    data = check_output(["xclip", "-selection", "c", "-o"])
    return data.decode("utf-8")

macOS : pbcopy & pbpaste

Par chance, macOS contient déjà les outils nécessaires : pbcopy et pbpaste.

from subprocess import PIPE, Popen

def copy(text: str) -> None:
    """Copy some *text* into the clipboard.
    Emulate: echo "blablabla" | pbcopy w
    """
    with Popen(["pbcopy", "w"], stdin=PIPE) as p:
        p.stdin.write(text.encode("utf-8"))
        p.stdin.close()
        p.wait()

def paste() -> str:
    """Get the text data from the clipboard.
    Emulate: pbpaste r
    """
    data = subprocess.check_output(["pbpaste", "r"])
    return data.decode("utf-8")

À partir de macOS 10.11 (El Capitan), ces fonctions ne peuvent être utilisées lorsqu'il n'y a pas d'utilisateur connecté (ce qui est fréquent si vous pratiquez l'intégration continue). C'est une limitation de l'OS : il n'est plus possible d'avoir accès à CFPasteboardCreate quand il n'y a pas de pasteboard, càd quand la machine est bloquée à l'écran de connexion.

pbcopy[7531:6748886] CFPasteboardRef CFPasteboardCreate(CFAllocatorRef, CFStringRef) : failed to create global data

Une autre version de ces fonctions, utilisant PyObjC, souffre du même problème. Donc si une bonne âme trouve une solution, je suis preneur.

from AppKit import NSPasteboard, NSStringPboardType
from Foundation import NSString, NSUTF8StringEncoding

def copy(text: str) -> None:
    pb = NSPasteboard.generalPasteboard()
    pb.declareTypes_owner_([NSStringPboardType], None)
    newStr = NSString.stringWithString_(text)
    newData = newStr.nsstring().dataUsingEncoding_(NSUTF8StringEncoding)
    pb.setData_forType_(newData, NSStringPboardType)

def paste() -> str:
    pb = NSPasteboard.generalPasteboard()
    return pb.stringForType_(NSStringPboardType)

Windows : win32com

Sur Windows, nous pouvons utiliser win32clipboard pour accéder aux fonctions de l'OS.

import win32clipboard

def copy(text: str) -> None:
    """Copy some *text* into the clipboard.
    Emulate: CTRL + C
    """
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT)
    win32clipboard.CloseClipboard()

def paste() -> str:
    """Get the text data from the clipboard.
    Emulate: CTRL + V
    """
    win32clipboard.OpenClipboard()
    text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
    win32clipboard.CloseClipboard()
    return text