"warnings" --- Έλεγχος προειδοποιήσεων
**************************************

**Πηγαίος κώδικας:** Lib/warnings.py

======================================================================

Τα μηνύματα προειδοποίησης συνήθως εκδίδονται σε καταστάσεις όπου
είναι χρήσιμο να ειδοποιηθεί ο χρήστης για κάποια κατάσταση σε ένα
πρόγραμμα, όπου αυτή η κατάσταση (κανονικά) δεν δικαιολογεί την
πρόκληση εξαίρεσης και τον τερματισμό του προγράμματος. Για
παράδειγμα, μπορεί να θέλετε να εκδώσετε μια προειδοποίηση όταν ένα
πρόγραμμα χρησιμοποιεί ένα απαρχαιωμένο module.

Οι προγραμματιστές Python εκδίδουν προειδοποιήσεις καλώντας τη
συνάρτηση "warn()" που ορίζεται σε αυτό το module. (Οι προγραμματιστές
C χρησιμοποιούν "PyErr_WarnEx()"; δείτε Exception Handling για
λεπτομέρειες).

Τα μηνύματα προειδοποίησης συνήθως γράφονται στο "sys.stderr", αλλά η
διάθεσή τους μπορεί να αλλάξει ευέλικτα, από την αγνόηση όλων των
προειδοποιήσεων έως την μετατροπή τους σε εξαιρέσεις. Η διάθεση των
προειδοποιήσεων μπορεί να διαφέρει με βάση την warning category, το
κείμενο του μηνύματος προειδοποίησης και την πηγή όπου εκδίδεται. Οι
επαναλήψεις μιας συγκεκριμένης προειδοποίησης για την ίδια πηγή
συνήθως καταστέλλονται.

Υπάρχουν δύο στάδια στον έλεγχο προειδοποιήσεων: πρώτον, κάθε φορά που
εκδίδεται μια προειδοποίηση, γίνεται μια εκτίμηση για το αν πρέπει να
εκδοθεί ένα μήνυμα ή όχι. Στη συνέχεια, εάν πρέπει να εκδοθεί ένα
μήνυμα, διαμορφώνεται και εκτυπώνεται χρησιμοποιώντας ένα ρυθμιζόμενο
από τον χρήστη hook.

Η εκτίμηση για το αν θα εκδοθεί ένα μήνυμα προειδοποίησης ελέγχεται
από το warning filter, το οποίο είναι μια ακολουθία κανόνων και
ενεργειών αντιστοίχισης. Οι κανόνες μπορούν να προστεθούν στο φίλτρο
καλώντας "filterwarnings()" και να επαναφερθούν στην προεπιλεγμένη
κατάστασή τους καλώντας "resetwarnings()".

Η εκτύπωση των μηνυμάτων προειδοποίησης γίνεται καλώντας
"showwarning()", η οποία μπορεί να αντικατασταθεί. Η προεπιλεγμένη
υλοποίηση αυτής της συνάρτησης διαμορφώνει το μήνυμα καλώντας
"formatwarning()", η οποία είναι επίσης διαθέσιμη για χρήση από
προσαρμοσμένες υλοποιήσεις.

Δείτε επίσης:

  Η "logging.captureWarnings()" σας επιτρέπει να χειρίζεστε όλες τις
  προειδοποιήσεις με την τυπική υποδομή καταγραφής.


Κατηγορίες Προειδοποίησης
=========================

Υπάρχουν αρκετές ενσωματωμένες εξαιρέσεις που αντιπροσωπεύουν
κατηγορίες προειδοποιήσεων. Αυτή η κατηγοριοποίηση είναι χρήσιμη για
να μπορείτε να φιλτράρετε ομάδες προειδοποιήσεων.

Παρόλο που τεχνικά αυτές είναι built-in exceptions, τεκμηριώνονται
εδώ, επειδή εννοιολογικά ανήκουν στο μηχανισμό προειδοποιήσεων.

Ο κώδικας χρήστη μπορεί να ορίσει επιπλέον κατηγορίες προειδοποιήσεων
υποκατηγοριοποιώντας μία από τις τυπικές κατηγορίες προειδοποιήσεων.
Μια κατηγορία προειδοποίησης πρέπει πάντα να είναι υποκλάση της κλάσης
"Warning".

Οι ακόλουθες κλάσεις κατηγοριών προειδοποιήσεων ορίζονται επί του
παρόντος:

