Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TypeError by patching register_default_jsonb from psycopg2 #350

Merged
merged 1 commit into from
Jul 27, 2022

Conversation

srprash
Copy link
Contributor

@srprash srprash commented Jul 27, 2022

Issue #, if available: #243

Description of changes:
As mentioned in the above issue, this change in Django's newer version calls psycopg2.extras.register_default_jsonb which in turn calls register_type but our existing patch fails to unwrap the connection to expected type. Therefore resulting in TypeError: argument 2 must be a connection, cursor or None.

This PR adds a patch for register_default_jsonb so that we unwrap the connection or cursor object (if it's wrapped) and pass it onto the wrapped function.

Testing:

The unit test case test_register_default_jsonb fails (as expected) when run without the fix but passes with the fix:

py38-ext-psycopg2 run-test: commands[1] | coverage run --append --source aws_xray_sdk -m pytest tests/ext/psycopg2
================================================================================================================================================= test session starts ==================================================================================================================================================
platform darwin -- Python 3.8.9, pytest-7.1.2, pluggy-1.0.0
cachedir: .tox/py38-ext-psycopg2/.pytest_cache
benchmark: 3.4.1 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /Users/srprash/Desktop/Work/XRay_SDK_GH/Python/Fork/aws-xray-sdk-python
plugins: benchmark-3.4.1, asyncio-0.19.0, aiohttp-1.0.4
asyncio: mode=strict
collected 8 items                                                                                                                                                                                                                                                                                                      

tests/ext/psycopg2/test_psycopg2.py .......F                                                                                                                                                                                                                                                                     [100%]

======================================================================================================================================================= FAILURES =======================================================================================================================================================
_____________________________________________________________________________________________________________________________________________ test_register_default_jsonb ______________________________________________________________________________________________________________________________________________

    def test_register_default_jsonb():
        with testing.postgresql.Postgresql() as postgresql:
            url = postgresql.url()
            dsn = postgresql.dsn()
            conn = psycopg2.connect('dbname=' + dsn['database'] +
                                    ' password=mypassword' +
                                    ' host=' + dsn['host'] +
                                    ' port=' + str(dsn['port']) +
                                    ' user=' + dsn['user'])
    
>           assert psycopg2.extras.register_default_jsonb(conn_or_curs=conn, loads=lambda x: x)

tests/ext/psycopg2/test_psycopg2.py:188: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.tox/py38-ext-psycopg2/lib/python3.8/site-packages/psycopg2/_json.py:150: in register_default_jsonb
    return register_json(conn_or_curs=conn_or_curs, globally=globally,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

conn_or_curs = <XRayTracedConn at 0x10f7eb240 for psycopg2.extensions.connection at 0x10f23bc10>, globally = False, loads = <function test_register_default_jsonb.<locals>.<lambda> at 0x10fe8ff70>, oid = 3802, array_oid = 3807, name = 'jsonb'

    def register_json(conn_or_curs=None, globally=False, loads=None,
                      oid=None, array_oid=None, name='json'):
        """Create and register typecasters converting :sql:`json` type to Python objects.
    
        :param conn_or_curs: a connection or cursor used to find the :sql:`json`
            and :sql:`json[]` oids; the typecasters are registered in a scope
            limited to this object, unless *globally* is set to `!True`. It can be
            `!None` if the oids are provided
        :param globally: if `!False` register the typecasters only on
            *conn_or_curs*, otherwise register them globally
        :param loads: the function used to parse the data into a Python object. If
            `!None` use `!json.loads()`, where `!json` is the module chosen
            according to the Python version (see above)
        :param oid: the OID of the :sql:`json` type if known; If not, it will be
            queried on *conn_or_curs*
        :param array_oid: the OID of the :sql:`json[]` array type if known;
            if not, it will be queried on *conn_or_curs*
        :param name: the name of the data type to look for in *conn_or_curs*
    
        The connection or cursor passed to the function will be used to query the
        database and look for the OID of the :sql:`json` type (or an alternative
        type if *name* if provided). No query is performed if *oid* and *array_oid*
        are provided.  Raise `~psycopg2.ProgrammingError` if the type is not found.
    
        """
        if oid is None:
            oid, array_oid = _get_json_oids(conn_or_curs, name)
    
        JSON, JSONARRAY = _create_json_typecasters(
            oid, array_oid, loads=loads, name=name.upper())
    
>       register_type(JSON, not globally and conn_or_curs or None)
E       TypeError: argument 2 must be a connection, cursor or None

.tox/py38-ext-psycopg2/lib/python3.8/site-packages/psycopg2/_json.py:120: TypeError

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@srprash srprash requested a review from a team as a code owner July 27, 2022 22:38
Copy link
Contributor

@carolabadeer carolabadeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@srprash srprash merged commit 4b664e8 into aws:master Jul 27, 2022
@raffclar
Copy link

Hey there! Has this fix been released?

@srprash
Copy link
Contributor Author

srprash commented Sep 27, 2022

Hi @raffclar
This hasn't been released yet. We will prioritize a release soon.

@raffclar
Copy link

Thanks @srprash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants