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
|
New Features
|
||||||
------------------------------
|
------------------------------
|
||||||
* Added `mangle` and `unmangle` as core functions
|
* Added `mangle` and `unmangle` as core functions
|
||||||
|
* `defclass` in Python 3 now supports specifying metaclasses and other
|
||||||
|
keyword arguments
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
------------------------------
|
------------------------------
|
||||||
|
@ -2057,11 +2057,12 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
bases_expr = []
|
bases_expr = []
|
||||||
bases = Result()
|
bases = Result()
|
||||||
|
keywords = []
|
||||||
if expressions:
|
if expressions:
|
||||||
base_list = expressions.pop(0)
|
base_list = expressions.pop(0)
|
||||||
if not isinstance(base_list, HyList):
|
if not isinstance(base_list, HyList):
|
||||||
raise HyTypeError(base_list, "Base classes must be a list.")
|
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()
|
body = Result()
|
||||||
|
|
||||||
@ -2092,7 +2093,7 @@ class HyASTCompiler(object):
|
|||||||
expressions,
|
expressions,
|
||||||
decorator_list=[],
|
decorator_list=[],
|
||||||
name=ast_str(class_name),
|
name=ast_str(class_name),
|
||||||
keywords=[],
|
keywords=keywords,
|
||||||
starargs=None,
|
starargs=None,
|
||||||
kwargs=None,
|
kwargs=None,
|
||||||
bases=bases_expr,
|
bases=bases_expr,
|
||||||
|
@ -214,6 +214,13 @@ def test_ast_good_defclass():
|
|||||||
can_compile("(defclass a [])")
|
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():
|
def test_ast_bad_defclass():
|
||||||
"Make sure AST can't compile invalid defclass"
|
"Make sure AST can't compile invalid defclass"
|
||||||
cant_compile("(defclass)")
|
cant_compile("(defclass)")
|
||||||
|
@ -37,3 +37,11 @@
|
|||||||
(setv x (+ x a))
|
(setv x (+ x a))
|
||||||
(else (setv x (+ x 50))))
|
(else (setv x (+ x 50))))
|
||||||
(assert (= x 53)))))
|
(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)
|
(assert (= (foo :b 20 :a 10 :c 30)
|
||||||
(, 10 20 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