Skip to content

Commit 7bf7061

Browse files
authored
Merge branch 'dev' into gaaguiar/init_refactoring
2 parents 23d8255 + c68f88b commit 7bf7061

File tree

26 files changed

+394
-201
lines changed

26 files changed

+394
-201
lines changed

.github/workflows/ci_docker_con_workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
python-version: [ 3.7, 3.8, 3.9, "3.10" ]
19+
python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11" ]
2020
permissions: read-all
2121
env:
2222
CONSUMPTION_DOCKER_TEST: "true"

azure_functions_worker/_thirdparty/typing_inspect.py

Lines changed: 38 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,10 @@
1212
# NOTE: This module must support Python 2.7 in addition to Python 3.x
1313

1414
import sys
15-
NEW_TYPING = sys.version_info[:3] >= (3, 7, 0) # PEP 560
16-
if NEW_TYPING:
17-
import collections.abc
18-
19-
if NEW_TYPING:
20-
from typing import (
21-
Generic, Callable, Union, TypeVar, ClassVar, Tuple, _GenericAlias
22-
)
23-
else:
24-
from typing import (
25-
Callable, CallableMeta, Union, _Union, TupleMeta, TypeVar,
26-
_ClassVar, GenericMeta,
27-
)
15+
import collections.abc
16+
from typing import (
17+
Generic, Callable, Union, TypeVar, ClassVar, Tuple, _GenericAlias
18+
)
2819

2920
NEW_39_TYPING = sys.version_info[:3] >= (3, 9, 0) # PEP 560
3021
if NEW_39_TYPING:
@@ -33,17 +24,6 @@
3324

3425
# from mypy_extensions import _TypedDictMeta
3526

36-
37-
def _gorg(cls):
38-
"""This function exists for compatibility with old typing versions."""
39-
assert isinstance(cls, GenericMeta)
40-
if hasattr(cls, '_gorg'):
41-
return cls._gorg
42-
while cls.__origin__ is not None:
43-
cls = cls.__origin__
44-
return cls
45-
46-
4727
def is_generic_type(tp):
4828
"""Test if the given type is a generic type. This includes Generic itself,
4929
but excludes special typing constructs such as Union, Tuple, Callable,
@@ -66,13 +46,10 @@ def is_generic_type(tp):
6646
return (isinstance(tp, type) and issubclass(tp, Generic)
6747
or ((isinstance(tp, _GenericAlias) or isinstance(tp, _SpecialGenericAlias)) # NoQA E501
6848
and tp.__origin__ not in (Union, tuple, ClassVar, collections.abc.Callable))) # NoQA E501
69-
if NEW_TYPING:
70-
return (isinstance(tp, type)
71-
and issubclass(tp, Generic)
72-
or isinstance(tp, _GenericAlias)
73-
and tp.__origin__ not in (Union, tuple, ClassVar, collections.abc.Callable)) # NoQA E501
74-
return (isinstance(tp, GenericMeta) and not
75-
isinstance(tp, (CallableMeta, TupleMeta)))
49+
return (isinstance(tp, type)
50+
and issubclass(tp, Generic)
51+
or isinstance(tp, _GenericAlias)
52+
and tp.__origin__ not in (Union, tuple, ClassVar, collections.abc.Callable)) # NoQA E501
7653

7754

7855
def is_callable_type(tp):
@@ -94,12 +71,10 @@ class MyClass(Callable[[int], int]):
9471
9572
get_origin(tp) is collections.abc.Callable # Callable prior to Python 3.7 # NoQA E501
9673
"""
97-
if NEW_TYPING:
98-
return (tp is Callable or isinstance(tp, _GenericAlias) and
99-
tp.__origin__ is collections.abc.Callable or
100-
isinstance(tp, type) and issubclass(tp, Generic) and
101-
issubclass(tp, collections.abc.Callable))
102-
return type(tp) is CallableMeta
74+
return (tp is Callable or isinstance(tp, _GenericAlias) and
75+
tp.__origin__ is collections.abc.Callable or
76+
isinstance(tp, type) and issubclass(tp, Generic) and
77+
issubclass(tp, collections.abc.Callable))
10378

