What to use for Python string.find? - python

The documentation for Python 2.7 lists string.find as a deprecated function but does not (unlike atoi and atol) provide an alternative.
I'm coding in 2.7 at the moment so I'm happy to use it but I would like to know:
what is it going to be replaced with?
is that usable in 2.7 (if so, I'll use it now so as to avoid recoding later)?

Almost the entire string module has been moved to the str type as method functions.
Why are you using the string module, when almost everything you need is already part of the string type?
http://docs.python.org/library/stdtypes.html#str.find
The string type -- and it's methods -- is not deprecated. Indeed, it will me morphed to include Unicode in Python 3.

A lot of methods in string have been replaced by the str class. Here is str.find.

Related

Keeping alias types simple in Python documentation?

I'm trying to use the typing module to document my Python package, and I have a number of situations where several different types are allowable for a function parameter. For instance, you can either pass a number, an Envelope object (one of the classes in my package), or a list of numbers from which an Envelope is constructed, or a list of lists of numbers from which an envelope is constructed. So I make an alias type as follows:
NumberOrEnvelope = Union[Sequence[Real], Sequence[Sequence[Real]], Real, Envelope]
Then I write the function:
def example_function(parameter: NumberOrEnvelope):
...
And that looks great to me. However, when I create the documentation using Sphinx, I end up with this horrifically unreadable function signature:
example_function(parameter: Union[Sequence[numbers.Real], Sequence[Sequence[numbers.Real]], numbers.Real, expenvelope.envelope.Envelope])
Same thing also with the hints that pop up when I start to try to use the function in PyCharm.
Is there some way I can have it just leave it as "NumberOrEnvelope". Ideally that would also link in the documentation to a clarification of what "NumberOrEnvelope" is, though even if it didn't it would be way better than what's appearing now.
I had the same issue and used https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_type_aliases, introduced in version 3.3.
In your sphinx conf.py, insert this section. It does not seem to make much sense at the first sight, but does the trick:
autodoc_type_aliases = dict(NumberOrEnvelope='NumberOrEnvelope')
Warning: It only works in modules that start with from __future__ import annotation
Note: If there is a target in the documentation, type references even have a hyperlink to the definition. I have classes, documented elsewhere with autoclass, which are used as types of function parameters, and the docs show the nice names of the types with links.
Support for this appears to be in the works.
See Issue #6518.
That issue can be closed by the recent updates to Pull Request #8007 (under review).
If you want the fix ASAP, you can perhaps try using that build.
EDIT: This doesn't quite work, sadly.
Turns out after a little more searching, I found what I was looking for. Instead of:
NumberOrEnvelope = Union[Sequence[Real], Sequence[Sequence[Real]], Real, Envelope]
I found that you can create your own compound type that does the same thing:
NumberOrEnvelope = TypeVar("NumberOrEnvelope", Sequence[Real], Sequence[Sequence[Real]], Real, Envelope)
This displays in documentation as "NumberOrEnvelope", just as I wanted.

In Python Docstrings, What Does `:obj:` do?

I keep seeing docstrings that have lines that read like this:
param : :obj: str
I can't find a reference to what :obj: stands for or does. It seems like it would denote a str object, but I also see
param : int
which doesn't seem to jibe.
Thanks.
This is Sphinx-related syntax to insert a link to the `str object in the standard Python documentation. See also Python Documentation (:obj:`str`) vs (str).
This is not built-in Python functionality. The author of the code you're looking at is using some external tool to automatically generate documentation. It looks like Sphinx syntax, but I'm not sure.
I assume you're finding these at the docstrings for functions and methods. The are identifying the types of arguments for the automatic documentation generator to correctly document the function/method signature.

Python 2.6: encode() takes no keyword arguments

Hopefully simple question here, I have a value that based on if its unicode, must be encoded. I use the built in string.encode class
code is simple:
if value_t is unicode:
values += (value.encode('utf-8', errors='backslashreplace'), None)
continue
However it returns "encode() takes no keyword arguments"
I am running this in python 2.6, I couldn't find any documentation saying this didn't exist in 2.6
Is there a way for me to make sure it isn't being overwritten by an encode function in a different library? or some sort of solution to it.
It seems like you are able to use string.encode in 2.6 (https://docs.python.org/2.6/howto/unicode.html) so I am not really sure why it wouldn't be working. I am working on one file in a fairly big system, so I am worried this is somehow being overwritten. Either that or some module I need isn't installed..But i am lost
The Python docs for encode explain why you're seeing this issue. Specifically: Changed in version 2.7: Support for keyword arguments added
Since method signatures tend to change from version to version, You should always read the relevant documentation to version you are working with
From str.encode documentation for python 2.6, the method signature is:
str.encode([encoding[, errors]])
There is no errors keyword argument, but the second parameter can be used for the same purpose.

Force str() and the two string literals to create a custom string?

I have a subclass of the 'str' object and I need to apply it to the application domain. Since the application is full of string literal and str() casts it will take a long time to change all of them to the custom string class. I know it is possible to override 'str()' but I'm not sure about string literals.
I know it is not a good idea but the application requires it. Is it possible to do it in Python? And if not, does it require me to modify 'stringlib' which is the C implementation of the 'str' object?
I'm also aware of the fact that modifying the parser to make the application run is considered to be a very bad programming practice. Can this be achieved via an extension rather than a parser modification?
You cannot modify built-in types, e.g. you cannot add new attributes at runtime1:
>>> setattr(str, "hello", lambda: "Hello custom str!")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'str'
I would try to parse all literal strings and replace them with the constructor of your custom string subclass. This is first and foremost:
explicit, which makes it easier for you and other to remember, that this string is different.
Typically i18n libraries have some kind of string literal detection routines for code, which could come in handy during detection. Once these strings are gathered, it's more or less just replace.
1 This is also one reason, python isn't as flexible as ruby. You can't just write test libraries, that monkey patch core classes and add methods like should_equal to every object in the runtime. Here is an entertaining tech talk about these nuances and their consequencies: http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-death.html
I ran into this question because I was trying to do something similar - str.format behavior from python >=2.7 working on python >= 2.4. FormattableString from stringformat (https://github.com/florentx/stringformat) seemed like the right thing, but it was only useful if I could make it work on literals.
Despite most comments, monkey-patching builtins and literals in python does appear to be possible using code I found here: https://gist.github.com/295200. This appears to be written by Armin Ronacher - certainly not by me.
In the end, I was able to do something like this in python 2.6 even though it normally works only in 2.7.
dx = get_class_dict(str)
dx['format'] = lambda x,*args,**kargs: FormattableString(x).format(*args,**kargs)
print "We've monkey patched {}, {}".format('str', 'with multiple parameters')
The example in the link above shows how to add a new method instead of replacing an existing one.
This little exercise prompted me to add the str and unicode monkey patching to the stringformat package, so now you can just do this:
# should work on python down to 2.4
import stringformat
print "[{0:{width}.{precision}s}]".format('hello world', width=8, precision=5)
This can be cloned from here: "https://github.com/igg/stringformat", untill/unless it gets pulled into the "official" stringformat. Ha. Only two hyperlinks for me, so no clicky for you!

assertEquals vs. assertEqual in python

Is there a difference between assertEquals and assertEqual in the python unittest.TestCase?
And if there is not, why are there two functions? Only for convenience?
Actually, in Python 2.6, both assertEqual and assertEquals are convenience aliases to failUnlessEqual. The source declares them thus:
# Synonyms for assertion methods
assertEqual = assertEquals = failUnlessEqual
In Python 3, to your point, failUnlessEqual is explicitly deprecated. assertEquals carries this comment :-)
# Synonyms for assertion methods
# The plurals are undocumented. Keep them that way to discourage use.
# Do not add more. Do not remove.
# Going through a deprecation cycle on these would annoy many people.
So, the upshot appears to be that you should use whatever you like for Python 2.x, but tend toward assertEqual for Python 3.
A 3.3 update: From 26.3.7.1.1. Deprecated aliases :
For historical reasons, some of the TestCase methods had one or more aliases that are now deprecated. The following table lists the correct names along with their deprecated aliases:
Method Name | Deprecated alias | Deprecated alias
--------------+------------------+-----------------
assertEqual() | failUnlessEqual | assertEquals
...
Not just for Python 3.x, since Python 2.7 assertEquals has been deprecated as well:
Method Name | Deprecated alias(es)
_________________________________________________________
assertEqual() | failUnlessEqual, assertEquals
From 25.3.7.1.1. Deprecated aliases
I think this was tension between the "only one obvious way to do it" vs. "alias to make the overall code flow semantically". Personally I found I like to read
failIf(some_condition)
over
assertFalse(some_condition)
but liked
assertEqual(a, b)
over the other two (assertEquals(a, b) bothers my sense of grammar).
The "only one obvious way to do it" has taken precedence going forward.
I don't find any mention of assertEquals in http://docs.python.org/library/unittest.html. However, when I import TestCase and then do a "help(TestCase)", it's listed. I think it's just a synonym for convenience.
I know it doesn't answer the specific question, but if you got here while searching for:
using deprecated method assertEquals()
You just need to change the call to .assertEqual() (remove the 's' in equalS)

Categories