2

I have a simple piece of Python code, I have a number of enums defined like this:

import sys
from time import sleep
from enum import Enum

class BW(Enum):
    LTE1p4           = 0
    LTE3             = 1
    LTE5             = 2
    LTE10            = 3
    LTE15            = 4
    LTE20            = 5

I want member functions of a class to only accept this Enum type as an argument and the script should not run otherwise, here is my main class:

class Breithorn:
    def __init__(self):
        self.RX_Settings = {}
        self.TX_Settings = {}

    def RX_BW(self,BW):
        self.RX_Settings['BW'] = BW

I want the member function to only accept these kind of calls:

Breithorn.RX_BW(BW.LTE5)

And reject (syntax error) these kind of calls:

Breithorn.RX_BW(44)

Can someone explain how to do this?

Holloway
  • 6,412
  • 1
  • 26
  • 33
  • The existing answers cover the question, but if you just want a syntax warming when using it incorrectly you could look at using python3.5 and its new [type annotations](https://www.python.org/dev/peps/pep-0484/#acceptable-type-hints) which some editors pay attention to. – Holloway Jan 27 '16 at 11:52

3 Answers3

3

You cannot make this a Syntax Error, as that is discovered in the parsing process, at which point the parser has no idea what those symbols are bound to.

You can check the type at runtime in the function and raise an exception.

Python uses duck typing, to discover these kind of problems you need unit or integration tests.

Community
  • 1
  • 1
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • Thanks you, I've tried this and it looks like its working, is this correct? def SetRX_BW(self,bw): if type(bw) != BW: print "Must be BW.xxx format" return self.RX_Settings['BW'] = bw – Eoin O Connell Jan 27 '16 at 11:49
  • @EoinOConnell, raise an exception, don't just print an error. – Holloway Jan 27 '16 at 11:54
1

SyntaxErrors are usually discovered by Python itself, and indicate that Python doesn't know how to parse the program code. For example:

if False;

is a SyntaxError because the line does not end with a colon (:). While you could manually generate one like this:

    def RX_BW(self, BW_val):
        if not isinstance(BW_val, BW):
            raise SyntaxError('%s is not a member of %s' % (BW_val, BW))

That doesn't make much sense. What you probably want is to raise a TypeError as the type of the passed in argument doesn't match the expectation:

    def RX_BW(self, BW_val):
        if not isinstance(BW_val, BW):
            raise TypeError('%s is not a member of %s' % (BW_val, BW))
        self.RX_Settings['BW'] = BW_val

As a side note: notice I the changed the name of the parameter so that we could check against the Enum.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
  • This highlights the issue perfectly - to raise any type of Exception, your python code must be parsed and executing already. – qneill Apr 03 '19 at 13:45
0

The only thing you can do is use assert to check this at runtime. Python is completely dynamic typed, so you cannot throw a syntax error for stuff like that.

class Breithorn:
    def __init__(self):
        self.RX_Settings = {}
        self.TX_Settings = {}

    def RX_BW(self,vat):
        assert isinstance(val,BW), "Breithorn.RX_BW(): input value is not of type BW"
        self.RX_Settings['BW'] = BW

Assert automatically throws an AssertionError if it is not fulfilled.

Dakkaron
  • 5,930
  • 2
  • 36
  • 51