Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

ctypes-unicode-proclaunch

A minimal, robust, and Unicode-aware process launching library using ctypes.

  • No:
    • Shell involvement: Arguments are not interpolated or globbed by any shell, ensuring "what you pass is what you get".
    • Python subprocess abstractions: No Popen/communicate/universal_newlines/encoding drama.
  • Yes:
    • Native system call usage for maximum control and correctness.
      • CreateProcessW (NT)
      • fork and execve (POSIX)
    • Unicode on both Python 2 and 3.
    • Fully typed.

Features

  • Precise Process Spawning: Direct system call wrappers, not wrappers around wrappers.
  • Escape-proof Argument Passing: Arguments are not interpreted or glob-expanded.
  • Full Unicode Support: Give and receive Unicode paths/arguments everywhere.
  • Explicit Environment: Can supply a Unicode environment dictionary. Does not mutate global environment variables.
  • Handles Redirection: Pass open file descriptors for stdin, stdout, stderr just like with the C API.

Installation

pip install ctypes-unicode-proclaunch

Usage

Process Launched

A Python script print_argv.py:

# coding=utf-8
from __future__ import print_function
import sys

if __name__ == '__main__':
    for i, arg in enumerate(sys.argv):
        print('sys.argv[%d]=%s' % (i, arg))

NT

# coding=utf-8
from ctypes_unicode_proclaunch import launch, wait

# No `cmd.exe`'s handling of special characters:
process_handle_1 = launch([u'python', u'print_argv.py', u'%USERNAME%'])
wait(process_handle_1)
# sys.argv[0]=print_argv.py
# sys.argv[1]=%USERNAME%

process_handle_2 = launch([u'python', u'print_argv.py', u'Hello', u'&', u'python', u'print_argv.py', u'injected'])
wait(process_handle_2)
# sys.argv[0]=print_argv.py
# sys.argv[1]=Hello
# sys.argv[2]=&
# sys.argv[3]=python
# sys.argv[4]=print_argv.py
# sys.argv[5]=injected

process_handle_3 = launch([u'python', u'print_argv.py', u'*.txt'])
wait(process_handle_3)
# sys.argv[0]=print_argv.py
# sys.argv[1]=*.txt

POSIX

# coding=utf-8
from ctypes_unicode_proclaunch import launch, wait

pid_1 = launch([u'python', u'print_argv.py', u'$HOME'])
wait(pid_1)
# sys.argv[0]=print_argv.py
# sys.argv[1]=$HOME

pid_2 = launch([u'python', u'print_argv.py', u'"test"', u'>', u'$file'])
wait(pid_2)
# sys.argv[0]=print_argv.py
# sys.argv[1]="test"
# sys.argv[2]=>
# sys.argv[3]=$file

pid_3 = launch([u'python', u'print_argv.py', u'*.txt'])
wait(pid_3)
# sys.argv[0]=print_argv.py
# sys.argv[1]=*.txt

Custom Environment and File Redirection

# coding=utf-8
from ctypes_unicode_proclaunch import launch, wait
from read_unicode_environment_variables_dictionary import read_unicode_environment_variables_dictionary

# Doesn't modify `os.environ`
unicode_environment_variables_dictionary = read_unicode_environment_variables_dictionary()
unicode_environment_variables_dictionary[u'COVERAGE_FILE'] = u'test_coverage.sqlite3'

# We pass the file descriptors of the opened files for redirection.
# Just as in the Unix C API.
# The launched processes DO NOT respect the encodings you specified if you opened the files in text mode.
# This means that you should always open files in binary mode (`'rb'`, `'wb'`, etc.) to make that explicit.
with open('test_stdin.txt', 'rb') as f_0, open('test_stdout.txt', 'wb') as f_1, open('test_stderr.txt', 'wb') as f_2:
    pid_or_process_handle = launch(
        [u'python', u'-m', u'coverage', u'run', u'test.py'],
        environment=unicode_environment_variables_dictionary,
        stdin_file_descriptor=f_0.fileno(),
        stdout_file_descriptor=f_1.fileno(),
        stderr_file_descriptor=f_2.fileno()
    )
    wait(pid_or_process_handle)

Contributing

Contributions are welcome! Please submit pull requests or open issues on the GitHub repository.

License

This project is licensed under the MIT License.

Release files for ctypes-unicode-proclaunch 0.1.0a5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ctypes-unicode-proclaunch 0.1.0a5
File Size Uploaded
ctypes_unicode_proclaunch-0.1.0a5.tar.gz 14.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ctypes-unicode-proclaunch 0.1.0a5
File Interpreter ABI Platform
ctypes_unicode_proclaunch-0.1.0a5-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 24.4 kB

Release files / ctypes_unicode_proclaunch-0.1.0a5.tar.gz

Download URL ctypes_unicode_proclaunch-0.1.0a5.tar.gz
Size 14.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c8ab699592945c04fa035ea982a0d97284782e8658b243787601b9aac9b1ac23
BLAKE2b-256 checksum
How to use checksums
71971bdaea8657d3b748ad72a5ab6f11b2645e6ea8a06d6e289c8d94162c7c9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / ctypes_unicode_proclaunch-0.1.0a5-py2.py3-none-any.whl

Download URL ctypes_unicode_proclaunch-0.1.0a5-py2.py3-none-any.whl
Size 10.4 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
1bc8a98f35dcc8e496b4b2139bcdf426ae6b146316fd2fe8cbaa1d63c1cabeae
BLAKE2b-256 checksum
How to use checksums
49a19bf50fd27f4029d2013d1b83c5f5fd337ebbe65b17c1b8451d94002a358c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page