Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Namespace package as extension to existing package

Is it possible to add something to namespace/path of existing package which is not a namespace package?

Lets say a have a extisting external package named package.

I use it in my project.py like this:

from package.module import Class

Is it possible to create package called extension to namespace of package so its importable from package.extension?

from package.module import Class
from package.extension.module import ExtensionClass

Is it possible to just install both packages using pip/setuptools without adding monkey patches into my project.py in which I want to import from both package and package.extension?


Partial Solution

I've been able to achieve what I need in two ways: by modifying original package and by monkey patching in project.py

Structure:

./test.py
./demo/test.py
./demo/__init__.py
./extension/demo/__init__.py
./extension/demo/extension/test.py
./extension/demo/extension/__init__.py
./extension/__init__.py

Contents of ./test.py:

import demo.test
demo.test.hello()

import demo.extension.test
demo.extension.test.hello()

Partial Solution 1 - modify original package

I've modified demo/__init__.py so it contains:

import pkgutil

__path__ = pkgutil.extend_path(__path__, __name__)

Execution example:

$ export PYTHONPATH=extension
$ python test.py 
Hello! I'm demo.
Hello! I'm extension.

Partial Solution 2 - modify original package

I've modified ./test.py so it contains monkey patch:

import pkgutil
import demo
demo.__path__ = pkgutil.extend_path(demo.__path__, demo.__name__)

import demo.test
demo.test.hello()

import demo.extension.test
demo.extension.test.hello()

Execution example:

$ export PYTHONPATH=extension
$ python test.py 
Hello! I'm demo.
Hello! I'm extension.

The problem (again)

One of the solution requires the owner of original package to allow extensions, the other solution requires monkey patching. Is there a possibility that package installed via setup.py/pip will not require chaning of original package or monkey patching?

like image 499
seler Avatar asked Oct 31 '22 23:10

seler


1 Answers

This may be not too helpful, but you can check Flask and some of its extensions sources. Flask extensions works exactly like you describe, eg.:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
like image 166
andrzej3393 Avatar answered Nov 15 '22 05:11

andrzej3393