File: defclass.hy

package info (click to toggle)
hy 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,632 kB
  • sloc: python: 7,299; makefile: 38; sh: 27
file content (146 lines) | stat: -rw-r--r-- 3,415 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
(defn test-defclass []
  (defclass A)
  (assert (isinstance (A) A)))


(defn test-defclass-inheritance []
  (defclass A [])
  (assert (isinstance (A) object))
  (defclass A [object])
  (assert (isinstance (A) object))
  (defclass B [A])
  (assert (isinstance (B) A))
  (defclass C [object])
  (defclass D [B C])
  (assert (isinstance (D) A))
  (assert (isinstance (D) B))
  (assert (isinstance (D) C))
  (assert (not (isinstance (A) D))))


(defn test-defclass-attrs []
  (defclass A []
    (setv x 42))
  (assert (= A.x 42))
  (assert (= (getattr (A) "x")  42)))


(defn test-defclass-attrs-fn []
  (defclass B []
    (setv x 42)
    (setv y (fn [self value]
      (+ self.x value))))
  (assert (= B.x 42))
  (assert (= (.y (B) 5) 47))
  (setv b (B))
  (setv B.x 0)
  (assert (= (.y b 1) 1)))


(defn test-defclass-dynamic-inheritance []
  (defclass A [((fn [] (if True list dict)))]
    (setv x 42))
  (assert (isinstance (A) list))
  (defclass A [((fn [] (if False list dict)))]
    (setv x 42))
  (assert (isinstance (A) dict)))


(defn test-defclass-no-fn-leak []
  (defclass A []
    (setv x (fn [] 1)))
  (try
   (do
    (x)
    (assert False))
   (except [NameError])))

(defn test-defclass-docstring []
  (defclass A []
    (setv __doc__ "doc string")
    (setv x 1))
  (setv a (A))
  (assert (= a.__doc__ "doc string"))
  (defclass B []
    "doc string"
    (setv x 1))
  (setv b (B))
  (assert (= b.x 1))
  (assert (= b.__doc__ "doc string"))
  (defclass MultiLine []
    "begin a very long multi-line string to make
     sure that it comes out the way we hope
     and can span 3 lines end."
    (setv x 1))
  (setv mL (MultiLine))
  (assert (= mL.x 1))
  (assert (in "begin" mL.__doc__))
  (assert (in "end" mL.__doc__)))

(defn test-defclass-macroexpand []
  (defmacro M [] `(defn x [self x] (setv self._x x)))
  (defclass A [] (M))
  (setv a (A))
  (a.x 1)
  (assert (= a._x 1)))

(defn test-defclass-syntax []
  "defclass syntax with properties and methods and side-effects"
  (setv foo 1)
  (defclass A []
    (setv x 1)
    (setv y 2)
    (global foo)
    (setv foo 2)
    (defn greet [self]
      "Greet the caller"

      "hello!"))
  (setv a (A))
  (assert (= a.x 1))
  (assert (= a.y 2))
  (assert foo 2)
  (assert (.greet a) "hello"))

(defn test-class-sideeffects []
  "defclass should run all expressions."
  (defn set-sentinel []
    (setv set-sentinel.set True))
  (setv set-sentinel.set False)

  (defclass A []
    (set-sentinel))

  (assert set-sentinel.set))


(defn test-pep-3115 []
  "Test setting a metaclass with `:metaclass`, and using `__prepare__`."

  (defclass MyDict [dict]
    (defn __setitem__ [self key value]
      (dict.__setitem__ self (+ "prefixed_" key) value)))
  (defclass MyMetaclass [type]
    (defn [classmethod] __prepare__ [metacls name bases]
      (MyDict)))
  (defclass MyClass [:metaclass MyMetaclass]
    (defn [classmethod] method [self] 1))

  (assert (= (MyClass.prefixed-method) 1)))


(defn test-pep-487 []
  (defclass QuestBase []
    (defn __init-subclass__ [cls swallow #** kwargs]
      (setv cls.swallow swallow)))

  (defclass Quest [QuestBase :swallow "african"])
  (assert (= (. (Quest) swallow) "african")))


(do-mac (when hy.compat.PY3_12 '(defn test-type-params []
  (import tests.resources.tp :as ttp)
  (defclass :tp [#^ int A  #** B] C)
  (assert (= (ttp.show C) [
    [ttp.TypeVar "A" int #()]
    [ttp.ParamSpec "B" None #()]])))))