{"id":6148,"library":"pyobjc-framework-networkextension","title":"PyObjC Framework NetworkExtension","description":"PyObjC Framework NetworkExtension provides Python wrappers for Apple's NetworkExtension framework on macOS. It enables Python applications to interact with system-level networking features, such as VPN configuration and management. Currently at version 12.1, this library is part of the larger PyObjC project, which generally aligns its release cadence with new macOS SDK versions.","status":"active","version":"12.1","language":"en","source_language":"en","source_url":"https://github.com/ronaldoussoren/pyobjc","tags":["macOS","PyObjC","NetworkExtension","system-api","networking"],"install":[{"cmd":"pip install pyobjc-framework-NetworkExtension","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Provides the core Python-Objective-C bridge functionality required by all PyObjC framework bindings.","package":"pyobjc-core","optional":false}],"imports":[{"note":"PyObjC maps Objective-C frameworks directly to Python modules with the same name.","symbol":"NetworkExtension","correct":"import NetworkExtension"},{"symbol":"NEVPNManager","correct":"from NetworkExtension import NEVPNManager"}],"quickstart":{"code":"import NetworkExtension\nimport objc\nfrom Foundation import NSLog\nimport threading\n\n# Note: Accessing NetworkExtension APIs typically requires specific\n# entitlements in your application's Info.plist and proper code signing.\n# This script may require root privileges or fail without them.\n\ndef completion_handler(managers, error):\n    if error:\n        NSLog('Error loading VPN configurations: %@', error)\n    elif managers:\n        NSLog('Found %d VPN configurations:', len(managers))\n        for manager in managers:\n            NSLog('  - Name: %@, Enabled: %@', manager.localizedDescription(), 'Yes' if manager.enabled() else 'No')\n    else:\n        NSLog('No VPN configurations found.')\n    \n    # Signal that the async operation is complete\n    completion_event.set()\n\nNSLog('Attempting to load VPN configurations...')\n\n# Use a threading.Event to wait for the asynchronous callback in a script\ncompletion_event = threading.Event()\n\nmanager_class = NetworkExtension.NEVPNManager\nmanager = manager_class.sharedManager()\n\n# loadAllFromPreferencesWithCompletionHandler_ is an asynchronous call.\n# The Objective-C block is automatically translated to a Python callable.\nmanager.loadAllFromPreferencesWithCompletionHandler_(completion_handler)\n\n# Wait for the completion handler to be called (max 5 seconds)\ncompletion_event.wait(5.0)\n\nNSLog('Quickstart finished.')\n","lang":"python","description":"This quickstart demonstrates how to list existing VPN configurations using `NEVPNManager`. It retrieves the shared manager instance, asynchronously loads all VPN preferences, and prints the names and enabled status of any found configurations. Note that proper entitlements and code signing are usually required for real-world usage of NetworkExtension APIs."},"warnings":[{"fix":"Upgrade to Python 3.10 or newer, or use an older PyObjC version compatible with your Python environment.","message":"PyObjC 12.0 (and thus pyobjc-framework-networkextension 12.0) dropped support for Python 3.9. PyObjC 11.0 dropped support for Python 3.8. Ensure your Python version meets the `requires_python` specification (currently >=3.10).","severity":"breaking","affected_versions":">=11.0"},{"fix":"Review custom Python-implemented Objective-C classes, especially `__new__` and `__init__` methods, to ensure correct reference handling under the updated ARC semantics. Consult PyObjC's documentation on initializer methods.","message":"Starting with PyObjC 11.1, the core bridge's Automatic Reference Counting (ARC) behavior for Objective-C initializer methods (`init` family) was aligned with `clang`'s documentation. This means `init` methods now correctly 'steal' a reference to `self` and return a new one. This can affect custom Objective-C classes implemented in Python, particularly in how references are managed during initialization.","severity":"breaking","affected_versions":">=11.1"},{"fix":"If implementing Objective-C classes in Python and providing a custom `__new__`, ensure `__init__` is used as expected. If relying on PyObjC's default `__new__`, be aware that `__init__` might not be called in the traditional Python sense for initial object setup.","message":"PyObjC 10.3 initially removed support for calling `__init__` when a user-defined `__new__` was present in an Objective-C class implemented in Python. While 10.3.1 re-enabled this for user-implemented `__new__`, `__init__` still cannot be used when relying on PyObjC's *default* `__new__` implementation.","severity":"gotcha","affected_versions":"10.3.x"},{"fix":"Always consult Apple's Developer documentation for framework deprecations when updating macOS or PyObjC. Be prepared to update code if a framework or specific APIs are removed.","message":"Framework bindings can be removed following Apple's deprecation schedule. For example, `IMServicePlugIn` bindings were removed in PyObjC 10.0 because the framework was deprecated in macOS 10.13 and removed in macOS 14.","severity":"breaking","affected_versions":">=10.0"},{"fix":"When working with Cocoa URL objects, ensure `os.fspath()` is only called on URLs known to refer to local filesystem paths. For other URL types, use appropriate `NSURL` or `CFURLRef` methods for path extraction or conversion.","message":"As of PyObjC 10.1, `os.fspath(someURL)` will raise a `TypeError` if the provided Cocoa `NSURL` or `CFURLRef` object does *not* refer to a local filesystem path. It correctly works for local filesystem paths, enabling their use with Python's filesystem APIs.","severity":"gotcha","affected_versions":">=10.1"},{"fix":"If using Python 3.13 with experimental free-threading, thoroughly test your PyObjC applications. Consider running without free-threading enabled if stability issues arise, or stick to older Python versions if strict stability is paramount.","message":"Experimental free-threading support (PEP 703) introduced in Python 3.13 is *experimentally* supported by PyObjC 11.0. Older versions like 10.3 explicitly stated they did not support it. While `pyobjc-core` 12.1 is listed as compatible with 'Python :: Free Threading :: 3 - Stable' on PyPI, users should exercise caution with experimental features.","severity":"gotcha","affected_versions":">=10.3"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}