Skip to content

fix: _cleaned_columns function now works with python multiline and typings #556

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

Merged

Conversation

Igralino
Copy link
Contributor

@Igralino Igralino commented Jan 7, 2025

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

Previously columns parameter of def _cleaned_columns was typed as "str", but actually tuple of strings was passed from def pre_upsert.
The logic inside the function was also made for one string rather than for tuple of strings.

What is the new behavior?

  • The typing is changed to columns: Tuple[str, ...]
  • Logic inside the function is fixed. Now each column-string is cleaned out of whitespaces.

Additional context

My custom made test ran without errors:

import unittest
from typing import Tuple


def _cleaned_columns(columns: Tuple[str, ...]) -> str:
    quoted = False
    cleaned = []

    for column in columns:
        clean_column = ""
        for char in column:
            if char.isspace() and not quoted:
                continue
            if char == '"':
                quoted = not quoted
            clean_column += char
        cleaned.append(clean_column)

    return ",".join(cleaned)


def wrap(*columns: str) -> str:
    return _cleaned_columns(columns)


class TestWrapFunction(unittest.TestCase):
    def test_wrap_single_column(self):
        self.assertEqual(wrap("column1"), "column1")

    def test_wrap_multiple_columns(self):
        self.assertEqual(wrap("column1", "column2"), "column1,column2")

    def test_wrap_columns_with_spaces(self):
        self.assertEqual(wrap(" column1 ", " column2 "), "column1,column2")

    def test_wrap_columns_with_quotes(self):
        self.assertEqual(wrap('"column1"', '"column2"'), '"column1","column2"')

    def test_wrap_columns_with_mixed_spaces_and_quotes(self):
        self.assertEqual(wrap(' "column1" ', ' "column2" '), '"column1","column2"')

    def test_wrap_no_columns(self):
        self.assertEqual(wrap(), "")

    def test_wrap_single_column_with_spaces(self):
        self.assertEqual(wrap(" column1 "), "column1")

    def test_wrap_single_column_with_quotes(self):
        self.assertEqual(wrap('"column1"'), '"column1"')

    def test_wrap_mixed_columns(self):
        self.assertEqual(wrap(" column1 ", '"column2"'), 'column1,"column2"')

@Igralino Igralino requested a review from grdsdev as a code owner January 7, 2025 21:22
@Igralino Igralino changed the title Bug fix: fix _cleaned_columns function fix: fix _cleaned_columns function logic and typings Jan 7, 2025
@grdsdev grdsdev requested a review from silentworks January 8, 2025 10:15
@silentworks
Copy link
Contributor

This is marked as a bug fix, which bug is this fixing? I haven't seen any issues opened about this bug. Also you would need to include tests in the PR that show the previous behavior still working while the new behavior is working too.

@Igralino
Copy link
Contributor Author

Igralino commented Jan 8, 2025

This is marked as a bug fix, which bug is this fixing? I haven't seen any issues opened about this bug.

I found the bug myself :)
I had this code and it didn't work:

self.supabase.table('videos').select("""
id, post_id, video_id, duration,
posts(id)
""").execute()

So after a while a discovered that multiline string are treated incorrectly due to incorrect behavior of _cleaned_columns - it treated tuple of strings as one string.

Result of running tests with new code:
 (igralino/fix__cleaned_columns_func)> poetry run pytest
The "poetry.dev-dependencies" section is deprecated and will be removed in a future version. Use "poetry.group.dev.dependencies" instead.
/Users/igralino/Library/Caches/pypoetry/virtualenvs/postgrest-cqWbsz8Z-py3.12/lib/python3.12/site-packages/pytest_asyncio/plugin.py:207: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session"

  warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
========================================================================================== test session starts ==========================================================================================
platform darwin -- Python 3.12.2, pytest-8.3.4, pluggy-1.5.0
rootdir: /Users/igralino/Documents/Programming/postgrest-py
configfile: pyproject.toml
plugins: cov-6.0.0, asyncio-0.25.0, anyio-4.7.0, depends-1.0.1
asyncio: mode=Mode.AUTO, asyncio_default_fixture_loop_scope=None
collected 239 items                                                                                                                                                                                     

tests/_async/test_client.py ........                                                                                                                                                              [  3%]
tests/_async/test_filter_request_builder.py .................................                                                                                                                     [ 17%]
tests/_async/test_filter_request_builder_integration.py .....................................                                                                                                     [ 32%]
tests/_async/test_query_request_builder.py .                                                                                                                                                      [ 33%]
tests/_async/test_request_builder.py .....................................                                                                                                                        [ 48%]
tests/_sync/test_client.py ........                                                                                                                                                               [ 51%]
tests/_sync/test_filter_request_builder.py .................................                                                                                                                      [ 65%]
tests/_sync/test_filter_request_builder_integration.py .....................................                                                                                                      [ 81%]
tests/_sync/test_query_request_builder.py .                                                                                                                                                       [ 81%]
tests/_sync/test_request_builder.py .....................................                                                                                                                         [ 97%]
tests/test_utils.py .......                                                                                                                                                                       [100%]

========================================================================================== 239 passed in 3.85s ==========================================================================================

@coveralls
Copy link

coveralls commented Jan 8, 2025

Pull Request Test Coverage Report for Build 12659542336

Details

  • 11 of 12 (91.67%) changed or added relevant lines in 1 file are covered.
  • 3 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.06%) to 95.597%

Changes Missing Coverage Covered Lines Changed/Added Lines %
postgrest/base_request_builder.py 11 12 91.67%
Files with Coverage Reduction New Missed Lines %
postgrest/types.py 1 97.87%
postgrest/base_request_builder.py 2 88.12%
Totals Coverage Status
Change from base Build 12546361645: 0.06%
Covered Lines: 1737
Relevant Lines: 1817

💛 - Coveralls

1 similar comment
@coveralls
Copy link

Pull Request Test Coverage Report for Build 12659542336

Details

  • 11 of 12 (91.67%) changed or added relevant lines in 1 file are covered.
  • 3 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.06%) to 95.597%

Changes Missing Coverage Covered Lines Changed/Added Lines %
postgrest/base_request_builder.py 11 12 91.67%
Files with Coverage Reduction New Missed Lines %
postgrest/types.py 1 97.87%
postgrest/base_request_builder.py 2 88.12%
Totals Coverage Status
Change from base Build 12546361645: 0.06%
Covered Lines: 1737
Relevant Lines: 1817

💛 - Coveralls

@silentworks silentworks changed the title fix: fix _cleaned_columns function logic and typings fix: _cleaned_columns function now works with python multiline and typings Jan 8, 2025
@silentworks silentworks merged commit 4127576 into supabase:main Jan 8, 2025
9 of 10 checks passed
@silentworks
Copy link
Contributor

Thank you for this PR @Igralino. I will get a release out soon with it.

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.

3 participants