





from __future__ import annotations

from collections.abc import Iterable, Iterator
from dataclasses import dataclass

snake_case_							=			(3, 9, -1_1, 0, 7, 5, 1, -1)
snake_case_							=			(4, 6, 2, 0, 8, 1_0, 3, -2)
@dataclass
class        snake_case_		:
  lowerCamelCase    :int
  lowerCamelCase    :Node | None

class        snake_case_		:







  def __init__(		self			,     __lowercase   )				->   str:
    lowerCamelCase   : Node | None								=None
    for i in sorted(UpperCAmelCase__			,     reverse=UpperCAmelCase__   ):
      lowerCamelCase   : str								=Node(UpperCAmelCase__			,     self.head   )







  def __iter__(		self   )				->   List[Any]:
    lowerCamelCase   : Any								=self.head
    while node:
      yield node.data
      lowerCamelCase   : str								=node.next_node







  def __len__(		self   )				->   Optional[int]:
    return sum(1 for _ in self   )







  def __str__(		self   )				->   int:
    return " -> ".join([str(UpperCAmelCase__   ) for node in self]   )


def 					A__	(       SCREAMING_SNAKE_CASE_							,       SCREAMING_SNAKE_CASE_		)   ->     SortedLinkedList:
  return SortedLinkedList(list(SCREAMING_SNAKE_CASE_		) + list(SCREAMING_SNAKE_CASE_		)		)


if __name__ == "__main__":
    import doctest

    doctest.testmod()
    snake_case_							=			SortedLinkedList
    print(merge_lists(SSL(test_data_odd), SSL(test_data_even)))








import collections
import json
import math
import os
import re
import time
from fnmatch import fnmatch
from typing import Dict

import requests
from slack_sdk import WebClient


snake_case_							=			WebClient(token=os.environ['''CI_SLACK_BOT_TOKEN'''])


def 					A__	(       SCREAMING_SNAKE_CASE_		)   ->     int:
		lowerCamelCase   : Tuple								=test_results.split(''' '''		)

		lowerCamelCase   : List[str]								=0
		lowerCamelCase   : Optional[Any]								=0

		# When the output is short enough, the output is surrounded by = signs: "== OUTPUT =="
		# When it is too long, those signs are not present.
		lowerCamelCase   : Optional[int]								=expressions[-2] if '''=''' in expressions[-1] else expressions[-1]

		for i, expression in enumerate(SCREAMING_SNAKE_CASE_		):
				if "failed" in expression:
						failed += int(expressions[i - 1]		)
				if "passed" in expression:
						success += int(expressions[i - 1]		)

		return failed, success, time_spent


def 					A__	(       SCREAMING_SNAKE_CASE_		)   ->     int:
		lowerCamelCase   : Union[str, Any]								={}
		lowerCamelCase   : Tuple								=None
		lowerCamelCase   : List[str]								=False
		for line in failures_short_lines.split('''\n'''		):
				if re.search(R'''_ \[doctest\]'''							,       SCREAMING_SNAKE_CASE_		):
						lowerCamelCase   : Optional[int]								=True
						lowerCamelCase   : Any								=line.split(''' '''		)[2]
				elif in_error and not line.split(''' '''		)[0].isdigit():
						lowerCamelCase   : Tuple								=line
						lowerCamelCase   : Optional[Any]								=False

		return failures