+------------------------------------+-------------------------------------------------+
| Κλάση                              | Περιγραφή                                       |
|====================================|=================================================|
| "Warning"                          | Αυτή είναι η βασική κλάση όλων των κατηγοριών   |
|                                    | προειδοποιήσεων. Είναι μια υποκλάση της         |
|                                    | "Exception".                                    |
+------------------------------------+-------------------------------------------------+
| "UserWarning"                      | Η προεπιλεγμένη κατηγορία για την "warn()".     |
+------------------------------------+-------------------------------------------------+
| "DeprecationWarning"               | Βασική κατηγορία για προειδοποιήσεις σχετικά με |
|                                    | απαρχαιωμένες λειτουργίες όταν αυτές οι         |
|                                    | προειδοποιήσεις προορίζονται για άλλους         |
|                                    | προγραμματιστές Python (αγνοούνται από          |
|                                    | προεπιλογή, εκτός εάν ενεργοποιούνται από       |
|                                    | κώδικα στο "__main__").                         |
+------------------------------------+-------------------------------------------------+
| "SyntaxWarning"                    | Βασική κατηγορία για προειδοποιήσεις σχετικά με |
|                                    | αμφίβολες συντακτικές λειτουργίες (συνήθως      |
|                                    | εκδίδονται κατά τη μεταγλώττιση κώδικα πηγής    |
|                                    | Python και επομένως δεν μπορούν να κατασταλούν  |
|                                    | από τα φίλτρα χρόνου εκτέλεσης)                 |
+------------------------------------+-------------------------------------------------+
| "RuntimeWarning"                   | Βασική κατηγορία για προειδοποιήσεις σχετικά με |
|                                    | αμφίβολες λειτουργίες χρόνου εκτέλεσης.         |
+------------------------------------+-------------------------------------------------+
| "FutureWarning"                    | Βασική κατηγορία για προειδοποιήσεις σχετικά με |
|                                    | απαρχαιωμένες λειτουργίες όταν αυτές οι         |
|                                    | προειδοποιήσεις προορίζονται για τελικούς       |
|                                    | χρήστες εφαρμογών που είναι γραμμένες σε        |
|                                    | Python.                                         |
+------------------------------------+-------------------------------------------------+
| "PendingDeprecationWarning"        | Βασική κατηγορία για προειδοποιήσεις σχετικά με |
|                                    | λειτουργίες που θα απαρχαιωθούν στο μέλλον      |
|                                    | (αγνοούνται από προεπιλογή).                    |
+------------------------------------+-------------------------------------------------+
| "ImportWarning"                    | Βασική κατηγορία για προειδοποιήσεις που        |
|                                    | ενεργοποιούνται κατά τη διαδικασία εισαγωγής    |
|                                    | ενός module (αγνοούνται από προεπιλογή).        |
+------------------------------------+-------------------------------------------------+
| "UnicodeWarning"                   | Βασική κατηγορία για προειδοποιήσεις που        |
|                                    | σχετίζονται με το Unicode.                      |
+------------------------------------+-------------------------------------------------+
| "BytesWarning"                     | Βασική κατηγορία για προειδοποιήσεις που        |
|                                    | σχετίζονται με "bytes" και "bytearray".         |
+------------------------------------+-------------------------------------------------+
| "ResourceWarning"                  | Βασική κατηγορία για προειδοποιήσεις που        |
|                                    | σχετίζονται με τη χρήση πόρων (αγνοούνται από   |
|                                    | προεπιλογή).                                    |
+------------------------------------+-------------------------------------------------+

Άλλαξε στην έκδοση 3.7: Προηγουμένως, οι "DeprecationWarning" και
"FutureWarning" διακρίνονταν με βάση το αν μια λειτουργία αφαιρούνταν
εντελώς ή άλλαζε τη συμπεριφορά της. Τώρα διακρίνονται με βάση το
κοινό στο οποίο απευθύνονται και τον τρόπο με τον οποίο χειρίζονται τα
προεπιλεγμένα φίλτρα προειδοποιήσεων.


Το Φίλτρο Προειδοποιήσεων
=========================

Το φίλτρο προειδοποιήσεων ελέγχει αν οι προειδοποιήσεις αγνοούνται,
εμφανίζονται ή μετατρέπονται σε σφάλματα (προκαλώντας εξαίρεση).

Εννοιολογικά, το φίλτρο προειδοποιήσεων διατηρεί μια διατεταγμένη
λίστα προδιαγραφών φίλτρων. Κάθε συγκεκριμένη προειδοποίηση
αντιστοιχίζεται σε κάθε προδιαγραφή φίλτρου στη λίστα με τη σειρά
μέχρι να βρεθεί μια αντιστοιχία. Το φίλτρο καθορίζει τη διάθεση της
αντιστοιχίας. Κάθε καταχώριση είναι μια πλειάδα της μορφής (*action*,
*message*, *category*, *module*, *lineno*), όπου:

* *action* είναι μία από τις ακόλουθες συμβολοσειρές:

  +-----------------+------------------------------------------------+
  | Τιμή            | Διάθεση                                        |
  |=================|================================================|
  | ""default""     | εκτυπώνει την πρώτη εμφάνιση των ταιριασμένων  |
  |                 | προειδοποιήσεων για κάθε τοποθεσία (module +   |
  |                 | αριθμός γραμμής) όπου εκδίδεται η              |
  |                 | προειδοποίηση                                  |
  +-----------------+------------------------------------------------+
  | ""error""       | μετατρέπει τις ταιριασμένες προειδοποιήσεις σε |
  |                 | εξαιρέσεις                                     |
  +-----------------+------------------------------------------------+
  | ""ignore""      | ποτέ δεν εκτυπώνει τις ταιριασμένες            |
  |                 | προειδοποιήσεις                                |
  +-----------------+------------------------------------------------+
  | ""always""      | πάντα εκτυπώνει τις ταιριασμένες               |
  |                 | προειδοποιήσεις                                |
  +-----------------+------------------------------------------------+
  | ""all""         | ψευδώνυμο για το "always"                      |
  +-----------------+------------------------------------------------+
  | ""module""      | εκτυπώνει την πρώτη εμφάνιση των ταιριασμένων  |
  |                 | προειδοποιήσεων για κάθε module όπου εκδίδεται |
  |                 | η προειδοποίηση (ανεξάρτητα από τον αριθμό     |
  |                 | γραμμής)                                       |
  +-----------------+------------------------------------------------+
  | ""once""        | εκτυπώνει μόνο την πρώτη εμφάνιση των          |
  |                 | ταιριασμένων προειδοποιήσεων, ανεξάρτητα από   |
  |                 | την τοποθεσία                                  |
  +-----------------+------------------------------------------------+

* Το *message* είναι μια συμβολοσειρά που περιέχει μια κανονική
  έκφραση με την οποία πρέπει να ταιριάζει η αρχή του μηνύματος
  προειδοποίησης, ανεξάρτητα από το αν είναι πεζά ή κεφαλαία. Στην
  "-W" και "PYTHONWARNINGS", *message* είναι μια κυριολεκτική
  συμβολοσειρά που πρέπει να περιέχει η αρχή του μηνύματος
  προειδοποίησης (ανεξάρτητα από το αν είναι πεζά ή κεφαλαία),
  αγνοώντας οποιοδήποτε κενό στην αρχή ή στο τέλος του *message*.