10479

10580
def is_tuple_type(tp):
@@ -120,12 +95,10 @@ class MyClass(Tuple[str, int]):
12095
12196
get_origin(tp) is tuple # Tuple prior to Python 3.7
12297
"""
123-
if NEW_TYPING:
124-
return (tp is Tuple or isinstance(tp, _GenericAlias) and
125-
tp.__origin__ is tuple or
126-
isinstance(tp, type) and issubclass(tp, Generic) and
127-
issubclass(tp, tuple))
128-
return type(tp) is TupleMeta
98+
return (tp is Tuple or isinstance(tp, _GenericAlias) and
99+
tp.__origin__ is tuple or
100+
isinstance(tp, type) and issubclass(tp, Generic) and
101+
issubclass(tp, tuple))
129102

130103

131104
def is_union_type(tp):
@@ -136,10 +109,8 @@ def is_union_type(tp):
136109
is_union_type(Union[int, int]) == False
137110
is_union_type(Union[T, int]) == True
138111
"""
139-
if NEW_TYPING:
140-
return (tp is Union or
141-
isinstance(tp, _GenericAlias) and tp.__origin__ is Union)
142-
return type(tp) is _Union
112+
return (tp is Union or
113+
isinstance(tp, _GenericAlias) and tp.__origin__ is Union)
143114

144115

145116
def is_typevar(tp):
@@ -161,10 +132,8 @@ def is_classvar(tp):
161132
is_classvar(ClassVar[int]) == True
162133
is_classvar(ClassVar[List[T]]) == True
163134
"""
164-
if NEW_TYPING:
165-
return (tp is ClassVar or
166-
isinstance(tp, _GenericAlias) and tp.__origin__ is ClassVar)
167-
return type(tp) is _ClassVar
135+
return (tp is ClassVar or
136+
isinstance(tp, _GenericAlias) and tp.__origin__ is ClassVar)
168137

169138

170139
def get_last_origin(tp):
@@ -179,16 +148,8 @@ def get_last_origin(tp):
179148
get_last_origin(List[Tuple[T, T]][int]) == List[Tuple[T, T]]
180149
get_last_origin(List) == List
181150
"""
182-
if NEW_TYPING:
183-
raise ValueError('This function is only supported in Python 3.6,'
184-
' use get_origin instead')
185-
sentinel = object()
186-
origin = getattr(tp, '__origin__', sentinel)
187-
if origin is sentinel:
188-
return None
189-
if origin is None:
190-
return tp
191-
return origin
151+
raise ValueError('This function is only supported in Python 3.6,'
152+
' use get_origin instead')
192153

193154

194155
def get_origin(tp):
@@ -202,17 +163,10 @@ def get_origin(tp):
202163
get_origin(Union[T, int]) == Union
203164
get_origin(List[Tuple[T, T]][int]) == list # List prior to Python 3.7
204165
"""
205-
if NEW_TYPING:
206-
if isinstance(tp, _GenericAlias):
207-
return tp.__origin__ if tp.__origin__ is not ClassVar else None
208-
if tp is Generic:
209-
return Generic
210-
return None
211-
if isinstance(tp, GenericMeta):
212-
return _gorg(tp)
213-
if is_union_type(tp):
214-
return Union
215-
166+
if isinstance(tp, _GenericAlias):
167+
return tp.__origin__ if tp.__origin__ is not ClassVar else None
168+
if tp is Generic:
169+
return Generic
216170
return None
217171

218172

@@ -231,16 +185,9 @@ def get_parameters(tp):
231185
get_parameters(Union[S_co, Tuple[T, T]][int, U]) == (U,)
232186
get_parameters(Mapping[T, Tuple[S_co, T]]) == (T, S_co)
233187
"""
234-
if NEW_TYPING:
235-
if (isinstance(tp, _GenericAlias) or isinstance(tp, type) and
236-
issubclass(tp, Generic) and tp is not Generic): # NoQA E129
237-
return tp.__parameters__
238-
return ()
239-
if (
240-
is_generic_type(tp) or is_union_type(tp) or
241-
is_callable_type(tp) or is_tuple_type(tp)
242-
):
243-
return tp.__parameters__ if tp.__parameters__ is not None else ()
188+
if (isinstance(tp, _GenericAlias) or isinstance(tp, type) and
189+
issubclass(tp, Generic) and tp is not Generic): # NoQA E129
190+
return tp.__parameters__
244191
return ()
245192

