Skip to content

Commit 143cb24

Browse files
YunchuWangpeterstone2017
andauthored
Revert "Enabled dependency isolation by default (#1055)" (#1092)
* Revert "Enabled dependency isolation by default (#1055)" This reverts commit b1085b5. * Enable dependency isolation for python 3.10 by default * fix dep isolation python 3.10 unit tests * add copyright to dependency.py Co-authored-by: peterstone2017 <[email protected]>
1 parent 999d793 commit 143cb24

File tree

5 files changed

+101
-38
lines changed

5 files changed

+101
-38
lines changed

azure_functions_worker/constants.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
PYTHON_THREADPOOL_THREAD_COUNT_MAX = sys.maxsize
4444
PYTHON_THREADPOOL_THREAD_COUNT_MAX_37 = 32
4545

46-
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT = True
46+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT = False
47+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT_310 = True
4748
PYTHON_ENABLE_WORKER_EXTENSIONS_DEFAULT = False
4849
PYTHON_ENABLE_WORKER_EXTENSIONS_DEFAULT_39 = True
4950

azure_functions_worker/utils/dependency.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
3+
from azure_functions_worker.utils.common import is_true_like
4+
from typing import List, Optional
5+
from types import ModuleType
36
import importlib
47
import inspect
58
import os
69
import re
710
import sys
8-
from types import ModuleType
9-
from typing import List, Optional
1011

11-
from azure_functions_worker.utils.common import is_true_like
12+
from ..logging import logger
1213
from ..constants import (
1314
AZURE_WEBJOBS_SCRIPT_ROOT,
1415
CONTAINER_NAME,
1516
PYTHON_ISOLATE_WORKER_DEPENDENCIES,
16-
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT
17+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT,
18+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT_310
1719
)
18-
from ..logging import logger
20+
from ..utils.common import is_python_version
1921
from ..utils.wrappers import enable_feature_by
2022

2123

@@ -75,7 +77,12 @@ def is_in_linux_consumption(cls):
7577
@classmethod
7678
@enable_feature_by(
7779
flag=PYTHON_ISOLATE_WORKER_DEPENDENCIES,
78-
flag_default=PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT)
80+
flag_default=(
81+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT_310 if
82+
is_python_version('3.10') else
83+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT
84+
)
85+
)
7986
def use_worker_dependencies(cls):
8087
"""Switch the sys.path and ensure the worker imports are loaded from
8188
Worker's dependenciess.
@@ -101,7 +108,12 @@ def use_worker_dependencies(cls):
101108
@classmethod
102109
@enable_feature_by(
103110
flag=PYTHON_ISOLATE_WORKER_DEPENDENCIES,
104-
flag_default=PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT)
111+
flag_default=(
112+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT_310 if
113+
is_python_version('3.10') else
114+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT
115+
)
116+
)
105117
def prioritize_customer_dependencies(cls, cx_working_dir=None):
106118
"""Switch the sys.path and ensure the customer's code import are loaded
107119
from CX's deppendencies.
@@ -170,7 +182,11 @@ def reload_customer_libraries(cls, cx_working_dir: str):
170182
"""
171183
use_new_env = os.getenv(PYTHON_ISOLATE_WORKER_DEPENDENCIES)
172184
if use_new_env is None:
173-
use_new = PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT
185+
use_new = (
186+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT_310 if
187+
is_python_version('3.10') else
188+
PYTHON_ISOLATE_WORKER_DEPENDENCIES_DEFAULT
189+
)
174190
else:
175191
use_new = is_true_like(use_new_env)
176192

tests/endtoend/dependency_isolation_functions/dependency_isolation_stein/function_app.py

Whitespace-only changes.

tests/unittests/test_rpc_messages.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import unittest
99

1010
from azure_functions_worker import protos, testutils
11+
from azure_functions_worker.utils.common import is_python_version
1112

1213

1314
class TestGRPC(testutils.AsyncTestCase):
@@ -126,7 +127,13 @@ def test_failed_azure_namespace_import(self):
126127

127128
@unittest.skipIf(sys.platform == 'win32',
128129
'Linux .sh script only works on Linux')
130+
@unittest.skipIf(
131+
is_python_version('3.10'),
132+
'In Python 3.10, isolate worker dependencies is turned on by default.'
133+
' Reloading all customer dependencies on specialization is a must.'
134+
' This partially reloading namespace feature is no longer needed.'
135+
)
129136
def test_successful_azure_namespace_import(self):
130137
self._verify_azure_namespace_import(
131138
'true',
132-
'module_b fails to import')
139+
'module_b is imported')

tests/unittests/test_utilities_dependency.py

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
3-
import importlib.util
43
import os
54
import sys
5+
import importlib.util
66
import unittest
77
from unittest.mock import patch
88

99
from azure_functions_worker import testutils
10+
from azure_functions_worker.utils.common import is_python_version
1011
from azure_functions_worker.utils.dependency import DependencyManager
1112

1213

@@ -228,7 +229,7 @@ def test_add_to_sys_path_no_duplication(self):
228229

229230
def test_add_to_sys_path_import_module(self):
230231
DependencyManager._add_to_sys_path(self._customer_deps_path, True)
231-
import common_module # NoQA
232+
import common_module # NoQA
232233
self.assertEqual(
233234
common_module.package_location,
234235
os.path.join(self._customer_deps_path, 'common_module')
@@ -239,7 +240,7 @@ def test_add_to_sys_path_import_namespace_path(self):
239240
into sys.path
240241
"""
241242
DependencyManager._add_to_sys_path(self._customer_deps_path, True)
242-
import common_namespace # NoQA
243+
import common_namespace # NoQA
243244
self.assertEqual(len(common_namespace.__path__), 1)
244245
self.assertEqual(
245246
common_namespace.__path__[0],
@@ -516,7 +517,7 @@ def test_clear_path_importer_cache_and_modules_retain_namespace(self):
516517
sys.path.insert(0, self._worker_deps_path)
517518

518519
# Ensure new import is from _worker_deps_path
519-
import common_module as worker_mod # NoQA
520+
import common_module as worker_mod # NoQA
520521
self.assertIn('common_module', sys.modules)
521522
self.assertEqual(
522523
worker_mod.package_location,
@@ -554,6 +555,41 @@ def test_use_worker_dependencies_disable(self):
554555
with self.assertRaises(ImportError):
555556
import common_module # NoQA
556557

558+
@unittest.skipUnless(
559+
sys.version_info.major == 3 and sys.version_info.minor != 10,
560+
'Test only available for Python 3.6, 3.7, 3.8 or 3.9'
561+
)
562+
def test_use_worker_dependencies_default_python_36_37_38_39(self):
563+
# Feature should be disabled in Python 3.6, 3.7, 3.8 and 3.9
564+
# Setup paths
565+
DependencyManager.worker_deps_path = self._worker_deps_path
566+
DependencyManager.cx_deps_path = self._customer_deps_path
567+
DependencyManager.cx_working_dir = self._customer_func_path
568+
569+
# The common_module cannot be imported since feature is disabled
570+
DependencyManager.use_worker_dependencies()
571+
with self.assertRaises(ImportError):
572+
import common_module # NoQA
573+
574+
@unittest.skipUnless(
575+
sys.version_info.major == 3 and sys.version_info.minor == 10,
576+
'Test only available for Python 3.10'
577+
)
578+
def test_use_worker_dependencies_default_python_310(self):
579+
# Feature should be enabled in Python 3.10 by default
580+
# Setup paths
581+
DependencyManager.worker_deps_path = self._worker_deps_path
582+
DependencyManager.cx_deps_path = self._customer_deps_path
583+
DependencyManager.cx_working_dir = self._customer_func_path
584+
585+
# Ensure the common_module is imported from _worker_deps_path
586+
DependencyManager.use_worker_dependencies()
587+
import common_module # NoQA
588+
self.assertEqual(
589+
common_module.package_location,
590+
os.path.join(self._worker_deps_path, 'common_module')
591+
)
592+
557593
def test_prioritize_customer_dependencies(self):
558594
# Setup app settings
559595
os.environ['PYTHON_ISOLATE_WORKER_DEPENDENCIES'] = 'true'
@@ -592,51 +628,54 @@ def test_prioritize_customer_dependencies_disable(self):
592628
with self.assertRaises(ImportError):
593629
import common_module # NoQA
594630

595-
def test_prioritize_customer_dependencies_from_working_directory(self):
596-
self._initialize_scenario()
597-
631+
@unittest.skipIf(is_python_version('3.10'),
632+
'Test not available for python 3.10')
633+
def test_prioritize_customer_dependencies_default_python_36_37_38_39(self):
634+
# Feature should be disabled in Python 3.6, 3.7, 3.8 and 3.9
598635
# Setup paths
599636
DependencyManager.worker_deps_path = self._worker_deps_path
600637
DependencyManager.cx_deps_path = self._customer_deps_path
601638
DependencyManager.cx_working_dir = self._customer_func_path
602639

603-
# Ensure the func_specific_module is imported from _customer_func_path
640+
# Ensure the common_module is imported from _customer_deps_path
604641
DependencyManager.prioritize_customer_dependencies()
605-
import func_specific_module # NoQA
606-
self.assertEqual(
607-
func_specific_module.package_location,
608-
os.path.join(self._customer_func_path, 'func_specific_module')
609-
)
642+
with self.assertRaises(ImportError):
643+
import common_module # NoQA
610644

611-
def test_reload_customer_libraries_dependency_isolation_true(self):
612-
os.environ['PYTHON_ISOLATE_WORKER_DEPENDENCIES'] = 'true'
645+
@unittest.skipUnless(
646+
sys.version_info.major == 3 and sys.version_info.minor == 10,
647+
'Test only available for Python 3.10'
648+
)
649+
def test_prioritize_customer_dependencies_default_python_310(self):
650+
# Feature should be enabled in Python 3.10 by default
613651
# Setup paths
614652
DependencyManager.worker_deps_path = self._worker_deps_path
615653
DependencyManager.cx_deps_path = self._customer_deps_path
616654
DependencyManager.cx_working_dir = self._customer_func_path
617655

618-
DependencyManager.reload_customer_libraries(self._customer_deps_path)
656+
# Ensure the common_module is imported from _customer_deps_path
657+
DependencyManager.prioritize_customer_dependencies()
619658
import common_module # NoQA
620659
self.assertEqual(
621660
common_module.package_location,
622-
os.path.join(self._customer_deps_path, 'common_module'))
661+
os.path.join(self._customer_deps_path, 'common_module')
662+
)
663+
664+
def test_prioritize_customer_dependencies_from_working_directory(self):
665+
self._initialize_scenario()
623666

624-
def test_reload_customer_libraries_dependency_isolation_false(self):
625-
os.environ['PYTHON_ISOLATE_WORKER_DEPENDENCIES'] = 'false'
626667
# Setup paths
627668
DependencyManager.worker_deps_path = self._worker_deps_path
628669
DependencyManager.cx_deps_path = self._customer_deps_path
629670
DependencyManager.cx_working_dir = self._customer_func_path
630671

631-
DependencyManager._add_to_sys_path(self._worker_deps_path, True)
632-
import azure.functions # NoQA
633-
634-
DependencyManager._add_to_sys_path(self._customer_deps_path, True)
635-
DependencyManager.reload_customer_libraries(self._customer_deps_path)
636-
# Checking if azure.functions gets reloaded
637-
self.assertIn(
638-
os.path.join(self._customer_deps_path, 'azure', 'functions'),
639-
sys.modules['azure.functions'].__path__)
672+
# Ensure the func_specific_module is imported from _customer_func_path
673+
DependencyManager.prioritize_customer_dependencies()
674+
import func_specific_module # NoQA
675+
self.assertEqual(
676+
func_specific_module.package_location,
677+
os.path.join(self._customer_func_path, 'func_specific_module')
678+
)
640679

641680
def test_remove_module_cache(self):
642681
# First import the common_module and create a sys.modules cache

0 commit comments

Comments
 (0)