* Το *category* είναι μια κλάση (μια υποκλάση της "Warning") της
  οποίας η κατηγορία προειδοποίησης πρέπει να είναι υποκλάση για να
  ταιριάζει.

* Το *module* είναι μια συμβολοσειρά που περιέχει μια κανονική έκφραση
  με την οποία πρέπει να ταιριάζει η αρχή του πλήρως προσδιορισμένου
  ονόματος του module, με διάκριση πεζών-κεφαλαίων. Στην "-W" και
  "PYTHONWARNINGS", *module* είναι μια κυριολεκτική συμβολοσειρά με
  την οποία πρέπει να είναι ίσο το πλήρως προσδιορισμένο όνομα του
  module (με διάκριση πεζών-κεφαλαίων), αγνοώντας οποιοδήποτε κενό
  στην αρχή ή στο τέλος του *module*.

* Το *lineno* είναι ένας ακέραιος αριθμός με τον οποίο πρέπει να
  ταιριάζει ο αριθμός γραμμής όπου συνέβη η προειδοποίηση, ή "0" για
  να ταιριάζουν όλοι οι αριθμοί γραμμών.

Δεδομένου ότι η κλάση "Warning" προέρχεται από την ενσωματωμένη κλάση
"Exception", για να μετατρέψουμε μια προειδοποίηση σε σφάλμα απλώς
προκαλούμε "category(message)".

Εάν αναφερθεί μια προειδοποίηση και δεν ταιριάζει με κανένα
καταχωρημένο φίλτρο, τότε εφαρμόζεται η ενέργεια "default" (εξ ου και
το όνομά της).


Κριτήρια Καταστολής Επαναλαμβανόμενων Προειδοποιήσεων
-----------------------------------------------------

Τα φίλτρα που καταστέλλουν τις επαναλαμβανόμενες προειδοποιήσεις
εφαρμόζουν τα ακόλουθα κριτήρια για να προσδιορίσουν αν μια
προειδοποίηση θεωρείται επανάληψη:

* ""default"": Μια προειδοποίηση θεωρείται επανάληψη μόνο αν τα
  (*message*, *category*, *module*, *lineno*) είναι όλα τα ίδια.

* ""module"": Μια προειδοποίηση θεωρείται επανάληψη αν τα (*message*,
  *category*, *module*) είναι τα ίδια, αγνοώντας τον αριθμό γραμμής.

* ""once"": Μια προειδοποίηση θεωρείται επανάληψη αν τα (*message*,
  *category*) είναι τα ίδια, αγνοώντας το module και τον αριθμό
  γραμμής.


Περιγραφή Φίλτρων Προειδοποιήσεων
---------------------------------

Το φίλτρο προειδοποιήσεων αρχικοποιείται από τις επιλογές "-W" που
δίνονται στη γραμμή εντολών του διερμηνέα Python και από τη μεταβλητή
"PYTHONWARNINGS" περιβάλλοντος. Ο διερμηνέας αποθηκεύει τα
επιχειρήματα για όλες τις παρεχόμενες καταχωρίσεις χωρίς ερμηνεία στο
"sys.warnoptions". Το module "warnings" αναλύει αυτά όταν εισαχθεί για
πρώτη φορά (οι μη έγκυρες επιλογές αγνοούνται, αφού εκτυπώσουν ένα
μήνυμα στο "sys.stderr").

Τα μεμονωμένα φίλτρα προειδοποιήσεων καθορίζονται ως ακολουθία πεδίων
διαχωρισμένων με άνω και κάτω τελεία:

   action:message:category:module:line

Η σημασία του καθενός από αυτά τα πεδία περιγράφεται στο Το Φίλτρο
Προειδοποιήσεων. Όταν απαριθμούνται πολλαπλά φίλτρα σε μία μόνο γραμμή
(όπως για το "PYTHONWARNINGS"), τα μεμονωμένα φίλτρα διαχωρίζονται με
κόμματα και τα φίλτρα που απαριθμούνται αργότερα έχουν προτεραιότητα
έναντι αυτών που απαριθμούνται πριν από αυτά (καθώς εφαρμόζονται από
αριστερά προς τα δεξιά, και τα πιο πρόσφατα εφαρμοσμένα φίλτρα έχουν
προτεραιότητα έναντι των προηγούμενων).

Τα συνήθως χρησιμοποιούμενα φίλτρα προειδοποιήσεων εφαρμόζονται είτε
σε όλες τις προειδοποιήσεις, προειδοποιήσεις σε μια συγκεκριμένη
κατηγορία ή προειδοποιήσεις που προκαλούνται από συγκεκριμένα modules
ή πακέτα. Μερικά παραδείγματα:

   default                      # Εμφάνιση όλων των προειδοποιήσεων (ακόμη και αυτών που αγνοούνται από προεπιλογή)
   ignore                       # Αγνόηση όλων των προειδοποιήσεων
   error                        # Μετατροπή όλων των προειδοποιήσεων σε σφάλματα
   error::ResourceWarning       # Αντιμετώπιση των μηνυμάτων ResourceWarning ως σφάλματα
   default::DeprecationWarning  # Εμφάνιση μηνυμάτων DeprecationWarning
   ignore,default:::mymodule    # Αναφορά μόνο προειδοποιήσεων που ενεργοποιούνται από το "mymodule"
   error:::mymodule             # Μετατροπή προειδοποιήσεων σε σφάλματα στο "mymodule"


Προεπιλεγμένο φίλτρο προειδοποιήσεων
------------------------------------

Από προεπιλογή, η Python εγκαθιστά αρκετά φίλτρα προειδοποιήσεων, τα
οποία μπορούν να αντικατασταθούν από την επιλογή γραμμής εντολών "-W",
τη μεταβλητή περιβάλλοντος "PYTHONWARNINGS" και κλήσεις στη
"filterwarnings()".

