Skip to content

Commit

Permalink
start docs + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lazka committed Aug 14, 2016
1 parent 795c001 commit 223410b
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 62 deletions.
42 changes: 42 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
=================
API Documentation
=================

Package Related
---------------

.. autodata:: senf.version

.. autodata:: senf.version_string


Fsnative Related
----------------

.. autofunction:: senf.fsnative


Documentation Types
-------------------

These types only exist for documentation purposes and represent different
types depending on the Python version and platform used.

.. currentmodule:: senf

.. class:: text()

Represents :obj:`unicode` under Python 2 and :obj:`str` under Python 3.


.. class:: bytes()

Represents :obj:`python:str` under Python 2 and :obj:`python3:bytes` under
Python 3.


.. class:: fsnative_type()

Represents a file name which can be :obj:`python:str` or
:obj:`python:unicode` under Python 2 and :obj:`python3:str` +
``surrogateescape`` under Python 3.
90 changes: 90 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,93 @@
.. image:: images/header.svg
:align: center
:width: 400px

.. toctree::
:hidden:
:titlesonly:

api


What?
-----

**senf** makes filename handing easier by papering over platform differences
in Python 2 and by making it easier to migrate to Python 3 or to have a mixed
Py2/Py3 code base. While at it, it improves the Unicode support for Python 2
under Windows to be on par with Python 3.

It supports Python 2.6, 2.7, 3.3+, works with PyPy, and only depends on the
stdlib.

::

import os
from senf import fsnative, print_

# This supports unicode file names under Py2/3 on Linux/macOS/Window
for entry in os.listdir(fsnative(u"my_dir")):
print_(u"File: ", entry)


Who?
----

You might want to use senf if you

* use Python 2 and want to improve your Windows support
* use Python 2 and want to move to Python 3
* have a library which needs to support both Python 2 and Python 3
* want to print filenames under Python 3


How?
----

The core type it introduces is the ``fsnative`` type which actually is

- `unicode` under Py2 + Windows
- `str` under Py2 on other platforms
- `str` under Py3 + Windows
- `str` + ``surrogateescape`` under Py3 on other platforms [#]_

The type is used for file names, environment variables and process arguments
and senf provides functions so you can tread it as an opaque type and not have
to worry about its content or encoding.

The other nice thing about the ``fsnative`` type is that you can mix it with
ASCII `str` on all Python versions and platforms [#]_ which means minimal
change to your code:

::

os.path.join(some_fsnative_path, "somefile")
some_fsnative_path.endswith(".txt")
some_fsnative_path == "foo.txt"

For non-ASCII text you will need to use the ``fsnative`` wrapper:

::

os.path.join(some_fsnative_path, fsnative(u"Gewürze"))


The provided functions and constants can be split into three categories:

1) Helper functions to work with the fsnative type
2) Alternative implementations of stdlib functions for introducing Unicode
support under Windows + Python 2 (os.environ for example)
3) Wrappers for constants and functions which don't return a fsnative path
by default (os.sep, mkdtemp() with default arguments)

senf does not monkey patch stdlib functions, it just provides alternatives and
wrappers.

----

.. [#] Under Python 3, bytes is also a valid type for paths under Unix.
We decide to not use/allow it as there are stdlib modules, like
pathlib, which don't support bytes and mixing bytes with
str + surrogateescape doesn't work.
.. [#] As long as you don't use "unicode_literals", which we strongly
recommend.
69 changes: 9 additions & 60 deletions senf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,70 +12,13 @@
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

"""
senf makes filename handing easier by papering over platform differences
in Python 2 and by making it easier to migrate to Python 3 or to have a mixed
Py2/Py3 code base. While at it, it improves the Unicode support for Python 2
under Windows.
It supports Python 2.6, 2.7, 3.3+, works with PyPy, and only depends on the
stdlib.
The core type it introduces is the "fsnative" type which actually is
* unicode under Py2 + Windows
* str under Py2 on other platforms
* str under Py3 + Windows
* str+surrogateescape under Py3 on other platforms [0]
The type is used for file names, environment variables and process arguments
and senf provides functions so you can tread it as an opaque type and not have
to worry about its content or encoding.
The other nice thing about the fsnative type is that you can mix it with ASCII
str on all Python versions and platforms [1] which means minimal change to you
code:
::
os.path.join(some_fsnative_path, "somefile")
some_fsnative_path.endswith(".txt")
some_fsnative_path == "foo.txt"
For unicode text you will need to use the `fsnative` wrapper:
::
os.path.join(some_fsnative_path, fsnative(u"Gewürze"))
The provided functions and constants can be split into three categories:
1) Helper functions to work with the fsnative type
2) Alternative implementations of stdlib functions for introducing Unicode
support under Windows + Python 2 (os.environ for example)
3) Wrappers for constants and functions which don't return a fsnative path
by default (os.sep, mkdtemp() with default arguments)
senf does not monkey patch stdlib functions, it just provides alternatives and
wrappers.
----
[0] Under Python 3, bytes is also a valid type for paths under Unix.
We decide to not use/allow it as there are stdlib modules, like pathlib,
which don't support bytes and mixing bytes with str+surrogateescape
doesn't work.
[1] As long as you don't use "unicode_literals", which we strongly recommend.
"""


version = (0, 0, 0)
"""The version tuple (major, minor, micro)"""
"""Tuple[`int`, `int`, `int`]: The version tuple (major, minor, micro)"""


version_string = u".".join(map(str, version))
"""A version string"""
"""`senf.text`: A version string"""


environ = None
Expand All @@ -97,7 +40,13 @@ def expandvars():


def fsnative(text):
"""Takes text and returns a fsnative path object."""
"""Takes text and returns a fsnative path object.
Args:
text (text): The text convert to a path
Returns:
fsnative_type: The new path
"""
pass


Expand Down
27 changes: 27 additions & 0 deletions senf/_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Christoph Reiter
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

import sys


PY2 = sys.version_info[0] == 2
PY3 = not PY2


if PY2:
string_types = (str, unicode)
text_type = unicode
elif PY3:
string_types = (str,)
text_type = str
14 changes: 14 additions & 0 deletions senf/_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Christoph Reiter
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

10 changes: 8 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
# included in all copies or substantial portions of the Software.

import senf
from senf._compat import text_type


def test_foo():
print(senf)
def test_version():
assert isinstance(senf.version, tuple)
assert len(senf.version) == 3


def test_version_string():
assert isinstance(senf.version_string, text_type)

0 comments on commit 223410b

Please sign in to comment.