1.1 --- a/deducer.py Sat Sep 02 01:19:52 2023 +0200
1.2 +++ b/deducer.py Sat Sep 02 01:48:44 2023 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Deduce types for usage observations.
1.6
1.7 -Copyright (C) 2014, 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2014-2018, 2023 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -2749,39 +2749,56 @@
1.13
1.14 if access_first_attribute:
1.15
1.16 + # Access via the accessor's class.
1.17 +
1.18 if first_method == "relative-class":
1.19 if assigning:
1.20 - emit(("__store_via_class", accessor, attrname, "<assexpr>"))
1.21 + emit(("<set_attr_ref>", ("__get_class_attr_ref", accessor, attrname)))
1.22 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.23 else:
1.24 accessor = ("__load_via_class", accessor, attrname)
1.25
1.26 + # Access via the accessor itself.
1.27 +
1.28 elif first_method == "relative-object":
1.29 if assigning:
1.30 - emit(("__store_via_object", accessor, attrname, "<assexpr>"))
1.31 + emit(("<set_attr_ref>", ("__get_object_attr_ref", accessor, attrname)))
1.32 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.33 else:
1.34 accessor = ("__load_via_object", accessor, attrname)
1.35
1.36 + # Access via a class accessor or the accessor's class.
1.37 +
1.38 elif first_method == "relative-object-class":
1.39 if assigning:
1.40 - emit(("__get_class_and_store", accessor, attrname, "<assexpr>"))
1.41 + emit(("__raise_type_error",))
1.42 else:
1.43 accessor = ("__get_class_and_load", accessor, attrname)
1.44
1.45 + # Access via the accessor's class.
1.46 +
1.47 elif first_method == "check-class":
1.48 if assigning:
1.49 - emit(("__check_and_store_via_class", accessor, attrname, "<assexpr>"))
1.50 + emit(("__raise_type_error",))
1.51 else:
1.52 accessor = ("__check_and_load_via_class", accessor, attrname)
1.53
1.54 + # Access via the accessor itself.
1.55 +
1.56 elif first_method == "check-object":
1.57 if assigning:
1.58 - emit(("__check_and_store_via_object", accessor, attrname, "<assexpr>"))
1.59 + emit(("<set_attr_ref>", ("__check_and_get_object_attr_ref", accessor, attrname)))
1.60 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.61 else:
1.62 accessor = ("__check_and_load_via_object", accessor, attrname)
1.63
1.64 + # Access via a class accessor or the accessor's class.
1.65 + # Here, only access via the accessor is supported.
1.66 +
1.67 elif first_method == "check-object-class":
1.68 if assigning:
1.69 - emit(("__check_and_store_via_any", accessor, attrname, "<assexpr>"))
1.70 + emit(("<set_attr_ref>", ("__check_and_get_object_attr_ref", accessor, attrname)))
1.71 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.72 else:
1.73 accessor = ("__check_and_load_via_any", accessor, attrname)
1.74
1.75 @@ -2815,12 +2832,14 @@
1.76
1.77 if traversal_mode == "class":
1.78 if assigning:
1.79 - emit(("__store_via_class", accessor, attrname, "<assexpr>"))
1.80 + emit(("<set_attr_ref>", ("__get_class_attr_ref", accessor, attrname)))
1.81 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.82 else:
1.83 accessor = ("__load_via_class", accessor, attrname)
1.84 else:
1.85 if assigning:
1.86 - emit(("__store_via_object", accessor, attrname, "<assexpr>"))
1.87 + emit(("<set_attr_ref>", ("__get_object_attr_ref", accessor, attrname)))
1.88 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.89 else:
1.90 accessor = ("__load_via_object", accessor, attrname)
1.91
1.92 @@ -2855,10 +2874,11 @@
1.93 # Constrain instructions involving certain special
1.94 # attribute names.
1.95
1.96 - to_search = attrname == "__data__" and "object" or "any"
1.97 + to_search = attrname != "__data__" and "any" or "object"
1.98
1.99 if assigning:
1.100 - emit(("__check_and_store_via_%s" % to_search, accessor, attrname, "<assexpr>"))
1.101 + emit(("<set_attr_ref>", ("__check_and_get_object_attr_ref", accessor, attrname)))
1.102 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.103 else:
1.104 accessor = ("__check_and_load_via_%s" % to_search, accessor, attrname)
1.105
1.106 @@ -2879,7 +2899,8 @@
1.107
1.108 if final_method == "static-assign":
1.109 parent, attrname = origin.rsplit(".", 1)
1.110 - emit(("__store_via_object", parent, attrname, "<assexpr>"))
1.111 + emit(("<set_attr_ref>", ("__get_object_attr_ref", parent, attrname)))
1.112 + emit(("__store_via_attr_ref", "<attr_ref>", "<assexpr>"))
1.113
1.114 # Invoked attributes employ a separate context.
1.115