pathlib.Path.relative_to doesn't resolve path - python-3.x

I'm getting a nonsymetric behavior when using Path.relative_to versus os.path.relpath, see examples below. In Correspondence to tools in the os module, I was guided to believe they behave the same.
I'm working with two paths here
C:\Sync\Rmaster_head_\bin
C:\Sync\installed
I'm using Python 3.9.15.
os.path.relpath
>>> import os.path
>>> import pathlib
>>> start = pathlib.Path(r"../../installed")
>>> rel_path = os.path.relpath(pathlib.Path(r"C:/Sync/Rmaster_head_/bin"), start=start)
>>> rel_path
'..\\..\\..\\..\\Sync\\Rmaster_head_\\bin'
>>> start / pathlib.Path(rel_path)
WindowsPath('../../installed/../../../../Sync/Rmaster_head_/bin')
>>> (start / pathlib.Path(rel_path)).resolve()
WindowsPath('C:/Sync/Rmaster_head_/bin')
pathlib.Path.relative_to in both directions
>>> pathlib.Path(r"C:/Sync/Rmaster_head_/bin").relative_to(pathlib.Path(r"../../installed"))
Traceback (most recent call last):
File "C:\Sync\installed\R2023.1.175_install\sys\python3\x86_64-unknown-winnt_i19v19\lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "C:\Sync\installed\R2023.1.175_install\sys\python3\x86_64-unknown-winnt_i19v19\lib\pathlib.py", line 939, in relative_to
raise ValueError("{!r} is not in the subpath of {!r}"
ValueError: 'C:\\Sync\\Rmaster_head_\\bin' is not in the subpath of '..\\..\\installed' OR one path is relative and the other is absolute.
>>> pathlib.Path(r"../../installed").relative_to(pathlib.Path(r"C:/Sync/Rmaster_head_/bin"))
Traceback (most recent call last):
File "C:\Sync\installed\R2023.1.175_install\sys\python3\x86_64-unknown-winnt_i19v19\lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "C:\Sync\installed\R2023.1.175_install\sys\python3\x86_64-unknown-winnt_i19v19\lib\pathlib.py", line 939, in relative_to
raise ValueError("{!r} is not in the subpath of {!r}"
ValueError: '..\\..\\installed' is not in the subpath of 'C:\\Sync\\Rmaster_head_\\bin' OR one path is relative and the other is absolute.
I've noticed that the exception says that one of the paths is relative, but it doesn't also work when using full paths.
>>> path1 = pathlib.Path(r"C:\Sync\Rmaster_head_\bin")
>>> path2 = pathlib.Path(r"C:\Sync\installed\R2023.1.175_install\documentation")
>>> os.path.relpath(path1, start=path2)
'..\\..\\..\\Rmaster_head_\\bin'
>>> os.path.relpath(path2, start=path1)
'..\\..\\installed\\R2023.1.175_install\\documentation'
and path1.relative_to(path2) and path2.relative_to(path1) both fail.
What am I missing?

What you're missing is the notes about these methods in the pathlib documentation:
Below the documentation of relative_to():
NOTE: This function is part of PurePath and works with strings. It does not check or access the underlying file structure.
Although it would still be possible to derive the relative path you're looking for based on strings, apparently the method doesn't do that. The example and the error message are clear about this.
That the function is different than os.path.relpath() is also explicitly mentions at the top of the section you mentioned in your question:
Note: Although os.path.relpath() and PurePath.relative_to() have some overlapping use-cases, their semantics differ enough to warrant not considering them equivalent.
Unfortunately, this (along with some other things) means that pathlib cannot be used to fully replace the os functions. In many cases you'll have to use a mix of both :(

Related

How can I execute python module on Python3 if I encountered print without parants

I want to launch pybrain tests on Python3 but I get error:
Traceback (most recent call last):
File "runtests.py", line 107, in <module>
runner.run(make_test_suite())
File "runtests.py", line 72, in make_test_suite
test_package = __import__(test_package_path, fromlist=module_names)
File "B:\msys64\mingw64\bin\WinPython\Python373\lib\site-packages\pybrain\tests\__init__.py", line 1, in <module>
from helpers import gradientCheck, buildAppropriateDataset, xmlInvariance, \
File "B:\msys64\mingw64\bin\WinPython\Python373\Lib\site-packages\pybrain\tests\helpers.py", line 42
print 'Module has no parameters'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('Module has no parameters')?
I looked helpers.py and found that prints are without parents(as operators, I think it was in Python2).How can I fix that?Can I import some module to
execute with such problem, for example six, but I don t know what it does.

Python 3 unable to find file

My code is listed below. I am just trying to follow along with a tutorial. I am working on eventually applying this to a long list in a csv format. However, I cannot seem to get this simple code to run without throwing an error. The error is the dreaded FileNotFoundError: [WinError 2] The system cannot find the file specified. Any help is greatly appreciated.
import simplekml
import subprocess
import pandas as pd
# names in a list
names = ['test_1',
'test_2',
'test_3']
# lat and longs
latitudes = [47.547921, 48.018745, 47.982146]
longitudes = [-105.125498, -105.325687, -105.6547821]
# piecing together the name, long, and lat values into variable called locations
locations = pd.DataFrame({'names': names,
'longitudes': longitudes,
'latitudes': latitudes})
# creating an instance of the simplekml class
points_kml = simplekml.Kml()
# iterating over the locations variable
for i in locations.itertuples():
points_kml.newpoint(name=i.names, coords=[(i.longitudes, i.latitudes)])
# assigning the variable points_kml_path to where we want to save the file we are creating
points_kml_path = 'c:/Users/rexmo/Documents/points_kml.kml'
points_kml.save(points_kml_path)
# open with Google Earth Pro
#subprocess.call(['open', points_kml_path])
subprocess.run(['open', points_kml_path])
My traceback error is as follows:
runfile('C:/Users/rexmo/Documents/Work/spotter_problems/untitled0.py', wdir='C:/Users/rexmo/Documents/Work/spotter_problems')
Traceback (most recent call last):
File "C:\Users\rexmo\Documents\Work\spotter_problems\untitled0.py", line 31, in <module>
subprocess.run(['open', points_kml_path])
File "C:\Users\rexmo\anaconda3\lib\subprocess.py", line 488, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Users\rexmo\anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 104, in __init__
super(SubprocessPopen, self).__init__(*args, **kwargs)
File "C:\Users\rexmo\anaconda3\lib\subprocess.py", line 800, in __init__
restore_signals, start_new_session)
File "C:\Users\rexmo\anaconda3\lib\subprocess.py", line 1207, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
The file is being written to the directory listed in the code. I can double click the file in the folder and it is opened in Google Earth as expected. I am at a loss as to what to do.
You could try pathlib?
from pathlib import Path
# Replace this line
points_kml_path = 'c:/Users/rexmo/Documents/points_kml.kml'
# With this
points_kml_path = Path.home() / 'Documents' / 'points_kml.kml'
# Edit, I don't know if you might need it as a string
points_kml_path = Path.home() / 'Documents' / 'points_kml.kml'
points_kml_path = str(points_kml_path)
So I have found 2 different ways to get the result that I wanted, which was simply to fire up Google Earth with the points created in the above script. The first and seemingly less complicated is
import os
os.startfile(points_kml_path)
The other seemingly slightly less complicated way is
# Path to Google Earth exe
earth = 'c:\Program Files\Google\Google Earth Pro\client\googleearth.exe'
subprocess.run([earth, points_kml_path])
It seems weird that I would need to explicitly show the full path to the Google Earth executable. If there is another way I would still be interested in hearing about it.

tokenizer has no attribute oov_token

Traceback (most recent call last):
File "dac.py", line 87, in
X_train=load_create_padded_data(X_train=X_train,savetokenizer=False,isPaddingDone=False,maxlen=sequence_length,tokenizer_path='./New_Tokenizer.tkn')
File "/home/dpk/Downloads/DAC/New_Utils.py", line 92, in load_create_padded_data
X_train=tokenizer.texts_to_sequences(X_train)
File "/home/dpk/anaconda2/envs/venv/lib/python2.7/site-packages/keras_preprocessing/text.py", line 278, in texts_to_sequences
return list(self.texts_to_sequences_generator(texts))
File "/home/dpk/anaconda2/envs/venv/lib/python2.7/site-packages/keras_preprocessing/text.py", line 296, in texts_to_sequences_generator
oov_token_index = self.word_index.get(self.oov_token)
AttributeError: 'Tokenizer' object has no attribute 'oov_token'
Probably this one:
You can manually set tokenizer.oov_token = None to fix this.
Pickle is not a reliable way to serialize objects since it assumes
that the underlying Python code/modules you're importing have not
changed. In general, DO NOT use pickled objects with a different
version of the library than what was used at pickling time. That's not
a Keras issue, it's a generic Python/Pickle
https://github.com/keras-team/keras/issues/9099
To fix this I manually set
self.oov_token = None
But not
tokenizer.oov_token = None

Does the object.attribute syntax in python count as a name?

I am wondering if something counts as a name if it is expressed as an object.attribute syntax. The motivation comes from trying to understand this code from Learning Python:
def makeopen(id):
original = builtins.open
def custom(*pargs, **kargs):
print('Custom open call %r' %id, pargs, kargs)
return original(*pargs,*kargs)
builtins.open(custom)
I wanted to map out each name/variable to the scope that they exist in. I am unsure what to do with builtins.open. Is builtins.open a name? In the book the author does state that object.attribute lookup follows completely different rules to plain looksups, which would mean to me that builtins.open is not a name at all, since the execution model docs say that scopes define where names are visible. Since object.attribute syntax is visible in any scope, it doesn't fit into this classification and is not a name.
However the conceptual problem I have is then defining what builtins.open is? It is still a reference to an object, and can be rebound to any other object. In that sense it is a name, even although it doesn't follow scope rules?
Thank you.
builtins.open is just another way to access the global open function:
import builtins
print(open)
# <built-in function open>
print(builtins.open)
# <built-in function open>
print(open == builtins.open)
# True
From the docs:
This module provides direct access to all ‘built-in’ identifiers of
Python; for example, builtins.open is the full name for the built-in
function open()
Regarding the second part of your question, I'm not sure what you mean. (Almost) every "name" in Python can be reassigned to something completely different.
>>> list
<class 'list'>
>>> list = 1
>>> list
1
However, everything under builtins is protected, otherwise some nasty weird behavior was bound to happen in case someone(thing) reassigned its attributes during runtime.
>>> import builtins
>>> builtins.list = 1
Traceback (most recent call last):
File "C:\Program Files\PyCharm 2018.2.1\helpers\pydev\_pydev_comm\server.py", line 34, in handle
self.processor.process(iprot, oprot)
File "C:\Program Files\PyCharm 2018.2.1\helpers\third_party\thriftpy\_shaded_thriftpy\thrift.py", line 266, in process
self.handle_exception(e, result)
File "C:\Program Files\PyCharm 2018.2.1\helpers\third_party\thriftpy\_shaded_thriftpy\thrift.py", line 254, in handle_exception
raise e
File "C:\Program Files\PyCharm 2018.2.1\helpers\third_party\thriftpy\_shaded_thriftpy\thrift.py", line 263, in process
result.success = call()
File "C:\Program Files\PyCharm 2018.2.1\helpers\third_party\thriftpy\_shaded_thriftpy\thrift.py", line 228, in call
return f(*(args.__dict__[k] for k in api_args))
File "C:\Program Files\PyCharm 2018.2.1\helpers\pydev\_pydev_bundle\pydev_console_utils.py", line 217, in getFrame
return pydevd_thrift.frame_vars_to_struct(self.get_namespace(), hidden_ns)
File "C:\Program Files\PyCharm 2018.2.1\helpers\pydev\_pydevd_bundle\pydevd_thrift.py", line 239, in frame_vars_to_struct
keys = dict_keys(frame_f_locals)
File "C:\Program Files\PyCharm 2018.2.1\helpers\pydev\_pydevd_bundle\pydevd_constants.py", line 173, in dict_keys
return list(d.keys())
TypeError: 'int' object is not callable

"unsized object" error trying to remove files from a directory

I'm trying to remove files that have an extension as .pcp from a directory.
If I list the directory I get:
>>> for i in os.listdir(folder):
... if i.endswith(".pcp"):
... print(i)
...
1.pcp
2.pcp
3.pcp
4.pcp
5.pcp
6.pcp
7.pcp
8.pcp
9.pcp
10.pcp
When if I run:
>>> for i in os.listdir(folder):
... if i.endswith(".pcp"):
... os.remove(os.path.join(dir, i))
...
I get the error:
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "C:\Program Files (x86)\IronPython 2.7\Lib\ntpath.py", line 96, in join
TypeError: len() of unsized object
Please can you point out what mistake I'm doing? Help greatly appreciated. Thanks.
it looks like you made a typo when calling
os.remove(os.path.join(dir, i))
You don't get a NameError because dir is a builtin function.
Instead, you may want to call the line below :
os.remove(os.path.join(folder, i))
You can also use the glob module:
import glob
files = glob.glob(os.path.join(folder,'*.pcp'))
for f in files:
os.remove(f)

Resources