SC006: DeprecatedAPIs
Overview
| Property | Value |
|---|---|
| ID | SC006 |
| Name | DeprecatedAPIs |
| Group | security |
| Severity | WARNING |
Description
Detects usage of deprecated Python standard library modules that have been deprecated in Python 3.9+ or are scheduled for removal in Python 3.12+.
Using deprecated modules poses both compatibility and security risks:
- Code will break when modules are removed in future Python versions
- Deprecated modules often lack security updates
- Alternative modules provide better APIs and performance
What it checks
Deprecated modules detected
| Module | Reason | Replacement |
|---|---|---|
distutils |
Deprecated in Python 3.10, removed in 3.12 | setuptools or build |
imp |
Deprecated since Python 3.4 | importlib |
optparse |
Deprecated since Python 3.2 | argparse |
cgi |
Deprecated in Python 3.11 | urllib.parse |
cgitb |
Deprecated in Python 3.11 | Standard logging |
imghdr |
Deprecated in Python 3.11 | python-magic |
mailcap |
Deprecated in Python 3.11 | mimetypes |
msilib |
Deprecated in Python 3.11 | N/A (Windows-specific) |
nis |
Deprecated in Python 3.11 | N/A (Unix-specific) |
nntplib |
Deprecated in Python 3.11 | Third-party alternatives |
ossaudiodev |
Deprecated in Python 3.11 | N/A (Linux-specific) |
pipes |
Deprecated in Python 3.11 | subprocess |
sndhdr |
Deprecated in Python 3.11 | python-magic |
spwd |
Deprecated in Python 3.11 | N/A (Unix-specific) |
sunau |
Deprecated in Python 3.11 | Third-party audio libraries |
telnetlib |
Deprecated in Python 3.11 | telnetlib3 or asyncio |
uu |
Deprecated in Python 3.11 | base64 |
xdrlib |
Deprecated in Python 3.11 | struct or third-party |
Import patterns detected
Both import styles are detected:
# Direct import
import distutils
# From import
from distutils.core import setup
# Submodule import
import distutils.utilResult states
- PASSED: No deprecated module imports found
- FAILED: Deprecated imports detected with file, line, and module name
- SKIPPED: Unable to parse Python files (syntax errors)
How to fix
Replace distutils with setuptools
# Bad: deprecated distutils
from distutils.core import setup
from distutils.util import strtobool
# Good: use setuptools
from setuptools import setup
# For strtobool, implement your own or use a utility
def strtobool(val: str) -> bool:
return val.lower() in ("y", "yes", "t", "true", "1")Replace imp with importlib
# Bad: deprecated imp
import imp
module = imp.load_source("mymod", "path/to/module.py")
# Good: use importlib
import importlib.util
spec = importlib.util.spec_from_file_location("mymod", "path/to/module.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)Replace optparse with argparse
# Bad: deprecated optparse
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename")
# Good: use argparse
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("-f", "--file", dest="filename")Replace cgi with urllib.parse
# Bad: deprecated cgi
import cgi
form = cgi.FieldStorage()
value = cgi.escape(user_input)
# Good: use urllib.parse and html
from urllib.parse import parse_qs
from html import escape
query = parse_qs(environ.get("QUERY_STRING", ""))
safe_value = escape(user_input)Replace pipes with subprocess
# Bad: deprecated pipes
import pipes
quoted = pipes.quote(user_input)
# Good: use shlex
import shlex
quoted = shlex.quote(user_input)Replace telnetlib with telnetlib3
# Bad: deprecated telnetlib
import telnetlib
tn = telnetlib.Telnet("host", 23)
# Good: use telnetlib3 (async)
import asyncio
import telnetlib3
async def connect():
reader, writer = await telnetlib3.open_connection("host", 23)
# Use reader/writerReplace uu with base64
# Bad: deprecated uu
import uu
uu.encode(in_file, out_file)
# Good: use base64
import base64
with open(in_file, "rb") as f:
encoded = base64.b64encode(f.read())Why WARNING severity?
This check is a WARNING because:
- Deprecated modules still work in current Python versions
- Migration may require significant refactoring
- Some deprecated modules have no direct 1:1 replacements
- Code should be updated before Python version upgrades
Configuration
Skip this check
[tool.pycmdcheck]
skip = ["SC006"]CLI
pycmdcheck --skip SC006Skip entire security group
pycmdcheck --skip-group security