Σε κανονικές εκδόσεις, το προεπιλεγμένο φίλτρο προειδοποιήσεων έχει
τις ακόλουθες καταχωρήσεις (με σειρά προτεραιότητας):

   default::DeprecationWarning:__main__
   ignore::DeprecationWarning
   ignore::PendingDeprecationWarning
   ignore::ImportWarning
   ignore::ResourceWarning

Σε μια debug build, η λίστα των προεπιλεγμένων φίλτρων προειδοποιήσεων
είναι κενή.

Άλλαξε στην έκδοση 3.2: "DeprecationWarning" αγνοείται πλέον από
προεπιλογή επιπλέον της "PendingDeprecationWarning".

Άλλαξε στην έκδοση 3.7: "DeprecationWarning" εμφανίζεται ξανά από
προεπιλογή όταν ενεργοποιείται άμεσα από κώδικα στο "__main__".

Άλλαξε στην έκδοση 3.7: "BytesWarning" δεν εμφανίζεται πλέον στη λίστα
προεπιλεγμένων φίλτρων και αντ' αυτού διαμορφώνεται μέσω
"sys.warnoptions" όταν "-b" καθορίζεται δύο φορές.


Αντικατάσταση του προεπιλεγμένου φίλτρου
----------------------------------------

Οι προγραμματιστές εφαρμογών γραμμένων σε Python μπορεί να επιθυμούν
να αποκρύψουν *όλες* τις προειδοποιήσεις επιπέδου Python από τους
χρήστες τους από προεπιλογή, και να τις εμφανίζουν μόνο κατά την
εκτέλεση δοκιμών ή άλλως εργαζόμενοι στην εφαρμογή. Το χαρακτηριστικό
"sys.warnoptions" που χρησιμοποιείται για τη μετάδοση διαμορφώσεων
φίλτρων στον διερμηνέα μπορεί να χρησιμοποιηθεί ως δείκτης για να
υποδείξει αν οι προειδοποιήσεις πρέπει να απενεργοποιηθούν ή όχι:

   import sys

   if not sys.warnoptions:
       import warnings
       warnings.simplefilter("ignore")

Οι προγραμματιστές εργαλείων εκτέλεσης δοκιμών για κώδικα Python
συνιστάται να διασφαλίζουν αντ' αυτού ότι *όλες* οι προειδοποιήσεις
εμφανίζονται από προεπιλογή για τον κώδικα υπό δοκιμή, χρησιμοποιώντας
κώδικα όπως:

   import sys

   if not sys.warnoptions:
       import os, warnings
       warnings.simplefilter("default") # Αλλαγή του φίλτρου σε αυτή τη διαδικασία
       os.environ["PYTHONWARNINGS"] = "default" # Επηρεάζει επίσης τις υποδιαδικασίες

Τέλος, οι προγραμματιστές διαδραστικών κελυφών που εκτελούν κώδικα
χρήστη σε ένα namespace διαφορετικό από το "__main__" συνιστάται να
διασφαλίζουν ότι τα μηνύματα "DeprecationWarning" γίνονται ορατά από
προεπιλογή, χρησιμοποιώντας κώδικα όπως ο παρακάτω (όπου το "user_ns"
είναι το module που χρησιμοποιείται για την εκτέλεση κώδικα που
εισάγεται διαδραστικά):

   import warnings
   warnings.filterwarnings("default", category=DeprecationWarning,
                                      module=user_ns.get("__name__"))


Προσωρινή Καταστολή Προειδοποιήσεων
===================================

Εάν χρησιμοποιείτε κώδικα που γνωρίζετε ότι θα προκαλέσει μια
προειδοποίηση, όπως μια απαρχαιωμένη λειτουργία, αλλά δεν θέλετε να
δείτε την προειδοποίηση (ακόμη και όταν οι προειδοποιήσεις έχουν
ρυθμιστεί ρητά μέσω της γραμμής εντολών), τότε είναι δυνατό να
καταστείλετε την προειδοποίηση χρησιμοποιώντας τον "catch_warnings"
context manager:

   import warnings

   def fxn():
       warnings.warn("deprecated", DeprecationWarning)

   with warnings.catch_warnings():
       warnings.simplefilter("ignore")
       fxn()

Ενώ βρίσκεστε μέσα στον context manager, όλες οι προειδοποιήσεις θα
απλώς θα αγνοούνται. Αυτό σας επιτρέπει να χρησιμοποιείτε γνωστό
απαρχαιωμένο κώδικα χωρίς να χρειάζεται να δείτε την προειδοποίηση,
χωρίς να καταστέλλετε την προειδοποίηση για άλλο κώδικα που μπορεί να
μην είναι ενήμερος για τη χρήση απαρχαιωμένου κώδικα.

   Σημείωση:

     Δείτε το Συγχρονισμένη ασφάλεια των Context Managers για
     λεπτομέρειες σχετικά με την ασφάλεια ταυτόχρονης εκτέλεσης του
     "catch_warnings" context manager όταν χρησιμοποιείται σε
     προγράμματα που χρησιμοποιούν πολλαπλές νηματοειδείς διαδικασίες
     ή ασύγχρονες λειτουργίες.


Δοκιμή Προειδοποιήσεων
======================

Για να δοκιμάσετε προειδοποιήσεις που προκαλούνται από κώδικα,
χρησιμοποιήστε τον "catch_warnings" context manager. Με αυτόν μπορείτε
προσωρινά να μεταβάλλετε το φίλτρο προειδοποιήσεων για να διευκολύνετε
τις δοκιμές σας. Για παράδειγμα, κάντε το ακόλουθο για να καταγράψετε
όλες τις προειδοποιήσεις που έχουν προκληθεί για έλεγχο:

   import warnings

   def fxn():
       warnings.warn("deprecated", DeprecationWarning)

   with warnings.catch_warnings(record=True) as w:
       # Cause all warnings to always be triggered.
       warnings.simplefilter("always")
       # Trigger a warning.
       fxn()
       # Verify some things
       assert len(w) == 1
       assert issubclass(w[-1].category, DeprecationWarning)
       assert "deprecated" in str(w[-1].message)