246193

@@ -256,17 +203,8 @@ def get_last_args(tp):
256203
get_last_args(Callable[[T], int]) == (T, int)
257204
get_last_args(Callable[[], int]) == (int,)
258205
"""
259-
if NEW_TYPING:
260-
raise ValueError('This function is only supported in Python 3.6,'
261-
' use get_args instead')
262-
if is_classvar(tp):
263-
return (tp.__type__,) if tp.__type__ is not None else ()
264-
if (
265-
is_generic_type(tp) or is_union_type(tp) or
266-
is_callable_type(tp) or is_tuple_type(tp)
267-
):
268-
return tp.__args__ if tp.__args__ is not None else ()
269-
return ()
206+
raise ValueError('This function is only supported in Python 3.6,'
207+
' use get_args instead')
270208

271209

272210
def _eval_args(args):
@@ -307,29 +245,13 @@ def get_args(tp, evaluate=None):
307245
(int, Tuple[Optional[int], Optional[int]])
308246
get_args(Callable[[], T][int], evaluate=True) == ([], int,)
309247
"""
310-
if NEW_TYPING:
311-
if evaluate is not None and not evaluate:
312-
raise ValueError('evaluate can only be True in Python 3.7')
313-
if isinstance(tp, _GenericAlias):
314-
res = tp.__args__
315-
if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: # NoQA E501
316-
res = (list(res[:-1]), res[-1])
317-
return res
318-
return ()
319-
if is_classvar(tp):
320-
return (tp.__type__,)
321-
if (
322-
is_generic_type(tp) or is_union_type(tp) or
323-
is_callable_type(tp) or is_tuple_type(tp)
324-
):
325-
tree = tp._subs_tree()
326-
if isinstance(tree, tuple) and len(tree) > 1:
327-
if not evaluate:
328-
return tree[1:]
329-
res = _eval_args(tree[1:])
330-
if get_origin(tp) is Callable and res[0] is not Ellipsis:
331-
res = (list(res[:-1]), res[-1])
332-
return res
248+
if evaluate is not None and not evaluate:
249+
raise ValueError('evaluate can only be True in Python 3.7')
250+
if isinstance(tp, _GenericAlias):
251+
res = tp.__args__
252+
if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: # NoQA E501
253+
res = (list(res[:-1]), res[-1])
254+
return res
333255
return ()
334256

335257

azure_functions_worker/bindings/generic.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,7 @@ def decode(cls, data: datumdef.Datum, *, trigger_metadata) -> typing.Any:
5151
return result
5252

5353
@classmethod
54-
def has_implicit_output(cls) -> bool:
55-
return False
54+
def has_implicit_output(cls, bind_name: Optional[str]) -> bool:
55+
if bind_name == 'durableClient':
56+
return False
57+
return True

azure_functions_worker/bindings/meta.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,15 @@ def check_output_type_annotation(bind_name: str, pytype: type) -> bool:
5555
def has_implicit_output(bind_name: str) -> bool:
5656
binding = get_binding(bind_name)
5757

