pycontribs / jira

Python Jira library. Development chat available on https://matrix.to/#/#pycontribs:matrix.org
https://jira.readthedocs.io
BSD 2-Clause "Simplified" License
1.96k stars 870 forks source link

JIRA.create_issue_link crash when passing IssueLinkType #1604

Closed rynkk closed 1 year ago

rynkk commented 1 year ago

Bug summary

According to the type annotations of JIRA.create_issue_link the method accepts the type-argument either as a string or as an IssueLinkType object. If you pass an instance of IssueLinkType it will not be translated and thus cause a Serialization-Exception when trying to post.

@translate_resource_args
def create_issue_link(
    self,
    type: Union[str, IssueLinkType],
    inwardIssue: str,
    outwardIssue: str,
    comment: Optional[Dict[str, Any]] = None,
) -> Response:
    ...

I can submit a PR with the solution mentioned below and new tests next week, probably.


Jannik Meinecke (jannik.meinecke@mercedes-benz.com) on behalf of MBition GmbH. Provider Information

Is there an existing issue for this?

Jira Instance type

Jira Cloud (Hosted by Atlassian)

Jira instance version

No response

jira-python version

3.4.0

Python Interpreter version

3.9

Which operating systems have you used?

Reproduction steps

jira: JIRA

link_types = jira.issue_link_types()

# take any link type
link_type = link_types[0]

# fake issue-keys, will never get to post anyways
issue_one  = "proj-1"
issue_two = "proj-2"

jira.create_issue_link(link_type, issue_one, issue_two)

Stack trace

Traceback (most recent call last):
  File "C:/Users/***.py", line 73, in main
    created_link = jira.create_issue_link(correct_link_type, issue, issue_to_link)
  File "C:\Users\***\venv\lib\site-packages\jira\client.py", line 119, in wrapper
    result = func(*arg_list, **kwargs)
  File "C:\Users\***\venv\lib\site-packages\jira\client.py", line 2497, in create_issue_link
    return self._session.post(url, data=json.dumps(data))
  File "C:\Program Files\Python39\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Program Files\Python39\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files\Python39\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Program Files\Python39\lib\json\encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type IssueLinkType is not JSON serializable

Expected behaviour

Fitting to the current way to handle automated convertion; IssueLinkType should probably be parsed into its name by translate_resource_args.

def translate_resource_args(func: Callable):
    """Decorator that converts Issue and Project resources to their keys when used as arguments."""

    @wraps(func)
    def wrapper(*args: Any, **kwargs: Any) -> Any:
        arg_list = []
        for arg in args:
            if isinstance(arg, (Issue, Project)):
                arg_list.append(arg.key)
+           elif isinstance(arg, IssueLinkType):
+               arg_list.append(arg.name)
            else:
                arg_list.append(arg)
        result = func(*arg_list, **kwargs)
        return result

    return wrapper

Might be sensible to check for other cases of this, too.

Additional Context

No response

dmcbride64 commented 1 year ago

I was able to reproduce this issue.

The same behavior is seen if you retrieve the issue link type using issue_link_type(id), as well.

rynkk commented 1 year ago

Sorry for the delay, I did not manage to find time, yet. I hope I will be able to work on it within the next two weeks and also catch some other related oversights in the process.


Jannik Meinecke (jannik.meinecke@mercedes-benz.com) on behalf of MBition GmbH. Provider Information

rynkk commented 1 year ago

The same behavior is seen if you retrieve the issue link type using issue_link_type(id), as well.

@dmcbride64 can you elaborate on this? I am unable to reproduce your issue.


Jannik Meinecke (jannik.meinecke@mercedes-benz.com) on behalf of MBition GmbH. Provider Information

dmcbride64 commented 1 year ago

The same behavior is seen if you retrieve the issue link type using issue_link_type(id), as well.

@dmcbride64 can you elaborate on this? I am unable to reproduce your issue.

Jannik Meinecke (jannik.meinecke@mercedes-benz.com) on behalf of MBition GmbH. Provider Information

@rynkk

Reproduce

Get a list of valid link types:

link_types = jira.issue_link_types()
print(link_types)

[<JIRA IssueLinkType: name='Blocks', id='10000'>, <JIRA IssueLinkType: name='Cloners', id='10001'>, <JIRA IssueLinkType: name='Duplicate', id='10002'>, <JIRA IssueLinkType: name='Issue split', id='10300'>, <JIRA IssueLinkType: name='Relates', id='10003'>]

Pick any valid link type 'id' from the list and use it to create an issue link:

link_type = jira.issue_link_type(10000)
jira.create_issue_link(link_type, "SANDBOX-255", "SANDBOX-257")

TypeError: Object of type IssueLinkType is not JSON serializable

rynkk commented 1 year ago

@dmcbride64 I see, thanks for the clarification. This seems like the exact same problem as I described (calling it with the IssueLinkType-object). So seeing how the PR was merged, it should work again if you update your jira version!


Jannik Meinecke (jannik.meinecke@mercedes-benz.com) on behalf of MBition GmbH. Provider Information

dmcbride64 commented 1 year ago

@rynkk

Yes, I believe that's true. Just a slight wrinkle on the original issue. Only mentioned for completeness.