Make a custom class that inherits TextIOWrapper

300 views Asked by At

I am trying to make a method in a class which returns an object that behaves like a buffered file stream (python's built-in class, TextIOWrapper), Plus, I am trying to add some more features(method) on it.

It would look similar to:

class ReadFile:

    def __init__(self):
        self._i = 0

    def do_magic(self, file):
        # ...

        io = open(file)
        return io



if __name__ == "__main__":
    import pandas as pd

    rf = ReadFile()
    a = rf.do_magic("./data.csv")
    data = pd.read_csv(a) # this should work

    # a.desired_feature() # I want this as well

My first try was make a child class of TextIOWrapper and casting.


class _TextIOWrapper(io.TextIOWrapper):
    pass

# ...

    def do_magic(self, file):
        # ...

        io = open(file)

        io.__class__ = _TextIOWrapper
        return io

And it gives me an TypeError:

Traceback (most recent call last):
  File "d.py", line 56, in <module>
    a = rf.do_magic("./data.csv")
  File "d.py", line 45, in do_magic
    io.__class__ = _TextIOWrapper
TypeError: __class__ assignment only supported for heap types or ModuleType subclasses

My second try was adding the feature(method) on the built-in.

def add_method(cls):
    def decorator(func):
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            return func(*args, **kwargs)
        setattr(cls, func.__name__, wrapper)
        return func
    return decorator


@add_method(io.TextIOWrapper)
def desired_feature(self):
        return None

Which gives me another TypeError:

Traceback (most recent call last):
  File "d.py", line 26, in <module>
    @add_method(io.TextIOWrapper)
  File "d.py", line 21, in decorator
    setattr(cls, func.__name__, wrapper)
TypeError: can't set attributes of built-in/extension type '_io.TextIOWrapper'

Is there any other workaround that could make desired_feature() work?

0

There are 0 answers