58-
# If the binding does not have metaclass of meta.InConverter
59-
# The implicit_output does not exist
60-
return getattr(binding, 'has_implicit_output', lambda: False)()
58+
# Need to pass in bind_name to exempt Durable Functions
59+
if binding is generic.GenericBinding:
60+
return (getattr(binding, 'has_implicit_output', lambda: False)
61+
(bind_name))
62+
63+
else:
64+
# If the binding does not have metaclass of meta.InConverter
65+
# The implicit_output does not exist
66+
return getattr(binding, 'has_implicit_output', lambda: False)()
6167

6268

6369
def from_incoming_proto(

azure_functions_worker/functions.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,20 @@ def get_explicit_and_implicit_return(binding_name: str,
7171
@staticmethod
7272
def get_return_binding(binding_name: str,
7373
binding_type: str,
74-
return_binding_name: str) -> str:
74+
return_binding_name: str,
75+
explicit_return_val_set: bool) \
76+
-> typing.Tuple[str, bool]:
77+
# prioritize explicit return value
78+
if explicit_return_val_set:
79+
return return_binding_name, explicit_return_val_set
7580
if binding_name == "$return":
7681
return_binding_name = binding_type
7782
assert return_binding_name is not None
83+
explicit_return_val_set = True
7884
elif bindings_utils.has_implicit_output(binding_type):
7985
return_binding_name = binding_type
8086

81-
return return_binding_name
87+
return return_binding_name, explicit_return_val_set
8288

8389
@staticmethod
8490
def validate_binding_direction(binding_name: str,
@@ -314,6 +320,7 @@ def add_function(self, function_id: str,
314320
params = dict(sig.parameters)
315321
annotations = typing.get_type_hints(func)
316322
return_binding_name: typing.Optional[str] = None
323+
explicit_return_val_set = False
317324
has_explicit_return = False
318325
has_implicit_return = False
319326

@@ -327,9 +334,11 @@ def add_function(self, function_id: str,
327334
binding_name, binding_info, has_explicit_return,
328335
has_implicit_return, bound_params)
329336

330-
return_binding_name = self.get_return_binding(binding_name,
331-
binding_info.type,
332-
return_binding_name)
337+
return_binding_name, explicit_return_val_set = \
338+
self.get_return_binding(binding_name,
339+
binding_info.type,
340+
return_binding_name,
341+
explicit_return_val_set)
333342

334343
requires_context = self.is_context_required(params, bound_params,
335344
annotations,
@@ -362,6 +371,7 @@ def add_indexed_function(self, function):
362371
function_id = str(uuid.uuid5(namespace=uuid.NAMESPACE_OID,
363372
name=func_name))
364373
return_binding_name: typing.Optional[str] = None
374+
explicit_return_val_set = False
365375
has_explicit_return = False
366376
has_implicit_return = False
367377

@@ -381,9 +391,11 @@ def add_indexed_function(self, function):
381391
binding.name, binding, has_explicit_return,
382392
has_implicit_return, bound_params)
383393

384-
return_binding_name = self.get_return_binding(binding.name,
385-
binding.type,
386-
return_binding_name)
394+
return_binding_name, explicit_return_val_set = \
395+
self.get_return_binding(binding.name,
396+
binding.type,
397+
return_binding_name,
398+
explicit_return_val_set)
387399

388400
requires_context = self.is_context_required(params, bound_params,
389401
annotations,

azure_functions_worker/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
33

4-
VERSION = '4.24.0'
4+
VERSION = '4.26.0'

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"azure_functions_worker._thirdparty",
7272
]
7373

74-
INSTALL_REQUIRES = ["azure-functions==1.19.0b2"]
74+
INSTALL_REQUIRES = ["azure-functions==1.19.0b3", "python-dateutil~=2.8.2"]
7575

7676
if sys.version_info[:2] == (3, 7):
7777
INSTALL_REQUIRES.extend(
@@ -108,8 +108,7 @@
108108
"opencv-python",
109109
"pandas",
110110
"numpy",
111-
"pre-commit",
112-
"python-dateutil~=2.8.2"
111+
"pre-commit"
113112
]
114113
}
115114

0 commit comments

Comments
 (0)