Skip to content

Commit

Permalink
Eliminate mutable default parameters from methods
Browse files Browse the repository at this point in the history
Fixed
-----

* Eliminate mutable default parameters from methods.

  Because the parameters are passed to observers,
  it is possible for an observer to accidentally
  -- and permanently -- modify a default argument.

  ```python
  observers = [lambda x: x.append("bad")]

  def demo(groups=[]):
      print(groups)
      for observer in observers:
          observer(groups)

  demo()  # []
  demo()  # ["bad"]
  demo()  # ["bad", "bad"]
  ```
  • Loading branch information
kurtmckee committed Oct 14, 2024
1 parent 0186f21 commit 0224bcc
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 9 deletions.
4 changes: 3 additions & 1 deletion src/smartcard/CardConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def doTransmit(self, command, protocol):
transmission."""
return [], 0, 0

def control(self, controlCode, command=[]):
def control(self, controlCode, command=None):
"""Send a control command and buffer. Internally calls
L{doControl()} class method and notify observers upon
command/response events. Subclasses must override the
Expand All @@ -197,6 +197,8 @@ def control(self, controlCode, command=[]):
@param command: list of bytes to transmit
"""
if command is None:
command = []
Observable.setChanged(self)
Observable.notifyObservers(
self, CardConnectionEvent("command", [controlCode, command])
Expand Down
4 changes: 3 additions & 1 deletion src/smartcard/CardConnectionDecorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ def transmit(self, command, protocol=None):
"""call inner component transmit"""
return self.component.transmit(command, protocol)

def control(self, controlCode, command=[]):
def control(self, controlCode, command=None):
"""call inner component control"""
if command is None:
command = []
return self.component.control(controlCode, command)

def getAttrib(self, attribId):
Expand Down
4 changes: 3 additions & 1 deletion src/smartcard/System.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import smartcard.reader.ReaderFactory


def readers(groups=[]):
def readers(groups=None):
"""Returns the list of smartcard readers in groups as
L{smartcard.reader.Reader}.
Expand All @@ -39,6 +39,8 @@ def readers(groups=[]):
>>> r=smartcard.readers(['SCard$DefaultReaders', 'MyReaderGroup'])
"""

if groups is None:
groups = []
return smartcard.reader.ReaderFactory.ReaderFactory.readers(groups)


Expand Down
4 changes: 3 additions & 1 deletion src/smartcard/pcsc/PCSCCardConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def doTransmit(self, command, protocol=None):
data = [(x + 256) % 256 for x in response[:-2]]
return list(data), sw1, sw2

def doControl(self, controlCode, command=[]):
def doControl(self, controlCode, command=None):
"""Transmit a control command to the reader and return response.
@param controlCode: control command
Expand All @@ -294,6 +294,8 @@ def doControl(self, controlCode, command=[]):
@return: response are the response bytes (if any)
"""
if command is None:
command = []
CardConnection.doControl(self, controlCode, command)
hresult, response = SCardControl(self.hcard, controlCode, command)
if hresult != SCARD_S_SUCCESS:
Expand Down
11 changes: 7 additions & 4 deletions src/smartcard/pcsc/PCSCReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@
from smartcard.scard import *


def __PCSCreaders__(hcontext, groups=[]):
def __PCSCreaders__(hcontext, groups=None):
"""Returns the list of PCSC smartcard readers in PCSC group.
If group is not specified, returns the list of all PCSC smartcard readers.
"""

# in case we have a string instead of a list
if isinstance(groups, str):
if groups is None:
groups = []
elif isinstance(groups, str):
groups = [groups]
hresult, readers = SCardListReaders(hcontext, groups)
if hresult != SCARD_S_SUCCESS:
Expand Down Expand Up @@ -104,7 +105,9 @@ def create(readername):
return PCSCReader(readername)

@staticmethod
def readers(groups=[]):
def readers(groups=None):
if groups is None:
groups = []
creaders = []
hcontext = PCSCContext().getContext()

Expand Down
4 changes: 3 additions & 1 deletion src/smartcard/reader/ReaderFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ def createReader(clazz, readername):
return ReaderFactory.factories[clazz].create(readername)

@staticmethod
def readers(groups=[]):
def readers(groups=None):
if groups is None:
groups = []
zreaders = []
for fm in ReaderFactory.factorymethods:
zreaders += fm(groups)
Expand Down

0 comments on commit 0224bcc

Please sign in to comment.