0

How to make this code run successfully and pass the mypy checks?

from datetime import datetime

class TimeStamp(str):
    """ID with a short form and a long form."""
    
    def __new__(cls, datetime) -> TimeStamp:
        short = str(datetime.timestamp())
        long = datetime.strftime("%Y-%m-%d %H:%M:%S")
        obj = str.__new__(cls, short)
        obj.short = short
        obj.long = long
        return obj

now = TimeStamp(datetime.now())
print(now)
print(now.long)

currently mypy untitled1.py results in the following errors:

untitled1.py:10: error: "TimeStamp" has no attribute "short"
untitled1.py:11: error: "TimeStamp" has no attribute "long"
untitled1.py:16: error: "TimeStamp" has no attribute "long"
Found 3 errors in 1 file (checked 1 source file)
Joooeey
  • 3,394
  • 1
  • 35
  • 49
  • Do you have a special reason to define `__new__` in your `TimeStamp` class? – tomjn Jun 09 '21 at 12:28
  • I was following this example: https://stackoverflow.com/questions/2673651/inheritance-from-str-or-int – Joooeey Jun 09 '21 at 12:34
  • I guess my question is why do you need to inherit from `str` at all? Presumably for some good reason. – tomjn Jun 09 '21 at 12:38
  • Good point. I was thinking about that for a while. This is for a much larger project and the class is actually a satellite image ID, not a timestamp. There are a bunch of functions already implemented that expect to receive a string but I've started adding type checks to many new other functions hat expect an ID object. I guess this could also be done with composition but it would require lots of changes to the codebase. – Joooeey Jun 09 '21 at 12:46

1 Answers1

0

MyPy is perfectly happy if I leave out the return type in __new__. But I have to make type annotations for the object attributes. So the solution looks like this:

from datetime import datetime

class TimeStamp(str):
    """ID with a short form and a long form."""
    
    short: str
    long: str
    
    def __new__(cls, datetime):
        short = str(datetime.timestamp())
        long = datetime.strftime("%Y-%m-%d %H:%M:%S")
        obj = str.__new__(cls, short)
        obj.short = short
        obj.long = long
        return obj

now = TimeStamp(datetime.now())
print(now)
print(now.long)

This passes the MyPy checks and can be run.

Joooeey
  • 3,394
  • 1
  • 35
  • 49