Skip to content
This repository was archived by the owner on Jan 4, 2025. It is now read-only.

Compatibility fix#124

Merged
GriceTurrble merged 1 commit intopython-amazon-mws:developfrom
lakam99:patch-1
Jun 25, 2020
Merged

Compatibility fix#124
GriceTurrble merged 1 commit intopython-amazon-mws:developfrom
lakam99:patch-1

Conversation

@lakam99
Copy link
Copy Markdown
Contributor

@lakam99 lakam99 commented Jul 12, 2019

Line 126 gives ValueError when passing sequence. Using any() will allow for full compatibility.

Line 126 gives ValueError when passing sequence. Using any() will allow for full compatibility.
@codecov
Copy link
Copy Markdown

codecov bot commented Jul 12, 2019

Codecov Report

Merging #124 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #124   +/-   ##
=======================================
  Coverage   46.67%   46.67%           
=======================================
  Files           4        4           
  Lines         632      632           
  Branches       64       64           
=======================================
  Hits          295      295           
  Misses        322      322           
  Partials       15       15
Impacted Files Coverage Δ
mws/utils.py 71.84% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ccef002...3f7fecf. Read the comment docs.

@elcolumbio
Copy link
Copy Markdown
Contributor

That is interesting, maybe i start to understand your issues. You are using your own data objects and run in issues.
I think we don't support this at all at the moment. Like we need to replace all check isinstance(value, list, ...) code parts with duck typing and more?
Maybe you can confirm and we can have the discussion if we should go that way.
I think it is not too much work since we have not too many parts where we have user input.

@lakam99
Copy link
Copy Markdown
Contributor Author

lakam99 commented Jul 24, 2019

Yes, I believe if you use a more general function to check if a list type is empty, you would increase the compatibility.
In my case, I read data from a spreadsheet into a pandas DataFrame object. However, DataFrames are ambiguous when it comes to truth values. The only general way to check if it's empty or not is by using any(). I've yet to come across an iterable data type in python that doesn't support its use so I don't think there would be any more problems with it after that.

@elcolumbio
Copy link
Copy Markdown
Contributor

We are talking about python iterables. There is at least one we don't want to iterate over its a string. But maybe all others are fine. So you should test for string and than you should try to iterate and if it fails ask for forgiveness and return the object as is. I am interested if you can make it work for your datatypes.

@elcolumbio
Copy link
Copy Markdown
Contributor

Most important we need more tests for more values. This is very likely to cause issues. I am not sure but probably we loose parameters already here in our actual version and in your one too. So we have to improve the if statement for the values. For example (very uncomplete):
value = False , value = [False, False], value = '', value = ([(True)])
They will not produce the same results.

@lakam99
Copy link
Copy Markdown
Contributor Author

lakam99 commented Aug 3, 2019

I think I have a function that could handle what is trying to be done.

def arg_is_iter(arg):
    return '__iter__' in dir(arg)

def any_iter(arg):

    if arg_is_iter(arg):
        if 'any' in dir(arg):
            #Object has built in method
            
            return any_iter(arg.any())
            #Call the method again to make sure the object is
            #for sure iterable now
        
        return any(arg)
    else:
        return bool(arg)

I've also provided test cases here

@GriceTurrble GriceTurrble changed the base branch from master to develop February 25, 2020 19:12
@GriceTurrble
Copy link
Copy Markdown
Member

GriceTurrble commented Feb 25, 2020

Looking at this in hindsight, I sense our attempts to ask permission rather than forgiveness are biting us here.

This is the current code:

def enumerate_param(param, values):
    if not any(values):
        # if not values -> returns ValueError
        return {}
    if not isinstance(values, (list, tuple, set)):
        # Coerces a single value to a list before continuing.
        values = [values, ]
    if not param.endswith('.'):
        # Ensure this enumerated param ends in '.'
        param += '.'
    # Return final output: dict comprehension of the enumerated param and values.
    return {
        '{}{}'.format(param, idx+1): val
        for idx, val in enumerate(values)
    }

I think we can clean this up for basically two cases:

  1. Check if values implements either __iter__ or __getitem__.=, indicating it is iterable.
  2. Special case: covert a single string (which is iterable, but the outcome of iterating it is undesirable) to a list with a string element.

End result:

def enumerate_param(param, values):
    # Coerce values to a list if it is not iterable or a string.
    if isinstance(values, str):
        values = [values,]
    if "__iter__" not in dir(values) and "__getitem__" not in dir(values):
        values = [values,]

    # Ensure this enumerated param ends in '.'
    if not param.endswith('.'):
        param += '.'

    output = {}
    for idx, val in enumerate(values):
        output['{}{}'.format(param, idx+1)] = val
    return output

No need for a shortcut test, no checking specifically for lists or sets or tuples, basic duck typing.

Copy link
Copy Markdown
Member

@GriceTurrble GriceTurrble left a comment

Choose a reason for hiding this comment

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

Despite earlier discussion, this is a small change that has a tangible benefit in this use-case with seemingly little consequence. Accepting.

Thank you! Sorry it took so long.

@GriceTurrble GriceTurrble merged commit 9a4f85c into python-amazon-mws:develop Jun 25, 2020
Lacrymology added a commit to Shiphero/python-amazon-mws that referenced this pull request Jul 10, 2020
* upstream/develop:
  Add Feeds utility to convert dict FeedOptions to string (python-amazon-mws#181)
  Ensure correct decoding of bytes (python-amazon-mws#168)
  Compatibility fix (python-amazon-mws#124)
  Implement a couple of function for the OutboundShipments API. (python-amazon-mws#96)
  Added OutboundShipments.create_fulfillment_order (python-amazon-mws#95)
  added UpdateReportAcknowledgements (python-amazon-mws#101)
  Update feeds.py (python-amazon-mws#166)
  added easyship api support for indian marketplace (python-amazon-mws#169)
  Moving Slack link up, removing gitter chat link
  add all current marketplaces and alphabetize by country code (python-amazon-mws#155)
  Updated slack invite link
  Slack invite link (python-amazon-mws#152)
  Slack invite link
  fix clean_params (python-amazon-mws#106)
  add in NL marketplace information
  Fix flake8 warnings
  Update develop branch CI + package metadata
  include mws.apis in setup.py
  Fix bug: Remove trailing comma
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants