Add metaclass support, support PEP 3115 and PEP 487
This commit is contained in:
parent
75af667fa1
commit
c663d38e33
2
NEWS.rst
2
NEWS.rst
@ -19,6 +19,8 @@ Other Breaking Changes
|
||||
New Features
|
||||
------------------------------
|
||||
* Added `mangle` and `unmangle` as core functions
|
||||
* `defclass` in Python 3 now supports specifying metaclasses and other
|
||||
keyword arguments
|
||||
|
||||
Bug Fixes
|
||||
------------------------------
|
||||
|
@ -2057,11 +2057,12 @@ class HyASTCompiler(object):
|
||||
|
||||
bases_expr = []
|
||||
bases = Result()
|
||||
keywords = []
|
||||
if expressions:
|
||||
base_list = expressions.pop(0)
|
||||
if not isinstance(base_list, HyList):
|
||||
raise HyTypeError(base_list, "Base classes must be a list.")
|
||||
bases_expr, bases, _ = self._compile_collect(base_list)
|
||||
bases_expr, bases, keywords = self._compile_collect(base_list, with_kwargs=PY3)
|
||||
|
||||
body = Result()
|
||||
|
||||
@ -2092,7 +2093,7 @@ class HyASTCompiler(object):
|
||||
expressions,
|
||||
decorator_list=[],
|
||||
name=ast_str(class_name),
|
||||
keywords=[],
|
||||
keywords=keywords,
|
||||
starargs=None,
|
||||
kwargs=None,
|
||||
bases=bases_expr,
|
||||
|
@ -214,6 +214,13 @@ def test_ast_good_defclass():
|
||||
can_compile("(defclass a [])")
|
||||
|
||||
|
||||
@pytest.mark.skipif(not PY3, reason="Python 3 supports class keywords")
|
||||
def test_ast_good_defclass_with_metaclass():
|
||||
"Make sure AST can compile valid defclass with keywords"
|
||||
can_compile("(defclass a [:metaclass b])")
|
||||
can_compile("(defclass a [:b c])")
|
||||
|
||||
|
||||
def test_ast_bad_defclass():
|
||||
"Make sure AST can't compile invalid defclass"
|
||||
cant_compile("(defclass)")
|
||||
|
@ -37,3 +37,11 @@
|
||||
(setv x (+ x a))
|
||||
(else (setv x (+ x 50))))
|
||||
(assert (= x 53)))))
|
||||
|
||||
(defn test-pep-487 []
|
||||
(defclass QuestBase []
|
||||
[--init-subclass-- (fn [cls swallow &kwargs kwargs]
|
||||
(setv cls.swallow swallow))])
|
||||
|
||||
(defclass Quest [QuestBase :swallow "african"])
|
||||
(assert (= (. (Quest) swallow) "african")))
|
||||
|
@ -84,3 +84,26 @@
|
||||
(assert (= (foo :b 20 :a 10 :c 30)
|
||||
(, 10 20 30)))))
|
||||
|
||||
(defn test-pep-3115 []
|
||||
(defclass member-table [dict]
|
||||
[--init-- (fn [self] (setv self.member-names []))
|
||||
|
||||
--setitem-- (fn [self key value]
|
||||
(if (not-in key self)
|
||||
(.append self.member-names key))
|
||||
(dict.--setitem-- self key value))])
|
||||
|
||||
(defclass OrderedClass [type]
|
||||
[--prepare-- (classmethod (fn [metacls name bases] (member-table)))
|
||||
|
||||
--new-- (fn [cls name bases classdict]
|
||||
(setv result (type.--new-- cls name bases (dict classdict)))
|
||||
(setv result.member-names classdict.member-names)
|
||||
result)])
|
||||
|
||||
(defclass MyClass [:metaclass OrderedClass]
|
||||
[method1 (fn [self] (pass))
|
||||
method2 (fn [self] (pass))])
|
||||
|
||||
(assert (= (. (MyClass) member-names)
|
||||
["__module__" "__qualname__" "method1" "method2"])))
|
||||
|
Loading…
Reference in New Issue
Block a user