Registry / serialization / six
library1.17.0pypypi✓ verified 25d ago

six is a Python 2 and 3 compatibility library that provides utility functions for smoothing over differences between the two Python versions, enabling codebases to run on both without modification. It consists of a single Python file (six.py) covering string types, integer types, standard library moves, metaclass helpers, and more. Current version is 1.17.0, released December 2024. The project is in maintenance mode: Python 2 reached end-of-life in 2020, and in 2024 it is entirely normal for projects to support only Python 3, so new code should not take a dependency on six — it is primarily relevant for maintaining legacy dual-version codebases or as a transitive dependency.

pip install six
INSTALL
IMPORT
SIG · SIX
S
six
serializationpythonv1.17.0
Install
1.7s avg
Import
11ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.17.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.012s · 17.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.008s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

six
import six
Top-level import; all constants, helpers, and the moves virtual module are accessed as attributes of the six module object.
string_types / text_type / binary_type
import six isinstance(value, six.string_types)
isinstance(value, str)
On Python 2 string_types is (basestring,); on Python 3 it is (str,). Using bare str misses unicode on Py2.
six.moves (stdlib remaps)
from six.moves import urllib from six.moves import range from six.moves import configparser
import six.moves
six.moves is a virtual module implemented via a PEP 302 meta path hook inside six.py — there is no moves.py on disk. Direct 'import six.moves' can fail with ModuleNotFoundError in some environments (frozen importers, vendored copies, Python 3.12+). Always use 'from six.moves import <name>'.
with_metaclass
from six import with_metaclass class MyClass(with_metaclass(Meta, Base)): pass
class MyClass(object, metaclass=Meta): pass # Py3-only syntax
Use with_metaclass() or the @add_metaclass decorator only when the codebase must remain Py2-compatible; on Py3-only code use the native metaclass= keyword directly.
add_metaclass
from six import add_metaclass @add_metaclass(Meta) class MyClass(object): pass
Decorator alternative to with_metaclass; produces an equivalent class but applied post-construction.
reraise
from six import reraise reraise(tp, value, tb=None)
Wraps Python 3's 'raise value.with_traceback(tb)' syntax which is a SyntaxError on Python 2.
six.moves.urllib
from six.moves.urllib.parse import urlencode from six.moves.urllib.request import urlopen
from six.moves import urllib urllib.parse.urlencode(…)
six.moves.urllib sub-namespaces (parse, request, response, error, robotparser) must be imported individually; accessing them as attributes of the moves.urllib object is unreliable without first importing the sub-module.

Demonstrate the most common six patterns: version guards, type checks, and stdlib moves.

import six from six.moves import urllib from six.moves.urllib.parse import urlencode # Version guard if six.PY2: print("Running on Python 2") else: print("Running on Python 3") # Cross-version type check value = u"hello" assert isinstance(value, six.text_type) # unicode on Py2, str on Py3 assert isinstance(b"bytes", six.binary_type) # str on Py2, bytes on Py3 assert isinstance(value, six.string_types) # catches both str/unicode on Py2 # Stdlib move: urllib.parse.urlencode works on both versions params = urlencode({"key": "value", "foo": "bar"}) print("Encoded:", params) # Integer types (int + long on Py2, int only on Py3) assert isinstance(42, six.integer_types) # Metaclass compatibility from six import with_metaclass class Meta(type): pass class MyBase(with_metaclass(Meta, object)): pass print("Metaclass:", type(MyBase))
Debug
Known issues
deprecatedsix exists solely to support Python 2/3 dual-compatibility. Python 2 reached end-of-life in January 2020. New projects targeting Python 3 only should not use six — use native Python 3 syntax instead (e.g. 'class Foo(metaclass=Meta)', 'from urllib.parse import urlencode', f-strings, etc.).
fix
Remove six and use Python 3 native equivalents. Tools like 'pyupgrade' and 'ruff --select UP' can automate the removal of six patterns.
affects: all
breakingsix.moves is a virtual module backed by a meta path hook in six.py — there is no moves.py file on disk. In environments with frozen importers, custom loaders, or when a vendored/stale copy of six is present (e.g. inside a third-party library's vendor folder), 'import six.moves' or 'from six.moves import X' can raise ModuleNotFoundError even though 'import six' succeeds.
fix
Always use the current PyPI release (1.17.0). If a dependency vendors its own stale six, override it in sys.modules before importing that library: import six; import sys; sys.modules['lib.vendor.six'] = six
affects: < 1.16.0 (vendored copies); also surfaces on Python 3.12+
gotchaNaming any of your own files 'six.py' or any variable 'six' shadows the installed library and causes confusing ImportError or AttributeError failures downstream.
fix
Rename your file or variable. Check with: python -c "import six; print(six.__file__)" to verify the correct module is being loaded.
affects: all
gotchasix.moves.urllib sub-modules (parse, request, error, response, robotparser) must each be explicitly imported before use. Accessing them as attributes of a previously imported 'urllib' alias from six.moves is not reliably populated until the sub-module is imported.
fix
Use 'from six.moves.urllib.parse import urlencode' etc., rather than 'from six.moves import urllib' followed by 'urllib.parse.urlencode()'.
affects: all
gotchasix.add_metaclass() with __slots__ containing '__weakref__' or '__dict__' was silently broken before 1.8.0 — the decorator re-created the class without preserving slot semantics correctly.
fix
Use six >= 1.8.0. Prefer with_metaclass() over add_metaclass() when __slots__ are involved, or switch to Python 3 native metaclass= syntax.
affects: < 1.8.0
gotchasix.moves aliases follow Python 3 naming conventions with dots replaced by underscores (e.g. html.parser → html_parser, http.client → http_client). Importing the Python 2 module name directly (e.g. 'from six.moves import HTMLParser') will raise ImportError.
fix
Use the underscore-separated Python 3 name: 'from six.moves import html_parser'. Refer to https://six.readthedocs.io/#module-six.moves for the full mapping table.
affects: all
gotchasix.PY34 (a constant that was True when running on Python 3.4+) was present in some versions and relied upon by downstream libraries but is not part of the documented public API. It was removed in later releases, breaking code that imported it directly.
fix
Use 'import sys; sys.version_info >= (3, 4)' for version gating instead of six.PY34.
affects: mixed; PY34 was undocumented and has been removed
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'six'
The `six` library is not installed in the Python environment being used.
fix
pip install six
ImportError: cannot import name 'cStringIO' from 'six.moves'
`six.moves` provides a Python 2/3 compatible `StringIO` class, but does not expose `cStringIO` directly, which was a Python 2-specific module.
fix
from six.moves import StringIO
TypeError: a bytes-like object is required, not 'str'
Code intended for Python 2 (where `str` was bytes) is run in Python 3 (where `str` is Unicode), and a function expects actual bytes.
fix
Use `six.ensure_binary(your_string)` or `six.b(your_string)` to explicitly convert the string to a bytes object for Python 2/3 compatibility.
AttributeError: 'dict' object has no attribute 'iteritems'
In Python 3, dictionary methods like `iteritems()` were removed, replaced by `items()`, which return view objects.
fix
Use `six.iteritems(my_dict)` for Python 2/3 compatible iteration, or `my_dict.items()` if the codebase is Python 3 only.
Upgrade
Version history
1.17.0latest on PyPI · released Dec 4, 2024
Audit
Dependencies

No dependency data recorded yet.

Agent activity
10 hits · last 30 days
node
8
Resources