Μπορείτε επίσης να κάνετε όλες τις προειδοποιήσεις να είναι εξαιρέσεις
χρησιμοποιώντας το "error" αντί για το "always". Ένα πράγμα που πρέπει
να γνωρίζετε είναι ότι εάν μια προειδοποίηση έχει ήδη προκληθεί λόγω
ενός κανόνα "once"/"default", τότε ανεξάρτητα από τα φίλτρα που έχουν
οριστεί, η προειδοποίηση δεν θα εμφανιστεί ξανά εκτός εάν έχει
καθαριστεί το μητρώο προειδοποιήσεων που σχετίζεται με την
προειδοποίηση.

Μόλις ο context manager τερματιστεί, το φίλτρο προειδοποιήσεων
επαναφέρεται στην κατάσταση που βρισκόταν όταν εισήλθε το context.
Αυτό αποτρέπει τις δοκιμές από το να αλλάζουν το φίλτρο
προειδοποιήσεων με απροσδόκητους τρόπους μεταξύ των δοκιμών και να
οδηγούν σε απροσδιόριστα αποτελέσματα δοκιμών.

   Σημείωση:

     Δείτε το Συγχρονισμένη ασφάλεια των Context Managers για
     λεπτομέρειες σχετικά με την ασφάλεια ταυτόχρονης εκτέλεσης του
     "catch_warnings" context manager όταν χρησιμοποιείται σε
     προγράμματα που χρησιμοποιούν πολλαπλές νηματοειδείς διαδικασίες
     ή ασύγχρονες λειτουργίες.

Όταν δοκιμάζετε πολλαπλές λειτουργίες που προκαλούν τον ίδιο τύπο
προειδοποίησης, είναι σημαντικό να τις δοκιμάζετε με τρόπο που να
επιβεβαιώνει ότι κάθε λειτουργία προκαλεί μια νέα προειδοποίηση (π.χ.
ρυθμίστε τις προειδοποιήσεις να προκαλούνται ως εξαιρέσεις και ελέγξτε
ότι οι λειτουργίες προκαλούν εξαιρέσεις, ελέγξτε ότι το μήκος της
λίστας προειδοποιήσεων συνεχίζει να αυξάνεται μετά από κάθε
λειτουργία, ή αλλιώς διαγράψτε τις προηγούμενες καταχωρίσεις από τη
λίστα προειδοποιήσεων πριν από κάθε νέα λειτουργία).


Ενημέρωση κώδικα για νέες εκδόσεις εξαρτήσεων
=============================================

Οι κατηγορίες προειδοποιήσεων που ενδιαφέρουν κυρίως τους
προγραμματιστές Python (αντί για τους τελικούς χρήστες εφαρμογών
γραμμένων σε Python) αγνοούνται από προεπιλογή.

Σημειωτέον, αυτή η λίστα "αγνοείται από προεπιλογή" περιλαμβάνει την
"DeprecationWarning" (για κάθε module εκτός από το "__main__"), που
σημαίνει ότι οι προγραμματιστές πρέπει να βεβαιωθούν ότι δοκιμάζουν
τον κώδικά τους με τις συνήθεις αγνοούμενες προειδοποιήσεις να
γίνονται ορατές, προκειμένου να λαμβάνουν έγκαιρες ειδοποιήσεις για
μελλοντικές αλλαγές που σπάνε το API (είτε στην τυπική βιβλιοθήκη είτε
σε πακέτα τρίτων).

Στην ιδανική περίπτωση, ο κώδικας θα έχει μια κατάλληλη σουίτα
δοκιμών, και το εργαλείο εκτέλεσης δοκιμών θα φροντίζει να ενεργοποιεί
όλες τις προειδοποιήσεις αυτοματοποιημένα κατά την εκτέλεση δοκιμών
(το εργαλείο εκτέλεσης δοκιμών που παρέχεται από το module "unittest"
το κάνει αυτό).

Σε λιγότερο ιδανικές περιπτώσεις, οι εφαρμογές μπορούν να ελεγχθούν
για τη χρήση απαρχαιωμένων διεπαφών περνώντας "-Wd" στον διερμηνέα
Python (αυτή είναι συντομογραφία για "-W default") ή ρυθμίζοντας
"PYTHONWARNINGS=default" στο περιβάλλον. Αυτό ενεργοποιεί την
προεπιλεγμένη διαχείριση για όλες τις προειδοποιήσεις,
συμπεριλαμβανομένων αυτών που αγνοούνται από προεπιλογή. Για να
αλλάξετε ποια ενέργεια λαμβάνεται για τις αντιμετωπιζόμενες
προειδοποιήσεις, μπορείτε να αλλάξετε ποιο όρισμα περνιέται στο "-W"
(π.χ. "-W error"). Δείτε τη σημαία "-W" για περισσότερες λεπτομέρειες
σχετικά με το τι είναι δυνατό.


Διαθέσιμες λειτουργίες
======================

warnings.warn(message, category=None, stacklevel=1, source=None, *, skip_file_prefixes=())

   Εκδίδει μια προειδοποίηση, ή ίσως την αγνοεί ή κάνει raise μια
   εξαίρεση. Το *category* επιχείρημα, αν δοθεί, πρέπει να είναι μια
   warning category class· η προεπιλογή είναι "UserWarning".
   Εναλλακτικά, το *message* μπορεί να είναι μια "Warning" παρουσία,
   στην οποία περίπτωση το *category* θα αγνοηθεί και θα
   χρησιμοποιηθεί το "message.__class__". Σε αυτή την περίπτωση, το
   κείμενο του μηνύματος θα είναι "str(message)". Αυτή η λειτουργία
   προκαλεί μια εξαίρεση αν η συγκεκριμένη προειδοποίηση που εκδίδεται
   μετατραπεί σε σφάλμα από το warnings filter. Το *stacklevel*
   επιχείρημα μπορεί να χρησιμοποιηθεί από wrapper functions γραμμένες
   σε Python, όπως αυτό:

      def deprecated_api(message):
          warnings.warn(message, DeprecationWarning, stacklevel=2)

   Αυτό κάνει την προειδοποίηση να αναφέρεται στον καλούντα της
   "deprecated_api", αντί στην πηγή της ίδιας της "deprecated_api"
   (δεδομένου ότι το δεύτερο θα αναιρούσε τον σκοπό του μηνύματος
   προειδοποίησης).

   Το *skip_file_prefixes* όρισμα λέξεων-κλειδιών μπορεί να
   χρησιμοποιηθεί για να υποδείξει ποια stack frames αγνοούνται κατά
   την καταμέτρηση των επιπέδων στοίβας. Αυτό μπορεί να είναι χρήσιμο
   όταν θέλετε η προειδοποίηση να εμφανίζεται πάντα σε σημεία κλήσης
   εκτός ενός πακέτου όταν ένα σταθερό *stacklevel* δεν ταιριάζει σε
   όλες τις διαδρομές κλήσης ή είναι διαφορετικά δύσκολο να
   διατηρηθεί. Εάν παρέχεται, πρέπει να είναι μια πλειάδα
   συμβολοσειρών. Όταν παρέχονται προθέματα, το stacklevel
   παρακάμπτεται αυτοματοποιημένα ώστε να είναι "max(2, stacklevel)".
   Για να προκαλέσετε την απόδοση μιας προειδοποίησης στον καλούντα
   από εκτός του τρέχοντος πακέτου, μπορείτε να γράψετε:

      # example/lower.py
      _warn_skips = (os.path.dirname(__file__),)

      def one_way(r_luxury_yacht=None, t_wobbler_mangrove=None):
          if r_luxury_yacht:
              warnings.warn("Please migrate to t_wobbler_mangrove=.",
                            skip_file_prefixes=_warn_skips)

      # example/higher.py
      from . import lower

      def another_way(**kw):
          lower.one_way(**kw)

   Αυτό κάνει την προειδοποίηση να αναφέρεται τόσο στα σημεία κλήσης
   της "example.lower.one_way()" όσο και της
   "package.higher.another_way()" μόνο από κώδικα κλήσης που ζει εκτός
   του πακέτου "example".

   *source*, αν παρέχεται, είναι το καταστραμμένο αντικείμενο που
   εξέπεμψε μια "ResourceWarning".

   Άλλαξε στην έκδοση 3.6: Προστέθηκε η παράμετρος *source*.

   Άλλαξε στην έκδοση 3.12: Προστέθηκε το *skip_file_prefixes*.

warnings.warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None)

   Αυτή είναι μια διεπαφή χαμηλού επιπέδου στη λειτουργικότητα της
   "warn()", με την οποία περνιούνται ρητά το μήνυμα, η κατηγορία, το
   όνομα αρχείου και ο αριθμός γραμμής, και προαιρετικά άλλα ορίσματα.
   Το *message* πρέπει να είναι μια συμβολοσειρά και το *category* μια
   υποκλάση του "Warning" ή το *message* μπορεί να είναι μια παρουσία
   "Warning", στην οποία περίπτωση το *category* θα αγνοηθεί.

   *module*, αν παρέχεται, θα πρέπει να είναι το όνομα module. Εάν δεν
   περνιέται module, χρησιμοποιείται το όνομα αρχείου με το ".py"
   αφαιρεμένο.

   *registry*, αν παρέχεται, θα πρέπει να είναι το
   "__warningregistry__" λεξικό του module. Εάν δεν περνιέται μητρώο,
   κάθε προειδοποίηση αντιμετωπίζεται ως η πρώτη εμφάνιση, δηλαδή, οι
   ενέργειες φίλτρου ""default"", ""module"" και ""once""
   αντιμετωπίζονται ως ""always"".

   *module_globals*, αν παρέχεται, θα πρέπει να είναι το παγκόσμιο
   namespace που χρησιμοποιείται από τον κώδικα για τον οποίο
   εκδίδεται η προειδοποίηση. (Αυτό το όρισμα χρησιμοποιείται για την
   υποστήριξη εμφάνισης πηγής για modules που βρίσκονται σε αρχεία zip
   ή άλλες πηγές εισαγωγής εκτός συστήματος αρχείων).

   *source*, αν παρέχεται, είναι το καταστραμμένο αντικείμενο που
   εξέπεμψε μια "ResourceWarning".

   Άλλαξε στην έκδοση 3.6: Προσθήκη της παραμέτρου *source*.

warnings.showwarning(message, category, filename, lineno, file=None, line=None)

   Γράφει μια προειδοποίηση σε ένα αρχείο. Η προεπιλεγμένη υλοποίηση
   καλεί τη "formatwarning(message, category, filename, lineno, line)"
   και γράφει τη συμβολοσειρά αποτέλεσμα στο *file*, που έχει
   προεπιλογή το "sys.stderr". Μπορείτε να αντικαταστήσετε αυτή τη
   λειτουργία με οποιοδήποτε καλέσιμο αναθέτοντας στην
   "warnings.showwarning". Το *line* είναι μια γραμμή πηγαίου κώδικα
   που θα συμπεριληφθεί στο μήνυμα προειδοποίησης· αν το *line* δεν
   παρέχεται, η "showwarning()" θα προσπαθήσει να διαβάσει τη γραμμή
   που καθορίζεται από το *filename* και το *lineno*.

warnings.formatwarning(message, category, filename, lineno, line=None)

   Μορφοποιεί μια προειδοποίηση με τον τυπικό τρόπο. Αυτό επιστρέφει
   μια συμβολοσειρά που μπορεί να περιέχει ενσωματωμένες αλλαγές
   γραμμής και τελειώνει σε αλλαγή γραμμής. Το *line* είναι μια γραμμή
   πηγαίου κώδικα που θα συμπεριληφθεί στο μήνυμα προειδοποίησης· αν
   το *line* δεν παρέχεται, η "formatwarning()" θα προσπαθήσει να
   διαβάσει τη γραμμή που καθορίζεται από το *filename* και το
   *lineno*.

