From 8564e5695179886b49e0a3e7fb2a7eeab21663dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=A4ufl?= Date: Tue, 11 Oct 2022 15:22:51 +0200 Subject: [PATCH 01/13] Run tests against Python 3.10 and 3.11 --- .github/workflows/UnitTesting.yaml | 4 ++- setup.py | 2 ++ tox.ini | 48 +++++++++++++++--------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.github/workflows/UnitTesting.yaml b/.github/workflows/UnitTesting.yaml index 264ea231..36dc1696 100644 --- a/.github/workflows/UnitTesting.yaml +++ b/.github/workflows/UnitTesting.yaml @@ -21,10 +21,12 @@ jobs: py37: 3.7 py38: 3.8 py39: 3.9 + py310: '3.10' + py311: '3.11' strategy: fail-fast: false matrix: - python-version: [py27, py34, py35, py36, py37, py38, py39] + python-version: [py27, py34, py35, py36, py37, py38, py39, py310, py311] testenv: [core, ext] steps: - name: Checkout repo diff --git a/setup.py b/setup.py index 4e1593b8..4b1df155 100644 --- a/setup.py +++ b/setup.py @@ -37,6 +37,8 @@ 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', ], install_requires=[ diff --git a/tox.ini b/tox.ini index a1c194f6..40fb6122 100644 --- a/tox.ini +++ b/tox.ini @@ -1,50 +1,50 @@ [tox] skip_missing_interpreters = True envlist = - py{27,34,35,36,37,38,39}-core + py{27,34,35,36,37,38,39,310,311}-core ; Unavailable for python 2.7 & 3.4 - py{35,36,37,38,39}-ext-aiobotocore + py{35,36,37,38,39,310,311}-ext-aiobotocore ; Unavailable for python 2.7 & 3.4 - py{35,36,37,38,39}-ext-aiohttp + py{35,36,37,38,39,310,311}-ext-aiohttp - py{27,34,35,36,37,38,39}-ext-botocore + py{27,34,35,36,37,38,39,310,311}-ext-botocore - py{27,34,35,36,37,38,39}-ext-bottle + py{27,34,35,36,37,38,39,310,311}-ext-bottle ; Django2 (2.2+) is only for python 3.5 + py{35,36,37,38,39}-ext-django-2 ; Django3 is only for python 3.6+ - py{36,37,38,39}-ext-django-3 + py{36,37,38,39,310}-ext-django-3 ; Django4 is only for python 3.8+ - py{38,39}-ext-django-4 + py{38,39,310,311}-ext-django-4 - py{27,34,35,36,37,38,39}-ext-flask + py{27,34,35,36,37,38,39,310,311}-ext-flask - py{27,34,35,36,37,38,39}-ext-flask_sqlalchemy + py{27,34,35,36,37,38,39,310,311}-ext-flask_sqlalchemy - py{27,34,35,36,37,38,39}-ext-httplib + py{27,34,35,36,37,38,39,310,311}-ext-httplib - py{37,38,39}-ext-httpx + py{37,38,39,310,311}-ext-httpx - py{27,34,35,36,37,38,39}-ext-pg8000 + py{27,34,35,36,37,38,39,310,311}-ext-pg8000 - py{27,34,35,36,37,38,39}-ext-psycopg2 + py{27,34,35,36,37,38,39,310,311}-ext-psycopg2 - py{27,34,35,36,37,38,39}-ext-pymysql + py{27,34,35,36,37,38,39,310,311}-ext-pymysql - py{27,34,35,36,37,38,39}-ext-pynamodb + py{27,34,35,36,37,38,39,310,311}-ext-pynamodb - py{27,34,35,36,37,38,39}-ext-requests + py{27,34,35,36,37,38,39,310,311}-ext-requests - py{27,34,35,36,37,38,39}-ext-sqlalchemy + py{27,34,35,36,37,38,39,310,311}-ext-sqlalchemy - py{27,34,35,36,37,38,39}-ext-sqlalchemy_core + py{27,34,35,36,37,38,39,310,311}-ext-sqlalchemy_core - py{27,34,35,36,37,38,39}-ext-sqlite3 + py{27,34,35,36,37,38,39,310,311}-ext-sqlite3 [testenv] passenv = TOXENV CI CODECOV_* @@ -68,7 +68,7 @@ deps = py34: typing >= 3.7.4.3 ; Python 3.5+ only deps - py{35,36,37,38,39}: pytest-asyncio + py{35,36,37,38,39,310,311}: pytest-asyncio ext-aiobotocore: aiobotocore >= 0.10.0 ext-aiobotocore: pytest-asyncio @@ -102,7 +102,7 @@ deps = py{27,34,35}-ext-pynamodb: pynamodb >=3.3.1,<4.4 py{27,34,35}-ext-pynamodb: botocore <1.28 - py{36,37,38,39}-ext-pynamodb: pynamodb >=3.3.1 + py{36,37,38,39,310,311}-ext-pynamodb: pynamodb >=3.3.1 ext-psycopg2: psycopg2 ext-psycopg2: testing.postgresql @@ -112,7 +112,7 @@ deps = ext-pymysql: testing.mysqld py{27,34,35}-ext-pymysql: pymysql < 1.0.0 - py{36,37,38,39}-ext-pymysql: pymysql >= 1.0.0 + py{36,37,38,39,310,311}-ext-pymysql: pymysql >= 1.0.0 setenv = DJANGO_SETTINGS_MODULE = tests.ext.django.app.settings @@ -124,7 +124,7 @@ commands = ; Async methods are only available for python 3.5+ py{27,34}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext --ignore tests/test_async_local_storage.py --ignore tests/test_async_recorder.py - py{35,36,37,38,39}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext + py{35,36,37,38,39,310,311}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext ext-aiobotocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiobotocore @@ -157,7 +157,7 @@ commands = ext-sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy ; sqlalchemy_core - 2.0 style execution is not supported for python 3.4 & 3.5 - py{27,36,37,38,39}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core + py{27,36,37,38,39,310,311}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core py{34,35}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core --ignore tests/ext/sqlalchemy_core/test_sqlalchemy_core_2.py ext-sqlite3: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlite3 From 6742b556f461c6a48af2368bda86b82fad1c3a88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Feb 2023 02:16:16 +0000 Subject: [PATCH 02/13] Bump werkzeug from 1.0.1 to 2.2.3 in /sample-apps/flask Bumps [werkzeug](https://github.com/pallets/werkzeug) from 1.0.1 to 2.2.3. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/1.0.1...2.2.3) --- updated-dependencies: - dependency-name: werkzeug dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- sample-apps/flask/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-apps/flask/requirements.txt b/sample-apps/flask/requirements.txt index ae5d4b09..2813fa6c 100644 --- a/sample-apps/flask/requirements.txt +++ b/sample-apps/flask/requirements.txt @@ -9,6 +9,6 @@ Jinja2==2.11.3 MarkupSafe==1.1.1 requests==2.23.0 urllib3==1.26.5 -Werkzeug==1.0.1 +Werkzeug==2.2.3 flask-sqlalchemy==2.4.3 aws_xray_sdk==2.6.0 From d703eeea94423b1f25d1b9fd163d8486961cc84f Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:48:48 -0700 Subject: [PATCH 03/13] CI fix - version pinning sqlalchemy to 1.x (#381) --- tox.ini | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 40fb6122..b2b9a8ec 100644 --- a/tox.ini +++ b/tox.ini @@ -88,10 +88,11 @@ deps = ext-flask_sqlalchemy: flask >= 0.10 ext-flask_sqlalchemy: Flask-SQLAlchemy <= 2.5.1 + ext-flask_sqlalchemy: sqlalchemy >=1.0.0,<2.0.0 - ext-sqlalchemy: sqlalchemy + ext-sqlalchemy: sqlalchemy >=1.0.0,<2.0.0 - ext-sqlalchemy_core: sqlalchemy + ext-sqlalchemy_core: sqlalchemy >=1.0.0,<2.0.0 ext-sqlalchemy_core: testing.postgresql ext-sqlalchemy_core: psycopg2 From cf29651bb07289bc5a3aa264b206a1459804b66c Mon Sep 17 00:00:00 2001 From: Wang Date: Tue, 28 Mar 2023 10:55:13 -0700 Subject: [PATCH 04/13] fix sample app dependencies imcompatible with xray sdk --- sample-apps/flask/requirements.txt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/sample-apps/flask/requirements.txt b/sample-apps/flask/requirements.txt index 2813fa6c..d0e05170 100644 --- a/sample-apps/flask/requirements.txt +++ b/sample-apps/flask/requirements.txt @@ -1,14 +1,11 @@ boto3 -certifi==2022.12.7 -chardet==3.0.4 -click==7.1.2 -Flask==1.1.2 -idna==2.9 -itsdangerous==1.1.0 -Jinja2==2.11.3 -MarkupSafe==1.1.1 -requests==2.23.0 -urllib3==1.26.5 +certifi +chardet +Flask +idna +requests +urllib3 Werkzeug==2.2.3 -flask-sqlalchemy==2.4.3 +flask-sqlalchemy==2.5.1 +SQLAlchemy==1.4 aws_xray_sdk==2.6.0 From 2ff005b2080241a86faf803f4cc419aa9dcc9fd1 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Wed, 29 Mar 2023 15:56:07 -0700 Subject: [PATCH 05/13] Start MySQL from GH actions, upgrade ubuntu, and remove python versions for tests --- .github/workflows/UnitTesting.yaml | 19 +++++------ tests/ext/pymysql/test_pymysql.py | 51 +++++++++++++++--------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/UnitTesting.yaml b/.github/workflows/UnitTesting.yaml index 36dc1696..e30fc0c5 100644 --- a/.github/workflows/UnitTesting.yaml +++ b/.github/workflows/UnitTesting.yaml @@ -9,29 +9,30 @@ on: jobs: test: - # "setup-python" action doesn't provide python 3.4 binaries for ubuntu-latest. - # Sticking to Ubuntu 18.04 as recommended here: - # https://github.com/actions/setup-python/issues/185#issuecomment-768232756 - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: - py27: 2.7 - py34: 3.4 - py35: 3.5 - py36: 3.6 py37: 3.7 py38: 3.8 py39: 3.9 py310: '3.10' py311: '3.11' + DB_DATABASE: test_db + DB_USER: root + DB_PASSWORD: root strategy: fail-fast: false matrix: - python-version: [py27, py34, py35, py36, py37, py38, py39, py310, py311] + python-version: [py37, py38, py39, py310, py311] testenv: [core, ext] steps: - name: Checkout repo uses: actions/checkout@v3 + - name: Start MySQL + run: | + sudo /etc/init.d/mysql start + mysql -e 'CREATE DATABASE ${{ env.DB_DATABASE }};' -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} + - name: Setup Python uses: actions/setup-python@v4 with: diff --git a/tests/ext/pymysql/test_pymysql.py b/tests/ext/pymysql/test_pymysql.py index 0fa3beb1..be2d9c38 100644 --- a/tests/ext/pymysql/test_pymysql.py +++ b/tests/ext/pymysql/test_pymysql.py @@ -1,13 +1,17 @@ import pymysql import pytest -import testing.mysqld from aws_xray_sdk.core import patch from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core.context import Context from aws_xray_sdk.ext.pymysql import unpatch +MYSQL_USER = "root" +MYSQL_PASSWORD = "root" +MYSQL_HOST = "localhost" +MYSQL_PORT = 3306 +MYSQL_DB_NAME = "test_db" @pytest.fixture(scope='module', autouse=True) def patch_module(): @@ -32,46 +36,41 @@ def construct_ctx(): def test_execute_dsn_kwargs(): q = 'SELECT 1' - with testing.mysqld.Mysqld() as mysqld: - dsn = mysqld.dsn() - conn = pymysql.connect(database=dsn['db'], - user=dsn['user'], - password='', - host=dsn['host'], - port=dsn['port']) - cur = conn.cursor() - cur.execute(q) + conn = pymysql.connect(database=MYSQL_DB_NAME, + user=MYSQL_USER, + password=MYSQL_PASSWORD, + host=MYSQL_HOST, + port=MYSQL_PORT) + cur = conn.cursor() + cur.execute(q) subsegment = xray_recorder.current_segment().subsegments[-1] assert subsegment.name == 'execute' sql = subsegment.sql assert sql['database_type'] == 'MySQL' - assert sql['user'] == dsn['user'] + assert sql['user'] == MYSQL_USER assert sql['driver_version'] == 'PyMySQL' assert sql['database_version'] def test_execute_bad_query(): q = "SELECT blarg" - with testing.mysqld.Mysqld() as mysqld: - dsn = mysqld.dsn() - conn = pymysql.connect(database=dsn['db'], - user=dsn['user'], - password='', - host=dsn['host'], - port=dsn['port']) - - cur = conn.cursor() - try: - cur.execute(q) - except Exception: - pass - + conn = pymysql.connect(database=MYSQL_DB_NAME, + user=MYSQL_USER, + password=MYSQL_PASSWORD, + host=MYSQL_HOST, + port=MYSQL_PORT) + cur = conn.cursor() + try: + cur.execute(q) + except Exception: + pass + subsegment = xray_recorder.current_segment().subsegments[-1] assert subsegment.name == "execute" sql = subsegment.sql assert sql['database_type'] == 'MySQL' - assert sql['user'] == dsn['user'] + assert sql['user'] == MYSQL_USER assert sql['driver_version'] == 'PyMySQL' assert sql['database_version'] From 95713eba0e691203ec7635404c70a97e25fae89b Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Thu, 30 Mar 2023 13:30:53 -0700 Subject: [PATCH 06/13] remove python versions 2.7,3.4,3.5,3.6 from tox.ini --- tox.ini | 65 ++++++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/tox.ini b/tox.ini index b2b9a8ec..b28999b3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,50 +1,46 @@ [tox] skip_missing_interpreters = True envlist = - py{27,34,35,36,37,38,39,310,311}-core + py{37,38,39,310,311}-core - ; Unavailable for python 2.7 & 3.4 - py{35,36,37,38,39,310,311}-ext-aiobotocore + py{37,38,39,310,311}-ext-aiobotocore - ; Unavailable for python 2.7 & 3.4 - py{35,36,37,38,39,310,311}-ext-aiohttp + py{37,38,39,310,311}-ext-aiohttp - py{27,34,35,36,37,38,39,310,311}-ext-botocore + py{37,38,39,310,311}-ext-botocore - py{27,34,35,36,37,38,39,310,311}-ext-bottle + py{37,38,39,310,311}-ext-bottle - ; Django2 (2.2+) is only for python 3.5 + - py{35,36,37,38,39}-ext-django-2 + py{37,38,39}-ext-django-2 - ; Django3 is only for python 3.6+ - py{36,37,38,39,310}-ext-django-3 + py{37,38,39,310}-ext-django-3 ; Django4 is only for python 3.8+ py{38,39,310,311}-ext-django-4 - py{27,34,35,36,37,38,39,310,311}-ext-flask + py{37,38,39,310,311}-ext-flask - py{27,34,35,36,37,38,39,310,311}-ext-flask_sqlalchemy + py{37,38,39,310,311}-ext-flask_sqlalchemy - py{27,34,35,36,37,38,39,310,311}-ext-httplib + py{37,38,39,310,311}-ext-httplib py{37,38,39,310,311}-ext-httpx - py{27,34,35,36,37,38,39,310,311}-ext-pg8000 + py{37,38,39,310,311}-ext-pg8000 - py{27,34,35,36,37,38,39,310,311}-ext-psycopg2 + py{37,38,39,310,311}-ext-psycopg2 - py{27,34,35,36,37,38,39,310,311}-ext-pymysql + py{37,38,39,310,311}-ext-pymysql - py{27,34,35,36,37,38,39,310,311}-ext-pynamodb + py{37,38,39,310,311}-ext-pynamodb - py{27,34,35,36,37,38,39,310,311}-ext-requests + py{37,38,39,310,311}-ext-requests - py{27,34,35,36,37,38,39,310,311}-ext-sqlalchemy + py{37,38,39,310,311}-ext-sqlalchemy - py{27,34,35,36,37,38,39,310,311}-ext-sqlalchemy_core + py{37,38,39,310,311}-ext-sqlalchemy_core - py{27,34,35,36,37,38,39,310,311}-ext-sqlite3 + py{37,38,39,310,311}-ext-sqlite3 [testenv] passenv = TOXENV CI CODECOV_* @@ -59,16 +55,8 @@ deps = ; Packages common to all test environments wrapt - ; Python 2.7 only deps - py{27}: enum34 - py{27}: mock - py{27}: future - - ; Python 3.4 only deps - py34: typing >= 3.7.4.3 - ; Python 3.5+ only deps - py{35,36,37,38,39,310,311}: pytest-asyncio + py{37,38,39,310,311}: pytest-asyncio ext-aiobotocore: aiobotocore >= 0.10.0 ext-aiobotocore: pytest-asyncio @@ -101,9 +89,7 @@ deps = ext-django-4: Django >=4.0,<5.0 ext-django: django-fake-model - py{27,34,35}-ext-pynamodb: pynamodb >=3.3.1,<4.4 - py{27,34,35}-ext-pynamodb: botocore <1.28 - py{36,37,38,39,310,311}-ext-pynamodb: pynamodb >=3.3.1 + py{37,38,39,310,311}-ext-pynamodb: pynamodb >=3.3.1 ext-psycopg2: psycopg2 ext-psycopg2: testing.postgresql @@ -112,8 +98,7 @@ deps = ext-pg8000: testing.postgresql ext-pymysql: testing.mysqld - py{27,34,35}-ext-pymysql: pymysql < 1.0.0 - py{36,37,38,39,310,311}-ext-pymysql: pymysql >= 1.0.0 + py{37,38,39,310,311}-ext-pymysql: pymysql >= 1.0.0 setenv = DJANGO_SETTINGS_MODULE = tests.ext.django.app.settings @@ -123,9 +108,7 @@ setenv = commands = coverage erase - ; Async methods are only available for python 3.5+ - py{27,34}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext --ignore tests/test_async_local_storage.py --ignore tests/test_async_recorder.py - py{35,36,37,38,39,310,311}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext + py{37,38,39,310,311}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext ext-aiobotocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiobotocore @@ -157,9 +140,7 @@ commands = ext-sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy - ; sqlalchemy_core - 2.0 style execution is not supported for python 3.4 & 3.5 - py{27,36,37,38,39,310,311}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core - py{34,35}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core --ignore tests/ext/sqlalchemy_core/test_sqlalchemy_core_2.py + py{37,38,39,310,311}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core ext-sqlite3: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlite3 From eaffcc801138fcf44d540dbf500299285a453158 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Thu, 30 Mar 2023 13:58:31 -0700 Subject: [PATCH 07/13] update readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26f9f133..7cdea193 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,17 @@ AWS X-Ray supports using OpenTelemetry Python and the AWS Distro for OpenTelemet If you want additional features when tracing your Python applications, please [open an issue on the OpenTelemetry Python Instrumentation repository](https://github.com/open-telemetry/opentelemetry-python-contrib/issues/new?labels=feature-request&template=feature_request.md&title=X-Ray%20Compatible%20Feature%20Request). +### :mega: Python Versions End-of-Support Notice + +AWS X-Ray SDK for Python versions `>2.11.0` has dropped support for Python 2.7, 3.4, 3.5, and 3.6. + # AWS X-Ray SDK for Python ![Screenshot of the AWS X-Ray console](/images/example_servicemap.png?raw=true) ## Installing -The AWS X-Ray SDK for Python is compatible with Python 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, and 3.9. +The AWS X-Ray SDK for Python is compatible with Python 3.7, 3.8, 3.9, 3.10, and 3.11. Install the SDK using the following command (the SDK's non-testing dependencies will be installed). From 46bc57abbf4b73680a61a41080a5ba22e3698a6a Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Thu, 30 Mar 2023 14:19:24 -0700 Subject: [PATCH 08/13] cleanup tox.ini --- tox.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/tox.ini b/tox.ini index b28999b3..71fecd41 100644 --- a/tox.ini +++ b/tox.ini @@ -97,7 +97,6 @@ deps = ext-pg8000: pg8000 <= 1.20.0 ext-pg8000: testing.postgresql - ext-pymysql: testing.mysqld py{37,38,39,310,311}-ext-pymysql: pymysql >= 1.0.0 setenv = From 4138b2ef4c5c5bcbd8dd32a872792fa6cfb6db67 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Thu, 30 Mar 2023 15:29:02 -0700 Subject: [PATCH 09/13] Run MySQL step on condition --- .github/workflows/UnitTesting.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/UnitTesting.yaml b/.github/workflows/UnitTesting.yaml index e30fc0c5..cc4c6e05 100644 --- a/.github/workflows/UnitTesting.yaml +++ b/.github/workflows/UnitTesting.yaml @@ -29,6 +29,7 @@ jobs: uses: actions/checkout@v3 - name: Start MySQL + if: ${{ matrix.testenv == 'ext' }} run: | sudo /etc/init.d/mysql start mysql -e 'CREATE DATABASE ${{ env.DB_DATABASE }};' -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} From 32aabb8c4e4a9f22656ffec0fd953784e3075e33 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Fri, 31 Mar 2023 13:24:31 -0700 Subject: [PATCH 10/13] Release commit for v2.12.0 --- CHANGELOG.rst | 15 +++++++++++++++ aws_xray_sdk/version.py | 2 +- docs/conf.py | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3dab014c..be677535 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,21 @@ CHANGELOG Unreleased ========== +2.12.0 +========== +* improvement: Default Context Missing Strategy set to Log Error `PR372 https://github.com/aws/aws-xray-sdk-python/pull/372` +* bugfix: Pin tox version to <=3.27.1 to fix CI tests `PR374 https://github.com/aws/aws-xray-sdk-python/pull/374` +* improvement: Sample app dependency update `PR373 https://github.com/aws/aws-xray-sdk-python/pull/373` +* bugfix: Fix pynamodb tests for Python < 3.6 `PR375 https://github.com/aws/aws-xray-sdk-python/pull/375` +* improvement: Use latest GH Actions versions in CI tests `PR365 https://github.com/aws/aws-xray-sdk-python/pull/365` +* improvement: Simplify setup script `PR363 https://github.com/aws/aws-xray-sdk-python/pull/363` +* bugfix: Fix deprecation warnings related to asyncio `PR364 https://github.com/aws/aws-xray-sdk-python/pull/364` +* improvement: Run tests against Python 3.10 and 3.11 `PR376 https://github.com/aws/aws-xray-sdk-python/pull/376` +* improvement: Sample app dependency update `PR380 https://github.com/aws/aws-xray-sdk-python/pull/380` +* bugfix: Pin sqlalchemy version to 1.x to fix tests `PR381 https://github.com/aws/aws-xray-sdk-python/pull/381` +* bugfix: Fix sample app dependencies incompatibility with XRay SDK `PR382 https://github.com/aws/aws-xray-sdk-python/pull/382` +* bugfix: Start MySQL from GH Actions, upgrade Ubuntu, and remove Python versions for unit tests `PR384 https://github.com/aws/aws-xray-sdk-python/pull/384` + 2.11.0 ========== * bugfix: Fix TypeError by patching register_default_jsonb from psycopg2 `PR350 https://github.com/aws/aws-xray-sdk-python/pull/350` diff --git a/aws_xray_sdk/version.py b/aws_xray_sdk/version.py index a13b4dce..2622af9b 100644 --- a/aws_xray_sdk/version.py +++ b/aws_xray_sdk/version.py @@ -1 +1 @@ -VERSION = '2.11.0' +VERSION = '2.12.0' diff --git a/docs/conf.py b/docs/conf.py index 59c3e5de..c7fd8eb9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -62,9 +62,9 @@ # built documents. # # The short X.Y version. -version = u'2.11.0' +version = u'2.12.0' # The full version, including alpha/beta/rc tags. -release = u'2.11.0' +release = u'2.12.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From 150f0ea3ea06447987b8b2b2e7c8b358b89b43e3 Mon Sep 17 00:00:00 2001 From: Michael K Date: Mon, 17 Apr 2023 20:38:31 +0000 Subject: [PATCH 11/13] Cleanup after drop of support for Python < 3.7 (#387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove unused config for Travis CI * Remove classifiers for unsupported Python versions * Add `python_requires` and remove unused dependencies * Use Python 3 style `super()` calls * Use “new style” classes Stop inheriting from object explicitly * Remove compatibility code for Python < 3.7 * Remove unnecessary future imports * Remove `string_types` from compat module --- .travis.yml | 26 ------------------ aws_xray_sdk/core/__init__.py | 11 +++----- aws_xray_sdk/core/async_context.py | 27 +++++-------------- aws_xray_sdk/core/context.py | 2 +- aws_xray_sdk/core/daemon_config.py | 2 +- aws_xray_sdk/core/emitters/udp_emitter.py | 2 +- .../core/models/default_dynamic_naming.py | 2 +- aws_xray_sdk/core/models/dummy_entities.py | 6 ++--- aws_xray_sdk/core/models/entity.py | 12 ++++----- aws_xray_sdk/core/models/facade_segment.py | 2 +- aws_xray_sdk/core/models/segment.py | 10 +++---- aws_xray_sdk/core/models/subsegment.py | 10 +++---- aws_xray_sdk/core/models/throwable.py | 6 ++--- aws_xray_sdk/core/models/trace_header.py | 2 +- aws_xray_sdk/core/patcher.py | 21 +++++++-------- aws_xray_sdk/core/plugins/ec2_plugin.py | 9 +------ aws_xray_sdk/core/recorder.py | 9 +++---- aws_xray_sdk/core/sampling/connector.py | 15 +++-------- aws_xray_sdk/core/sampling/local/reservoir.py | 2 +- aws_xray_sdk/core/sampling/local/sampler.py | 2 +- .../core/sampling/local/sampling_rule.py | 2 +- aws_xray_sdk/core/sampling/reservoir.py | 2 +- aws_xray_sdk/core/sampling/rule_cache.py | 2 +- aws_xray_sdk/core/sampling/rule_poller.py | 2 +- aws_xray_sdk/core/sampling/sampler.py | 2 +- aws_xray_sdk/core/sampling/sampling_rule.py | 2 +- aws_xray_sdk/core/sampling/target_poller.py | 2 +- .../core/streaming/default_streaming.py | 2 +- aws_xray_sdk/core/utils/atomic_counter.py | 2 +- aws_xray_sdk/core/utils/compat.py | 12 +-------- aws_xray_sdk/ext/boto_utils.py | 2 -- aws_xray_sdk/ext/bottle/middleware.py | 2 +- aws_xray_sdk/ext/dbapi2.py | 4 +-- aws_xray_sdk/ext/django/conf.py | 2 +- aws_xray_sdk/ext/django/db.py | 6 ++--- aws_xray_sdk/ext/django/middleware.py | 2 +- aws_xray_sdk/ext/flask/middleware.py | 2 +- aws_xray_sdk/ext/httplib/patch.py | 25 +++++------------ aws_xray_sdk/ext/pymongo/patch.py | 2 +- .../ext/sqlalchemy/util/decorators.py | 12 +++------ aws_xray_sdk/ext/sqlalchemy_core/patch.py | 9 ++----- aws_xray_sdk/ext/util.py | 12 +++------ aws_xray_sdk/sdk_config.py | 2 +- setup.py | 8 +----- tests/ext/aiohttp/test_middleware.py | 18 +++++-------- tests/ext/django/test_settings.py | 12 +++------ tests/ext/flask_sqlalchemy/test_query.py | 1 - tests/ext/httplib/test_httplib.py | 19 +++++-------- tests/ext/pynamodb/test_pynamodb.py | 2 +- tests/ext/sqlalchemy/test_query.py | 1 - tests/ext/sqlalchemy_core/test_base.py | 2 -- .../mock_submodule/mock_subfile.py | 4 +-- tests/test_plugins.py | 7 ++--- tests/test_serialize_entities.py | 2 +- tests/test_trace_entities.py | 10 +++---- tests/util.py | 14 ++++------ 56 files changed, 123 insertions(+), 267 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2970fcde..00000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: python -dist: xenial -python: - - "2.7" - - "3.4" - - "3.5" - - "3.6" - - "3.7" - - "3.8" - - "3.9" - -addons: - postgresql: "9.6" - -install: - - pip install tox tox-travis - -notifications: - email: - recipients: - - aws-xray-peryton@amazon.com - on_success: never - on_failure: always - -script: - - tox diff --git a/aws_xray_sdk/core/__init__.py b/aws_xray_sdk/core/__init__.py index cb94eed9..8abbe449 100644 --- a/aws_xray_sdk/core/__init__.py +++ b/aws_xray_sdk/core/__init__.py @@ -1,13 +1,8 @@ +from .async_recorder import AsyncAWSXRayRecorder +from .patcher import patch, patch_all from .recorder import AWSXRayRecorder -from .patcher import patch_all, patch -from .utils.compat import PY35 - -if not PY35: - xray_recorder = AWSXRayRecorder() -else: - from .async_recorder import AsyncAWSXRayRecorder - xray_recorder = AsyncAWSXRayRecorder() +xray_recorder = AsyncAWSXRayRecorder() __all__ = [ 'patch', diff --git a/aws_xray_sdk/core/async_context.py b/aws_xray_sdk/core/async_context.py index acba00e2..59d92d50 100644 --- a/aws_xray_sdk/core/async_context.py +++ b/aws_xray_sdk/core/async_context.py @@ -1,11 +1,8 @@ import asyncio -import sys import copy from .context import Context as _Context -_GTE_PY37 = sys.version_info.major == 3 and sys.version_info.minor >= 7 - class AsyncContext(_Context): """ @@ -16,7 +13,7 @@ class AsyncContext(_Context): Also overrides clear_trace_entities """ def __init__(self, *args, loop=None, use_task_factory=True, **kwargs): - super(AsyncContext, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._loop = loop if loop is None: @@ -35,7 +32,7 @@ def clear_trace_entities(self): self._local.clear() -class TaskLocalStorage(object): +class TaskLocalStorage: """ Simple task local storage """ @@ -51,10 +48,7 @@ def __setattr__(self, name, value): else: # Set task local attributes - if _GTE_PY37: - task = asyncio.current_task(loop=self._loop) - else: - task = asyncio.Task.current_task(loop=self._loop) + task = asyncio.current_task(loop=self._loop) if task is None: return None @@ -68,10 +62,7 @@ def __getattribute__(self, item): # Return references to local objects return object.__getattribute__(self, item) - if _GTE_PY37: - task = asyncio.current_task(loop=self._loop) - else: - task = asyncio.Task.current_task(loop=self._loop) + task = asyncio.current_task(loop=self._loop) if task is None: return None @@ -82,10 +73,7 @@ def __getattribute__(self, item): def clear(self): # If were in a task, clear the context dictionary - if _GTE_PY37: - task = asyncio.current_task(loop=self._loop) - else: - task = asyncio.Task.current_task(loop=self._loop) + task = asyncio.current_task(loop=self._loop) if task is not None and hasattr(task, 'context'): task.context.clear() @@ -104,10 +92,7 @@ def task_factory(loop, coro): del task._source_traceback[-1] # flake8: noqa # Share context with new task if possible - if _GTE_PY37: - current_task = asyncio.current_task(loop=loop) - else: - current_task = asyncio.Task.current_task(loop=loop) + current_task = asyncio.current_task(loop=loop) if current_task is not None and hasattr(current_task, 'context'): if current_task.context.get('entities'): # NOTE: (enowell) Because the `AWSXRayRecorder`'s `Context` decides diff --git a/aws_xray_sdk/core/context.py b/aws_xray_sdk/core/context.py index 4b4f08b4..63e994de 100644 --- a/aws_xray_sdk/core/context.py +++ b/aws_xray_sdk/core/context.py @@ -14,7 +14,7 @@ CXT_MISSING_STRATEGY_KEY = 'AWS_XRAY_CONTEXT_MISSING' -class Context(object): +class Context: """ The context storage class to store trace entities(segments/subsegments). The default implementation uses threadlocal to store these entities. diff --git a/aws_xray_sdk/core/daemon_config.py b/aws_xray_sdk/core/daemon_config.py index 34b66a37..0331d052 100644 --- a/aws_xray_sdk/core/daemon_config.py +++ b/aws_xray_sdk/core/daemon_config.py @@ -6,7 +6,7 @@ DEFAULT_ADDRESS = '127.0.0.1:2000' -class DaemonConfig(object): +class DaemonConfig: """The class that stores X-Ray daemon configuration about the ip address and port for UDP and TCP port. It gets the address string from ``AWS_TRACING_DAEMON_ADDRESS`` and then from recorder's diff --git a/aws_xray_sdk/core/emitters/udp_emitter.py b/aws_xray_sdk/core/emitters/udp_emitter.py index 03785a2e..16e1e509 100644 --- a/aws_xray_sdk/core/emitters/udp_emitter.py +++ b/aws_xray_sdk/core/emitters/udp_emitter.py @@ -12,7 +12,7 @@ DEFAULT_DAEMON_ADDRESS = '127.0.0.1:2000' -class UDPEmitter(object): +class UDPEmitter: """ The default emitter the X-Ray recorder uses to send segments/subsegments to the X-Ray daemon over UDP using a non-blocking socket. If there is an diff --git a/aws_xray_sdk/core/models/default_dynamic_naming.py b/aws_xray_sdk/core/models/default_dynamic_naming.py index ff417736..343acc4a 100644 --- a/aws_xray_sdk/core/models/default_dynamic_naming.py +++ b/aws_xray_sdk/core/models/default_dynamic_naming.py @@ -1,7 +1,7 @@ from ..utils.search_pattern import wildcard_match -class DefaultDynamicNaming(object): +class DefaultDynamicNaming: """ Decides what name to use on a segment generated from an incoming request. By default it takes the host name and compares it to a pre-defined pattern. diff --git a/aws_xray_sdk/core/models/dummy_entities.py b/aws_xray_sdk/core/models/dummy_entities.py index 6d962d71..78eea9c4 100644 --- a/aws_xray_sdk/core/models/dummy_entities.py +++ b/aws_xray_sdk/core/models/dummy_entities.py @@ -18,9 +18,9 @@ class DummySegment(Segment): def __init__(self, name='dummy'): no_op_id = os.getenv('AWS_XRAY_NOOP_ID') if no_op_id and no_op_id.lower() == 'false': - super(DummySegment, self).__init__(name=name, traceid=TraceId().to_id()) + super().__init__(name=name, traceid=TraceId().to_id()) else: - super(DummySegment, self).__init__(name=name, traceid=NoOpTraceId().to_id(), entityid='0000000000000000') + super().__init__(name=name, traceid=NoOpTraceId().to_id(), entityid='0000000000000000') self.sampled = False def set_aws(self, aws_meta): @@ -87,7 +87,7 @@ class DummySubsegment(Subsegment): """ def __init__(self, segment, name='dummy'): - super(DummySubsegment, self).__init__(name, 'dummy', segment) + super().__init__(name, 'dummy', segment) no_op_id = os.getenv('AWS_XRAY_NOOP_ID') if no_op_id and no_op_id.lower() == 'false': super(Subsegment, self).__init__(name) diff --git a/aws_xray_sdk/core/models/entity.py b/aws_xray_sdk/core/models/entity.py index 3583bf28..a2150a5e 100644 --- a/aws_xray_sdk/core/models/entity.py +++ b/aws_xray_sdk/core/models/entity.py @@ -6,7 +6,7 @@ import json -from ..utils.compat import annotation_value_types, string_types +from ..utils.compat import annotation_value_types from ..utils.conversion import metadata_to_dict from .throwable import Throwable from . import http @@ -21,7 +21,7 @@ ORIGIN_TRACE_HEADER_ATTR_KEY = '_origin_trace_header' -class Entity(object): +class Entity: """ The parent class for segment/subsegment. It holds common properties and methods on segment and subsegment. @@ -113,7 +113,7 @@ def put_http_meta(self, key, value): return if key == http.STATUS: - if isinstance(value, string_types): + if isinstance(value, str): value = int(value) self.apply_status_code(value) @@ -139,7 +139,7 @@ def put_annotation(self, key, value): """ self._check_ended() - if not isinstance(key, string_types): + if not isinstance(key, str): log.warning("ignoring non string type annotation key with type %s.", type(key)) return @@ -165,7 +165,7 @@ def put_metadata(self, key, value, namespace='default'): """ self._check_ended() - if not isinstance(namespace, string_types): + if not isinstance(namespace, str): log.warning("ignoring non string type metadata namespace") return @@ -271,7 +271,7 @@ def serialize(self): def to_dict(self): """ Convert Entity(Segment/Subsegment) object to dict - with required properties that have non-empty values. + with required properties that have non-empty values. """ entity_dict = {} diff --git a/aws_xray_sdk/core/models/facade_segment.py b/aws_xray_sdk/core/models/facade_segment.py index 545a914a..5f16aba5 100644 --- a/aws_xray_sdk/core/models/facade_segment.py +++ b/aws_xray_sdk/core/models/facade_segment.py @@ -22,7 +22,7 @@ def __init__(self, name, entityid, traceid, sampled): sampled=sampled, ) - super(FacadeSegment, self).__init__( + super().__init__( name=name, entityid=entityid, traceid=traceid, diff --git a/aws_xray_sdk/core/models/segment.py b/aws_xray_sdk/core/models/segment.py index ce6ca8b7..b26dc1ab 100644 --- a/aws_xray_sdk/core/models/segment.py +++ b/aws_xray_sdk/core/models/segment.py @@ -63,7 +63,7 @@ def __init__(self, name, entityid=None, traceid=None, if not name: raise SegmentNameMissingException("Segment name is required.") - super(Segment, self).__init__(name) + super().__init__(name) if not traceid: traceid = TraceId().to_id() @@ -85,7 +85,7 @@ def add_subsegment(self, subsegment): Add input subsegment as a child subsegment and increment reference counter and total subsegments counter. """ - super(Segment, self).add_subsegment(subsegment) + super().add_subsegment(subsegment) self.increment() def increment(self): @@ -127,7 +127,7 @@ def remove_subsegment(self, subsegment): """ Remove the reference of input subsegment. """ - super(Segment, self).remove_subsegment(subsegment) + super().remove_subsegment(subsegment) self.decrement_subsegments_size() def set_user(self, user): @@ -135,7 +135,7 @@ def set_user(self, user): set user of a segment. One segment can only have one user. User is indexed and can be later queried. """ - super(Segment, self)._check_ended() + super()._check_ended() self.user = user def set_service(self, service_info): @@ -160,7 +160,7 @@ def to_dict(self): Convert Segment object to dict with required properties that have non-empty values. """ - segment_dict = super(Segment, self).to_dict() + segment_dict = super().to_dict() del segment_dict['ref_counter'] del segment_dict['_subsegments_counter'] diff --git a/aws_xray_sdk/core/models/subsegment.py b/aws_xray_sdk/core/models/subsegment.py index 6737d18d..3c4289e9 100644 --- a/aws_xray_sdk/core/models/subsegment.py +++ b/aws_xray_sdk/core/models/subsegment.py @@ -95,7 +95,7 @@ def __init__(self, name, namespace, segment): support `aws`, `remote` and `local`. :param Segment segment: The parent segment """ - super(Subsegment, self).__init__(name) + super().__init__(name) if not segment: raise SegmentNotFoundException("A parent segment is required for creating subsegments.") @@ -114,7 +114,7 @@ def add_subsegment(self, subsegment): reference counter and total subsegments counter of the parent segment. """ - super(Subsegment, self).add_subsegment(subsegment) + super().add_subsegment(subsegment) self.parent_segment.increment() def remove_subsegment(self, subsegment): @@ -124,7 +124,7 @@ def remove_subsegment(self, subsegment): :param Subsegment: subsegment to remove. """ - super(Subsegment, self).remove_subsegment(subsegment) + super().remove_subsegment(subsegment) self.parent_segment.decrement_subsegments_size() def close(self, end_time=None): @@ -136,7 +136,7 @@ def close(self, end_time=None): :param int end_time: Epoch in seconds. If not specified current time will be used. """ - super(Subsegment, self).close(end_time) + super().close(end_time) self.parent_segment.decrement_ref_counter() def set_sql(self, sql): @@ -154,7 +154,7 @@ def to_dict(self): Convert Subsegment object to dict with required properties that have non-empty values. """ - subsegment_dict = super(Subsegment, self).to_dict() + subsegment_dict = super().to_dict() del subsegment_dict['parent_segment'] diff --git a/aws_xray_sdk/core/models/throwable.py b/aws_xray_sdk/core/models/throwable.py index 43f76b7c..21d6483f 100644 --- a/aws_xray_sdk/core/models/throwable.py +++ b/aws_xray_sdk/core/models/throwable.py @@ -3,12 +3,10 @@ import binascii import logging -from ..utils.compat import string_types - log = logging.getLogger(__name__) -class Throwable(object): +class Throwable: """ An object recording exception infomation under trace entity `cause` section. The information includes the stack trace, @@ -31,7 +29,7 @@ def __init__(self, exception, stack, remote=False): message = None # do not record non-string exception message - if isinstance(message, string_types): + if isinstance(message, str): self.message = message self.type = type(exception).__name__ diff --git a/aws_xray_sdk/core/models/trace_header.py b/aws_xray_sdk/core/models/trace_header.py index b15fb8a7..b00c19cd 100644 --- a/aws_xray_sdk/core/models/trace_header.py +++ b/aws_xray_sdk/core/models/trace_header.py @@ -10,7 +10,7 @@ HEADER_DELIMITER = ";" -class TraceHeader(object): +class TraceHeader: """ The sampling decision and trace ID are added to HTTP requests in tracing headers named ``X-Amzn-Trace-Id``. The first X-Ray-integrated diff --git a/aws_xray_sdk/core/patcher.py b/aws_xray_sdk/core/patcher.py index bcdb59c1..8e4687e3 100644 --- a/aws_xray_sdk/core/patcher.py +++ b/aws_xray_sdk/core/patcher.py @@ -8,7 +8,7 @@ import wrapt from aws_xray_sdk import global_sdk_config -from .utils.compat import PY2, is_classmethod, is_instance_method +from .utils.compat import is_classmethod, is_instance_method log = logging.getLogger(__name__) @@ -55,17 +55,14 @@ def patch_all(double_patch=False): def _is_valid_import(module): module = module.replace('.', '/') - if PY2: - return bool(pkgutil.get_loader(module)) - else: - realpath = os.path.realpath(module) - is_module = os.path.isdir(realpath) and ( - os.path.isfile('{}/__init__.py'.format(module)) or os.path.isfile('{}/__init__.pyc'.format(module)) - ) - is_file = not is_module and ( - os.path.isfile('{}.py'.format(module)) or os.path.isfile('{}.pyc'.format(module)) - ) - return is_module or is_file + realpath = os.path.realpath(module) + is_module = os.path.isdir(realpath) and ( + os.path.isfile('{}/__init__.py'.format(module)) or os.path.isfile('{}/__init__.pyc'.format(module)) + ) + is_file = not is_module and ( + os.path.isfile('{}.py'.format(module)) or os.path.isfile('{}.pyc'.format(module)) + ) + return is_module or is_file def patch(modules_to_patch, raise_errors=True, ignore_module_patterns=None): diff --git a/aws_xray_sdk/core/plugins/ec2_plugin.py b/aws_xray_sdk/core/plugins/ec2_plugin.py index 5b8d3d2f..c749bbd4 100644 --- a/aws_xray_sdk/core/plugins/ec2_plugin.py +++ b/aws_xray_sdk/core/plugins/ec2_plugin.py @@ -1,13 +1,6 @@ import json import logging - -from aws_xray_sdk.core.utils.compat import PY2 - -if PY2: - from future.standard_library import install_aliases - install_aliases() - -from urllib.request import urlopen, Request +from urllib.request import Request, urlopen log = logging.getLogger(__name__) diff --git a/aws_xray_sdk/core/recorder.py b/aws_xray_sdk/core/recorder.py index 1710fb40..debc1604 100644 --- a/aws_xray_sdk/core/recorder.py +++ b/aws_xray_sdk/core/recorder.py @@ -18,7 +18,6 @@ from .plugins.utils import get_plugin_modules from .lambda_launcher import check_in_lambda from .exceptions.exceptions import SegmentNameMissingException, SegmentNotFoundException -from .utils.compat import string_types from .utils import stacktrace log = logging.getLogger(__name__) @@ -40,7 +39,7 @@ } -class AWSXRayRecorder(object): +class AWSXRayRecorder: """ A global AWS X-Ray recorder that will begin/end segments/subsegments and send them to the X-Ray daemon. This recorder is initialized during @@ -288,7 +287,7 @@ def _begin_subsegment_helper(self, name, namespace='local', beginWithoutSampling if not segment: log.warning("No segment found, cannot begin subsegment %s." % name) return None - + current_entity = self.get_trace_entity() if not current_entity.sampled or beginWithoutSampling: subsegment = DummySubsegment(segment, name) @@ -486,7 +485,7 @@ def _populate_runtime_context(self, segment, sampling_decision): segment.set_aws(copy.deepcopy(self._aws_metadata)) segment.set_service(SERVICE_INFO) - if isinstance(sampling_decision, string_types): + if isinstance(sampling_decision, str): segment.set_rule_name(sampling_decision) def _send_segment(self): @@ -562,7 +561,7 @@ def dynamic_naming(self): @dynamic_naming.setter def dynamic_naming(self, value): - if isinstance(value, string_types): + if isinstance(value, str): self._dynamic_naming = DefaultDynamicNaming(value, self.service) else: self._dynamic_naming = value diff --git a/aws_xray_sdk/core/sampling/connector.py b/aws_xray_sdk/core/sampling/connector.py index b8e288fe..a510a197 100644 --- a/aws_xray_sdk/core/sampling/connector.py +++ b/aws_xray_sdk/core/sampling/connector.py @@ -10,10 +10,9 @@ from .sampling_rule import SamplingRule from aws_xray_sdk.core.models.dummy_entities import DummySegment from aws_xray_sdk.core.context import Context -from aws_xray_sdk.core.utils.compat import PY2 -class ServiceConnector(object): +class ServiceConnector: """ Connector class that translates Centralized Sampling poller functions to actual X-Ray back-end APIs and communicates with X-Ray daemon as the @@ -137,16 +136,8 @@ def _dt_to_epoch(self, dt): """ Convert a offset-aware datetime to POSIX time. """ - if PY2: - # The input datetime is from botocore unmarshalling and it is - # offset-aware so the timedelta of subtracting this time - # to 01/01/1970 using the same tzinfo gives us - # Unix Time (also known as POSIX Time). - time_delta = dt - datetime(1970, 1, 1).replace(tzinfo=dt.tzinfo) - return int(time_delta.total_seconds()) - else: - # Added in python 3.3+ and directly returns POSIX time. - return int(dt.timestamp()) + # Added in python 3.3+ and directly returns POSIX time. + return int(dt.timestamp()) def _is_rule_valid(self, record): # We currently only handle v1 sampling rules. diff --git a/aws_xray_sdk/core/sampling/local/reservoir.py b/aws_xray_sdk/core/sampling/local/reservoir.py index ac65d741..2be7bc6f 100644 --- a/aws_xray_sdk/core/sampling/local/reservoir.py +++ b/aws_xray_sdk/core/sampling/local/reservoir.py @@ -2,7 +2,7 @@ import threading -class Reservoir(object): +class Reservoir: """ Keeps track of the number of sampled segments within a single second. This class is implemented to be diff --git a/aws_xray_sdk/core/sampling/local/sampler.py b/aws_xray_sdk/core/sampling/local/sampler.py index ebc09413..1db0163a 100644 --- a/aws_xray_sdk/core/sampling/local/sampler.py +++ b/aws_xray_sdk/core/sampling/local/sampler.py @@ -11,7 +11,7 @@ SUPPORTED_RULE_VERSION = (1, 2) -class LocalSampler(object): +class LocalSampler: """ The local sampler that holds either custom sampling rules or default sampling rules defined locally. The X-Ray recorder diff --git a/aws_xray_sdk/core/sampling/local/sampling_rule.py b/aws_xray_sdk/core/sampling/local/sampling_rule.py index 7d0a5dcb..adc0fdf5 100644 --- a/aws_xray_sdk/core/sampling/local/sampling_rule.py +++ b/aws_xray_sdk/core/sampling/local/sampling_rule.py @@ -3,7 +3,7 @@ from aws_xray_sdk.core.utils.search_pattern import wildcard_match -class SamplingRule(object): +class SamplingRule: """ One SamolingRule represents one rule defined from local rule json file or from a dictionary. It can be either a custom rule or default rule. diff --git a/aws_xray_sdk/core/sampling/reservoir.py b/aws_xray_sdk/core/sampling/reservoir.py index 14188b34..d542fe30 100644 --- a/aws_xray_sdk/core/sampling/reservoir.py +++ b/aws_xray_sdk/core/sampling/reservoir.py @@ -2,7 +2,7 @@ from enum import Enum -class Reservoir(object): +class Reservoir: """ Centralized thread-safe reservoir which holds fixed sampling quota, borrowed count and TTL. diff --git a/aws_xray_sdk/core/sampling/rule_cache.py b/aws_xray_sdk/core/sampling/rule_cache.py index 2cec5190..fca9df62 100644 --- a/aws_xray_sdk/core/sampling/rule_cache.py +++ b/aws_xray_sdk/core/sampling/rule_cache.py @@ -4,7 +4,7 @@ TTL = 60 * 60 # The cache expires 1 hour after the last refresh time. -class RuleCache(object): +class RuleCache: """ Cache sampling rules and quota retrieved by ``TargetPoller`` and ``RulePoller``. It will not return anything if it expires. diff --git a/aws_xray_sdk/core/sampling/rule_poller.py b/aws_xray_sdk/core/sampling/rule_poller.py index 301e04b0..07758766 100644 --- a/aws_xray_sdk/core/sampling/rule_poller.py +++ b/aws_xray_sdk/core/sampling/rule_poller.py @@ -8,7 +8,7 @@ DEFAULT_INTERVAL = 5 * 60 # 5 minutes on sampling rules fetch -class RulePoller(object): +class RulePoller: def __init__(self, cache, connector): diff --git a/aws_xray_sdk/core/sampling/sampler.py b/aws_xray_sdk/core/sampling/sampler.py index 8c09d59b..b793dd20 100644 --- a/aws_xray_sdk/core/sampling/sampler.py +++ b/aws_xray_sdk/core/sampling/sampler.py @@ -14,7 +14,7 @@ log = logging.getLogger(__name__) -class DefaultSampler(object): +class DefaultSampler: """Making sampling decisions based on centralized sampling rules defined by X-Ray control plane APIs. It will fall back to local sampler if centralized sampling rules are not available. diff --git a/aws_xray_sdk/core/sampling/sampling_rule.py b/aws_xray_sdk/core/sampling/sampling_rule.py index fb4c6508..9dbe55b1 100644 --- a/aws_xray_sdk/core/sampling/sampling_rule.py +++ b/aws_xray_sdk/core/sampling/sampling_rule.py @@ -4,7 +4,7 @@ from aws_xray_sdk.core.utils.search_pattern import wildcard_match -class SamplingRule(object): +class SamplingRule: """ Data model for a single centralized sampling rule definition. """ diff --git a/aws_xray_sdk/core/sampling/target_poller.py b/aws_xray_sdk/core/sampling/target_poller.py index 2d4f7574..3a233805 100644 --- a/aws_xray_sdk/core/sampling/target_poller.py +++ b/aws_xray_sdk/core/sampling/target_poller.py @@ -6,7 +6,7 @@ log = logging.getLogger(__name__) -class TargetPoller(object): +class TargetPoller: """ The poller to report the current statistics of all centralized sampling rules and retrieve the new allocated diff --git a/aws_xray_sdk/core/streaming/default_streaming.py b/aws_xray_sdk/core/streaming/default_streaming.py index 1e02ed7b..6c23ddaf 100644 --- a/aws_xray_sdk/core/streaming/default_streaming.py +++ b/aws_xray_sdk/core/streaming/default_streaming.py @@ -1,7 +1,7 @@ import threading -class DefaultStreaming(object): +class DefaultStreaming: """ The default streaming strategy. It uses the total count of a segment's children subsegments as a threshold. If the threshold is diff --git a/aws_xray_sdk/core/utils/atomic_counter.py b/aws_xray_sdk/core/utils/atomic_counter.py index 5dfe14d7..4a3e54ee 100644 --- a/aws_xray_sdk/core/utils/atomic_counter.py +++ b/aws_xray_sdk/core/utils/atomic_counter.py @@ -1,7 +1,7 @@ import threading -class AtomicCounter(object): +class AtomicCounter: """ A helper class that implements a thread-safe counter. """ diff --git a/aws_xray_sdk/core/utils/compat.py b/aws_xray_sdk/core/utils/compat.py index 88ec2998..00fbb352 100644 --- a/aws_xray_sdk/core/utils/compat.py +++ b/aws_xray_sdk/core/utils/compat.py @@ -1,16 +1,6 @@ import inspect -import sys - -PY2 = sys.version_info < (3,) -PY35 = sys.version_info >= (3, 5) - -if PY2: - annotation_value_types = (int, long, float, bool, str, unicode) # noqa: F821 - string_types = basestring # noqa: F821 -else: - annotation_value_types = (int, float, bool, str) - string_types = str +annotation_value_types = (int, float, bool, str) def is_classmethod(func): diff --git a/aws_xray_sdk/ext/boto_utils.py b/aws_xray_sdk/ext/boto_utils.py index cb65c854..9f7f41a6 100644 --- a/aws_xray_sdk/ext/boto_utils.py +++ b/aws_xray_sdk/ext/boto_utils.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import -# Need absolute import as botocore is also in the current folder for py27 import json import pkgutil diff --git a/aws_xray_sdk/ext/bottle/middleware.py b/aws_xray_sdk/ext/bottle/middleware.py index f51d9ca0..706cf303 100644 --- a/aws_xray_sdk/ext/bottle/middleware.py +++ b/aws_xray_sdk/ext/bottle/middleware.py @@ -7,7 +7,7 @@ calculate_segment_name, construct_xray_header, prepare_response_header -class XRayMiddleware(object): +class XRayMiddleware: """ Middleware that wraps each incoming request to a segment. """ diff --git a/aws_xray_sdk/ext/dbapi2.py b/aws_xray_sdk/ext/dbapi2.py index c3ed8241..3db4f44f 100644 --- a/aws_xray_sdk/ext/dbapi2.py +++ b/aws_xray_sdk/ext/dbapi2.py @@ -10,7 +10,7 @@ class XRayTracedConn(wrapt.ObjectProxy): def __init__(self, conn, meta={}): - super(XRayTracedConn, self).__init__(conn) + super().__init__(conn) self._xray_meta = meta def cursor(self, *args, **kwargs): @@ -25,7 +25,7 @@ class XRayTracedCursor(wrapt.ObjectProxy): def __init__(self, cursor, meta={}): - super(XRayTracedCursor, self).__init__(cursor) + super().__init__(cursor) self._xray_meta = meta # we preset database type if db is framework built-in diff --git a/aws_xray_sdk/ext/django/conf.py b/aws_xray_sdk/ext/django/conf.py index 091968e2..42f0b266 100644 --- a/aws_xray_sdk/ext/django/conf.py +++ b/aws_xray_sdk/ext/django/conf.py @@ -30,7 +30,7 @@ ) -class XRaySettings(object): +class XRaySettings: """ A object of Django settings to easily modify certain fields. The precedence for configurations at different places is as follows: diff --git a/aws_xray_sdk/ext/django/db.py b/aws_xray_sdk/ext/django/db.py index fdf7e27a..9106de58 100644 --- a/aws_xray_sdk/ext/django/db.py +++ b/aws_xray_sdk/ext/django/db.py @@ -21,7 +21,7 @@ def execute(self, query, *args, **kwargs): if xray_recorder.stream_sql: _previous_meta = copy.copy(self._xray_meta) self._xray_meta['sanitized_query'] = query - result = super(DjangoXRayTracedCursor, self).execute(query, *args, **kwargs) + result = super().execute(query, *args, **kwargs) if xray_recorder.stream_sql: self._xray_meta = _previous_meta return result @@ -30,7 +30,7 @@ def executemany(self, query, *args, **kwargs): if xray_recorder.stream_sql: _previous_meta = copy.copy(self._xray_meta) self._xray_meta['sanitized_query'] = query - result = super(DjangoXRayTracedCursor, self).executemany(query, *args, **kwargs) + result = super().executemany(query, *args, **kwargs) if xray_recorder.stream_sql: self._xray_meta = _previous_meta return result @@ -39,7 +39,7 @@ def callproc(self, proc, args): if xray_recorder.stream_sql: _previous_meta = copy.copy(self._xray_meta) self._xray_meta['sanitized_query'] = proc - result = super(DjangoXRayTracedCursor, self).callproc(proc, args) + result = super().callproc(proc, args) if xray_recorder.stream_sql: self._xray_meta = _previous_meta return result diff --git a/aws_xray_sdk/ext/django/middleware.py b/aws_xray_sdk/ext/django/middleware.py index d565be61..3c15bd33 100644 --- a/aws_xray_sdk/ext/django/middleware.py +++ b/aws_xray_sdk/ext/django/middleware.py @@ -19,7 +19,7 @@ CONTENT_LENGTH_KEY = 'content-length' -class XRayMiddleware(object): +class XRayMiddleware: """ Middleware that wraps each incoming request to a segment. """ diff --git a/aws_xray_sdk/ext/flask/middleware.py b/aws_xray_sdk/ext/flask/middleware.py index c0c1e226..fdc3b32f 100644 --- a/aws_xray_sdk/ext/flask/middleware.py +++ b/aws_xray_sdk/ext/flask/middleware.py @@ -8,7 +8,7 @@ from aws_xray_sdk.core.lambda_launcher import check_in_lambda, LambdaContext -class XRayMiddleware(object): +class XRayMiddleware: def __init__(self, app, recorder): self.app = app diff --git a/aws_xray_sdk/ext/httplib/patch.py b/aws_xray_sdk/ext/httplib/patch.py index bfb4fce2..91c5c24f 100644 --- a/aws_xray_sdk/ext/httplib/patch.py +++ b/aws_xray_sdk/ext/httplib/patch.py @@ -1,24 +1,17 @@ -from collections import namedtuple -import sys -import wrapt import fnmatch +from collections import namedtuple + import urllib3.connection +import wrapt from aws_xray_sdk.core import xray_recorder -from aws_xray_sdk.core.models import http from aws_xray_sdk.core.exceptions.exceptions import SegmentNotFoundException +from aws_xray_sdk.core.models import http from aws_xray_sdk.core.patcher import _PATCHED_MODULES -from aws_xray_sdk.ext.util import inject_trace_header, strip_url, unwrap, get_hostname - -if sys.version_info >= (3, 0, 0): - PY2 = False - httplib_client_module = 'http.client' - import http.client as httplib -else: - PY2 = True - httplib_client_module = 'httplib' - import httplib +from aws_xray_sdk.ext.util import get_hostname, inject_trace_header, strip_url, unwrap +httplib_client_module = 'http.client' +import http.client as httplib _XRAY_PROP = '_xray_prop' _XRay_Data = namedtuple('xray_data', ['method', 'host', 'url']) @@ -72,10 +65,6 @@ def http_response_processor(wrapped, instance, args, kwargs, return_value, def _xray_traced_http_getresponse(wrapped, instance, args, kwargs): - if not PY2 and kwargs.get('buffering', False): - # ignore py2 calls that fail as 'buffering` only exists in py2. - return wrapped(*args, **kwargs) - xray_data = getattr(instance, _XRAY_PROP, None) if not xray_data: return wrapped(*args, **kwargs) diff --git a/aws_xray_sdk/ext/pymongo/patch.py b/aws_xray_sdk/ext/pymongo/patch.py index 4d8cc1a4..cd8df5d9 100644 --- a/aws_xray_sdk/ext/pymongo/patch.py +++ b/aws_xray_sdk/ext/pymongo/patch.py @@ -15,7 +15,7 @@ class XrayCommandListener(monitoring.CommandListener): """ def __init__(self, record_full_documents): - super(XrayCommandListener, self).__init__() + super().__init__() self.record_full_documents = record_full_documents def started(self, event): diff --git a/aws_xray_sdk/ext/sqlalchemy/util/decorators.py b/aws_xray_sdk/ext/sqlalchemy/util/decorators.py index fa67befc..8480788d 100644 --- a/aws_xray_sdk/ext/sqlalchemy/util/decorators.py +++ b/aws_xray_sdk/ext/sqlalchemy/util/decorators.py @@ -1,18 +1,12 @@ import re import types +from urllib.parse import urlparse, uses_netloc + +from sqlalchemy.engine.base import Connection from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.ext.util import strip_url -from aws_xray_sdk.core.utils.compat import PY2 - -if PY2: - from future.standard_library import install_aliases - install_aliases() - -from urllib.parse import urlparse, uses_netloc -from sqlalchemy.engine.base import Connection - def decorate_all_functions(function_decorator): def decorator(cls): diff --git a/aws_xray_sdk/ext/sqlalchemy_core/patch.py b/aws_xray_sdk/ext/sqlalchemy_core/patch.py index acab1fd4..0551fe2b 100644 --- a/aws_xray_sdk/ext/sqlalchemy_core/patch.py +++ b/aws_xray_sdk/ext/sqlalchemy_core/patch.py @@ -1,20 +1,15 @@ import logging import sys - -if sys.version_info >= (3, 0, 0): - from urllib.parse import urlparse, uses_netloc -else: - from urlparse import urlparse, uses_netloc +from urllib.parse import urlparse, uses_netloc import wrapt +from sqlalchemy.sql.expression import ClauseElement from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core.patcher import _PATCHED_MODULES from aws_xray_sdk.core.utils import stacktrace from aws_xray_sdk.ext.util import unwrap -from sqlalchemy.sql.expression import ClauseElement - def _sql_meta(engine_instance, args): try: diff --git a/aws_xray_sdk/ext/util.py b/aws_xray_sdk/ext/util.py index ad9d5207..0c67e537 100644 --- a/aws_xray_sdk/ext/util.py +++ b/aws_xray_sdk/ext/util.py @@ -1,16 +1,10 @@ import re - -from aws_xray_sdk.core.models.trace_header import TraceHeader -from aws_xray_sdk.core.models import http +from urllib.parse import urlparse import wrapt -import sys - -if sys.version_info.major >= 3: # Python 3 and above - from urllib.parse import urlparse -else: # Python 2 and below - from urlparse import urlparse +from aws_xray_sdk.core.models import http +from aws_xray_sdk.core.models.trace_header import TraceHeader first_cap_re = re.compile('(.)([A-Z][a-z]+)') all_cap_re = re.compile('([a-z0-9])([A-Z])') diff --git a/aws_xray_sdk/sdk_config.py b/aws_xray_sdk/sdk_config.py index 33a8e495..6078c761 100644 --- a/aws_xray_sdk/sdk_config.py +++ b/aws_xray_sdk/sdk_config.py @@ -4,7 +4,7 @@ log = logging.getLogger(__name__) -class SDKConfig(object): +class SDKConfig: """ Global Configuration Class that defines SDK-level configuration properties. diff --git a/setup.py b/setup.py index 4b1df155..2318c29e 100644 --- a/setup.py +++ b/setup.py @@ -28,12 +28,7 @@ 'Natural Language :: English', 'License :: OSI Approved :: Apache Software License', 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', @@ -41,10 +36,9 @@ 'Programming Language :: Python :: 3.11', ], + python_requires=">=3.7", install_requires=[ - 'enum34;python_version<"3.4"', 'wrapt', - 'future;python_version<"3"', 'botocore>=1.11.3', ], diff --git a/tests/ext/aiohttp/test_middleware.py b/tests/ext/aiohttp/test_middleware.py index 025af6a1..84ecee75 100644 --- a/tests/ext/aiohttp/test_middleware.py +++ b/tests/ext/aiohttp/test_middleware.py @@ -5,22 +5,18 @@ """ import asyncio import sys -from aws_xray_sdk import global_sdk_config -try: - from unittest.mock import patch -except ImportError: - # NOTE: Python 2 dependency - from mock import patch +from unittest.mock import patch +import pytest from aiohttp import web from aiohttp.web_exceptions import HTTPUnauthorized -import pytest -from aws_xray_sdk.core.emitters.udp_emitter import UDPEmitter +from aws_xray_sdk import global_sdk_config from aws_xray_sdk.core.async_context import AsyncContext +from aws_xray_sdk.core.emitters.udp_emitter import UDPEmitter from aws_xray_sdk.core.models import http -from tests.util import get_new_stubbed_recorder from aws_xray_sdk.ext.aiohttp.middleware import middleware +from tests.util import get_new_stubbed_recorder class CustomStubbedEmitter(UDPEmitter): @@ -29,7 +25,7 @@ class CustomStubbedEmitter(UDPEmitter): """ def __init__(self, daemon_address='127.0.0.1:2000'): - super(CustomStubbedEmitter, self).__init__(daemon_address) + super().__init__(daemon_address) self.local = [] def send_entity(self, entity): @@ -42,7 +38,7 @@ def pop(self): return None -class ServerTest(object): +class ServerTest: """ Simple class to hold a copy of the event loop """ diff --git a/tests/ext/django/test_settings.py b/tests/ext/django/test_settings.py index 6c3c0f65..4867f90a 100644 --- a/tests/ext/django/test_settings.py +++ b/tests/ext/django/test_settings.py @@ -1,15 +1,11 @@ -try: - from unittest import mock -except ImportError: - # NOTE: Python 2 dependency - import mock +from unittest import mock import django -from aws_xray_sdk import global_sdk_config -from django.test import TestCase, override_settings -from django.conf import settings from django.apps import apps +from django.conf import settings +from django.test import TestCase, override_settings +from aws_xray_sdk import global_sdk_config from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core.sampling.sampler import LocalSampler diff --git a/tests/ext/flask_sqlalchemy/test_query.py b/tests/ext/flask_sqlalchemy/test_query.py index 69f0bd7a..b2732b8f 100644 --- a/tests/ext/flask_sqlalchemy/test_query.py +++ b/tests/ext/flask_sqlalchemy/test_query.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import import pytest from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core.context import Context diff --git a/tests/ext/httplib/test_httplib.py b/tests/ext/httplib/test_httplib.py index 5ddf9573..09aea4e2 100644 --- a/tests/ext/httplib/test_httplib.py +++ b/tests/ext/httplib/test_httplib.py @@ -1,18 +1,11 @@ +import http.client as httplib +from urllib.parse import urlparse + import pytest -import sys -from aws_xray_sdk.core import patch -from aws_xray_sdk.core import xray_recorder +from aws_xray_sdk.core import patch, xray_recorder from aws_xray_sdk.core.context import Context -from aws_xray_sdk.ext.util import strip_url, get_hostname - -if sys.version_info >= (3, 0, 0): - import http.client as httplib - from urllib.parse import urlparse -else: - import httplib - from urlparse import urlparse - +from aws_xray_sdk.ext.util import get_hostname, strip_url # httpbin.org is created by the same author of requests to make testing http easy. BASE_URL = 'httpbin.org' @@ -25,7 +18,7 @@ def construct_ctx(): so that later subsegment can be attached. After each test run it cleans up context storage again. """ - from aws_xray_sdk.ext.httplib import unpatch, reset_ignored + from aws_xray_sdk.ext.httplib import reset_ignored, unpatch patch(('httplib',)) xray_recorder.configure(service='test', sampling=False, context=Context()) diff --git a/tests/ext/pynamodb/test_pynamodb.py b/tests/ext/pynamodb/test_pynamodb.py index f1db1b37..d915a25a 100644 --- a/tests/ext/pynamodb/test_pynamodb.py +++ b/tests/ext/pynamodb/test_pynamodb.py @@ -58,7 +58,7 @@ def test_empty_response(): from aws_xray_sdk.ext.pynamodb.patch import pynamodb_meta_processor subsegment = xray_recorder.begin_subsegment('test') - class TempReq(object): + class TempReq: def __init__(self): self.headers = {'X-Amz-Target': 'ddb.ListTables'.encode('utf-8')} self.url = 'ddb.us-west-2' diff --git a/tests/ext/sqlalchemy/test_query.py b/tests/ext/sqlalchemy/test_query.py index c664b724..621e5b54 100644 --- a/tests/ext/sqlalchemy/test_query.py +++ b/tests/ext/sqlalchemy/test_query.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import import pytest from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core.context import Context diff --git a/tests/ext/sqlalchemy_core/test_base.py b/tests/ext/sqlalchemy_core/test_base.py index 74bbe976..f187ae4f 100644 --- a/tests/ext/sqlalchemy_core/test_base.py +++ b/tests/ext/sqlalchemy_core/test_base.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import pytest from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.ext.declarative import declarative_base diff --git a/tests/mock_module/mock_submodule/mock_subfile.py b/tests/mock_module/mock_submodule/mock_subfile.py index 840f96fd..7eb13b78 100644 --- a/tests/mock_module/mock_submodule/mock_subfile.py +++ b/tests/mock_module/mock_submodule/mock_subfile.py @@ -10,7 +10,7 @@ def mock_no_doublepatch(): pass -class MockClass(object): +class MockClass: def __init__(self): pass @@ -29,7 +29,7 @@ def mock_staticmethod(): class MockSubclass(MockClass): def __init__(self): - super(MockSubclass, self).__init__() + super().__init__() def mock_submethod(self): pass diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 9b6a2aab..4309780a 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1,9 +1,6 @@ +from unittest.mock import patch + from aws_xray_sdk.core.plugins.utils import get_plugin_modules -try: - from unittest.mock import patch -except ImportError: - # NOTE: Python 2 dependency - from mock import patch supported_plugins = ( 'ec2_plugin', diff --git a/tests/test_serialize_entities.py b/tests/test_serialize_entities.py index d46d737b..f3a041a6 100644 --- a/tests/test_serialize_entities.py +++ b/tests/test_serialize_entities.py @@ -258,7 +258,7 @@ def test_serialize_segment_with_exception(): class TestException(Exception): def __init__(self, message): - super(TestException, self).__init__(message) + super().__init__(message) segment_one = Segment('test') diff --git a/tests/test_trace_entities.py b/tests/test_trace_entities.py index 7d987ed0..421e9a5b 100644 --- a/tests/test_trace_entities.py +++ b/tests/test_trace_entities.py @@ -1,7 +1,6 @@ # -*- coding: iso-8859-15 -*- import pytest -import sys from aws_xray_sdk.core.models.segment import Segment from aws_xray_sdk.core.models.subsegment import Subsegment @@ -233,10 +232,7 @@ def test_add_exception_referencing(): subseg_cause = subseg.cause assert isinstance(subseg_cause, dict) - if sys.version_info.major == 2: - assert isinstance(seg_cause, basestring) - else: - assert isinstance(seg_cause, str) + assert isinstance(seg_cause, str) assert seg_cause == subseg_cause['exceptions'][0].id @@ -270,7 +266,7 @@ def test_add_exception_appending_exceptions(): def test_adding_subsegments_with_recorder(): xray_recorder.configure(sampling=False) xray_recorder.clear_trace_entities() - + segment = xray_recorder.begin_segment('parent'); subsegment = xray_recorder.begin_subsegment('sampled-child') unsampled_subsegment = xray_recorder.begin_subsegment_without_sampling('unsampled-child1') @@ -281,4 +277,4 @@ def test_adding_subsegments_with_recorder(): assert unsampled_subsegment.sampled == False assert unsampled_child_subsegment.sampled == False - xray_recorder.clear_trace_entities() \ No newline at end of file + xray_recorder.clear_trace_entities() diff --git a/tests/util.py b/tests/util.py index 074e712d..d5f51d12 100644 --- a/tests/util.py +++ b/tests/util.py @@ -4,13 +4,12 @@ from aws_xray_sdk.core.recorder import AWSXRayRecorder from aws_xray_sdk.core.emitters.udp_emitter import UDPEmitter from aws_xray_sdk.core.sampling.sampler import DefaultSampler -from aws_xray_sdk.core.utils.compat import PY35 class StubbedEmitter(UDPEmitter): def __init__(self, daemon_address='127.0.0.1:2000'): - super(StubbedEmitter, self).__init__(daemon_address) + super().__init__(daemon_address) self._local = threading.local() def send_entity(self, entity): @@ -36,12 +35,9 @@ def get_new_stubbed_recorder(): """ Returns a new AWSXRayRecorder object with emitter stubbed """ - if not PY35: - recorder = AWSXRayRecorder() - else: - from aws_xray_sdk.core.async_recorder import AsyncAWSXRayRecorder - recorder = AsyncAWSXRayRecorder() + from aws_xray_sdk.core.async_recorder import AsyncAWSXRayRecorder + recorder = AsyncAWSXRayRecorder() recorder.configure(emitter=StubbedEmitter(), sampler=StubbedSampler()) return recorder @@ -85,7 +81,7 @@ def find_subsegment_by_annotation(segment, key, value): result = _search_entity_by_annotation(entity, key, value) if result is not None: return result - return None + return None def _search_entity_by_annotation(entity, key, value): @@ -102,4 +98,4 @@ def _search_entity_by_annotation(entity, key, value): result = _search_entity_by_annotation(s, key, value) if result is not None: return result - return None \ No newline at end of file + return None From da588ee4d717364a0fe2d92dc9bc23cafa5be81c Mon Sep 17 00:00:00 2001 From: Lei Wang <66336933+wangzlei@users.noreply.github.com> Date: Wed, 26 Apr 2023 17:08:16 -0700 Subject: [PATCH 12/13] Disable IMDSv1 from Elastic Beanstalk Integration workflow verify the functionality in AWS Elastic Beanstalk. For AWS security reason we need to disable IMDSv1 from EB environment. --- terraform/eb.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/terraform/eb.tf b/terraform/eb.tf index 2840a8f5..db70062d 100644 --- a/terraform/eb.tf +++ b/terraform/eb.tf @@ -71,4 +71,10 @@ resource "aws_elastic_beanstalk_environment" "eb_env" { name = "XRayEnabled" value = "true" } + + setting { + namespace = "aws:autoscaling:launchconfiguration" + name = "DisableIMDSv1" + value = "true" + } } From 2976b25750d04ebe6dc7d0a3e399444896e82cae Mon Sep 17 00:00:00 2001 From: Ben Beasley Date: Mon, 1 May 2023 13:39:51 -0400 Subject: [PATCH 13/13] Support passing pytest arguments via tox (#390) This could be used, for example, to increase verbosity or to skip particular tests. Co-authored-by: Prashant Srivastava <50466688+srprash@users.noreply.github.com> --- tox.ini | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tox.ini b/tox.ini index 71fecd41..fbe9c333 100644 --- a/tox.ini +++ b/tox.ini @@ -107,41 +107,41 @@ setenv = commands = coverage erase - py{37,38,39,310,311}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext + py{37,38,39,310,311}-core: coverage run --append --source aws_xray_sdk -m pytest --ignore tests/ext {posargs} - ext-aiobotocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiobotocore + ext-aiobotocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiobotocore {posargs} - ext-aiohttp: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiohttp + ext-aiohttp: coverage run --append --source aws_xray_sdk -m pytest tests/ext/aiohttp {posargs} - ext-botocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/botocore + ext-botocore: coverage run --append --source aws_xray_sdk -m pytest tests/ext/botocore {posargs} - ext-bottle: coverage run --append --source aws_xray_sdk -m pytest tests/ext/bottle + ext-bottle: coverage run --append --source aws_xray_sdk -m pytest tests/ext/bottle {posargs} - ext-django: coverage run --append --source aws_xray_sdk -m pytest tests/ext/django + ext-django: coverage run --append --source aws_xray_sdk -m pytest tests/ext/django {posargs} - ext-flask: coverage run --append --source aws_xray_sdk -m pytest tests/ext/flask + ext-flask: coverage run --append --source aws_xray_sdk -m pytest tests/ext/flask {posargs} - ext-flask_sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/flask_sqlalchemy + ext-flask_sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/flask_sqlalchemy {posargs} - ext-httplib: coverage run --append --source aws_xray_sdk -m pytest tests/ext/httplib + ext-httplib: coverage run --append --source aws_xray_sdk -m pytest tests/ext/httplib {posargs} - ext-httpx: coverage run --append --source aws_xray_sdk -m pytest tests/ext/httpx + ext-httpx: coverage run --append --source aws_xray_sdk -m pytest tests/ext/httpx {posargs} - ext-pg8000: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pg8000 + ext-pg8000: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pg8000 {posargs} - ext-psycopg2: coverage run --append --source aws_xray_sdk -m pytest tests/ext/psycopg2 + ext-psycopg2: coverage run --append --source aws_xray_sdk -m pytest tests/ext/psycopg2 {posargs} - ext-pymysql: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pymysql + ext-pymysql: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pymysql {posargs} - ext-pynamodb: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pynamodb + ext-pynamodb: coverage run --append --source aws_xray_sdk -m pytest tests/ext/pynamodb {posargs} - ext-requests: coverage run --append --source aws_xray_sdk -m pytest tests/ext/requests + ext-requests: coverage run --append --source aws_xray_sdk -m pytest tests/ext/requests {posargs} - ext-sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy + ext-sqlalchemy: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy {posargs} - py{37,38,39,310,311}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core + py{37,38,39,310,311}-ext-sqlalchemy_core: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlalchemy_core {posargs} - ext-sqlite3: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlite3 + ext-sqlite3: coverage run --append --source aws_xray_sdk -m pytest tests/ext/sqlite3 {posargs} ; TODO: add additional logic to combine coverage from "core" and "ext" test runs ; codecov