**Make a test driver script to see what works what doesn't.**

_Using textblock as a driver variable target was going to be an other suggestion re your question on bringing in a text datablock when linking._  

**Re Text blocks**

Speculatively at issue here is drivers use evaluated scene objects, and text objects don't get evaluated... a custom prop may not update in the driver if animated.

    >>> eto = D.texts['Text'].evaluated_get(C.evaluated_depsgraph_get())
    >>> eto
    bpy.data.texts['Text']
    
    >>> eto.is_evaluated
    False

**A simple test driver**

_To fiddle about with drivers I often make use of this little test script_

 - Use `use_self` to pass the evaluated object. \

- Can pass all driver
   variables as as `locals()`

Generic test script.

    import bpy

    def test(*args, **kwargs):
        for arg in args:
            print(arg)
            
        return -1 # a simple val to indicate working

    bpy.app.driver_namespace["test"] = test

Now set up a driver and test the test.

[![enter image description here][1]][1]

The driver is on object "Circle", the text object evaluates to `None` as do most. However the matrix world of the cube object is passed.  As is the depsgraph the driver is using to evaluate the objects.

    <bpy_struct, Object("Circle") at 0x7f1cb1372e08, evaluated>
    {'text': None, 'var': Matrix(((1.0, 0.0, 0.0, 0.0),
            (0.0, 1.0, 0.0, 0.0),
            (0.0, 0.0, 1.0, 0.0),
            (0.0, 0.0, 0.0, 1.0))), 'depsgraph': <bpy_struct, Depsgraph at 0x7f1cbeb80108>}


[![enter image description here][2]][2]
_Adding a rotate driver on cube, the console shows updates the values for both viewing and rendering animation_

Now from the matrix world it appears we have all the transforms of the Cube object in our driver in one fell swoop.

The ideology of a driver is to return an int or float as the value of the driven property. Will find however can make this driver a "pseudo" copy transform constraint by adding before the return statement and re-running driver.

    args[0].matrix_world = args[1]['var']

which using better names is `self.matrix_world = cube.matrix_world`   If say the x location is being driven by this, then it is given that value and all others are taken from the matrix world..  This is **abuse** of the driver system .. but hey it's fun.

**Some answers using drivers**

This one adds drivers to drive material index of each face of a mesh
https://blender.stackexchange.com/a/183716/15543


  [1]: https://i.sstatic.net/6S4Zf.png
  [2]: https://i.sstatic.net/u8FP2.gif