fluentpython / example-code-2e

Example code for Fluent Python, 2nd edition (O'Reilly 2022)
https://amzn.to/3J48u2J
MIT License
3.17k stars 902 forks source link

The code `checked_demo.py` in Chapter 24 has TypeError: 'title' type hint must be callable? #30

Open danli349 opened 1 year ago

danli349 commented 1 year ago

Hello,

I run the code in https://github.com/fluentpython/example-code-2e/tree/master/24-class-metaprog/checked/metaclass/checked_demo.py

#!/usr/bin/env python3

# tag::MOVIE_DEMO[]
from checkedlib import Checked

class Movie(Checked):
    title: str
    year: int
    box_office: float

if __name__ == '__main__':
    movie = Movie(title='The Godfather', year=1972, box_office=137)
    print(movie)
    print(movie.title)
    # end::MOVIE_DEMO[]

    try:
        # remove the "type: ignore" comment to see Mypy error
        movie.year = 'MCMLXXII'  # type: ignore
    except TypeError as e:
        print(e)
    try:
        blockbuster = Movie(title='Avatar', year=2009, box_office='billions')
    except TypeError as e:
        print(e)

There is a TypeError:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [2], in <cell line: 6>()
      1 #!/usr/bin/env python3
      2 
      3 # tag::MOVIE_DEMO[]
      4 from checkedlib import Checked
----> 6 class Movie(Checked):
      7     title: str
      8     year: int

File D:\books/python/0.   Fluent Python, 2nd Edition/example-code-2e/24-class-metaprog/checked/metaclass\checkedlib.py:107, in CheckedMeta.__new__(meta_cls, cls_name, bases, cls_dict)
    105 type_hints = cls_dict.get('__annotations__', {})  # <3>
    106 for name, constructor in type_hints.items():   # <4>
--> 107     field = Field(name, constructor)  # <5>
    108     cls_dict[name] = field  # <6>
    109     slots.append(field.storage_name)  # <7>

File D:\books/python/0.   Fluent Python, 2nd Edition/example-code-2e/24-class-metaprog/checked/metaclass\checkedlib.py:76, in Field.__init__(self, name, constructor)
     74 def __init__(self, name: str, constructor: Callable) -> None:
     75     if not callable(constructor) or constructor is type(None):
---> 76         raise TypeError(f'{name!r} type hint must be callable')
     77     self.name = name
     78     self.storage_name = '_' + name  # <1>

TypeError: 'title' type hint must be callable

My python version is Python 3.8.13.

Thanks

jackjyq commented 1 year ago

The type hint does not support python3.8, you need python3.9 or newer.

https://peps.python.org/pep-0585/#parameters-to-generics-are-available-at-runtime

danli349 commented 1 year ago

@jackjyq Ok Thanks