warnings.filterwarnings(action, message='', category=Warning, module='', lineno=0, append=False)

   Εισάγει μια καταχώριση στη λίστα προδιαγραφών φίλτρων
   προειδοποιήσεων. Η καταχώριση εισάγεται στην αρχή από προεπιλογή·
   αν το *append* είναι αληθές, εισάγεται στο τέλος. Αυτό ελέγχει τους
   τύπους των επιχειρημάτων, συντάσσει τις κανονικές εκφράσεις
   *message* και *module*, και τις εισάγει ως πλειάδα στη λίστα
   φίλτρων προειδοποιήσεων. Οι καταχωρίσεις πιο κοντά στην αρχή της
   λίστας παρακάμπτουν τις καταχωρίσεις αργότερα στη λίστα, αν και οι
   δύο ταιριάζουν σε μια συγκεκριμένη προειδοποίηση. Τα παραλειφθέντα
   επιχειρήματα έχουν προεπιλογή μια τιμή που ταιριάζει με τα πάντα.

warnings.simplefilter(action, category=Warning, lineno=0, append=False)

   Εισάγει μια απλή καταχώριση στη λίστα προδιαγραφών φίλτρων
   προειδοποιήσεων. Η σημασία των παραμέτρων της λειτουργίας είναι
   όπως για την "filterwarnings()", αλλά δεν χρειάζονται κανονικές
   εκφράσεις καθώς το φίλτρο που εισάγεται ταιριάζει πάντα με
   οποιοδήποτε μήνυμα σε οποιοδήποτε module αρκεί να ταιριάζουν η
   κατηγορία και ο αριθμός γραμμής.

warnings.resetwarnings()

   Επαναφέρει το φίλτρο προειδοποιήσεων. Αυτό απορρίπτει την επίδραση
   όλων των προηγούμενων κλήσεων στην "filterwarnings()",
   συμπεριλαμβανομένων των επιλογών γραμμής εντολών "-W" και κλήσεων
   στην "simplefilter()".

@warnings.deprecated(msg, *, category=DeprecationWarning, stacklevel=1)

   Διακοσμητής για να υποδείξει ότι μια κλάση, λειτουργία ή
   υπερφόρτωση είναι απαρχαιωμένη.

   Όταν αυτός ο διακοσμητής εφαρμόζεται σε ένα αντικείμενο, μπορεί να
   εκδοθούν προειδοποιήσεις απαρχαιώσεως κατά την εκτέλεση όταν το
   αντικείμενο χρησιμοποιείται. Οι *static type checkers* θα παράγουν
   επίσης μια διάγνωση κατά τη χρήση του απαρχαιωμένου αντικειμένου.

   Χρήση:

      from warnings import deprecated
      from typing import overload

      @deprecated("Use B instead")
      class A:
          pass

      @deprecated("Use g instead")
      def f():
          pass

      @overload
      @deprecated("int support is deprecated")
      def g(x: int) -> int: ...
      @overload
      def g(x: str) -> int: ...

   Η προειδοποίηση που καθορίζεται από το *category* θα εκδοθεί κατά
   την εκτέλεση κατά τη χρήση απαρχαιωμένων αντικειμένων. Για
   λειτουργίες, αυτό συμβαίνει κατά τις κλήσεις· για κλάσεις, κατά την
   διαδικασία δημιουργίας στιγμιοτύπου και τη δημιουργία υποκλάσεων.
   Εάν το *category* είναι "None", δεν εκδίδεται καμία προειδοποίηση
   κατά την εκτέλεση. Το *stacklevel* καθορίζει πού εκδίδεται η
   προειδοποίηση. Εάν είναι "1" (η προεπιλογή), η προειδοποίηση
   εκδίδεται στον άμεσο καλούντα του απαρχαιωμένου αντικειμένου· αν
   είναι υψηλότερο, εκδίδεται πιο ψηλά στη στοίβα. Η συμπεριφορά του
   στατικού ελεγκτή τύπων δεν επηρεάζεται από τα επιχειρήματα
   *category* και *stacklevel*.

   Το μήνυμα απαρχαιώσεως που περνάει στον διακοσμητή αποθηκεύεται στο
   "__deprecated__" χαρακτηριστικό στο διακοσμημένο αντικείμενο. Εάν
   εφαρμόζεται σε μια υπερφόρτωση, ο διακοσμητής πρέπει να είναι μετά
   τον "@~typing.overload" διακοσμητή για να υπάρχει το χαρακτηριστικό
   στην υπερφόρτωση όπως επιστρέφεται από τη "typing.get_overloads()".

   Added in version 3.13: Δείτε το **PEP 702**.


Διαθέσιμοι Context Managers
===========================

