summaryrefslogtreecommitdiff
path: root/modules/language/python/module
diff options
context:
space:
mode:
Diffstat (limited to 'modules/language/python/module')
-rw-r--r--modules/language/python/module/collections.scm113
-rw-r--r--modules/language/python/module/collections/abc.scm19
-rw-r--r--modules/language/python/module/enum.py47
-rw-r--r--modules/language/python/module/python.scm8
4 files changed, 104 insertions, 83 deletions
diff --git a/modules/language/python/module/collections.scm b/modules/language/python/module/collections.scm
index 1a158c9..04f7ab6 100644
--- a/modules/language/python/module/collections.scm
+++ b/modules/language/python/module/collections.scm
@@ -94,20 +94,19 @@
(define-python-class OrderedDict (dict)
(define __init__
(lam (self (* args) (** kwds))
+ ((ref dict '__init__) self)
+
(if (> (len args) 1)
(raise TypeError
(format #f
"expected at most 1 arguments, got ~a"
(len args))))
- (try
- (lambda () (ref self '__root))
- (#:except AttributeError =>
- (lambda x
- (let* ((l (link)))
- (set self '__root l)
- (set-next! l l)
- (set-prev! l l)))))
+ (if (not (ref self '__root))
+ (let* ((l (link)))
+ (set self '__root l)
+ (set-next! l l)
+ (set-prev! l l)))
(set self '__map (dict))
(py-apply py-update self (* args) (** kwds))))
@@ -127,7 +126,7 @@
(set-key! link key)
(set-next! last link)
(set-prev! root link)
- (dict_setitem self key value)))))
+ (dict-set! self key value)))))
(define __delitem__
(lam (self key (= dict_delitem dict-del!))
@@ -145,7 +144,7 @@
(lambda (yield)
(let ((root (ref self '__root)))
(let lp ((curr (get-next root)))
- (if ((not (eq? curr root)))
+ (if (not (eq? curr root))
(let ((key (get-key curr)))
(yield key (pylist-ref self key))
(lp (get-next curr)))))))))))
@@ -209,11 +208,16 @@
(define __update update)
(define keys
- (lambda (self) _OrderedDictKeysView(self)))
+ (lambda (self)
+ (_OrderedDictKeysView self)))
+
(define items
- (lambda (self) _OrderedDictItemsView(self)))
+ (lambda (self)
+ (_OrderedDictItemsView self)))
+
(define values
- (lambda (self) _OrderedDictValuesView(self)))
+ (lambda (self)
+ (_OrderedDictValuesView self)))
(define __ne__ (ref MutableMapping '__ne__))
@@ -645,51 +649,54 @@
(make-p-class (string->symbol typename) '(())
(lambda (dict)
- (pylist-set! dict '__init__
- (eval (v `(lam
- (self
- ,@(map (lambda (key) `(= ,key #f))
- field_names))
+ (pylist-set! dict '__init__
+ (object-method
+ (eval (v `(lam
+ (self
+ ,@(map (lambda (key) `(= ,key #f))
+ field_names))
- ,@(map (lambda (key) `(set self ',key ,key))
- field_names)))
- mod))
+ ,@(map (lambda (key) `(set self ',key ,key))
+ field_names)))
+ mod)))
- (pylist-set! dict '__getitem__
- (lam (self i)
- (if (number? i)
- (ref self (list-ref field_names i))
- (ref self (scm-sym i)))))
+ (pylist-set! dict '__getitem__
+ (object-method
+ (lambda (self i)
+ (if (number? i)
+ (ref self (list-ref field_names i))
+ (ref self (scm-sym i))))))
- (pylist-set! dict '__setitem__
- (lam (self i val)
- (if (number? i)
- (set self (list-ref field_names i) val)
- (set self (scm-sym i) val))))
-
- (pylist-set! dict '__repr__
- (lam (self)
- (let ((l (map (lambda (x)
- (format #f "~a=~a"
- x
- (ref self x)))
- field_names)))
-
- (format #f "~a(~a~{,~a~})"
- typename
- (car l)
- (cdr l)))))
+ (pylist-set! dict '__setitem__
+ (object-method
+ (lambda (self i val)
+ (if (number? i)
+ (set self (list-ref field_names i) val)
+ (set self (scm-sym i) val)))))
+
+ (pylist-set! dict '__repr__
+ (object-method
+ (lambda (self . l)
+ (let ((l (map (lambda (x)
+ (format #f "~a=~a"
+ x
+ (ref self x)))
+ field_names)))
+ (format #f "~a(~a~{,~a~})"
+ typename
+ (car l)
+ (cdr l))))))
- (if (eq? module None)
- (set! module (module-name (current-module)))
- (if (string? (scm-str module))
- (set! module
- (+ '(language python module)
- (map scm-sym
- (string-split module #\.))))))
-
- (if verbose (pretty-print verbose))))))
+ (if (eq? module None)
+ (set! module (module-name (current-module)))
+ (if (string? (scm-str module))
+ (set! module
+ (+ '(language python module)
+ (map scm-sym
+ (string-split module #\.))))))
+
+ (if verbose (pretty-print verbose))))))
(define UserDict dict)
(define UserString pystring)
diff --git a/modules/language/python/module/collections/abc.scm b/modules/language/python/module/collections/abc.scm
index 4bd242d..4d442d3 100644
--- a/modules/language/python/module/collections/abc.scm
+++ b/modules/language/python/module/collections/abc.scm
@@ -516,7 +516,10 @@
(define __iter__
(lambda (self)
- ((ref (ref self '_mapping) 'items)))))
+ ((make-generator ()
+ (lambda (yield)
+ (for ((k v : (ref self '_mapping))) ()
+ (yield (list k v)))))))))
(define-python-class KeysView (MappingView Set)
;; Mixins
@@ -524,10 +527,13 @@
(lambda (self k)
(let ((m (ref self '_mapping)))
(in k m))))
-
+
(define __iter__
(lambda (self)
- ((ref (ref self '_mapping) 'keys)))))
+ ((make-generator ()
+ (lambda (yield)
+ (for ((k v : (ref self '_mapping))) ()
+ (yield k))))))))
(define-python-class ValuesView (MappingView)
;; Mixins
@@ -541,6 +547,7 @@
(define __iter__
(lambda (self)
- ((ref (ref self '_mapping) 'values)))))
-
-
+ ((make-generator ()
+ (lambda (yield)
+ (for ((k v : (ref self '_mapping))) ()
+ (yield v))))))))
diff --git a/modules/language/python/module/enum.py b/modules/language/python/module/enum.py
index 0f623f0..723fab7 100644
--- a/modules/language/python/module/enum.py
+++ b/modules/language/python/module/enum.py
@@ -50,14 +50,12 @@ def _make_class_unpicklable(cls):
_auto_null = object()
-
class auto:
"""
Instances are replaced with an appropriate value in Enum class suites.
"""
value = _auto_null
-
class _EnumDict(dict):
"""Track enum member order and ensure member names are not reused.
@@ -90,10 +88,10 @@ class _EnumDict(dict):
elif _is_dunder(key):
if key == '__order__':
key = '_order_'
- elif key in self._member_names:
+ elif (key in self._member_names):
# descriptor overwriting an enum?
raise TypeError('Attempted to reuse key: %r' % key)
- elif not _is_descriptor(value):
+ elif (not _is_descriptor(value)):
if key in self:
# enum overwriting a descriptor?
raise TypeError('%r already defined as: %r' % (key, self[key]))
@@ -105,13 +103,12 @@ class _EnumDict(dict):
self._last_values.append(value)
super().__setitem__(key, value)
-
# Dummy value for Enum as EnumMeta explicitly checks for it, but of course
# until EnumMeta finishes running the first time the Enum class doesn't exist.
# This is also why there are checks in EnumMeta like `if Enum is not None`
Enum = None
-
+pk('EnumMeta')
class EnumMeta(type):
"""Metaclass for Enum"""
@classmethod
@@ -132,13 +129,15 @@ class EnumMeta(type):
# cannot be mixed with other types (int, float, etc.) if it has an
# inherited __new__ unless a new __new__ is defined (or the resulting
# class will fail).
+
member_type, first_enum = metacls._get_mixins_(bases)
- __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
- first_enum)
+ new, save_new, use_args = metacls._find_new_(classdict, member_type,
+ first_enum)
# save enum items into separate mapping so they don't get baked into
# the new class
enum_members = {k: classdict[k] for k in classdict._member_names}
+
for name in classdict._member_names:
del classdict[name]
@@ -150,21 +149,19 @@ class EnumMeta(type):
if invalid_names:
raise ValueError('Invalid enum member name: {0}'.format(
','.join(invalid_names)))
-
+
# create a default docstring if one has not been provided
if '__doc__' not in classdict:
classdict['__doc__'] = 'An enumeration.'
# create our new Enum type
enum_class = super().__new__(metacls, cls, bases, classdict)
- pk(enum_class)
enum_class._member_names_ = [] # names in definition order
enum_class._member_map_ = OrderedDict() # name->value map
enum_class._member_type_ = member_type
# save attributes from super classes so we know if we can take
# the shortcut of storing members in the class dict
-
base_attributes = {a for b in enum_class.mro() for a in b.__dict__}
# Reverse value->name map for hashable values.
@@ -197,14 +194,16 @@ class EnumMeta(type):
args = (value, )
else:
args = value
+
if member_type is tuple: # special case for tuple enums
args = (args, ) # wrap it one more time
+
if not use_args:
- enum_member = __new__(enum_class)
+ enum_member = new(enum_class)
if not hasattr(enum_member, '_value_'):
enum_member._value_ = value
else:
- enum_member = __new__(enum_class, *args)
+ enum_member = new(enum_class, *args)
if not hasattr(enum_member, '_value_'):
if member_type is object:
enum_member._value_ = value
@@ -214,6 +213,7 @@ class EnumMeta(type):
enum_member._name_ = member_name
enum_member.__objclass__ = enum_class
enum_member.__init__(*args)
+
# If another member with the same value was already defined, the
# new member becomes an alias to the existing one.
for name, canonical_member in enum_class._member_map_.items():
@@ -223,11 +223,13 @@ class EnumMeta(type):
else:
# Aliases don't appear in member names (only in __members__).
enum_class._member_names_.append(member_name)
+
# performance boost for any member that would not shadow
# a DynamicClassAttribute
if member_name not in base_attributes:
setattr(enum_class, member_name, enum_member)
# now add to _member_map_
+
enum_class._member_map_[member_name] = enum_member
try:
# This may fail if value is not hashable. We can't add the value
@@ -370,8 +372,6 @@ class EnumMeta(type):
if name in member_map:
raise AttributeError('Cannot reassign members.')
- pk('set',name)
-
super().__setattr__(name, value)
@@ -522,6 +522,7 @@ class EnumMeta(type):
return __new__, save_new, use_args
+pk('enum')
class Enum(metaclass=EnumMeta):
"""Generic enumeration.
@@ -529,7 +530,6 @@ class Enum(metaclass=EnumMeta):
Derive from this class to define new enumerations.
"""
- pk(1)
def __new__(cls, value):
# all enum instances are actually created during class construction
@@ -551,8 +551,6 @@ class Enum(metaclass=EnumMeta):
# still not found -- try _missing_ hook
return cls._missing_(value)
- pk(2)
-
def _generate_next_value_(name, start, count, last_values):
for last_value in reversed(last_values):
try:
@@ -562,8 +560,6 @@ class Enum(metaclass=EnumMeta):
else:
return start
- pk(3)
-
@classmethod
def _missing_(cls, value):
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
@@ -583,7 +579,7 @@ class Enum(metaclass=EnumMeta):
if m[0] != '_' and m not in self._member_map_
]
return (['__class__', '__doc__', '__module__'] + added_behavior)
- pk(4)
+
def __format__(self, format_spec):
# mixed-in Enums should use the mixed-in type's __format__, otherwise
# we can get strange results with the Enum name showing up instead of
@@ -611,7 +607,7 @@ class Enum(metaclass=EnumMeta):
# to have members named `name` and `value`. This works because enumeration
# members are not set directly on the enum class -- __getattr__ is
# used to look them up.
- pk(5)
+
@DynamicClassAttribute
def name(self):
"""The name of the Enum member."""
@@ -658,6 +654,7 @@ class Enum(metaclass=EnumMeta):
module_globals[name] = cls
return cls
+pk('intenum')
class IntEnum(int, Enum):
"""Enum where members are also (and must be) ints"""
@@ -666,6 +663,7 @@ class IntEnum(int, Enum):
def _reduce_ex_by_name(self, proto):
return self.name
+pk('flag')
class Flag(Enum):
"""Support for flags"""
@@ -773,7 +771,8 @@ class Flag(Enum):
]
inverted = reduce(_or_, inverted_members, self.__class__(0))
return self.__class__(inverted)
-
+
+pk('intflag')
class IntFlag(int, Flag):
"""Support for integer-based Flags"""
@@ -837,6 +836,8 @@ class IntFlag(int, Flag):
def __invert__(self):
result = self.__class__(~self._value_)
return result
+
+pk('rest')
def _high_bit(value):
"""returns index of highest bit, or -1 if value is zero or negative"""
diff --git a/modules/language/python/module/python.scm b/modules/language/python/module/python.scm
index 1a90757..7b01c93 100644
--- a/modules/language/python/module/python.scm
+++ b/modules/language/python/module/python.scm
@@ -324,7 +324,13 @@
(define-python-class StaticMethod ())
(define-python-class Funcobj ())
+(define-method (py-mod (s <string>) l)
+ (let* ((s (py-replace s "%s" "~a"))
+ (s (py-replace s "%r" "~a"))
+ (l (for ((x : l)) ((r '()))
+ (cons x r)
+ #:final (reverse r))))
+ (apply (@ (guile) format) #f s l)))
-