


"""simple docstring"""



import logging
import os
import threading
import time


try:
		import warnings
except ImportError:
		lowercase_							=							None

try:
		import msvcrt
except ImportError:
		lowercase_							=							None

try:
		import fcntl
except ImportError:
		lowercase_							=							None


# Backward compatibility
# ------------------------------------------------
try:
		TimeoutError
except NameError:
		lowercase_							=							OSError


# Data
# ------------------------------------------------
lowercase_							=							[
    'Timeout',
    'BaseFileLock',
    'WindowsFileLock',
    'UnixFileLock',
    'SoftFileLock',
    'FileLock',
]

lowercase_							=							'3.0.12'


lowercase_							=							None
def      UpperCAmelCase     (       )						-> str:


	"""simple docstring"""




	global _logger
	lowerCAmelCase_      							=			_logger or logging.getLogger(__name__	)
	return _logger







class    __a						( __snake_case							):







				def __init__( self      ,	UpperCAmelCase   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			lock_file
					return None







				def __str__( self   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			F"""The file lock '{self.lock_file}' could not be acquired."""
					return temp







class    __a						:







				def __init__( self      ,	UpperCAmelCase   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			lock
					return None







				def __enter__( self   ):

					'''simple docstring'''






					return self.lock







				def __exit__( self      ,	UpperCAmelCase      ,	UpperCAmelCase      ,	UpperCAmelCase   ):

					'''simple docstring'''






					self.lock.release()
					return None







class    __a						:







				def __init__( self      ,	UpperCAmelCase      ,	UpperCAmelCase=-1      ,	UpperCAmelCase=None   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			max_filename_length if max_filename_length is not None else 255
					# Hash the filename if it's too long
					lowerCAmelCase_      							=			self.hash_filename_if_too_long(UpperCAmelCase      ,	UpperCAmelCase   )
					# The path to the lock file.
					lowerCAmelCase_      							=			lock_file

					# The file descriptor for the *_lock_file* as it is returned by the
					# os.open() function.
					# This file lock is only NOT None, if the object currently holds the
					# lock.
					lowerCAmelCase_      							=			None

					# The default timeout value.
					lowerCAmelCase_      							=			timeout

					# We use this lock primarily for the lock counter.
					lowerCAmelCase_      							=			threading.Lock()

					# The lock counter is used for implementing the nested locking
					# mechanism. Whenever the lock is acquired, the counter is increased and
					# the lock is only released, when this value is 0 again.
					lowerCAmelCase_      							=			0
					return None







				@property
				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					return self._lock_file







				@property
				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					return self._timeout







				@timeout.setter
				def      lowerCamelCase_     ( self      ,	UpperCAmelCase   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			float(UpperCAmelCase   )
					return None







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					raise NotImplementedError()







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					raise NotImplementedError()







				@property
				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					return self._lock_file_fd is not None







				def      lowerCamelCase_     ( self      ,	UpperCAmelCase=None      ,	UpperCAmelCase=0.0_5   ):

					'''simple docstring'''






					if timeout is None:
						lowerCAmelCase_      							=			self.timeout

					# Increment the number right at the beginning.
					# We can still undo it, if something fails.
					with self._thread_lock:
						self._lock_counter += 1

					lowerCAmelCase_      							=			id(self   )
					lowerCAmelCase_      							=			self._lock_file
					lowerCAmelCase_      							=			time.time()
					try:
						while True:
							with self._thread_lock:
								if not self.is_locked:
									logger().debug(F"""Attempting to acquire lock {lock_id} on {lock_filename}"""   )
									self._acquire()

							if self.is_locked:
								logger().debug(F"""Lock {lock_id} acquired on {lock_filename}"""   )
								break
							elif timeout >= 0 and time.time() - start_time > timeout:
								logger().debug(F"""Timeout on acquiring lock {lock_id} on {lock_filename}"""   )
								raise Timeout(self._lock_file   )
							else:
								logger().debug(
								    F"""Lock {lock_id} not acquired on {lock_filename}, waiting {poll_intervall} seconds ..."""   )
								time.sleep(UpperCAmelCase   )
					except:  # noqa
						# Something did go wrong, so decrement the counter.
						with self._thread_lock:
							lowerCAmelCase_      							=			max(0      ,	self._lock_counter - 1   )

						raise
					return _Acquire_ReturnProxy(lock=self   )







				def      lowerCamelCase_     ( self      ,	UpperCAmelCase=False   ):

					'''simple docstring'''






					with self._thread_lock:
						if self.is_locked:
							self._lock_counter -= 1

							if self._lock_counter == 0 or force:
								lowerCAmelCase_      							=			id(self   )
								lowerCAmelCase_      							=			self._lock_file

								logger().debug(F"""Attempting to release lock {lock_id} on {lock_filename}"""   )
								self._release()
								lowerCAmelCase_      							=			0
								logger().debug(F"""Lock {lock_id} released on {lock_filename}"""   )

					return None







				def __enter__( self   ):

					'''simple docstring'''






					self.acquire()
					return self







				def __exit__( self      ,	UpperCAmelCase      ,	UpperCAmelCase      ,	UpperCAmelCase   ):

					'''simple docstring'''






					self.release()
					return None







				def __del__( self   ):

					'''simple docstring'''






					self.release(force=UpperCAmelCase   )
					return None







				def      lowerCamelCase_     ( self      ,	UpperCAmelCase      ,	UpperCAmelCase   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			os.path.basename(UpperCAmelCase   )
					if len(UpperCAmelCase   ) > max_length and max_length > 0:
						lowerCAmelCase_      							=			os.path.dirname(UpperCAmelCase   )
						lowerCAmelCase_      							=			str(hash(UpperCAmelCase   )   )
						lowerCAmelCase_      							=			filename[: max_length - len(UpperCAmelCase   ) - 8] + '''...''' + hashed_filename + '''.lock'''
						return os.path.join(UpperCAmelCase      ,	UpperCAmelCase   )
					else:
						return path







class    __a						( __snake_case							):







				def __init__( self      ,	UpperCAmelCase      ,	UpperCAmelCase=-1      ,	UpperCAmelCase=None   ):

					'''simple docstring'''






					from .file_utils import relative_to_absolute_path

					super().__init__(UpperCAmelCase      ,	timeout=UpperCAmelCase      ,	max_filename_length=UpperCAmelCase   )
					lowerCAmelCase_      							=			'''\\\\?\\''' + relative_to_absolute_path(self.lock_file   )







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			os.O_RDWR | os.O_CREAT | os.O_TRUNC

					try:
						lowerCAmelCase_      							=			os.open(self._lock_file      ,	UpperCAmelCase   )
					except OSError:
						pass
					else:
						try:
							msvcrt.locking(UpperCAmelCase      ,	msvcrt.LK_NBLCK      ,	1   )
						except OSError:
							os.close(UpperCAmelCase   )
						else:
							lowerCAmelCase_      							=			fd
					return None







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			self._lock_file_fd
					lowerCAmelCase_      							=			None
					msvcrt.locking(UpperCAmelCase      ,	msvcrt.LK_UNLCK      ,	1   )
					os.close(UpperCAmelCase   )

					try:
						os.remove(self._lock_file   )
					# Probably another instance of the application
					# that acquired the file lock.
					except OSError:
						pass
					return None







class    __a						( __snake_case							):







				def __init__( self      ,	UpperCAmelCase      ,	UpperCAmelCase=-1      ,	UpperCAmelCase=None   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			os.statvfs(os.path.dirname(UpperCAmelCase   )   ).f_namemax
					super().__init__(UpperCAmelCase      ,	timeout=UpperCAmelCase      ,	max_filename_length=UpperCAmelCase   )







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			os.O_RDWR | os.O_CREAT | os.O_TRUNC
					lowerCAmelCase_      							=			os.open(self._lock_file      ,	UpperCAmelCase   )

					try:
						fcntl.flock(UpperCAmelCase      ,	fcntl.LOCK_EX | fcntl.LOCK_NB   )
					except OSError:
						os.close(UpperCAmelCase   )
					else:
						lowerCAmelCase_      							=			fd
					return None







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			self._lock_file_fd
					lowerCAmelCase_      							=			None
					fcntl.flock(UpperCAmelCase      ,	fcntl.LOCK_UN   )
					os.close(UpperCAmelCase   )
					return None







class    __a						( __snake_case							):







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					lowerCAmelCase_      							=			os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
					try:
						lowerCAmelCase_      							=			os.open(self._lock_file      ,	UpperCAmelCase   )
					except OSError:
						pass
					else:
						lowerCAmelCase_      							=			fd
					return None







				def      lowerCamelCase_     ( self   ):

					'''simple docstring'''






					os.close(self._lock_file_fd   )
					lowerCAmelCase_      							=			None

					try:
						os.remove(self._lock_file   )
					# The file is already deleted and that's what we want.
					except OSError:
						pass
					return None




lowercase_							=							None

if msvcrt:
		lowercase_							=							WindowsFileLock
elif fcntl:
		lowercase_							=							UnixFileLock
else:
		lowercase_							=							SoftFileLock

		if warnings is not None:
				warnings.warn('only soft file lock is available')



"""simple docstring"""



import math
from datetime import datetime, timedelta
def      UpperCAmelCase     (       _lowercase :   int	)						-> datetime:


	"""simple docstring"""




	lowerCAmelCase_      							=			year % 1_9
	lowerCAmelCase_      							=			year % 4
	lowerCAmelCase_      							=			year % 7
	lowerCAmelCase_      							=			math.floor(year / 1_0_0	)
	lowerCAmelCase_      							=			math.floor((1_3 + 8 * leap_day_inhibits) / 2_5	)
	lowerCAmelCase_      							=			leap_day_inhibits / 4
	lowerCAmelCase_      							=			(
	    1_5 - lunar_orbit_correction + leap_day_inhibits - leap_day_reinstall_number
	) % 3_0
	lowerCAmelCase_      							=			(4 + leap_day_inhibits - leap_day_reinstall_number) % 7

	# days to be added to March 21
	lowerCAmelCase_      							=			(1_9 * metonic_cycle + secular_moon_shift) % 3_0

	# PHM -> Paschal Full Moon
	lowerCAmelCase_      							=			(
	    2 * julian_leap_year
	    + 4 * non_leap_year
	    + 6 * days_to_add
	    + century_starting_point
	) % 7

	if days_to_add == 2_9 and days_from_phm_to_sunday == 6:
		return datetime(_lowercase			,   4			,   1_9	)
	elif days_to_add == 2_8 and days_from_phm_to_sunday == 6:
		return datetime(_lowercase			,   4			,   1_8	)
	else:
		return datetime(_lowercase			,   3			,   2_2	) + timedelta(
		    days=int(days_to_add + days_from_phm_to_sunday	)	)


if __name__ == "__main__":
		for year in (19_94, 20_00, 20_10, 20_21, 20_23):
				lowercase_							=							'will be' if year > datetime.now().year else 'was'
				print(f"""Easter in {year} {tense} {gauss_easter(year)}""")