class        snake_case_		:







		def __init__(		self			,     __lowercase			,     __lowercase   )				->   Any:
				lowerCamelCase   : Optional[int]								=title

				lowerCamelCase   : Optional[int]								=doc_test_results['''time_spent'''].split(''','''   )[0]
				lowerCamelCase   : List[str]								=doc_test_results['''success''']
				lowerCamelCase   : Tuple								=doc_test_results['''failures''']
				lowerCamelCase   : List[Any]								=self.n_success + self.n_failures

				# Failures and success of the modeling tests
				lowerCamelCase   : Union[str, Any]								=doc_test_results







		@property
		def 			__lowercase   (		self   )				->   str:
				lowerCamelCase   : List[str]								=[self._time_spent]
				lowerCamelCase   : List[str]								=0

				for time in time_spent:
						lowerCamelCase   : List[str]								=time.split(''':'''   )

						# Time can be formatted as xx:xx:xx, as .xx, or as x.xx if the time spent was less than a minute.
						if len(__lowercase   ) == 1:
								lowerCamelCase   : Any								=[0, 0, time_parts[0]]

						lowerCamelCase		,   lowerCamelCase		,   lowerCamelCase   : Optional[int]								=int(time_parts[0]   ), int(time_parts[1]   ), float(time_parts[2]   )
						total_secs += hours * 3_6_0_0 + minutes * 6_0 + seconds

				lowerCamelCase		,   lowerCamelCase		,   lowerCamelCase   : List[str]								=total_secs // 3_6_0_0, (total_secs % 3_6_0_0) // 6_0, total_secs % 6_0
				return F"{int(__lowercase   )}h{int(__lowercase   )}m{int(__lowercase   )}s"







		@property
		def 			__lowercase   (		self   )				->   Dict:
				return {"type": "header", "text": {"type": "plain_text", "text": self.title}}







		@property
		def 			__lowercase   (		self   )				->   Dict:
				return {
				    "type": "section",
				    "text": {
				        "type": "plain_text",
				        "text": F"🌞 There were no failures: all {self.n_tests} tests passed. The suite ran in {self.time}.",
				        "emoji": True,
				    },
				    "accessory": {
				        "type": "button",
				        "text": {"type": "plain_text", "text": "Check Action results", "emoji": True},
				        "url": F"https://github.com/huggingface/transformers/actions/runs/{os.environ['GITHUB_RUN_ID']}",
				    },
				}







		@property
		def 			__lowercase   (		self   )				->   Dict:
				return {
				    "type": "section",
				    "text": {
				        "type": "plain_text",
				        "text": (
				            F"There were {self.n_failures} failures, out of {self.n_tests} tests.\nThe suite ran in"
				            F" {self.time}."
				        ),
				        "emoji": True,
				    },
				    "accessory": {
				        "type": "button",
				        "text": {"type": "plain_text", "text": "Check Action results", "emoji": True},
				        "url": F"https://github.com/huggingface/transformers/actions/runs/{os.environ['GITHUB_RUN_ID']}",
				    },
				}







		@property
		def 			__lowercase   (		self   )				->   Dict:
				lowerCamelCase   : int								=4_0
				lowerCamelCase   : str								={k: v['''failed'''] for k, v in doc_test_results.items() if isinstance(__lowercase			,     __lowercase   )}

				lowerCamelCase   : List[str]								=''''''
				for category, failures in category_failures.items():
						if len(__lowercase   ) == 0:
								continue

						if report != "":
								report += "\n\n"

						report += F"*{category} failures*:".ljust(line_length // 2   ).rjust(line_length // 2   ) + "\n"
						report += "`"
						report += "`\n`".join(__lowercase   )
						report += "`"

				return {
				    "type": "section",
				    "text": {
				        "type": "mrkdwn",
				        "text": F"The following examples had failures:\n\n\n{report}\n",
				    },
				}







		@property
		def 			__lowercase   (		self   )				->   str:
				lowerCamelCase   : Dict								=[self.header]

				if self.n_failures > 0:
						blocks.append(self.failures   )

				if self.n_failures > 0:
						blocks.extend([self.category_failures]   )

				if self.n_failures == 0:
						blocks.append(self.no_failures   )

				return json.dumps(__lowercase   )







		@staticmethod
		def 			__lowercase   (		)				->   Optional[Any]:
				lowerCamelCase   : Tuple								=[
				    {
				        '''type''': '''section''',
				        '''text''': {
				            '''type''': '''plain_text''',
				            '''text''': '''There was an issue running the tests.''',
				        },
				        '''accessory''': {
				            '''type''': '''button''',
				            '''text''': {'''type''': '''plain_text''', '''text''': '''Check Action results''', '''emoji''': True},
				            '''url''': F"https://github.com/huggingface/transformers/actions/runs/{os.environ['GITHUB_RUN_ID']}",
				        },
				    }
				]

				print('''Sending the following payload'''   )
				print(json.dumps({'''blocks''': json.loads(__lowercase   )}   )   )

				client.chat_postMessage(
				    channel=os.environ['''CI_SLACK_CHANNEL_ID_DAILY''']			,     text='''There was an issue running the tests.'''			,     blocks=__lowercase			,     )







		def 			__lowercase   (		self   )				->   Optional[int]:
				print('''Sending the following payload'''   )
				print(json.dumps({'''blocks''': json.loads(self.payload   )}   )   )

				lowerCamelCase   : int								=F"{self.n_failures} failures out of {self.n_tests} tests," if self.n_failures else '''All tests passed.'''

				lowerCamelCase   : Any								=client.chat_postMessage(
				    channel=os.environ['''CI_SLACK_CHANNEL_ID_DAILY''']			,     blocks=self.payload			,     text=__lowercase			,     )







		def 			__lowercase   (		self			,     __lowercase			,     __lowercase			,     __lowercase			,     __lowercase   )				->   Optional[int]:
				lowerCamelCase   : Union[str, Any]								=''''''
				for key, value in failures.items():
						lowerCamelCase   : Any								=value[:2_0_0] + ''' [Truncated]''' if len(__lowercase   ) > 2_5_0 else value
						failures_text += F"*{key}*\n_{value}_\n\n"

				lowerCamelCase   : Union[str, Any]								=job_name
				lowerCamelCase   : List[str]								={'''type''': '''section''', '''text''': {'''type''': '''mrkdwn''', '''text''': text}}

				if job_link is not None:
						lowerCamelCase   : Optional[int]								={
						    '''type''': '''button''',
						    '''text''': {'''type''': '''plain_text''', '''text''': '''GitHub Action job''', '''emoji''': True},
						    '''url''': job_link,
						}

				return [
				    {"type": "header", "text": {"type": "plain_text", "text": title.upper(), "emoji": True}},
				    content,
				    {"type": "section", "text": {"type": "mrkdwn", "text": failures_text}},
				]







		def 			__lowercase   (		self   )				->   Tuple:
				if self.thread_ts is None:
						raise ValueError('''Can only post reply if a post has been made.'''   )

				lowerCamelCase   : str								=self.doc_test_results.pop('''job_link'''   )
				self.doc_test_results.pop('''failures'''   )
				self.doc_test_results.pop('''success'''   )
				self.doc_test_results.pop('''time_spent'''   )

				lowerCamelCase   : Union[str, Any]								=sorted(self.doc_test_results.items()			,     key=lambda __lowercase   : t[0]   )
				for job, job_result in sorted_dict:
						if len(job_result['''failures''']   ):
								lowerCamelCase   : int								=F"*Num failures* :{len(job_result['failed']   )} \n"
								lowerCamelCase   : Optional[Any]								=job_result['''failures''']
								lowerCamelCase   : List[str]								=self.get_reply_blocks(__lowercase			,     __lowercase			,     __lowercase			,     text=__lowercase   )

								print('''Sending the following reply'''   )
								print(json.dumps({'''blocks''': blocks}   )   )

								client.chat_postMessage(
								    channel=os.environ['''CI_SLACK_CHANNEL_ID_DAILY''']			,     text=F"Results for {job}"			,     blocks=__lowercase			,     thread_ts=self.thread_ts['''ts''']			,     )

								time.sleep(1   )


def 					A__	(       )   ->     Union[str, Any]:
		lowerCamelCase   : Optional[Any]								=os.environ['''GITHUB_RUN_ID''']
		lowerCamelCase   : int								=F"https://api.github.com/repos/huggingface/transformers/actions/runs/{run_id}/jobs?per_page=100"
		lowerCamelCase   : Tuple								=requests.get(SCREAMING_SNAKE_CASE_		).json()
		lowerCamelCase   : Union[str, Any]								={}

		try:
				jobs.update({job['''name''']: job['''html_url'''] for job in result['''jobs''']}		)
				lowerCamelCase   : Any								=math.ceil((result['''total_count'''] - 1_0_0) / 1_0_0		)

				for i in range(SCREAMING_SNAKE_CASE_		):
						lowerCamelCase   : Optional[Any]								=requests.get(url + F"&page={i + 2}"		).json()
						jobs.update({job['''name''']: job['''html_url'''] for job in result['''jobs''']}		)

				return jobs
		except Exception as e:
				print('''Unknown error, could not fetch links.'''							,       SCREAMING_SNAKE_CASE_		)

		return {}


def 					A__	(       SCREAMING_SNAKE_CASE_		)   ->     Union[str, Any]:
		lowerCamelCase   : List[str]								={}

		if os.path.exists(SCREAMING_SNAKE_CASE_		):
				lowerCamelCase   : Optional[Any]								=os.listdir(SCREAMING_SNAKE_CASE_		)
				for file in files:
						try:
								with open(os.path.join(SCREAMING_SNAKE_CASE_							,       SCREAMING_SNAKE_CASE_		)							,       encoding='''utf-8'''		) as f:
										lowerCamelCase   : List[str]								=f.read()
						except UnicodeDecodeError as e:
								raise ValueError(F"Could not open {os.path.join(SCREAMING_SNAKE_CASE_							,       SCREAMING_SNAKE_CASE_		)}."		) from e

		return _artifact


def 					A__	(       )   ->     Any:
		class        snake_case_		:







				def __init__(		self			,     __lowercase   )				->   Optional[Any]:
						lowerCamelCase   : Optional[Any]								=name
						lowerCamelCase   : List[str]								=[]







				def __str__(		self   )				->   Any:
						return self.name







				def 			__lowercase   (		self			,     __lowercase   )				->   Dict:
						self.paths.append({'''name''': self.name, '''path''': path}   )

		lowerCamelCase   : Dict[str, Artifact]								={}

		lowerCamelCase   : List[Any]								=filter(os.path.isdir							,       os.listdir()		)
		for directory in directories:
				lowerCamelCase   : Tuple								=directory
				if artifact_name not in _available_artifacts:
						lowerCamelCase   : Any								=Artifact(SCREAMING_SNAKE_CASE_		)

						_available_artifacts[artifact_name].add_path(SCREAMING_SNAKE_CASE_		)

		return _available_artifacts


if __name__ == "__main__":
				snake_case_							=			get_job_links()
				snake_case_							=			retrieve_available_artifacts()

				snake_case_							=			collections.OrderedDict(
				    [
				        ('''*.py''', '''API Examples'''),
				        ('''*.md''', '''MD Examples'''),
				    ]
				)

				# This dict will contain all the information relative to each doc test category:
				# - failed: list of failed tests
				# - failures: dict in the format 'test': 'error_message'
				snake_case_							=			{
				    v: {
				        '''failed''': [],
				        '''failures''': {},
				    }
				    for v in docs.values()
				}

				# Link to the GitHub Action job
				snake_case_							=			github_actions_job_links.get('''run_doctests''')

				snake_case_							=			available_artifacts['''doc_tests_gpu_test_reports'''].paths[0]
				snake_case_							=			retrieve_artifact(artifact_path['''name'''])
				if "stats" in artifact:
								snake_case_,       snake_case_,       snake_case_							=			handle_test_results(artifact['''stats'''])
								snake_case_							=			failed
								snake_case_							=			success
								snake_case_							=			time_spent[1:-1] + ''', '''

								snake_case_							=			extract_first_line_failure(artifact['''failures_short'''])
								for line in artifact["summary_short"].split('''\n'''):
												if re.search('''FAILED''', line):
																snake_case_							=			line.replace('''FAILED ''', '''''')
																snake_case_							=			line.split()[0].replace('''\n''', '''''')

																if "::" in line:
																				snake_case_,       snake_case_							=			line.split('''::''')
																else:
																				snake_case_,       snake_case_							=			line, line

																for file_regex in docs.keys():
																				if fnmatch(file_path, file_regex):
																								snake_case_							=			docs[file_regex]
																								doc_test_results[category]["failed"].append(test)

																								snake_case_							=			all_failures[test] if test in all_failures else '''N/A'''
																								snake_case_							=			failure
																								break

				snake_case_							=			Message('''🤗 Results of the doc tests.''', doc_test_results)
				message.post()
				message.post_reply()

