Simple Python Old Email Eraser From Inbox
One nice programming principle is the principle of least astonishment, which you violate with your code. Imagine someone using your module and calling Connect_And_Login. If it was me I would be very astonished that suddenly many of my emails are deleted! At least the function does not have today as a default bedate, otherwise it would be a disaster waiting to happen.

It would be a lot better if that function just returned the mail object, which the function Mark_emails_as_Deleted then takes as parameter.

mail, inbox = connect_and_login(args.uname, args.path)
mark_emails_as_deleted(mail, args.bedate, inbox)


(Before the return in Connect_And_Login was actually superfluous,  because python automatically returns None at the end of a function body



And here we are at another thing. You should use a consistent naming scheme for your variables. Python actually has an official style guide, PEP8, which programmers are encouraged to follow to improve readability. It recommends using lower_case for variables and functions (and PascalCase for classes).

It also recommends avoiding unnecessary white-space, such as between an if block and an else block, or between try and except.



Excepting an import error and then just printing the error does you no good. It will print the error, try to continue running the code, encounter wherever that module is actually needed and fail there with another cryptic error code. The output saying that it was actually an import error is buried above the stacktrace. It is better to just let it fail as an import error or at least terminate the program there.



The different email provider could be stored in a dictionary mapping to their data. This way it is more easily extendable to more providers:

supported_provider = {"gmail.com":{"mail": "imap.gmail.com",
                                   "inbox": "INBOX",
                                    "url": 'https://www.google.com/settings/security/lesssecureapps'},
                       "yahoo.com": {...}}
provider = supported_provider[uname.split("@")[-1]]
mail = imaplib.IMAP4_SSL(provider['mail'])
inbox = provider['inbox']
url = provider['url']




It is in general faster, more readable and extendable to use str.format instead of string additions:

result, data = mail.search(None, '(BEFORE "{}")'.format(bedate))




Lastly, you could use the nice functionality of argparse to validate your input as a date as explained e.g. in this answer:

parser.add_argument('bedate', type=lambda s: datetime.datetime.strptime(s, '%d-%b-%Y'), help="Enter Date, Before this date all emails will be cleaned. Format: 01-Jan-2016")


%b is the abbreviated month name *in the current locale. So in English it will beJan, Feb, ..., Dec, while e.g. in German it will beJan, Feb, ..., Dez`. I guess gmail/yahoo can actually handle this because it is also localized for the user.