class warnings.catch_warnings(*, record=False, module=None, action=None, category=Warning, lineno=0, append=False)

   Ένας context manager που αντιγράφει και, κατά την έξοδο, επαναφέρει
   το φίλτρο προειδοποιήσεων και τη "showwarning()" λειτουργία. Αν το
   *record* επιχείρημα είναι "False" (η προεπιλογή) ο context manager
   επιστρέφει "None" κατά την είσοδο. Αν το *record* είναι "True",
   επιστρέφεται μια λίστα που γεμίζει προοδευτικά με αντικείμενα όπως
   βλέπονται από μια προσαρμοσμένη "showwarning()" λειτουργία (που
   επίσης καταστέλλει την έξοδο στο "sys.stdout"). Κάθε αντικείμενο
   στη λίστα έχει χαρακτηριστικά με τα ίδια ονόματα με τα επιχειρήματα
   της "showwarning()".

   Το όρισμα *module* παίρνει ένα module που θα χρησιμοποιηθεί αντί
   για το module που επιστρέφεται όταν εισάγετε το "warnings" του
   οποίου το φίλτρο θα προστατεύεται. Αυτό το επιχείρημα υπάρχει
   κυρίως για τη δοκιμή του "warnings" module.

   Αν το όρισμα *action* δεν είναι "None", τα υπόλοιπα ορίσματα
   περνιούνται στην "simplefilter()" σαν να είχε κληθεί αμέσως κατά
   την είσοδο στο context.

   Δείτε το Το Φίλτρο Προειδοποιήσεων για τη σημασία των παραμέτρων
   *category* και *lineno*.

   Σημείωση:

     Δείτε το Συγχρονισμένη ασφάλεια των Context Managers για
     λεπτομέρειες σχετικά με την ασφάλεια ταυτόχρονης εκτέλεσης του
     "catch_warnings" context manager όταν χρησιμοποιείται σε
     προγράμματα που χρησιμοποιούν πολλαπλές νηματοειδείς διαδικασίες
     ή ασύγχρονες λειτουργίες.

   Άλλαξε στην έκδοση 3.11: Προστέθηκαν οι παράμετροι *action*,
   *category*, *lineno* και *append*.


Συγχρονισμένη ασφάλεια των Context Managers
===========================================

Η συμπεριφορά του "catch_warnings" context manager εξαρτάται από τη
"sys.flags.context_aware_warnings" σημαία. Αν η σημαία είναι αληθής, ο
context manager συμπεριφέρεται με τρόπο ασφαλή για συγχρονισμό και
αλλιώς όχι. Η ασφάλεια για συγχρονισμό σημαίνει ότι είναι τόσο ασφαλής
για νήματα όσο και ασφαλής για χρήση μέσα σε asyncio coroutines και
εργασίες. Το να είναι ασφαλές για νήματα σημαίνει ότι η συμπεριφορά
είναι προβλέψιμη σε ένα πρόγραμμα με πολλαπλά νήματα. Η σημαία έχει
προεπιλογή να είναι αληθής για builds με ελεύθερα νήματα και ψευδής
αλλιώς.

Αν η "context_aware_warnings" σημαία είναι ψευδής, τότε το
"catch_warnings" θα τροποποιήσει τα παγκόσμια χαρακτηριστικά του
"warnings" module. Αυτό δεν είναι ασφαλές αν χρησιμοποιείται μέσα σε
ένα συγχρονισμένο πρόγραμμα (που χρησιμοποιεί πολλαπλά νήματα ή
χρησιμοποιεί asyncio coroutines). Για παράδειγμα, αν δύο ή περισσότερα
νήματα χρησιμοποιούν την "catch_warnings" κλάση ταυτόχρονα, η
συμπεριφορά είναι απροσδιόριστη.

Αν η σημαία είναι αληθής, το "catch_warnings" δεν θα τροποποιήσει τα
παγκόσμια χαρακτηριστικά και θα χρησιμοποιήσει αντ' αυτού μια
"ContextVar" για να αποθηκεύσει την νεοσυσταθείσα κατάσταση
φιλτραρίσματος προειδοποιήσεων. Μια μεταβλητή context παρέχει
αποθήκευση τοπική στο νήμα και καθιστά τη χρήση της "catch_warnings"
ασφαλή για νήματα.

Η παράμετρος *record* του context handler συμπεριφέρεται επίσης
διαφορετικά ανάλογα με την τιμή της σημαίας. Όταν το *record* είναι
αληθές και η σημαία είναι ψευδής, ο context manager λειτουργεί
αντικαθιστώντας και στη συνέχεια αργότερα επαναφέροντας τη
"showwarning()" λειτουργία του module. Αυτό δεν είναι ασφαλές για
συγχρονισμό.

Όταν το *record* είναι αληθές και η σημαία είναι αληθής, η
"showwarning()" λειτουργία δεν αντικαθίσταται. Αντ' αυτού, η κατάσταση
καταγραφής υποδεικνύεται από ένα εσωτερικό χαρακτηριστικό στη
μεταβλητή context. Σε αυτή την περίπτωση, η "showwarning()" λειτουργία
δεν θα επαναφερθεί κατά την έξοδο από τον context handler.

Η "context_aware_warnings" σημαία μπορεί να οριστεί με την "-X
context_aware_warnings" επιλογή γραμμής εντολών ή με τη μεταβλητή
περιβάλλοντος "PYTHON_CONTEXT_AWARE_WARNINGS".

   Σημείωση:

     Είναι πιθανό ότι οι περισσότερες εφαρμογές που επιθυμούν
     συμπεριφορά ασφαλή για νήματα του warnings module θα θέλουν
     επίσης να ορίσουν τη "thread_inherit_context" σημαία σε αληθές.
     Αυτή η σημαία προκαλεί τα νήματα που δημιουργούνται από την
     "threading.Thread" να ξεκινούν με ένα αντίγραφο των μεταβλητών
     context από το νήμα που τα ξεκινά. Όταν είναι αληθής, το context
     που καθιερώνεται από την "catch_warnings" σε ένα νήμα θα ισχύει
     επίσης για νέα νήματα που ξεκινούν από αυτό. Αν είναι ψευδής, τα
     νέα νήματα θα ξεκινούν με μια κενή μεταβλητή context
     προειδοποιήσεων, που σημαίνει ότι οποιοδήποτε φιλτράρισμα που
     καθιερώθηκε από έναν "catch_warnings" context manager δεν θα
     είναι πλέον ενεργό.

Άλλαξε στην έκδοση 3.14: Προστέθηκε η
"sys.flags.context_aware_warnings" σημαία και η χρήση μιας μεταβλητής
context για την "catch_warnings" αν η σημαία είναι αληθής. Οι
προηγούμενες εκδόσεις της Python συμπεριφέρονταν σαν να ήταν η σημαία
πάντα ορισμένη σε ψευδής.
